Files
famapp/STATUS.md
ginnoirandClaude Sonnet 4.6 b4dde92757 Implement dashboard composition (task 20)
- Add default_dashboard_layout jsonb to users + migration 0007
- Create _core/manifest.tsx with core.activity placeholder widget
- Register core manifest alongside calendar/lists/notes
- Update all three module manifests with real async server-component
  widget renders (upcoming events, month view, list items, notes)
- Add src/lib/dashboard.ts: computeDefaultLayout greedy packer +
  parseDashboardLayout Zod validator
- Build src/app/page.tsx: 12-col CSS Grid, static smColSpan lookup,
  per-widget Suspense for parallel loading, generic widget.render()
  dispatch — no widgetId branches
- Add tests/e2e/dashboard.spec.ts; all 4 E2E specs pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 13:24:56 -05:00

8.8 KiB
Raw Permalink Blame History

Status

Living progress tracker. Update at the end of each task. Codex and Claude Code both work on this project, so write status notes and next-step instructions for either agent to resume. Canonical briefs are AGENTS.md and CLAUDE.md; keep them synchronized. Task briefs live in docs/tasks/.

Done

  • 01 — Repo init & tooling (commit b89690a). pnpm 10 + TS strict + ESLint flat + Prettier. All acceptance criteria green.

  • 02 — Next.js app skeleton. Next.js 15 + React 19 + Tailwind v4 + shadcn/ui (button, card, input, dialog). pnpm dev serves placeholder, pnpm build produces .next/standalone/, pnpm lint clean. Added .npmrc with node-linker=hoisted for Windows symlink compatibility.

  • 03 — Drizzle + Postgres setup. drizzle-orm + postgres driver + drizzle-kit wired up. src/modules/_core/schema.ts declares users, households, household_members. docker-compose.dev.yaml starts Postgres 16. drizzle/0000_silent_magma.sql generated and applied. tsc --noEmit passes.

  • 04 — Module loader & registry. src/modules/_core/module.ts types (ModuleManifest, EntityTypeRegistration, DashboardWidget, etc.), registry.ts singleton with registerModule/getRegistry/getEntityType/getWidget, barrel _core/index.ts. Stub manifests for calendar, lists, notes. src/modules/index.ts loader. Root layout imports loader; AppNav reads registry for nav links. /debug/registry dumps full registry JSON (dev only). Uses zod v4 + built-in z.toJSONSchema(). tsc --noEmit, pnpm build, pnpm lint all clean.

  • 05 — Compose + Caddy. Dockerfile (3-stage: deps/builder/runner, pnpm fetch + offline install, non-root nextjs user, output: standalone), deploy/compose.yaml (famapp + famapp-db + full Authentik stack on famapp_net), deploy/Caddyfile.snippet, .env.production.example. docker build -t famapp . succeeds (~311 MB); docker compose -f deploy/compose.yaml config validates clean. Added .dockerignore and public/.gitkeep.

  • 06 — Authentik OIDC. next-auth@beta + @auth/drizzle-adapter wired up. src/lib/auth.ts configures OIDC provider (Authentik), database sessions, authorized callback guarding all routes except /login, /s/*, /api/auth/*. src/middleware.ts exports auth as middleware. src/app/api/auth/[...nextauth]/route.ts mounts the handlers. src/app/login/page.tsx has a single "Sign in with SSO" server action. getCurrentUser() available for server components/actions. Schema extended: users → added name/emailVerified/image; new accounts, sessions, verificationTokens tables; migration 0001_auth_tables.sql generated. deploy/authentik/README.md documents the manual Authentik bootstrap. tsc --noEmit and pnpm lint pass clean.

  • 07 — Household seed. pnpm db:seed inserts household "Home" idempotently (powered by tsx). signIn callback assigns owner to the first member of the household and member to all subsequent users. getCurrentSession() in src/lib/session.ts returns { user, household, role } and throws if unauthenticated or unmembered. /settings/household renders member list for all roles and a rename form for owner only. tsc --noEmit and pnpm lint both clean.

  • 08 — Theming infrastructure. CSS-variable multi-theme system (default + warm) × {light, dark, system}. users.theme + users.themeMode columns in migration 0002_naive_starbolt.sql. Theme registry in src/modules/_core/themes.ts (THEMES/THEME_MODES arrays — adding a third theme is one CSS block + one registry entry). Root layout reads session and sets data-theme/dark on <html> server-side; inline pre-paint <script> covers system mode and signed-out pages (no flash). useTheme() hook optimistically flips attributes, writes localStorage, and calls setUserTheme server action. <ThemePicker /> component mounts on /settings (select for theme, segmented buttons for mode). tsc --noEmit, pnpm lint, pnpm build all clean.

  • 10 — Calendar module. Added calendars and calendar_events schema + migration 0003_rainy_ravenous.sql, default Home/Personal calendar seeding, first-login default calendar creation, visibility-safe calendar/event queries, CRUD server actions, FullCalendar-backed /calendar UI with sidebar calendar management and event create/edit/delete/drag updates. Calendar manifest now registers share/reminder/search capabilities, two configurable widgets, and quick-add entries. Added Playwright happy-path spec in tests/e2e/calendar.spec.ts. pnpm db:generate, pnpm typecheck, pnpm lint, and pnpm build pass.

  • 11 — Lists module. Added lists and list_items schema + migration 0004_opposite_wraith.sql, default Shopping/Tasks seeding on first access/sign-in/seed, household-gated list and item CRUD server actions, reorder support, and Postgres LISTEN/NOTIFY to SSE bridge documented in ADR 0002. Added /lists grouped index, /lists/[id] keyboard-first item entry with checkbox toggles and swipe/delete, manifest entity/search/widget/quick-add registrations, and Playwright happy-path spec in tests/e2e/lists.spec.ts. pnpm typecheck, pnpm lint, and pnpm build pass.

  • 12 — Notes module. Added generic core reminders table plus household-scoped notes schema in migration 0006_new_hannibal_king.sql, notes CRUD server actions, reminder synchronization for notes.note, /notes index, /notes/new, /notes/[id] editor with safe markdown preview, manifest entity/search/reminder/share registration, notes.filtered widget registration, quick-add placeholder, and Playwright happy-path spec in tests/e2e/notes.spec.ts. pnpm typecheck, pnpm lint, pnpm build, and notes E2E pass.

  • 20 — Dashboard composition (single-dashboard MVP). Added default_dashboard_layout jsonb column to users + migration 0007_uneven_living_lightning.sql. Created src/modules/_core/manifest.tsx (core.activity placeholder widget) and registered it. Updated all three module manifests (calendar, lists, notes) with real async server component widget renders (data-fetching, empty states). Created src/lib/dashboard.ts (layout parsing + computeDefaultLayout greedy packer). Built src/app/page.tsx — 12-col CSS Grid, static smColSpan lookup for Tailwind class safety, per-widget <Suspense> for parallel loading, graceful skip for unknown widget IDs. pnpm typecheck, pnpm lint, pnpm build, and all 4 E2E specs pass.

Next up

  • Next task in docs/tasks/.

Development login/testing notes

  • Local development can use the documented Dev login flow in docs/dev-login.md. It creates a database-backed Auth.js session for DEV_LOGIN_EMAIL when ENABLE_DEV_LOGIN=true and NODE_ENV !== "production".
  • The production cleanup gate is tracked in docs/tasks/09-production-dev-login-removal.md. Complete it before first production deployment.

Phase 1 remaining

  • 03 Drizzle + Postgres → 04 module loader → 05 compose/Caddy → 06 Authentik OIDC → 07 household seed → 08 theming infrastructure (newly added; multi-theme + per-user dark/light, must land before module work so module UIs adopt the token system from day one).

Recent architectural decisions

  • Calendars are first-class entities. Like lists, users can create as many as they want with private or household visibility. Both calendar entities are independently shareable. Updated CLAUDE.md data model + task 10.
  • Uniform widget contract — no singletons. Every dashboard widget declares a configSchema and defaultConfig; every placement is an independent instance. Same widget can appear N times on a dashboard pointed at different things. Updated task 04; tasks 11/12 widget sections updated to match.
  • Per-user customizable dashboards. Each user can have any number of named dashboards, switch between them, drag/resize widgets, and configure each placement. Tasks 25 (multiple dashboards) and 26 (customizable layout + widget configuration) added; phase 3 index updated.

How to resume in a fresh session

  1. Open the repo root in VS Code.
  2. Tell Codex or Claude Code: "Read AGENTS.md, CLAUDE.md, and STATUS.md, then complete the next task in docs/tasks/. Stop at the acceptance criteria."
  3. After it lands, append the result to the Done section here, bump Next up, and commit.

Environment notes

  • Repo: https://github.com/ginnoir/famapp (HTTPS remote on origin).
  • Local dev tooling installed: Node 22+, pnpm 10.33.3.
  • .env is not committed; copy .env.example.env when needed.
  • VS Code recommended extensions in .vscode/extensions.json; copy .vscode/settings.json.example.vscode/settings.json for the workspace defaults.
  • Memory files (cross-session, only seen by Claude): C:\Users\MattC\.claude\projects\C--Users-MattC-Documents-famapp\memory\.