Register drizzle journal entries for 0022/0023 so prod migrations apply. Key edit-mode widget previews by index so bangs.stats shows live data. Add comments to notes detail pages.
116 lines
26 KiB
Markdown
116 lines
26 KiB
Markdown
# 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`](AGENTS.md) and [`CLAUDE.md`](CLAUDE.md); keep them synchronized. Task briefs live in [`docs/tasks/`](docs/tasks/).
|
||
|
||
## Done
|
||
|
||
- **80 — Quick-add create UI** (commit `68a573c`). Quick-add actions open create dialogs/sheets in-place via `createKey` + `QuickAddCreateHost`; calendar, lists, notes, garden, bangs wired. E2E in `tests/e2e/quick-add.spec.ts`.
|
||
- **81 — Dashboard edit live widgets** (commit `7eeb2f1`). Edit mode server-pre-renders real widget content via `DashboardWidgetContent` + `widgetContents` map; no placeholder→content reflow on save. E2E in `tests/e2e/dashboard.spec.ts`.
|
||
|
||
- **82 — Garden container plant count** (commit `700ee29`). Fixed broken Drizzle subquery in `getContainer` and refactored `listContainers` plant count aggregation. E2E in `tests/e2e/garden.spec.ts`.
|
||
|
||
- **83 — Bang edit and delete** (commit `753f653`). `updateBang`/`deleteBang` server actions with activity log; edit/delete UI on bang widget recent rows. E2E in `tests/e2e/bangs.spec.ts`.
|
||
|
||
- **84 — Back navigation** (commit `d090200`). Shared `DetailBackLink` on garden/notes/lists detail, create, and edit pages plus household settings. E2E in `tests/e2e/navigation.spec.ts`.
|
||
|
||
- **87 — HTTP API v1** (commits `ea5d1d0`, `d4304b0`, `e8d13be`). Household bearer token + session auth; `/api/v1/` routes for calendar, lists, notes, garden, bangs; OpenAPI in `docs/api/openapi.yaml`; owner token UI in Settings → Data. Unit tests: `api-auth`, `api-v1-calendar`, `api-v1-auth`. ADR 0006. Run `pnpm db:migrate` for migration `0019_household_api_tokens`.
|
||
|
||
- **85 — Rich-text notes** (ADR 0004 accepted `67f6752`). TipTap editor in `src/components/rich-text/`; notes create/edit + index/widget/share surfaces; interactive checklists; DOMPurify sanitization; lazy plain-text→HTML migration; mobile overflow CSS; uploads `?scope=notes`. Unit tests: `rich-text.test.ts`. E2E: `tests/e2e/notes.spec.ts` (formatted note + 375px overflow).
|
||
|
||
- **86 — Journal module** (ADR 0005 accepted `8e2ddd6`). Per-user `journal_entries` schema + migration `0020_journal_entries.sql`; mood catalog (multi-select), optional stress/pills, rich-text body; index with calendar dots, entry editor, Recharts mood tracker, insights (streak/trends/correlations); `/api/v1/journal/entries` CRUD with bearer token auth; OpenAPI updated. Unit tests: `journal-analytics.test.ts`. E2E: `tests/e2e/journal.spec.ts`. Run `pnpm db:migrate` for migration `0020`.
|
||
|
||
- **88 — LLM agent chat** (ADR 0006). Opt-in floating chat bubble; OpenAI-compatible LLM client (`LLM_BASE_URL` / `LLM_MODEL`); mock provider when unset; direct tool schemas → `/api/v1/` HTTP calls; `POST /api/agent/chat`. Per-user `assistant_enabled` (default off). Unit tests: `agent-chat.test.ts`. E2E: `tests/e2e/assistant.spec.ts`. Migration `0021`.
|
||
|
||
- **Journal + dashboard polish** (commit `a09747c`, follow-on to 86/81/80/85/88). Journal dashboard widgets (`journal.recent`, `journal.mood-tracker` with year/month config); journal quick-add dialog (moods, stress/pills on by default, `StressSlider`, rich-text reflection); mood tracker UI redesign + `?day=` navigation; `listMoodTrackerEntries` (500 cap) fixes widget Zod error. Dashboard edit mode uses cookie draft (`dashboard-editor-draft.ts`, `syncEditorDraftLayout`) so add/remove/config refreshes live widget previews. Rich-text in quick-add (notes, calendar, journal) and calendar event notes. Agent bubble UI + expanded API tools (garden care, share links, OpenAPI docs). Widget picker hover contrast fix. Gitea #38 (animation polish) remains open.
|
||
|
||
- **89 — Calendar reminders overhaul** (Gitea #28, commit `e1c2a09`). Multiple reminders per event via `syncCalendarEventReminders`; `ReminderPicker` with presets + custom offsets; migration `0022_multiple_reminders.sql` drops one-per-entity unique index, adds `offset_minutes` + `users.default_event_reminder_offsets`. Settings → Notifications default reminders editor. Create/edit/quick-add calendar flows updated; drag-reschedule resyncs existing offsets.
|
||
|
||
- **90 — Lists index inline add + edit** (Gitea #29, commit `e1c2a09`). `/lists` cards: inline task add row, pencil edit for name/type via `updateListProperties`.
|
||
|
||
- **91 — Comments on lists and tasks** (Gitea #30, commit `e1c2a09`). Generic `comments` table + `_core/comments.ts`; reusable `EntityComments` on list detail (list + per-item compact threads). Migration `0023_comments.sql`.
|
||
|
||
- **92 — Bang stats dashboard widget** (Gitea #31, commit `e1c2a09`). `bangs.stats` widget with monthly/yearly counts, average days between bangs, recent month breakdown.
|
||
|
||
- **P2 batch follow-ups** (release v0.5.4). Migration journal entries for `0022`/`0023` (prod apply fix); dashboard edit previews keyed by placement index (`bangs.stats` live in edit mode); notes comments; comment revalidation on `/notes`.
|
||
|
||
- **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.
|
||
- **21 — Quick-add registry**. Added `url: string` to `QuickAddAction` type (action is now optional). Added `getQuickAdds()` / `SerializedQuickAddItem` to registry (strips non-serializable `action` fn before crossing server→client boundary). Updated all three module manifests with navigation URLs. Built `QuickAddProvider` (context + cmd+k global shortcut), `QuickAddFab` (opens sheet, replaces plain button in dashboard), `QuickAddSheet` (bottom drawer / desktop popover grouped by module), and `CommandPalette` (cmdk-powered modal with arrow + enter + esc keyboard nav). Provider in root layout receives actions from `getQuickAdds()` at render time — adding a module's `quickAdds` automatically appears in both surfaces. Also added `.claude/**` to ESLint ignores to prevent stale worktree build artifacts from failing lint. `pnpm typecheck`, `pnpm lint`, `pnpm build`, and all 4 E2E specs pass.
|
||
- **22 — Activity log**. Added `activity_log` table to `_core/schema.ts` with index on `(household_id, created_at desc)`. Migration `0008_activity_log.sql` applied. `logActivity()` server function in `_core/activity.ts` reads current session and inserts a row. Added `ActivityLogEntry` type and optional `renderActivity?(entry): string` to `EntityTypeRegistration` in `_core/module.ts`. All three module manifests implement `renderActivity` for each entity type (human-readable, no hardcoded branches in the widget). Replaced `core.activity` widget stub with a real async server component that queries the last 20 rows via `getEntityType(entry.entityType)?.renderActivity(entry)`. Wired `logActivity()` into every create/update/delete in calendar, lists, and notes server actions. Also added `text` to `getAuthorizedItem` select so toggle/delete log the item text. `pnpm typecheck`, `pnpm lint`, `pnpm build`, and all 4 E2E specs pass.
|
||
- **30 — Share-link service**. Added `share_links` table to `_core/schema.ts` + migration `0009_share_links.sql`. Created `_core/share.ts` with `createShareLink`, `resolveShareToken`, `revokeShareLink`, and `getActiveShareLinks`. Token is 32 random bytes (URL-safe base64), stored as SHA-256 hash — raw token only returned at creation. `createShareLink` guards that the entity type is registered with `canShare === true`. `resolveShareToken` returns null for expired or revoked tokens. All three functions exported from `_core/index.ts`. `/settings` page gained a Share links card: lists active links (entity label, read/write capabilities, expiry) with a Revoke button per link (server action in `settings/actions.ts`). `pnpm typecheck`, `pnpm lint`, `pnpm build`, and all 4 E2E specs pass.
|
||
- **25 — Multiple dashboards per user**. Added `dashboards` table (migration `0012_dashboards.sql`). Migrated each user's `default_dashboard_layout` into a "Home" dashboard row with `is_default = true`; dropped the interim column. Server actions: `listDashboards`, `createDashboard`, `renameDashboard`, `deleteDashboard`, `setDefaultDashboard`, `reorderDashboards`, `saveDashboardLayout`, `resetDashboardLayout`, `resolveWidgetConfigOptions`. `/` redirects to the user's default `/d/<slug>`. Dashboard switcher in AppNav renders tabs (active highlighted client-side) with a `+` button to create new dashboards and a kebab menu on the active tab for rename / set-default / delete. `pnpm typecheck`, `pnpm lint`, `pnpm build` pass.
|
||
- **26 — Customizable layout + widget configuration**. Installed `react-grid-layout` v2. Dashboard pages check `?edit=1` to enter edit mode, rendering a client `DashboardEditor` instead of the static grid. Editor uses `react-grid-layout` with `gridConfig`/`dragConfig` v2 API; each widget shell shows a drag handle, configure button (⚙), and remove button (🗑). `WidgetPicker` is a two-step modal: step 1 lists all registry widgets grouped by category; step 2 is a `WidgetConfigurator` auto-generated from the widget's default config — handles `"all"|string[]` multi-selects, booleans, numbers, and enums. `resolveWidgetConfigOptions` server action fetches dynamic options (calendars, lists). Save validates each config against its registered Zod schema. Reset to defaults calls `computeDefaultLayout()`. `pnpm typecheck`, `pnpm build` pass.
|
||
- **31 — Public share viewer**. Made `actorId` nullable in `activity_log` (migration `0010_nullable_actor_id.sql`, `onDelete: "set null"`) for anonymous share-page mutations. Added `logShareActivity` to `_core/activity.ts` (no session, explicit `householdId`). Added `householdId` to `resolveShareToken` return. Added `renderSharedView` to `EntityTypeRegistration` type. Each module implements `loadForShare` (bare DB queries, no session) and `renderSharedView`: calendar shows upcoming 90-day events or single-event details, lists shows items with optional toggle, notes shows title + body. `toggleShareListItem` server action lives in `lists/server/share-actions.ts` — validates token write capability, verifies item→list→household chain, logs `share.toggle` with `actorId = null`. `/app/s/[token]/page.tsx` resolves token, dispatches to `loadForShare` + `renderSharedView`, returns friendly error for invalid/expired tokens, sets `noindex`. Middleware `/s/*` exemption confirmed present. `pnpm typecheck`, `pnpm lint`, `pnpm build`, and all 4 E2E specs pass.
|
||
|
||
- **50 — PWA shell**. `public/manifest.webmanifest` (name, short_name, icons, theme_color, display: standalone, start_url `/`). Placeholder PNG icons at 180, 192, 384, 512 (regular + maskable) generated by `scripts/generate-icons.mjs` (`pnpm gen:icons`); `public/icon.svg` committed as source. Hand-rolled service worker at `public/sw.js`: precaches `offline.html` on install, cache-first for `/_next/static/`, network-first for navigation with offline fallback, network-only for API routes. `src/components/pwa-register.tsx` registers the SW client-side. `src/components/install-prompt.tsx` shows a dismissible banner: `beforeinstallprompt` on Android/Chrome, a one-time "Add to Home Screen" hint on iOS (detected via UA + `navigator.maxTouchPoints`, suppressed in standalone mode). Root layout exports `viewport` (themeColor), updated `metadata` (manifest, appleWebApp, apple-touch-icon), and mounts both new components. `pnpm typecheck`, `pnpm lint`, `pnpm build` all clean.
|
||
- **51 — Offline shell + service worker caching**. `next.config.ts` generates `public/sw.js` as a side effect on every `next build` / `next dev` invocation, embedding a build timestamp as `CACHE_VERSION` (stable `"dev"` string in development to avoid hot-reload cache churn; epoch milliseconds in production). SW strategies: stale-while-revalidate for `/_next/static/` chunks and navigation HTML (cached page served instantly, network update fires in background); network-first with 2-second abort timeout for API GETs falling back to cache; network-only for mutations (POST/PATCH/DELETE/PUT) — if offline, all controlled clients receive `{ type: "OFFLINE_MUTATION" }` via `postMessage` and a synthetic 503 is returned. Activate handler evicts all `famapp-*` caches whose suffix doesn't match the current version, then claims clients. `pwa-register.tsx` extended with three inline toasts: amber "offline" banner (persistent, driven by `navigator.onLine` + `online`/`offline` events), red "changes can't be saved" toast (auto-dismisses in 4 s, driven by SW postMessage), and indigo "new version available — refresh" bottom toast (driven by `controllerchange` with `hadController` guard). `pnpm typecheck`, `pnpm build` pass.
|
||
|
||
- **40 — Web Push (VAPID)**. Installed `web-push` + `@types/web-push`. Added `pnpm vapid:generate` script (`scripts/vapid-generate.mjs`) that prints all three env vars to stdout. Added `push_subscriptions` table to `_core/schema.ts` + migration `0013_push_notify_reminders.sql`. Created `_core/push.ts` with `sendPush(userId, payload)` — iterates subscriptions, removes 404/410 stale entries. Added `push` and `notificationclick` event handlers to the generated `public/sw.js` template. Created `<PushOptIn />` client component on `/settings` (opt-in button → `subscribeToPush` server action, disable button → `unsubscribeFromPush`, test button → `sendTestNotification`). Documented `NEXT_PUBLIC_VAPID_PUBLIC_KEY` in `.env.example`. `pnpm typecheck`, `pnpm lint`, `pnpm build` pass.
|
||
|
||
- **42 — Notification bus + ntfy adapter**. Added `notifications` table and `notif_push`/`notif_inapp`/`notif_ntfy` columns on `users` (migration `0013_push_notify_reminders.sql`). Created `_core/notify.ts` with `notify(userId, { title, body, url, channels? })` — fans out to push (if VAPID configured), in-app DB insert, and ntfy POST (if `NTFY_URL`+`NTFY_TOPIC` set). Added `<NotificationBell />` async server component in `AppNav`: queries last 20 notifications, shows unread badge, dropdown inbox with mark-read and mark-all-read. Added `<NotifyChannelToggles />` client component with per-channel checkboxes in `/settings`. `pnpm typecheck`, `pnpm lint`, `pnpm build` pass.
|
||
|
||
- **41 — Reminders engine**. Added `fired_at` and `created_by` columns to `reminders` table (migration `0013_push_notify_reminders.sql`); default channel changed to `'auto'`. Created `_core/reminders.ts` with `scheduleReminder` (upsert by entity), `cancelReminder`, `listReminders`, and `tickReminders` (30 s tick, `pg_try_advisory_xact_lock` guard). `startReminderWorker()` started via `src/instrumentation.ts` on the Node.js runtime. Notes actions updated to use `scheduleReminder`/`cancelReminder` instead of raw SQL. Calendar `createEvent` accepts optional `remindMinutesBefore` and schedules a reminder; `deleteEvent` calls `cancelReminder`. Calendar-shell event dialog shows "Remind me 30 min before" checkbox (new events only, checked by default). Reminder worker confirmed starting on server boot (logged in dev server output). `pnpm typecheck`, `pnpm lint`, `pnpm build` pass.
|
||
|
||
- **60 — Postgres backups**. `famapp-backup` Alpine service added to `deploy/compose.yaml`; scripts in `deploy/backups/`: `backup.sh` (`pg_dump -Fc` for famapp-db + authentik-db nightly at 02:00), `retain.sh` (14 daily / 8 weekly / 6 monthly), `restore.sh` (restore from any dump file), `entrypoint.sh` (installs postgresql-client, sets up crontab, starts crond). Backup files stored in `backups` named Docker volume. Restore procedure in `deploy/backups/README.md`. `pnpm typecheck`, `pnpm lint`, `pnpm build` pass.
|
||
- **61 — Rate limiting on share links**. `src/lib/rate-limit.ts`: pure-JS Edge-compatible sliding-window counter (50 req/min, 1-min window, 10k-key LRU eviction) with `consume()`, `isRateLimited()`, and `recordFailure()` exports. `src/middleware.ts` calls `consume(ip:prefix)` for every `/s/[token]` request and returns 429 with `Retry-After: 60` when the bucket is exceeded. `src/app/s/[token]/page.tsx` additionally tracks only failed `resolveShareToken` lookups via `recordFailure()` in the Node.js runtime (separate module instance from middleware; Redis would unify them for multi-replica deployments). `pnpm typecheck`, `pnpm lint`, `pnpm build` pass.
|
||
- **62 — Structured logging**. Installed `pino` + `pino-pretty` (dev). `src/lib/logger.ts`: pino instance — JSON in production (`stdout`), pretty-printed in dev; level from `LOG_LEVEL` env (default `info`); `pid`/`hostname` stripped, ISO timestamps. `src/middleware.ts` logs every request as structured JSON via `console.log` (Edge-compatible; pino not available in Edge runtime) with `method`, `path`, `status`, `ms`, `authenticated`. All `console.error`/`console.log` calls in `_core/push.ts`, `_core/notify.ts`, `_core/reminders.ts` replaced with `logger.error`/`logger.info`; sensitive fields (endpoint URLs, keys) are never logged as named fields. `next.config.ts` adds `serverExternalPackages: ["pino","pino-pretty"]` so webpack does not bundle them. `pnpm typecheck`, `pnpm lint`, `pnpm build` pass.
|
||
|
||
## Next up
|
||
|
||
Phase 9 — Post-v0.1 (see `docs/superpowers/specs/2026-07-03-backlog-triage-design.md`, `docs/issues-map.md`).
|
||
|
||
**Batch order:**
|
||
|
||
1. ~~Bugs: tasks 80–84~~ — done
|
||
2. ~~API foundation: task 87 (+ ADR 0006)~~ — done
|
||
3. ~~Shared rich-text + notes overhaul: task 85 (+ ADR 0004)~~ — done
|
||
4. ~~Journal: task 86 (+ ADR 0005), including journal API endpoints~~ — done
|
||
5. ~~LLM agent chat: task 88~~ — done
|
||
|
||
P2/P3 backlog is filed on Gitea only (no task briefs yet) — see `docs/issues-map.md` designs 7–9, 11–12, 15–19.
|
||
|
||
**How to resume:** P2 batch #28–#31 complete (released v0.5.4). Next: remaining P2/P3 Gitea backlog (#32+) or homelab LLM wiring (`LLM_BASE_URL` in homelabstack `.env`).
|
||
|
||
## 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](AGENTS.md), [CLAUDE.md](CLAUDE.md), and [STATUS.md](STATUS.md), then complete the next task in [docs/tasks/](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\`.
|