For LLM: REQUIRED SUB-SKILL: Use @.github/prompts/execute-plan.prompt.md to implement this plan task-by-task.
Goal: Deliver a production-quality adult-only logging vertical slice: onboarding, manual food and water entries, asynchronous mock photo analysis, daily totals, history, and offline-safe synchronization.
Architecture: Keep domain behavior behind small interfaces in shared contracts and API application modules. The mobile app owns drafts and an offline command queue; the API owns identity, authorization, persistence, quotas, and accepted records. External systems remain replaceable adapters, with deterministic M0 mocks used until approved credentials exist.
Tech Stack: React Native/Expo Router, React Native Paper, TanStack Query, Zustand, React Hook Form, Zod, NestJS, REST/OpenAPI, Prisma/PostgreSQL, LocalStack S3/SQS, Vitest, React Native Testing Library, Maestro.
M1 includes:
M1 excludes:
Files:
packages/contracts/src/adult-profile.tspackages/contracts/src/diary.tspackages/contracts/src/sync.tspackages/contracts/src/adult-profile.test.tspackages/contracts/src/diary.test.tspackages/contracts/src/sync.test.tspackages/contracts/src/index.tsStep 1: Write failing tests
Cover:
ageVerified: true and a verification timestamp.manual, photo_estimate, or planned.provisional, confirmed, or needs_review.Step 2: Verify RED
corepack pnpm --filter @platepilot/contracts test
Expected: tests fail because the M1 schemas do not exist.
Step 3: Implement minimal contracts
Use strict Zod objects and inferred TypeScript types. Keep Prisma, HTTP, Expo, and provider types out of this package.
Step 4: Verify GREEN
corepack pnpm --filter @platepilot/contracts test
corepack pnpm --filter @platepilot/contracts typecheck
Expected: all contract tests pass.
Step 5: Commit checkpoint
Only if commit authorization is provided:
git add packages/contracts
git commit -m "feat(contracts): define adult diary and sync models"
Files:
apps/api/prisma/schema.prismaapps/api/prisma/migrations/<timestamp>_m1_adult_diary/migration.sqlapps/api/src/adult-profile/adult-profile.repository.tsapps/api/src/adult-profile/prisma-adult-profile.repository.tsapps/api/src/adult-profile/adult-profile.repository.test.tsapps/api/src/diary/diary.repository.tsapps/api/src/diary/prisma-diary.repository.tsapps/api/src/diary/diary.repository.test.tsStep 1: Write failing repository tests
Test through repository interfaces:
Step 2: Verify RED
Start PostgreSQL and run the dedicated integration target:
docker compose up -d postgres
corepack pnpm --filter @platepilot/api test:integration
Expected: tests fail because repositories and diary tables are absent.
Step 3: Implement the minimal schema and adapters
Add adult-scoped meal, food-item, water, and client-operation tables. Use internal UUID primary keys and prefixed public IDs. Add unique and foreign-key constraints for subject, public ID, idempotency key, and ownership.
Step 4: Generate and inspect the migration
corepack pnpm --filter @platepilot/api exec prisma migrate dev --name m1_adult_diary
corepack pnpm prisma:generate
Verify that the migration contains no child/dependent fields and no public photo URLs.
Step 5: Verify GREEN
corepack pnpm --filter @platepilot/api test:integration
corepack pnpm prisma:validate
Step 6: Commit checkpoint
Only with authorization:
git add apps/api/prisma apps/api/src/adult-profile apps/api/src/diary
git commit -m "feat(api): persist private adult diary records"
Files:
apps/api/src/auth/current-adult.tsapps/api/src/auth/mock-auth.guard.tsapps/api/src/auth/auth.module.tsapps/api/src/adult-profile/adult-profile.service.tsapps/api/src/adult-profile/adult-profile.controller.tsapps/api/src/adult-profile/adult-profile.service.test.tsapps/api/src/adult-profile/adult-profile.controller.test.tsapps/api/src/app.module.tsStep 1: Write failing tests
Cover:
Step 2: Verify RED
corepack pnpm --filter @platepilot/api test -- src/auth src/adult-profile
Step 3: Implement minimal behavior
Use the existing IdentityProvider seam and mock adapter. Keep authorization in an API-owned module rather than controllers.
Step 4: Verify GREEN
corepack pnpm --filter @platepilot/api test
corepack pnpm --filter @platepilot/api typecheck
Step 5: Commit checkpoint
Only with authorization:
git add apps/api/src/auth apps/api/src/adult-profile apps/api/src/app.module.ts
git commit -m "feat(api): add adult onboarding boundary"
Files:
apps/api/src/diary/diary.service.tsapps/api/src/diary/diary.controller.tsapps/api/src/diary/diary.module.tsapps/api/src/diary/diary.service.test.tsapps/api/src/diary/diary.controller.test.tsapps/api/src/app.module.tsStep 1: Write failing tests
Cover:
Step 2: Verify RED
corepack pnpm --filter @platepilot/api test -- src/diary
Step 3: Implement minimal behavior
Controllers validate transport input and delegate. The diary service owns authorization, idempotency, optimistic concurrency, totals, and repository orchestration.
Step 4: Verify GREEN
corepack pnpm --filter @platepilot/api test
corepack pnpm --filter @platepilot/api test:integration
Step 5: Commit checkpoint
Only with authorization:
git add apps/api/src/diary packages/contracts
git commit -m "feat(api): add manual meal and water logging"
Files:
apps/api/src/photo/photo-storage.tsapps/api/src/photo/localstack-photo-storage.tsapps/api/src/photo/photo.controller.tsapps/api/src/photo/photo.service.tsapps/api/src/photo/photo.module.tsapps/api/src/photo/photo.service.test.tsapps/api/src/photo/photo.controller.test.tsapps/api/src/meal-analysis/meal-analysis.service.tsapps/api/src/app.module.tsStep 1: Write failing tests
Cover:
Step 2: Verify RED
corepack pnpm --filter @platepilot/api test -- src/photo src/meal-analysis
Step 3: Implement the deep module
Expose a small PhotoMealService interface. Keep storage, queue, provider, persistence, quota, and retention details behind it. Use LocalStack adapters and deterministic provider mocks only.
Step 4: Verify GREEN
docker compose up -d
corepack pnpm --filter @platepilot/api test
corepack pnpm --filter @platepilot/api test:integration
docker compose down
Step 5: Commit checkpoint
Only with authorization:
git add apps/api/src/photo apps/api/src/meal-analysis apps/api/prisma packages
git commit -m "feat(api): add asynchronous mock photo logging"
Files:
packages/api-client/apps/mobile/src/data/api-client.tsapps/mobile/src/data/offline-store.tsapps/mobile/src/data/sync-engine.tsapps/mobile/src/data/sync-engine.test.tspnpm-workspace.yamlapps/mobile/package.jsonStep 1: Write failing tests
Cover:
Step 2: Verify RED
corepack pnpm --filter @platepilot/mobile test -- src/data/sync-engine.test.ts
Step 3: Implement minimal offline infrastructure
Use an encrypted SQLite-backed store on native builds and a test adapter for Vitest. Keep access tokens in secure storage, never in Zustand or general query persistence. Generate the REST client from OpenAPI rather than hand-copying endpoint types.
Step 4: Verify GREEN
corepack pnpm --filter @platepilot/mobile test
corepack pnpm --filter @platepilot/mobile typecheck
Step 5: Commit checkpoint
Only with authorization:
git add packages/api-client apps/mobile/src/data apps/mobile/package.json
git commit -m "feat(mobile): add offline command synchronization"
Files:
apps/mobile/app/onboarding/apps/mobile/app/log/apps/mobile/app/history/apps/mobile/src/components/apps/mobile/src/features/diary/apps/mobile/src/features/photo/apps/mobile/src/features/water/apps/mobile/src/**/*.test.tsxapps/mobile/app/index.tsxapps/mobile/app/_layout.tsxStep 1: Write failing component tests
Cover:
ui_json migration with strict fail-closed validation and immutable
idempotency equivalence.originals/ objects: sanitize into
processing/, transactionally repoint the job, and delete the exact legacy source version.Step 2: Verify RED
corepack pnpm --filter @platepilot/mobile test
Step 3: Implement the approved Figma flow
Build from the reviewed design specification and shared tokens. Do not add new product scope while translating designs into code.
Step 4: Verify GREEN
corepack pnpm --filter @platepilot/mobile test
corepack pnpm --filter @platepilot/mobile typecheck
corepack pnpm expo:check
Step 5: Commit checkpoint
Only with authorization:
git add apps/mobile packages/design-tokens
git commit -m "feat(mobile): deliver adult diary experience"
Files:
apps/api/src/audit/audit-event.tsapps/api/src/audit/audit.service.tsapps/api/src/audit/audit.service.test.tsapps/api/src/telemetry/telemetry.module.tsdocs/threat-model.mdStep 1: Write failing tests
Verify:
Step 2: Verify RED
corepack pnpm --filter @platepilot/api test -- src/audit src/telemetry
Step 3: Implement minimal signals
Keep observability behind a small interface with an in-memory test adapter. Do not connect Sentry or AWS telemetry in M1 local mode.
Step 4: Verify GREEN
corepack pnpm --filter @platepilot/api test
corepack pnpm --filter @platepilot/api typecheck
Step 5: Commit checkpoint
Only with authorization:
git add apps/api/src/audit apps/api/src/telemetry docs/threat-model.md
git commit -m "feat(api): add privacy-safe audit signals"
Files:
apps/mobile/.maestro/onboarding-and-manual-log.yamlapps/mobile/.maestro/photo-analysis-recovery.yamlapps/mobile/.maestro/offline-sync-conflict.yamldocs/runbooks/m1-local-demo.mdStep 1: Define failing acceptance flows
The flows must prove:
Step 2: Verify RED
Run the API/mobile stack and execute the focused Maestro flows. Expected: fail before screens and fixtures exist.
Step 3: Implement only missing acceptance wiring
Do not add planning, households, subscriptions, or real providers.
Step 4: Verify GREEN
Run:
corepack pnpm check
corepack pnpm coverage
corepack pnpm compose:config
corepack pnpm prisma:validate
corepack pnpm expo:check
corepack pnpm cdk:synth
Then run the M1 integration and Maestro suites with PostgreSQL and LocalStack healthy.
Step 5: Commit checkpoint
Only with authorization:
git add .
git commit -m "feat: complete M1 adult logging vertical slice"