docs: complete Phase 9 backlog triage (issues map, briefs, ADRs)
Map design IDs to Gitea #1-#37, add tasks 80-88, stub ADRs 0004-0006, and point STATUS at the P1 batch order.
This commit is contained in:
+344
@@ -0,0 +1,344 @@
|
|||||||
|
# famapp Architecture Diagram
|
||||||
|
|
||||||
|
## System Overview
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ EXTERNAL LAYER │
|
||||||
|
├─────────────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||||
|
│ │ Browser │ │ Mobile PWA │ │ Share Link │ │
|
||||||
|
│ │ (Next.js) │ │ (Installed) │ │ (Public) │ │
|
||||||
|
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ └────────────────────────┴────────────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ HTTPS (Caddy Reverse Proxy) │
|
||||||
|
│ │ │
|
||||||
|
│ fam.ginnoir.com → :3000 │
|
||||||
|
│ auth.ginnoir.com → :9000 │
|
||||||
|
└──────────────────────────────────┼───────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
┌──────────────────────────────────┼───────────────────────────────────────────┐
|
||||||
|
│ APPLICATION LAYER │
|
||||||
|
├──────────────────────────────────┼───────────────────────────────────────────┤
|
||||||
|
│ │ │
|
||||||
|
│ ┌────────────────────────┴────────────────────────┐ │
|
||||||
|
│ │ Next.js 15 App Router │ │
|
||||||
|
│ │ (Node 24 LTS Container) │ │
|
||||||
|
│ └────────────────────────┬────────────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ┌───────────────────────────────┼───────────────────────────────┐ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ │ ┌───────────────────────────┐│ ┌───────────────────────────┐│ │
|
||||||
|
│ │ │ Middleware ││ │ Auth (NextAuth) ││ │
|
||||||
|
│ │ │ - Rate limiting ││ │ - OIDC (Authentik) ││ │
|
||||||
|
│ │ │ - Session check ││ │ - Session management ││ │
|
||||||
|
│ │ └───────────┬───────────────┘│ └───────────┬───────────────┘│ │
|
||||||
|
│ │ │ │ │ │ │
|
||||||
|
│ │ ┌───────────┴───────────────┐│ ┌───────────┴───────────────┐│ │
|
||||||
|
│ │ │ Routes (app/) ││ │ Module Registry ││ │
|
||||||
|
│ │ │ / → /d/{slug} ││ │ - Entity types ││ │
|
||||||
|
│ │ │ /d/[slug] (dashboard) ││ │ - Dashboard widgets ││ │
|
||||||
|
│ │ │ /calendar ││ │ - Quick-add actions ││ │
|
||||||
|
│ │ │ /lists ││ │ - Share handlers ││ │
|
||||||
|
│ │ │ /notes ││ │ - Search adapters ││ │
|
||||||
|
│ │ │ /garden ││ │ - Reminder handlers ││ │
|
||||||
|
│ │ │ /s/[token] (share) ││ │ - Activity renderers ││ │
|
||||||
|
│ │ │ /settings ││ │ - Toggle hooks ││ │
|
||||||
|
│ │ │ /api/* ││ └───────────┬───────────────┘│ │
|
||||||
|
│ │ └───────────┬───────────────┘ │ │ │
|
||||||
|
│ │ │ │ │ │
|
||||||
|
│ │ ┌───────────┴───────────────┬────────────────┴───────────────┐│ │
|
||||||
|
│ │ │ │ ││ │
|
||||||
|
│ │ │ ┌───────────────────────┴──────────────────────────────┐││ │
|
||||||
|
│ │ │ │ MODULE SYSTEM (src/modules/) │││ │
|
||||||
|
│ │ │ │ │││ │
|
||||||
|
│ │ │ │ ┌────────────────────────────────────────────────┐ │││ │
|
||||||
|
│ │ │ │ │ _core/ │ │││ │
|
||||||
|
│ │ │ │ │ - schema.ts (users, households, activity_log, │ │││ │
|
||||||
|
│ │ │ │ │ share_links, dashboards, reminders, push) │ │││ │
|
||||||
|
│ │ │ │ │ - registry.ts (module registration) │ │││ │
|
||||||
|
│ │ │ │ │ - share.ts (share-link service) │ │││ │
|
||||||
|
│ │ │ │ │ - push.ts (web push notifications) │ │││ │
|
||||||
|
│ │ │ │ │ - reminders.ts (reminder scheduling) │ │││ │
|
||||||
|
│ │ │ │ │ - activity.ts (activity logging) │ │││ │
|
||||||
|
│ │ │ │ │ - themes.ts (theme configuration) │ │││ │
|
||||||
|
│ │ │ │ └────────────────────────────────────────────────┘ │││ │
|
||||||
|
│ │ │ │ │││ │
|
||||||
|
│ │ │ │ ┌────────────────────────────────────────────────┐ │││ │
|
||||||
|
│ │ │ │ │ calendar/ │ │││ │
|
||||||
|
│ │ │ │ │ - schema.ts (calendars, calendar_events) │ │││ │
|
||||||
|
│ │ │ │ │ - server/ (queries, mutations, share-queries) │ │││ │
|
||||||
|
│ │ │ │ │ - components/ (shared-view, calendar views) │ │││ │
|
||||||
|
│ │ │ │ │ - manifest.tsx (widgets: upcoming, month) │ │││ │
|
||||||
|
│ │ │ │ └────────────────────────────────────────────────┘ │││ │
|
||||||
|
│ │ │ │ │││ │
|
||||||
|
│ │ │ │ ┌────────────────────────────────────────────────┐ │││ │
|
||||||
|
│ │ │ │ │ lists/ │ │││ │
|
||||||
|
│ │ │ │ │ - schema.ts (lists, list_items) │ │││ │
|
||||||
|
│ │ │ │ │ - server/ (queries, mutations, share-queries) │ │││ │
|
||||||
|
│ │ │ │ │ - components/ (shared-view, list-widget) │ │││ │
|
||||||
|
│ │ │ │ │ - manifest.tsx (widget: list items) │ │││ │
|
||||||
|
│ │ │ │ └────────────────────────────────────────────────┘ │││ │
|
||||||
|
│ │ │ │ │││ │
|
||||||
|
│ │ │ │ ┌────────────────────────────────────────────────┐ │││ │
|
||||||
|
│ │ │ │ │ notes/ │ │││ │
|
||||||
|
│ │ │ │ │ - schema.ts (notes) │ │││ │
|
||||||
|
│ │ │ │ │ - server/ (queries, mutations, share-queries) │ │││ │
|
||||||
|
│ │ │ │ │ - components/ (shared-view) │ │││ │
|
||||||
|
│ │ │ │ │ - manifest.tsx (widget: notes) │ │││ │
|
||||||
|
│ │ │ │ └────────────────────────────────────────────────┘ │││ │
|
||||||
|
│ │ │ │ │││ │
|
||||||
|
│ │ │ │ ┌────────────────────────────────────────────────┐ │││ │
|
||||||
|
│ │ │ │ │ garden/ │ │││ │
|
||||||
|
│ │ │ │ │ - schema.ts (plants, containers, care_logs) │ │││ │
|
||||||
|
│ │ │ │ │ - server/ (queries, mutations, share-queries) │ │││ │
|
||||||
|
│ │ │ │ │ - components/ (plant-widget, shared-view) │ │││ │
|
||||||
|
│ │ │ │ │ - manifest.tsx (widgets: care-due, overview) │ │││ │
|
||||||
|
│ │ │ │ └────────────────────────────────────────────────┘ │││ │
|
||||||
|
│ │ │ │ │││ │
|
||||||
|
│ │ │ │ ┌────────────────────────────────────────────────┐ │││ │
|
||||||
|
│ │ │ │ │ bangs/ │ │││ │
|
||||||
|
│ │ │ │ │ - schema.ts (bang_events) │ │││ │
|
||||||
|
│ │ │ │ │ - server/ (queries) │ │││ │
|
||||||
|
│ │ │ │ │ - components/ (bang-widget) │ │││ │
|
||||||
|
│ │ │ │ │ - manifest.tsx (widget: bang counter) │ │││ │
|
||||||
|
│ │ │ │ └────────────────────────────────────────────────┘ │││ │
|
||||||
|
│ │ │ │ │││ │
|
||||||
|
│ │ │ └────────────────────────────────────────────────────┘││ │
|
||||||
|
│ │ │ ││ │
|
||||||
|
│ │ └─────────────────────────────────────────────────────────┘│ │
|
||||||
|
│ │ │ │
|
||||||
|
│ └────────────────────────────────────────────────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ┌───────────────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ Shared Libraries (src/lib/) │ │
|
||||||
|
│ │ - db.ts (Drizzle client) │ │
|
||||||
|
│ │ - auth.ts (NextAuth configuration) │ │
|
||||||
|
│ │ - session.ts (session helpers) │ │
|
||||||
|
│ │ - dashboard.ts (dashboard helpers) │ │
|
||||||
|
│ │ - logger.ts (pino logging) │ │
|
||||||
|
│ │ - minio.ts (S3 client for uploads) │ │
|
||||||
|
│ │ - rate-limit.ts (rate limiting) │ │
|
||||||
|
│ └───────────────────────────────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
└───────────────────────────────────────┬─────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
┌───────────────────────────────────────┼─────────────────────────────────────┐
|
||||||
|
│ DATA LAYER │
|
||||||
|
├───────────────────────────────────────┼─────────────────────────────────────┤
|
||||||
|
│ │ │
|
||||||
|
│ ┌─────────────────────────────┴──────────────────────────┐ │
|
||||||
|
│ │ Postgres 16 (famapp-db) │ │
|
||||||
|
│ │ (Dedicated Container) │ │
|
||||||
|
│ └─────────────────────────────┬──────────────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ┌────────────────────────────────────┼────────────────────────────┐ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ │ Core Tables │ Module Tables │ │
|
||||||
|
│ │ ┌──────────────────────────────┐ │ ┌──────────────────────┐ │ │
|
||||||
|
│ │ │ users │ │ │ calendars │ │ │
|
||||||
|
│ │ │ accounts │ │ │ calendar_events │ │ │
|
||||||
|
│ │ │ sessions │ │ │ lists │ │ │
|
||||||
|
│ │ │ verification_tokens │ │ │ list_items │ │ │
|
||||||
|
│ │ │ households │ │ │ notes │ │ │
|
||||||
|
│ │ │ household_members │ │ │ garden_plants │ │ │
|
||||||
|
│ │ │ activity_log │ │ │ garden_containers │ │ │
|
||||||
|
│ │ │ share_links │ │ │ garden_care_logs │ │ │
|
||||||
|
│ │ │ dashboards │ │ │ bang_events │ │ │
|
||||||
|
│ │ │ reminders │ │ └──────────────────────┘ │ │
|
||||||
|
│ │ │ push_subscriptions │ │ │ │
|
||||||
|
│ │ │ notifications │ │ │ │
|
||||||
|
│ │ └──────────────────────────────┘ │ │ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ └────────────────────────────────────┴────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ AUTHENTICATION LAYER │
|
||||||
|
├─────────────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ Authentik (auth.ginnoir.com) │ │
|
||||||
|
│ │ (Separate Docker Stack) │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
|
||||||
|
│ │ │ authentik- │ │ authentik- │ │ authentik- │ │ │
|
||||||
|
│ │ │ server │ │ worker │ │ redis │ │ │
|
||||||
|
│ │ │ (:9000) │ │ │ │ │ │ │
|
||||||
|
│ │ └──────┬───────┘ └──────────────┘ └──────┬───────┘ │ │
|
||||||
|
│ │ │ │ │ │
|
||||||
|
│ │ └────────────────┬─────────────────┘ │ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ │ ┌───────────────────────┴──────────────────┐ │ │
|
||||||
|
│ │ │ authentik-db (Postgres 16) │ │ │
|
||||||
|
│ │ │ (Dedicated Container) │ │ │
|
||||||
|
│ │ └──────────────────────────────────────────┘ │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ - OIDC Provider for famapp │ │
|
||||||
|
│ │ - Forward-auth for *arr apps (future) │ │
|
||||||
|
│ │ - User management │ │
|
||||||
|
│ └─────────────────────────────────────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Module System Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ MODULE REGISTRATION FLOW │
|
||||||
|
└─────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
1. Module Registration (src/modules/index.ts)
|
||||||
|
┌─────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ import { registerModule } from "./_core/registry"; │
|
||||||
|
│ import coreManifest from "./_core/manifest"; │
|
||||||
|
│ import calendarManifest from "./calendar/manifest"; │
|
||||||
|
│ import listsManifest from "./lists/manifest"; │
|
||||||
|
│ import notesManifest from "./notes/manifest"; │
|
||||||
|
│ import gardenManifest from "./garden/manifest"; │
|
||||||
|
│ import bangsManifest from "./bangs/manifest"; │
|
||||||
|
│ │
|
||||||
|
│ registerModule(coreManifest); │
|
||||||
|
│ registerModule(calendarManifest); │
|
||||||
|
│ registerModule(listsManifest); │
|
||||||
|
│ registerModule(notesManifest); │
|
||||||
|
│ registerModule(gardenManifest); │
|
||||||
|
│ registerModule(bangsManifest); │
|
||||||
|
└─────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
2. Registry Storage (src/modules/_core/registry.ts)
|
||||||
|
┌─────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ const modules = new Map<string, ModuleManifest>(); │
|
||||||
|
│ const entityTypes = new Map<string, EntityTypeRegistration>(); │
|
||||||
|
│ const widgets = new Map<string, DashboardWidget>(); │
|
||||||
|
│ │
|
||||||
|
│ registerModule() stores: │
|
||||||
|
│ - Module metadata (id, name, nav) │
|
||||||
|
│ - Entity types (with share/reminder/search handlers) │
|
||||||
|
│ - Dashboard widgets (with render functions) │
|
||||||
|
│ - Quick-add actions │
|
||||||
|
└─────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
3. Module Manifest Structure (src/modules/_core/module.ts)
|
||||||
|
┌─────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ ModuleManifest { │
|
||||||
|
│ id: string; // "calendar", "lists", etc. │
|
||||||
|
│ name: string; // "Calendar", "Lists", etc. │
|
||||||
|
│ nav?: { // Navigation entry │
|
||||||
|
│ href: string; // "/calendar" │
|
||||||
|
│ label: string; // "Calendar" │
|
||||||
|
│ icon?: string; // "calendar" │
|
||||||
|
│ }; │
|
||||||
|
│ entities: EntityTypeRegistration[]; // Entity type declarations │
|
||||||
|
│ dashboardWidgets?: DashboardWidget[]; // Widget declarations │
|
||||||
|
│ quickAdds?: QuickAddAction[]; // Quick-add actions │
|
||||||
|
│ } │
|
||||||
|
└─────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
4. Entity Type Registration
|
||||||
|
┌─────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ EntityTypeRegistration { │
|
||||||
|
│ type: string; // "calendar.event", "lists.item", etc. │
|
||||||
|
│ label: { singular, plural }; │
|
||||||
|
│ share?: { │
|
||||||
|
│ canShare: boolean; │
|
||||||
|
│ defaultCapabilities?: string[]; │
|
||||||
|
│ }; │
|
||||||
|
│ reminder?: { canRemind: boolean }; │
|
||||||
|
│ search?: { search: (query, householdId) => SearchResult[] }; │
|
||||||
|
│ resolveUrl: (id) => string; │
|
||||||
|
│ canShareEntity?: (id, ctx) => Promise<boolean>; │
|
||||||
|
│ loadForShare?: (id, ctx) => Promise<unknown>; │
|
||||||
|
│ renderSharedView?: (data, capabilities, token) => ReactNode; │
|
||||||
|
│ renderActivity?: (entry) => string; │
|
||||||
|
│ } │
|
||||||
|
└─────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
5. Dashboard Widget Registration
|
||||||
|
┌─────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ DashboardWidget { │
|
||||||
|
│ id: string; // "calendar.upcoming", "lists.list", etc│
|
||||||
|
│ title: string; │
|
||||||
|
│ description: string; │
|
||||||
|
│ category?: string; // "Calendar", "Lists", etc. │
|
||||||
|
│ defaultSize: { w, h }; │
|
||||||
|
│ minSize?: { w, h }; │
|
||||||
|
│ maxSize?: { w, h }; │
|
||||||
|
│ defaultPriority: number; // For default dashboard ordering │
|
||||||
|
│ configSchema: ZodType; // Zod schema for widget config │
|
||||||
|
│ defaultConfig: unknown; │
|
||||||
|
│ resolveConfigOptions?: (ctx) => Promise<unknown>; │
|
||||||
|
│ render: (props) => ReactNode; // Server component render │
|
||||||
|
│ } │
|
||||||
|
└─────────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Data Flow Patterns
|
||||||
|
|
||||||
|
### Share Link Flow
|
||||||
|
```
|
||||||
|
User creates share link
|
||||||
|
→ Module's canShareEntity() checks permissions
|
||||||
|
→ Core share.ts creates share_links record
|
||||||
|
→ Returns token: /s/<token>
|
||||||
|
|
||||||
|
Public viewer accesses /s/<token>
|
||||||
|
→ Middleware rate-limits by IP:token prefix
|
||||||
|
→ Share viewer loads share_links record
|
||||||
|
→ Module's loadForShare() loads entity data
|
||||||
|
→ Module's renderSharedView() renders public view
|
||||||
|
→ Share-link grants scoped read/write per capabilities
|
||||||
|
```
|
||||||
|
|
||||||
|
### Activity Logging Flow
|
||||||
|
```
|
||||||
|
Any entity mutation (server action)
|
||||||
|
→ Core activity.ts logs activity_log entry
|
||||||
|
→ Includes: entityType, entityId, actorId, action, payload
|
||||||
|
→ Dashboard activity widget queries activity_log
|
||||||
|
→ Module's renderActivity() formats entry for display
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reminder Flow
|
||||||
|
```
|
||||||
|
Entity with remind_at field (note, event)
|
||||||
|
→ Module schedules reminder via core reminders.ts
|
||||||
|
→ reminders table stores: entityType, entityId, fireAt, channel
|
||||||
|
→ Background worker (planned) fires reminders
|
||||||
|
→ notify() fans out to: web push, in-app, optional ntfy
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dashboard Widget Flow
|
||||||
|
```
|
||||||
|
User configures dashboard layout
|
||||||
|
→ dashboards.layout stores: [{ widgetId, config, x, y, w, h }]
|
||||||
|
→ Dashboard page loads layout
|
||||||
|
→ For each widget: calls module's render() with config
|
||||||
|
→ Widget component queries data via module's server/ queries
|
||||||
|
→ Renders widget in grid layout
|
||||||
|
```
|
||||||
|
|
||||||
|
## Key Design Principles
|
||||||
|
|
||||||
|
1. **Module Isolation**: Modules only import from `_core` and `lib/` - never from sibling modules
|
||||||
|
2. **Generic Core Services**: Sharing, reminders, activity log, search work against any registered entity type
|
||||||
|
3. **Household Scoping**: All entity data scoped to household_id; permissions gated by household membership
|
||||||
|
4. **Server Actions**: All mutations use Next.js server actions; route handlers only for webhooks/SSE/share viewer
|
||||||
|
5. **Type Safety**: TypeScript strict mode; Drizzle schema inference; Zod validation for all configs
|
||||||
|
6. **Extensibility**: Adding new features requires only creating a new module - no core changes needed
|
||||||
|
7. **PWA First**: Installable PWA with web(push) notifications; no native apps required
|
||||||
|
8. **Privacy-First Sharing**: Share links are temporary, scoped, and revocable
|
||||||
|
|
||||||
|
## Future (Phase 9)
|
||||||
|
|
||||||
|
Placeholders only — details land with tasks 85–88:
|
||||||
|
|
||||||
|
- **`journal/` module** — per-user journal (task 86, Gitea #19)
|
||||||
|
- **Versioned HTTP API** (`/api/v1/…`) with token auth alongside OIDC session (task 87, Gitea #15)
|
||||||
|
- **LLM agent chat** — OpenAI-compatible tools over the API (task 88)
|
||||||
|
|
||||||
@@ -42,9 +42,19 @@ Living progress tracker. Update at the end of each task. Codex and Claude Code b
|
|||||||
|
|
||||||
## Next up
|
## Next up
|
||||||
|
|
||||||
- **Ready to tag v0.1.0.** All phase 1–7 tasks complete and production wiring verified.
|
Phase 9 — Post-v0.1 (see `docs/superpowers/specs/2026-07-03-backlog-triage-design.md`, `docs/issues-map.md`).
|
||||||
- Run `docs/tasks/09-pre-deploy-checklist.md` before pushing the tag.
|
|
||||||
- On the server: clone repo to `/srv/famapp`, copy `.env.production.example` → `/srv/famapp/deploy/.env`, fill in secrets (AUTH_SECRET, DB passwords, AUTHENTIK_SECRET_KEY, VAPID keys, AUTH_OIDC_CLIENT_ID/SECRET), add the Caddyfile snippet, bootstrap Authentik per `deploy/authentik/README.md`, then `docker compose -f deploy/compose.yaml up -d`.
|
**Batch order:**
|
||||||
|
|
||||||
|
1. Bugs: tasks 80–84 (quick-add, dashboard edit, garden count, bangs, back-nav)
|
||||||
|
2. API foundation: task 87 (+ ADR 0006)
|
||||||
|
3. Shared rich-text + notes overhaul: task 85 (+ ADR 0004); closes notes mobile overflow
|
||||||
|
4. Journal: task 86 (+ ADR 0005), including journal API endpoints
|
||||||
|
5. LLM agent chat: task 88
|
||||||
|
|
||||||
|
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:** Read AGENTS.md / CLAUDE.md / STATUS.md, open the next unchecked task in `docs/tasks/80`–`88`, stop at acceptance criteria.
|
||||||
|
|
||||||
## Development login/testing notes
|
## Development login/testing notes
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# 0004 — Rich-text editor library and storage format
|
||||||
|
|
||||||
|
Date: 2026-07-03
|
||||||
|
Status: proposed
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Journal (task 86) and notes overhaul (task 85) need a shared rich-text editor with emoji support. Research and choose an existing library (e.g. TipTap/ProseMirror-family) rather than building one. Gitea: [#8](https://gitea.ginnoir.com/ginnoir/famapp/issues/8) (epic [#7](https://gitea.ginnoir.com/ginnoir/famapp/issues/7)).
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
To be filled when research completes.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
To be filled when research completes.
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# 0005 — Journal / mood tracking research
|
||||||
|
|
||||||
|
Date: 2026-07-03
|
||||||
|
Status: proposed
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Journal module (task 86) needs mood multi-select, charts over time, and insights. Research existing libraries/components for mood tracking or journaling and record build-vs-adopt. Gitea: [#20](https://gitea.ginnoir.com/ginnoir/famapp/issues/20) (epic [#19](https://gitea.ginnoir.com/ginnoir/famapp/issues/19)).
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
To be filled when research completes.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
To be filled when research completes.
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# 0006 — API auth and LLM agent architecture
|
||||||
|
|
||||||
|
Date: 2026-07-03
|
||||||
|
Status: proposed
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
P1 needs a documented API with token auth coexisting with OIDC session auth, plus a provider-agnostic OpenAI-compatible agent that tool-calls the API. Decide MCP vs direct tools. Gitea: [#14](https://gitea.ginnoir.com/ginnoir/famapp/issues/14) (epic [#13](https://gitea.ginnoir.com/ginnoir/famapp/issues/13)). Tasks 87 then 88.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
To be filled when research completes.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
To be filled when research completes.
|
||||||
@@ -26,4 +26,7 @@ What this costs us, what it buys us.
|
|||||||
|
|
||||||
- [0002 — List realtime uses Postgres NOTIFY and SSE](0002-list-sse-notify.md)
|
- [0002 — List realtime uses Postgres NOTIFY and SSE](0002-list-sse-notify.md)
|
||||||
- [0003 — Release workflow (commitlint + release-it)](0003-release-workflow.md)
|
- [0003 — Release workflow (commitlint + release-it)](0003-release-workflow.md)
|
||||||
|
- [0004 — Rich-text editor library and storage format](0004-rich-text-editor.md) (proposed)
|
||||||
|
- [0005 — Journal / mood tracking research](0005-journal-research.md) (proposed)
|
||||||
|
- [0006 — API auth and LLM agent architecture](0006-api-llm-agent.md) (proposed)
|
||||||
<!-- END AUTO-GENERATED -->
|
<!-- END AUTO-GENERATED -->
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
# Issue map
|
||||||
|
|
||||||
|
Design IDs from `docs/superpowers/specs/2026-07-03-backlog-triage-design.md` → Gitea (`ginnoir/famapp`).
|
||||||
|
|
||||||
|
| Design | Gitea | Title | URL |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 1 | 1 | Quick-add opens create UI, not module page | https://gitea.ginnoir.com/ginnoir/famapp/issues/1 |
|
||||||
|
| 2 | 2 | Dashboard edit mode renders live widgets at true size | https://gitea.ginnoir.com/ginnoir/famapp/issues/2 |
|
||||||
|
| 3 | 3 | Garden container plant count is wrong | https://gitea.ginnoir.com/ginnoir/famapp/issues/3 |
|
||||||
|
| 4 | 4 | Bangs are not editable (add edit and delete) | https://gitea.ginnoir.com/ginnoir/famapp/issues/4 |
|
||||||
|
| 5 | 5 | Notes overflow horizontally on mobile | https://gitea.ginnoir.com/ginnoir/famapp/issues/5 |
|
||||||
|
| 6 | 6 | Missing back navigation on detail pages (audit + shared affordance) | https://gitea.ginnoir.com/ginnoir/famapp/issues/6 |
|
||||||
|
| 7 | 28 | Calendar reminders overhaul | https://gitea.ginnoir.com/ginnoir/famapp/issues/28 |
|
||||||
|
| 8 | 29 | Lists index: inline task add + list property edit | https://gitea.ginnoir.com/ginnoir/famapp/issues/29 |
|
||||||
|
| 9 | 30 | Comments on lists and tasks | https://gitea.ginnoir.com/ginnoir/famapp/issues/30 |
|
||||||
|
| 10 | 7 | Notes editor overhaul (shared rich-text component) | https://gitea.ginnoir.com/ginnoir/famapp/issues/7 |
|
||||||
|
| 10.1 | 8 | Research ADR: rich-text editor library and storage format | https://gitea.ginnoir.com/ginnoir/famapp/issues/8 |
|
||||||
|
| 10.2 | 9 | Shared rich-text editor component | https://gitea.ginnoir.com/ginnoir/famapp/issues/9 |
|
||||||
|
| 10.3 | 10 | Wire shared editor into notes create/edit | https://gitea.ginnoir.com/ginnoir/famapp/issues/10 |
|
||||||
|
| 10.4 | 11 | Render note formatting on all notes surfaces | https://gitea.ginnoir.com/ginnoir/famapp/issues/11 |
|
||||||
|
| 10.5 | 12 | Fix notes mobile horizontal overflow | https://gitea.ginnoir.com/ginnoir/famapp/issues/12 |
|
||||||
|
| 11 | 31 | Bang stats dashboard widget | https://gitea.ginnoir.com/ginnoir/famapp/issues/31 |
|
||||||
|
| 12 | 35 | Appearance / theming options | https://gitea.ginnoir.com/ginnoir/famapp/issues/35 |
|
||||||
|
| 13 | 19 | Journal module | https://gitea.ginnoir.com/ginnoir/famapp/issues/19 |
|
||||||
|
| 13.1 | 20 | Research ADR: journal/mood tracking build-vs-adopt | https://gitea.ginnoir.com/ginnoir/famapp/issues/20 |
|
||||||
|
| 13.2 | 21 | Journal schema + CRUD | https://gitea.ginnoir.com/ginnoir/famapp/issues/21 |
|
||||||
|
| 13.3 | 22 | Journal index (recent, browse, entry calendar) | https://gitea.ginnoir.com/ginnoir/famapp/issues/22 |
|
||||||
|
| 13.4 | 23 | Journal entry detail and create | https://gitea.ginnoir.com/ginnoir/famapp/issues/23 |
|
||||||
|
| 13.5 | 24 | Journal mood tracker view | https://gitea.ginnoir.com/ginnoir/famapp/issues/24 |
|
||||||
|
| 13.6 | 25 | Journal insights/stats views | https://gitea.ginnoir.com/ginnoir/famapp/issues/25 |
|
||||||
|
| 13.7 | 26 | Journal E2E happy path | https://gitea.ginnoir.com/ginnoir/famapp/issues/26 |
|
||||||
|
| 13.8 | 27 | Journal API endpoints | https://gitea.ginnoir.com/ginnoir/famapp/issues/27 |
|
||||||
|
| 14 | 13 | API + LLM agent chat | https://gitea.ginnoir.com/ginnoir/famapp/issues/13 |
|
||||||
|
| 14.1 | 14 | Research ADR: API auth, surface shape, and LLM agent architecture | https://gitea.ginnoir.com/ginnoir/famapp/issues/14 |
|
||||||
|
| 14.2 | 15 | API surface + token auth for existing modules | https://gitea.ginnoir.com/ginnoir/famapp/issues/15 |
|
||||||
|
| 14.3 | 16 | LLM agent chat UI | https://gitea.ginnoir.com/ginnoir/famapp/issues/16 |
|
||||||
|
| 14.4 | 17 | Map agent tool-calling to API | https://gitea.ginnoir.com/ginnoir/famapp/issues/17 |
|
||||||
|
| 14.5 | 18 | Agent smoke tests with mock provider | https://gitea.ginnoir.com/ginnoir/famapp/issues/18 |
|
||||||
|
| 15 | 32 | Pets module | https://gitea.ginnoir.com/ginnoir/famapp/issues/32 |
|
||||||
|
| 16 | 33 | Shopping/pantry module | https://gitea.ginnoir.com/ginnoir/famapp/issues/33 |
|
||||||
|
| 17 | 34 | Backups and exports | https://gitea.ginnoir.com/ginnoir/famapp/issues/34 |
|
||||||
|
| 18 | 36 | GPS locations for calendar events | https://gitea.ginnoir.com/ginnoir/famapp/issues/36 |
|
||||||
|
| 19 | 37 | Lists and notes cohesion (research proposal) | https://gitea.ginnoir.com/ginnoir/famapp/issues/37 |
|
||||||
|
|
||||||
|
## Dependencies (P1)
|
||||||
|
|
||||||
|
| Issue | Depends on |
|
||||||
|
| --- | --- |
|
||||||
|
| #5 (notes overflow) | #7 (rich-text epic) |
|
||||||
|
| #12 (mobile overflow child) | #8 (rich-text research ADR) |
|
||||||
|
| #19 (journal epic) | #7 (rich-text epic), #15 (API surface) |
|
||||||
|
| #16 (agent UI) | #15 (API surface) |
|
||||||
|
| #17 (tool-calling) | #15 (API surface) |
|
||||||
|
| #27 (journal API) | #15 (API surface) |
|
||||||
|
|
||||||
|
Native Gitea issue dependencies API 404s on this instance; dependencies are also noted as comments on the issues above.
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# 80 — Quick-add opens create UI
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Make every quick-add action open the entity's creation dialog/sheet instead of only navigating to a module page.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Task 21 shipped URL navigation as a placeholder. Users expect "New event" to start creating an event immediately.
|
||||||
|
|
||||||
|
## Depends on
|
||||||
|
|
||||||
|
- 21 (quick-add registry)
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Extend `QuickAddAction` / client handling so actions can open create UI (dialog/sheet) in-place.
|
||||||
|
- Wire calendar, lists, notes, garden, bangs (and any other registered) quick-adds to their create UIs.
|
||||||
|
- Keep FAB sheet and cmd-k behavior identical per action.
|
||||||
|
- Playwright: extend `tests/e2e/dashboard.spec.ts` and/or add `tests/e2e/quick-add.spec.ts`.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Fuzzy search across entities.
|
||||||
|
- New entity types.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] Each registered quick-add opens create UI with create controls visible.
|
||||||
|
- [ ] No quick-add is navigation-only unless explicitly documented as view-only (none in v1 set).
|
||||||
|
- [ ] E2E: FAB → action opens dialog/sheet (not only route change).
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Gitea: [ginnoir/famapp#1](https://gitea.ginnoir.com/ginnoir/famapp/issues/1)
|
||||||
|
- Prefer reusing existing create dialogs/sheets over new ones.
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# 81 — Dashboard edit mode live widgets
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
In dashboard edit mode, render each widget's real data at its true final size so layout matches the saved view.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Edit mode currently shows empty placeholders; on save, content-heavy widgets (e.g. Recent activity) expand and the grid reflows.
|
||||||
|
|
||||||
|
## Depends on
|
||||||
|
|
||||||
|
- 26 (customizable layout + widget configuration)
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- `DashboardEditor` / edit mode loads real widget components and data (not empty shells).
|
||||||
|
- Widgets size to content consistently between edit and view modes.
|
||||||
|
- Playwright: extend `tests/e2e/dashboard.spec.ts` — enter `?edit=1`, assert real content visible. Prefer height-stability assertion only if non-flaky.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Redesigning the widget picker or config schemas.
|
||||||
|
- New widget types.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] Edit mode shows real widget content for registered widgets.
|
||||||
|
- [ ] Saving layout does not cause a large content-driven reflow for content-heavy widgets.
|
||||||
|
- [ ] E2E covers real content visible in edit mode.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Gitea: [ginnoir/famapp#2](https://gitea.ginnoir.com/ginnoir/famapp/issues/2)
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
# 82 — Garden container plant count
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Fix container plant counts so a container with N plants displays N, and audit sibling counts for the same bug.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Containers (e.g. "plantie cabinet") show "0 plants" despite containing plants — likely a query/join or association bug.
|
||||||
|
|
||||||
|
## Depends on
|
||||||
|
|
||||||
|
- 71 (garden containers), 72 (garden plants)
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Find and fix the count query in `src/modules/garden/server/queries.ts` (and related UI).
|
||||||
|
- Audit other garden counts (lists, widgets) for the same pattern; fix or file follow-ups.
|
||||||
|
- Playwright: extend `tests/e2e/garden.spec.ts` — plant in container → count ≥ 1.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- New garden features.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] Container with N plants displays N (not 0).
|
||||||
|
- [ ] Sibling counts audited; fixed or follow-ups filed.
|
||||||
|
- [ ] E2E covers plant-in-container count.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Gitea: [ginnoir/famapp#3](https://gitea.ginnoir.com/ginnoir/famapp/issues/3)
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# 83 — Bang edit and delete
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Allow editing and deleting bang entries after creation (e.g. wrong date).
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Bangs can be recorded but not corrected. Only create exists today.
|
||||||
|
|
||||||
|
## Depends on
|
||||||
|
|
||||||
|
- Bangs module (in tree; no prior task number)
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Server actions for update and delete.
|
||||||
|
- UI on the bang widget (and any list surface) for edit/delete.
|
||||||
|
- Activity log for update/delete if other modules log similarly.
|
||||||
|
- Playwright: new `tests/e2e/bangs.spec.ts` — record → edit date → assert → delete → assert gone.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Bang stats widget (design #11 / Gitea #31) — separate P2 issue.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] Edit a bang (e.g. change date) and see the update.
|
||||||
|
- [ ] Delete a bang and it no longer appears.
|
||||||
|
- [ ] E2E covers edit and delete.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Gitea: [ginnoir/famapp#4](https://gitea.ginnoir.com/ginnoir/famapp/issues/4)
|
||||||
|
- Related (not blocking): #31 bang stats widget.
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# 84 — Back navigation on detail pages
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Audit detail routes lacking back affordances and add a shared header/back pattern consistently.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Individual plant pages (and other detail routes) have no in-page "back" except global nav.
|
||||||
|
|
||||||
|
## Depends on
|
||||||
|
|
||||||
|
- Existing app routes under `src/app/`
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Audit all routes in `src/app/` for detail pages missing back; list them in the PR description.
|
||||||
|
- Shared back affordance (header/back component).
|
||||||
|
- Apply consistently to plant, note, list, and other detail pages.
|
||||||
|
- Playwright: `tests/e2e/navigation.spec.ts` or per-module — Back visible and returns to parent.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Redesigning global nav or dashboard tabs.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] Audit list included in PR.
|
||||||
|
- [ ] Shared back control on detail pages.
|
||||||
|
- [ ] E2E covers representative detail routes.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Gitea: [ginnoir/famapp#6](https://gitea.ginnoir.com/ginnoir/famapp/issues/6)
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# 85 — Rich-text notes overhaul
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Land a shared rich-text editor (ADR 0004), wire it through notes create/edit and all display surfaces, and fix mobile horizontal overflow.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Journal (86) and notes need modern formatting and emoji. Notes currently overflow sideways on mobile. P1 pulls the full notes overhaul into this batch.
|
||||||
|
|
||||||
|
## Depends on
|
||||||
|
|
||||||
|
- 12 (notes module)
|
||||||
|
- ADR `0004-rich-text-editor.md` (research child: Gitea #8)
|
||||||
|
- Batch order: after bugs 80–84 and API foundation 87 is preferred for notes API extension, but editor work can proceed once ADR is accepted
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Research and accept ADR 0004 (library e.g. TipTap, storage format, shared component contract).
|
||||||
|
- Shared editor component used by notes (and later journal).
|
||||||
|
- Notes create/edit use the shared editor.
|
||||||
|
- Render formatting on index, widgets, and share view.
|
||||||
|
- Fix mobile overflow (closes Gitea #5 / design #5).
|
||||||
|
- Playwright: extend `tests/e2e/notes.spec.ts` — formatted note visible; 375px no horizontal overflow.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Journal module (86) — consumes the shared editor after this lands.
|
||||||
|
- Appearance/theming epic.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] ADR 0004 accepted with library and storage format chosen.
|
||||||
|
- [ ] Shared editor component in tree.
|
||||||
|
- [ ] Notes create/edit use it.
|
||||||
|
- [ ] Formatting renders on all notes surfaces.
|
||||||
|
- [ ] Mobile overflow fixed; E2E green.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Gitea epic: [#7](https://gitea.ginnoir.com/ginnoir/famapp/issues/7); children #8–#12; overflow bug [#5](https://gitea.ginnoir.com/ginnoir/famapp/issues/5)
|
||||||
|
- Design: `docs/superpowers/specs/2026-07-03-backlog-triage-design.md`
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# 86 — Journal module
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Ship a per-user journal module with entries, mood tracking, insights, and journal API endpoints on the existing API foundation.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
P1 personal journaling with mood/stress/pills tracking and stats, without blocking on P2 work.
|
||||||
|
|
||||||
|
## Depends on
|
||||||
|
|
||||||
|
- 85 (shared rich-text editor)
|
||||||
|
- 87 (API surface for existing modules — journal adds endpoints the same way)
|
||||||
|
- ADR `0005-journal-research.md` (Gitea #20)
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Research ADR 0005 (mood/journal libs; build-vs-adopt).
|
||||||
|
- Schema + CRUD (per-user entries).
|
||||||
|
- Index: last 5–10 entries compact, browse all, small calendar of days with entries.
|
||||||
|
- Entry detail and create: **date (default today) and time (default now) required**; everything else optional.
|
||||||
|
- Fields: rich note text (shared editor); numerical stress; mood with color/emoji options and **multi-select**; took-my-pills-today boolean.
|
||||||
|
- Module-level mood-tracker view over time.
|
||||||
|
- Per-user insights/stats (trends, streaks, correlations — propose specifics in ADR/implementation).
|
||||||
|
- Journal API endpoints (additive on 87).
|
||||||
|
- Playwright: new `tests/e2e/journal.spec.ts` — minimal entry → recent list → detail → mood tracker loads.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Household-shared journals (per-user only).
|
||||||
|
- LLM agent tools for journal (88 can add later).
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] ADR 0005 accepted.
|
||||||
|
- [ ] Create entry with only date/time.
|
||||||
|
- [ ] Index, detail, mood tracker, and insights views work.
|
||||||
|
- [ ] Journal API endpoints documented and callable with token auth.
|
||||||
|
- [ ] E2E happy path green.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Gitea epic: [#19](https://gitea.ginnoir.com/ginnoir/famapp/issues/19); children #20–#27
|
||||||
|
- Depends on #7 (rich-text) and #15 (API surface)
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# 87 — API surface + token auth
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Documented HTTP API for existing modules (calendar, lists, notes, garden, bangs) with token auth suitable for non-browser clients, coexisting with OIDC session auth.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
API-early batch order: foundation lands after bugs so journal and notes can extend it; LLM agent (88) maps tools onto it.
|
||||||
|
|
||||||
|
## Depends on
|
||||||
|
|
||||||
|
- ADR `0006-api-llm-agent.md` research half (Gitea #14) — auth model and API shape decided before implementation
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Architecture ADR 0006: token auth vs OIDC session coexistence; API shape; additive versioning (no freeze that blocks journal).
|
||||||
|
- Token auth for non-browser clients.
|
||||||
|
- Endpoints for existing entities: events, lists/items, notes, garden, bangs (dashboards as needed).
|
||||||
|
- API docs (OpenAPI or equivalent living doc).
|
||||||
|
- Vitest for auth + route handlers; optional Playwright smoke only if useful.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- LLM agent chat UI and tool-calling (88).
|
||||||
|
- Journal endpoints (86 adds them).
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] ADR 0006 documents auth coexistence and API shape.
|
||||||
|
- [ ] Token-authenticated client can read/write covered entities.
|
||||||
|
- [ ] Session (OIDC) auth still works for the web app.
|
||||||
|
- [ ] Docs list endpoints and auth.
|
||||||
|
- [ ] Unit/integration tests for auth and handlers.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Gitea: epic [#13](https://gitea.ginnoir.com/ginnoir/famapp/issues/13); research [#14](https://gitea.ginnoir.com/ginnoir/famapp/issues/14); implementation [#15](https://gitea.ginnoir.com/ginnoir/famapp/issues/15)
|
||||||
|
- Batch step 6 (after bugs 80–84)
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# 88 — LLM agent chat
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Natural-language chat that acts on the app via tool-calling against the API, using a provider-agnostic OpenAI-compatible endpoint (self-hosted on the homelab).
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Users should say "add milk to the shopping list" or "what's on the calendar Friday?" and have the agent use the API.
|
||||||
|
|
||||||
|
## Depends on
|
||||||
|
|
||||||
|
- 87 (API surface)
|
||||||
|
- ADR `0006-api-llm-agent.md` agent half (MCP yes/no, tool mapping)
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Agent chat UI in the app.
|
||||||
|
- OpenAI-compatible client (provider-agnostic).
|
||||||
|
- Tool-calling mapped to API endpoints from 87 (and journal if present).
|
||||||
|
- Decide MCP vs direct tools in ADR 0006.
|
||||||
|
- Smoke tests with **mock/stub** provider in CI — no live LLM in CI.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Training or fine-tuning models.
|
||||||
|
- Forward-auth for other homelab apps.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] Chat UI sends prompts and shows responses.
|
||||||
|
- [ ] Tools call the API successfully in dev against the homelab endpoint.
|
||||||
|
- [ ] CI uses mock provider only.
|
||||||
|
- [ ] ADR 0006 records provider and MCP decisions.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Gitea: [#16](https://gitea.ginnoir.com/ginnoir/famapp/issues/16), [#17](https://gitea.ginnoir.com/ginnoir/famapp/issues/17), [#18](https://gitea.ginnoir.com/ginnoir/famapp/issues/18)
|
||||||
|
- Depends on [#15](https://gitea.ginnoir.com/ginnoir/famapp/issues/15)
|
||||||
@@ -79,3 +79,17 @@ Every task file has these sections:
|
|||||||
- [73 — Garden care tracking](73-garden-care-tracking.md)
|
- [73 — Garden care tracking](73-garden-care-tracking.md)
|
||||||
- [74 — Garden integrations](74-garden-integrations.md)
|
- [74 — Garden integrations](74-garden-integrations.md)
|
||||||
- [75 — Garden dashboard](75-garden-dashboard.md)
|
- [75 — Garden dashboard](75-garden-dashboard.md)
|
||||||
|
|
||||||
|
### Phase 9 — Post-v0.1
|
||||||
|
|
||||||
|
Batch order (bugs → API → editor/notes → journal → agent). Design: [`docs/superpowers/specs/2026-07-03-backlog-triage-design.md`](../superpowers/specs/2026-07-03-backlog-triage-design.md). Issue map: [`docs/issues-map.md`](../issues-map.md).
|
||||||
|
|
||||||
|
- [80 — Quick-add create UI](80-quick-add-create-ui.md)
|
||||||
|
- [81 — Dashboard edit live widgets](81-dashboard-edit-live-widgets.md)
|
||||||
|
- [82 — Garden plant count](82-garden-plant-count.md)
|
||||||
|
- [83 — Bang edit/delete](83-bang-edit-delete.md)
|
||||||
|
- [84 — Back navigation](84-back-navigation.md)
|
||||||
|
- [85 — Rich-text notes overhaul](85-rich-text-notes.md)
|
||||||
|
- [86 — Journal module](86-journal-module.md)
|
||||||
|
- [87 — API surface](87-api-surface.md)
|
||||||
|
- [88 — LLM agent chat](88-llm-agent-chat.md)
|
||||||
|
|||||||
Reference in New Issue
Block a user