Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
@@ -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.
84 changes: 84 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -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.
90 changes: 90 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -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`.