fiddy/docs/01_inspect_then_lifecycle_restructure.md
2026-02-11 23:45:15 -08:00

4.1 KiB

You are working in the existing “Fiddy” project (Next.js App Router + TS + Tailwind, external Postgres via pg, no ORM). This project already has implemented auth (DB sessions + HttpOnly cookies), groups (create/join/list/active), and entries CRUD scoped to active group, plus hooks for API calls.

IMPORTANT: Do NOT assume file locations. First, inspect the repo and identify the web app root folder (the one that contains app/, components/, hooks/, lib/). Apply changes only inside that web app root.

Goal: enforce long-term structure across backend, frontend, and the hooks layer (API ↔ services ↔ client wrappers ↔ hooks ↔ components). Preserve all existing behavior.

STEP 0 — Inventory (no code changes yet)

  1. Print a short “Current Structure Summary”:
    • where the web app root is
    • existing API route folders under app/api
    • existing modules in lib/ and what they do (auth/session/groups/entries/etc.)
    • existing hooks and which endpoints they call
  2. List any mismatches with the target layering below.

Target layering: A) app/api/* route handlers = thin (validation + call server service) B) lib/server/* = DB + authorization + business logic (“server-only”) C) lib/client/* = typed fetch helpers (no React) D) hooks/* = React state + calls lib/client E) components/* = UI only (call hooks)

STEP 1 — Add structure without breaking anything

  1. Create folders if missing:
    • lib/server
    • lib/client
    • lib/shared
  2. Add lib/client/fetch-json.ts (or equivalent) if missing:
    • wrapper around fetch that:
      • always includes credentials
      • returns typed JSON
      • normalizes errors into { error: { code, message } }
  3. Add lib/shared/types.ts (or equivalent) containing shared types used by hooks/components (User, Group, Entry, etc.), based on existing API responses.
  4. Move server-only code into lib/server/* where appropriate:
    • session helpers (get current user, require session)
    • DB access helpers
    • groups/entries/auth services Add import "server-only"; at top of every lib/server/* module. Update imports so client components/hooks NEVER import from lib/server.

STEP 2 — Route handlers become thin For each existing API route, refactor so route files:

  • validate request payload shape
  • call the corresponding lib/server service
  • return JSON
  • handle auth/membership via server service Preserve existing endpoints (do not rename routes):
  • Auth routes: register/login/logout + /api/auth/me (remember-me TTL behavior must remain)
  • Groups routes: create/join/list/active group
  • Entries routes: list/create/update/delete and group scoping must remain

STEP 3 — Hooks remain the single UI API surface Ensure hooks own API calling for UI:

  • use-auth.ts handles login/register/logout/me/session checks
  • use-groups.ts handles group list/create/join/active group
  • use-entries.ts handles list/create/update/delete Components/pages should not call fetch directly unless there is no hook for it.

STEP 4 — Preserve existing non-regression behavior Do not break these already-implemented behaviors:

  • Entries list endpoints never return receipt image bytes; bytes only come from a dedicated endpoint.
  • Dashboard is protected via server-side session check + redirect to /login.
  • Group invite code modal is shown immediately after group creation, then cleared, and the modal renders outside navbar/header so it overlays the viewport properly.

STEP 5 — Optional folder organization (only if safe) If the project already has or needs layout separation, introduce route groups:

  • app/(auth)/login and app/(auth)/register with auth-only layout (no navbar)
  • app/(app)/... with navbar layout BUT only do this if it does not conflict with existing routing and tests. Keep URLs unchanged.

STEP 6 — Tests + validation

  1. Update/add tests for any touched behavior:
    • auth tests (including /me and remember-me TTL behavior)
    • groups tests (create/join/list/active)
    • entries tests (CRUD + group scoping)
  2. Run TypeScript checks and fix imports.
  3. Provide a final “Changed Files” list and confirm URLs still work:
    • /login
    • /register
    • / Deliver all changes as a coherent refactor with minimal code churn.