diff --git a/API.md b/API.md new file mode 100644 index 0000000..6632076 --- /dev/null +++ b/API.md @@ -0,0 +1,96 @@ +# API Reference: CookieVoting + +This document outlines the core data models and server-side functions used in the CookieVoting application. + +## 1. Firestore Schema + +The application uses Cloud Firestore as its primary NoSQL database. + +### `events/{eventId}` + +Stores the configuration and metadata for a voting event. + +- **id**: `string` (unique event identifier) +- **name**: `string` (Event display name) +- **adminCode**: `string` (Secret code for joining as an admin) +- **status**: `enum` ('voting', 'completed') +- **resultsAvailableTime**: `timestamp` (When results become visible to voters) + +### `events/{eventId}/categories/{categoryId}` + +Represents a "Plate" or grouping of cookies within an event. + +- **id**: `string` (unique category identifier) +- **name**: `string` (Category name) +- **imageUrl**: `string` (URL to the full tray image) +- **cookies**: `array` of objects + - **id**: `string` (unique cookie identifier) + - **number**: `number` (sequential index within the category) + - **makerName**: `string` (optional baker name) + - **imageUrl**: `string` (URL to cropped cookie image) + +### `events/{eventId}/votes/{voteId}` + +Stores individual user votes. This collection is write-heavy and publicly accessible (anonymous auth). + +- **userId**: `string` (Firebase Auth UID) +- **votes**: `map` (categoryId -> cookieNumber) +- **timestamp**: `timestamp` (When the vote was cast) + +### `cookie_batches/{batchId}` + +Tracks the state of the automated cookie detection pipeline. Not directly exposed to voters. + +- **status**: `enum` ('uploading', 'processing', 'review_required', 'ready', 'error') +- **originalImageRef**: `string` (Storage path: `uploads/{batchId}/original.jpg`) +- **detectedObjects**: `array` of objects (Google Cloud Vision API output) + - **normalizedVertices**: `array` of {x, y} coordinates (0-1 range) + - **confidence**: `number` (0-1 score) +- **paddingPercentage**: `number` (Default: 0.1) + +--- + +## 2. Cloud Functions + +These functions are deployed to Firebase Functions (`functions/src/index.ts`). + +### Storage Triggers + +#### `processCookieImage` +- **Trigger**: `google.storage.object.finalize` +- **Path**: `uploads/{batchId}/original.jpg` +- **Description**: + 1. Detects upload of a new tray image. + 2. Calls **Google Cloud Vision API** (Object Localization). + 3. Updates `cookie_batches/{batchId}` with `detectedObjects`. + 4. Sets status to `review_required`. + +### Callable Functions (HTTPS) + +#### `confirmCookieCrops` +- **Auth Required**: Yes (`admin: true`) +- **Input**: `{ batchId: string, crops: Array<{ x, y, width, height }> }` +- **Description**: + 1. Admins confirm the final crop coordinates. + 2. Uses `sharp` to physically crop the high-res original image. + 3. Uploads cropped images to `processed_cookies/{batchId}/{cookieId}.jpg`. + 4. Updates the target `Category` with new cookie entries. + 5. Sets batch status to `ready`. + +#### `addAdminRole` +- **Auth Required**: Yes (`admin: true`) +- **Input**: `{ email: string }` +- **Description**: Grants the `admin` custom claim to a user by email. + +#### `removeAdminRole` +- **Auth Required**: Yes (`admin: true`) +- **Input**: `{ email: string }` OR `{ uid: string }` +- **Description**: Revokes the `admin` custom claim. + +--- + +## 3. Storage Structure + +- **`uploads/{batchId}/original.jpg`**: Raw, high-res images uploaded by admins. Triggers detection. +- **`processed_cookies/{batchId}/{cookieId}.jpg`**: Final, cropped cookie images used in the voting UI. +- **`shared/cookies/`**: Reusable cookie images. diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 0000000..5d43f3a --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,84 @@ +# Architecture: CookieVoting + +## 1. System Overview + +**CookieVoting** is a hybrid application combining a modern React 19 frontend with a serverless Firebase backend. It is designed to facilitate cookie competitions by automating the detection and categorization of cookies from tray photos. + +### Core Stack +- **Frontend**: React 19, TypeScript, Vite, Tailwind CSS (v4). +- **Backend**: Firebase (Firestore, Storage, Functions, Auth). +- **AI/ML**: Google Cloud Vision API (Production) / Google Gemini (Experimental/Local). +- **Testing**: Vitest (Unit/Integration), Playwright (E2E). + +--- + +## 2. The Cookie Detection Pipeline + +The core feature of the application is the "Detect-Review-Crop" workflow, which automates the extraction of individual cookie images from a single group photo. + +### detection-pipeline.mermaid +```mermaid +sequenceDiagram + participant Admin as Admin UI + participant Storage as Firebase Storage + participant Function as Cloud Function (processCookieImage) + participant Vision as Google Cloud Vision API + participant Firestore as Firestore (cookie_batches) + participant Sharp as Cloud Function (confirmCookieCrops) + + Note over Admin, Storage: 1. Upload Phase + Admin->>Storage: Upload original.jpg to uploads/{batchId}/ + + Note over Storage, Firestore: 2. Detection Phase + Storage->>Function: onObjectFinalized trigger + Function->>Vision: Send image for Object Localization + Vision-->>Function: Return bounding boxes + Function->>Firestore: Create/Update cookie_batches/{batchId} (status: review_required) + + Note over Admin, Firestore: 3. Review Phase + Admin->>Firestore: Read detected objects + Admin->>Admin: Adjust/Add/Delete bounding boxes + Admin->>Function: Call confirmCookieCrops(batchId, finalCrops) + + Note over Sharp, Storage: 4. Cropping Phase + Function->>Sharp: Download original & Crop images + Sharp->>Storage: Save to processed_cookies/{batchId}/{cookieId}.jpg + Sharp->>Firestore: Update Category with new cookies + Sharp->>Firestore: Update batch status to 'ready' +``` + +### Critical Implementation Details + +1. **Event-Driven Architecture**: The upload of an image to a specific path (`uploads/{batchId}/original.jpg`) triggers the entire pipeline. +2. **State Management**: The state of the pipeline is tracked in the `cookie_batches` collection in Firestore. + - `uploading` -> `processing` -> `review_required` -> `ready` (or `error`). +3. **Hybrid AI**: + - **Production**: Uses **Google Cloud Vision API** (Object Localization) via Cloud Functions. This is the stable, deployed path. + - **Experimental**: A local script (`scripts/detect-all-images.js`) uses **Google Gemini** for detection. This is *not* part of the production pipeline and is used for research/batch processing. + +--- + +## 3. Frontend Architecture + +The frontend is a Single Page Application (SPA) built with Vite. + +- **State Management**: Uses `zustand` for global store management (e.g., `useEventStore`, `useAuthStore`). +- **Routing**: `react-router-dom` handles navigation between the Admin Dashboard, Voting Wizard, and Results. +- **Styling**: `tailwindcss` v4 with a mobile-first approach. +- **Real-time Updates**: Relies on Firestore real-time listeners (`onSnapshot`) for live voting results and batch processing status. + +--- + +## 4. Backend Architecture + +The backend logic is entirely serverless, residing in `functions/src/index.ts`. + +### Security Model +- **Authentication**: Firebase Auth (Anonymous for Voters, Email/Password for Admins). +- **Authorization**: Custom Claims (`admin: true`) protect sensitive operations. +- **Validation**: Firestore Security Rules (`firestore.rules`) enforce data integrity and access control at the database level. + +### Key Cloud Functions +1. `processCookieImage`: Triggered by Storage. Handles AI detection. +2. `confirmCookieCrops`: Callable. Handles high-fidelity image cropping using `sharp`. +3. `addAdminRole` / `removeAdminRole`: Callable. Manages RBAC. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..30d585d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,90 @@ +# Contributing to CookieVoting + +Thank you for your interest in contributing! This document outlines the development workflow, testing standards, and documentation guidelines. + +## 1. Getting Started + +### Prerequisites +- Node.js 20+ +- Firebase CLI (`npm install -g firebase-tools`) +- Docker (for Playwright testing, optional but recommended) + +### Setup +Run the setup script to install dependencies and configure the environment: + +```bash +bash scripts/setup.sh +``` + +This will: +- Install project dependencies (`npm install`). +- Install Cloud Functions dependencies (`npm install --prefix functions`). +- Verify your environment setup. + +## 2. Development Workflow + +### Verification (Single Source of Truth) +We use a unified verification script to ensure code quality. **Always run this before pushing changes.** + +```bash +npm run verify +``` + +This command runs: +- **Linting**: ESLint + Prettier. +- **Type Checking**: TypeScript (`tsc`). +- **Unit Tests**: Vitest. +- **Build**: Vite build. + +To skip the build step for faster feedback during local dev: +```bash +npm run verify -- --skip-build +``` + +### Local Emulators +To develop locally without affecting production data: + +```bash +npm run emulators:start +``` +This spins up Firestore, Auth, Storage, and Functions emulators. + +## 3. Testing Strategy + +We employ a "Testing Pyramid" approach: + +### Unit & Integration Testing (`vitest`) +Located in `src/tests/` and `functions/src/tests/`. +- Run all unit tests: `npm run test` +- Run integration tests: `npm run test:integration` + +### End-to-End Testing (`playwright`) +Located in `tests/e2e/`. These tests verify the full user journey. +- Run E2E tests: `npm run test:e2e` +- Run with UI: `npm run test:e2e:ui` + +**Note**: Playwright tests require the local dev server and emulators to be running. + +## 4. Documentation Standards + +We follow a strict "Persona-Based" documentation model to prevent drift. + +### 📜 Scribe (Technical Librarian) +- **Responsibility**: Maintains `ARCHITECTURE.md`, `API.md`, `CONTRIBUTING.md`. +- **Scope**: Deep technical dives, schema definitions, system diagrams. +- **Rule**: Never edits `README.md`. + +### 🌟 Showcase (Product Owner) +- **Responsibility**: Maintains `README.md`. +- **Scope**: High-level product overview, features, "hook", and quick start. +- **Rule**: Only links to Scribe's documents; doesn't duplicate technical details. + +## 5. Agent Rules + +If you are an AI agent or using AI tools, ensure you are following the latest project rules. +The rules are located in `ai/rules/` and synchronized to IDE-specific files via: + +```bash +bash scripts/sync-agent-rules.sh +``` +This script is automatically run before `npm run dev` and `npm run build`.