costco-grocery-list/PROJECT_INSTRUCTIONS.md
Nico 77ae5be445
All checks were successful
Build & Deploy Costco Grocery List / build (push) Successful in 1m10s
Build & Deploy Costco Grocery List / verify-images (push) Successful in 3s
Build & Deploy Costco Grocery List / deploy (push) Successful in 11s
Build & Deploy Costco Grocery List / notify (push) Successful in 1s
refactor
2026-02-22 01:27:03 -08:00

8.2 KiB
Raw Permalink Blame History

Project Instructions - Fiddy (External DB)

1) Core expectation

This project connects to an external Postgres instance (on-prem server). Dev and Prod must share the same schema through migrations.

2) Authority & doc order

  1. PROJECT_INSTRUCTIONS.md (this file) is the source of truth.
  2. DEBUGGING_INSTRUCTIONS.md (repo root) is required for bugfix work.
  3. Other instruction files (e.g. .github/copilot-instructions.md) must not conflict with this doc.

If anything conflicts, follow this doc.


3) Non-negotiables (hard rules)

External DB + migrations

  • DATABASE_URL points to on-prem Postgres (NOT a container).
  • Dev/Prod share schema via migrations in: packages/db/migrations.
  • Active migration runbook: docs/DB_MIGRATION_WORKFLOW.md (active set + status commands).

No background jobs

  • No cron/worker jobs. Any fix must work without background tasks.

Security / logging

  • Never log secrets (passwords, tokens, session cookies).
  • Never log receipt bytes.
  • Never log full invite codes - logs/audit store last4 only.

Server-side authorization only

  • Server-side RBAC only. Client checks are UX only and must not be trusted.

4) Non-regression contracts (do not break)

Auth

  • Custom email/password auth.
  • Sessions are DB-backed and stored in table sessions.
  • Session cookies are HttpOnly.

Receipts

  • Receipt images are stored in Postgres bytea table receipts.
  • Entries list endpoints must never return receipt image bytes.
  • Receipt bytes are fetched only via a separate endpoint when inspecting a single item.

Request IDs + audit

  • API must generate a request_id and return it in responses.
  • Audit logs must include request_id.
  • Audit logs must never store full invite codes (store last4 only).

5) Architecture contract (Backend <-> Client <-> Hooks <-> UI)

No-assumptions rule (required)

Before making structural changes, first scan the repo and identify:

  • where app/, components/, features/, hooks/, lib/ live
  • existing API routes and helpers
  • patterns already in use Do not invent files/endpoints/conventions. If something is missing, add it minimally and consistently.

Single mechanism rule (required)

For any cross-component state propagation concern, keep one canonical mechanism only:

  • Context OR custom events OR cache invalidation Do not keep old and new mechanisms in parallel. Remove superseded utilities/imports/files in the same PR.

Layering (hard boundaries)

For every domain (auth, groups, entries, receipts, etc.) follow this flow:

  1. API Route Handlers - app/api/.../route.ts
  • Thin: parse/validate input, call a server service, return JSON.
  • No direct DB queries in route files unless there is no existing server service.
  1. Server Services (DB + authorization) - lib/server/*
  • Own all DB access and authorization helpers.
  • Server-only modules must include: import "server-only";
  • Prefer small domain modules: lib/server/auth.ts, lib/server/groups.ts, lib/server/entries.ts, lib/server/receipts.ts, lib/server/session.ts.
  1. Client API Wrappers - lib/client/*
  • Typed fetch helpers only (no React state).
  • Centralize fetch + error normalization.
  • Always send credentials (cookies) and never trust client-side RBAC.
  1. Hooks (UI-facing API layer) - hooks/use-*.ts
  • Hooks are the primary interface for components/pages to call APIs.
  • Components should not call fetch() directly unless there is a strong reason.

API conventions

  • Prefer consistent JSON error shape:
    • { error: { code: string, message: string }, request_id?: string }
  • Validate inputs at the route boundary (shape/type), authorize in server services.
  • Mirror existing REST style used in the project.

Next.js route params checklist (required)

For app/api/**/[param]/route.ts:

  • Treat context.params as async and await it before reading properties.
    • Example: const { id } = await context.params;

Frontend structure preference

  • Prefer domain-first structure: features/<domain>/... + shared/....
  • Use components/* only for compatibility shims during migrations (remove them after imports are migrated).

Maintainability thresholds (refactor triggers)

  • Component files > 400 lines should be split into container/presentational parts.
  • Hook files > 150 lines should extract helper functions/services.
  • Functions with more than 3 nested branches should be extracted.

6) Decisions / constraints (Group Settings)

  • Add GROUP_OWNER role to group roles; migrate existing groups so the first admin becomes owner.
  • Join policy default is NOT_ACCEPTING. Policies: NOT_ACCEPTING, AUTO_ACCEPT, APPROVAL_REQUIRED.
  • Both owner and admins can approve join requests and manage invite links.
  • Invite links:
    • TTL limited to 1-7 days.
    • Settings are immutable after creation (policy, single-use, etc.).
    • Single-use does not override approval-required.
    • Expired links are retained and can be revived.
    • Single-use links are deleted after successful use.
    • Revive resets used_at and revoked_at, refreshes expires_at, and creates a new audit event.
  • No cron/worker jobs for now (auto ownership transfer and invite rotation are paused).
  • Group role icons must be consistent: owner, admin, member.

7) Do first (vertical slice)

  1. DB migrate command + schema
  2. Register/Login/Logout (custom sessions)
  3. Protected dashboard page
  4. Group create/join + group switcher (approval-based joins + optional join disable)
  5. Entries CRUD (no receipt bytes in list)
  6. Receipt upload/download endpoints
  7. Settings + Reports

8) Definition of done

  • Works via docker-compose.dev.yml with external DB
  • Migrations applied via npm run db:migrate
  • Tests + lint pass
  • RBAC enforced server-side
  • No large files
  • No TypeScript warnings or lint errors in touched files
  • No new cron/worker dependencies unless explicitly approved
  • No orphaned utilities/hooks/contexts after refactors
  • No duplicate mechanisms for the same state flow
  • Text encoding remains clean in user-facing strings/docs

9) Desktop + mobile UX checklist (required)

  • Touch: long-press affordance for item-level actions when no visible button.
  • Mouse: hover affordance on interactive rows/cards.
  • Tap targets remain >= 40px on mobile.
  • Modal overlays must close on outside click/tap.
  • For every frontend action that manipulates database state, show a toast/bubble notification with basic outcome details (action + target + success/failure).
  • Progress-type notifications must reuse the existing upload toaster pattern (UploadQueueContext + UploadToaster) for consistency.
  • Add Playwright UI tests for new UI features and critical flows.

10) Tests (required)

  • Add/update tests for API behavior changes (auth, groups, entries, receipts).
  • Include negative cases where applicable:
    • unauthorized
    • not-a-member
    • invalid input

11) Agent Response Legend (required)

Use emoji/icons in agent progress and final responses so status is obvious at a glance.

Legend:

  • 🔄 in progress
  • completed
  • 🧪 test/lint/verification result
  • 📄 documentation update
  • 🗄️ database or migration change
  • 🚀 deploy/release step
  • ⚠️ risk, blocker, or manual operator action needed
  • failed command or unsuccessful attempt
  • informational context
  • 🧭 recommendation or next-step option

Usage rules:

  • Include at least one status icon in each substantive agent response.
  • Use one icon per bullet/line; avoid icon spam.
  • Keep icon meaning consistent with this legend.

12) Commit Discipline (required)

  • Commit in small, logical slices (no broad mixed-purpose commits).
  • Each commit must:
    • follow Conventional Commits style (feat:, fix:, docs:, refactor:, test:, chore:)
    • include only related files for that slice
    • exclude secrets, credentials, and generated noise
  • Run verification before commit when applicable (lint/tests/build or targeted checks for touched areas).
  • Prefer frequent checkpoint commits during agentic work rather than one large end-state commit.
  • If a rule or contract changes, commit docs first (or in the same atomic slice as enforcing code).