fiddy/.github/copilot-instructions.md
2026-02-11 23:45:15 -08:00

5.4 KiB
Raw Blame History

Copilot Instructions — Fiddy (External DB)

Source of truth

  • Always consult PROJECT_INSTRUCTIONS.md at the repo root.
  • If any guidance conflicts, PROJECT_INSTRUCTIONS.md takes precedence.
  • Keep this file focused on architecture/stack; keep checklists and project workflow rules in PROJECT_INSTRUCTIONS.md.
  • When asked to fix bugs, follow DEBUGGING_INSTRUCTIONS.md at the repo root.

Stack

  • Monorepo (npm workspaces)
  • Next.js (App Router) + TypeScript + Tailwind
  • External Postgres (on-prem server) via node-postgres (pg). No ORM.
  • Docker Compose dev/prod
  • Gitea + act-runner CI/CD

Environment

  • Dev and Prod must use the same schema/migrations (packages/db/migrations).
  • DATABASE_URL points to the external DB server (NOT a container).

Auth

  • Custom email/password auth.
  • Use HttpOnly session cookies backed by DB table sessions.
  • NEVER trust client-side RBAC checks.

Receipts

  • Store receipt images in Postgres bytea table receipts.
  • Entries list endpoints must not return image bytes.
  • Image bytes only fetched by separate endpoint when inspecting a single item.

UI

  • Dark mode, minimal, mobile-first.
  • Dodger Blue accent (#1E90FF).
  • Top navbar: left nav dropdown, middle group selector, right user menu.

Code Rules

  • Small files, minimal comments.
  • Prefer single-line if without braces when only one line follows.
  • Heavy logic lives in components/hooks/services, not page files.
  • Prefer API calls via exported hooks/services for reusability and cleanliness (avoid raw fetch in components when possible).
  • Add/update unit tests with changes (TDD).
  • Heavy focus on code readability and maintainability; prioritize clean code over clever code.
    • ie. Separating different concerns into different files, and adding helper functions to avoid nested logic and improve readability, is preferred over clever one-liners or consolidating logic into fewer files.
    • ie. Separate groups of related codes by adding 3 line breaks between them

Data Model

  • Users (system_role USER|SYS_ADMIN)
  • Groups + membership (group_role MEMBER|GROUP_ADMIN)
  • Entries (group-scoped) + optional receipt_id
  • User settings (jsonb)
  • Reports for system admins

Architecture Contract (Backend ↔ Client ↔ Hooks ↔ UI)

No-Assumptions Rule (Required)

  • Before making structural changes, first scan the repo and identify:
    • the web app root (where app/, components/, hooks/, lib/ live)
    • existing API routes and helpers
    • existing patterns already in use
  • Do not invent files, endpoints, or conventions. If something is missing, add it minimally and consistently.

Layering (Hard Boundaries)

For every domain (auth, groups, entries, receipts, etc.), keep a consistent 4-layer flow:

  1. API Route Handlers (app/api/.../route.ts)
  • Thin: parse input, call a server service, return JSON.
  • No direct DB queries inside route files unless there is no existing server service.
  • Must enforce auth & membership checks on server.
  1. Server Services (DB + authorization) (lib/server/*)
  • Own all DB access and authorization helpers (sessions, requireGroupMember, etc.).
  • 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/session.ts.
  1. Client API Wrappers (lib/client/*)
  • Typed fetch helpers only (no React state).
  • Centralize fetchJson() / 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 theres a strong reason.

Domain Blueprint (Consistency Rule)

For any new feature/domain, prefer:

  • app/api/<domain>/...
  • lib/server/<domain>.ts
  • lib/client/<domain>.ts
  • hooks/use-<domain>.ts
  • components/<domain>/*
  • __tests__/<domain>.test.ts

API Conventions

  • Prefer consistent JSON response shape for errors:
    • { error: { code: string, message: string } }
  • Validate inputs at the route boundary (basic shape/type), and validate authorization in server services.
  • When adding endpoints, mirror existing REST style used in the project.

Non-Regression Contracts (Do Not Break)

  • Entries list endpoints must never include receipt image bytes; image bytes are fetched via a separate endpoint only.
  • Auth is DB-backed HttpOnly sessions; all auth checks are server-side.
  • Groups require server-side membership checks; active group persists per user.
  • Group invite codes:
    • shown once immediately after group creation
    • modal renders outside navbar/header so it overlays the viewport correctly
    • avoid re-exposing invite code elsewhere without explicit “group settings” work

UI Structure

  • Page files stay thin; heavy logic stays in hooks/services/components.
  • Dark mode, minimal, mobile-first.
  • Dodger Blue accent (#1E90FF).
  • Navbar: left nav dropdown, middle group selector, right user menu.

Environment

  • Dev and Prod must use the same schema/migrations (packages/db/migrations).
  • DATABASE_URL points to external Postgres (NOT a container).
  • DATABASE_URL format must be a full connection string; URL-encode special chars in passwords.

Tests (Required)

  • Add/update tests for API behavior changes:
    • auth
    • groups
    • entries (group scoping)
  • Tests must include negative cases: unauthorized, not-a-member, invalid inputs.