From 4dc18a4e72dfb93e4374e744f20008155a3c9660 Mon Sep 17 00:00:00 2001 From: oabrivard Date: Thu, 26 Mar 2026 22:51:02 +0100 Subject: [PATCH] docs: add spec for multi-theme synthesis support Co-Authored-By: Claude Opus 4.6 (1M context) --- .../specs/2026-03-26-multi-theme-design.md | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 docs/superpowers/specs/2026-03-26-multi-theme-design.md diff --git a/docs/superpowers/specs/2026-03-26-multi-theme-design.md b/docs/superpowers/specs/2026-03-26-multi-theme-design.md new file mode 100644 index 0000000..045bebc --- /dev/null +++ b/docs/superpowers/specs/2026-03-26-multi-theme-design.md @@ -0,0 +1,148 @@ +# Design: Multi-Theme Synthesis Support + +**Date**: 2026-03-26 +**Scope**: Allow users to create multiple themes, each with its own content settings and sources, generating syntheses per theme. + +--- + +## Context + +Currently each user has a single theme with one set of categories. Users who follow multiple topics (e.g. AI + Cybersecurity) must choose one or regenerate with different settings. This feature adds support for multiple themes per user. + +--- + +## 1. Data Model + +### New table: `themes` + +```sql +CREATE TABLE themes ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + name TEXT NOT NULL, + theme TEXT NOT NULL, + categories JSONB NOT NULL DEFAULT '[]', + max_items_per_category INTEGER NOT NULL DEFAULT 4, + max_age_days INTEGER NOT NULL DEFAULT 7, + summary_length INTEGER NOT NULL DEFAULT 3, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now() +); +CREATE INDEX idx_themes_user_id ON themes(user_id); +``` + +### Modified table: `sources` + +Add `theme_id UUID REFERENCES themes(id) ON DELETE CASCADE`. Sources become per-theme. + +### Modified table: `syntheses` + +Add `theme_id UUID REFERENCES themes(id) ON DELETE SET NULL`. Links each synthesis to its theme. `SET NULL` preserves syntheses when a theme is deleted. + +### Modified table: `settings` + +Remove columns that move to `themes`: `theme`, `categories`, `max_items_per_category`, `max_age_days`, `summary_length`. + +### Migration strategy + +1. Create `themes` table +2. For each user with settings, create a default theme from their current content settings +3. Add `theme_id` to `sources`, populate with the user's default theme +4. Add `theme_id` to `syntheses`, populate with the user's default theme +5. Drop moved columns from `settings` + +--- + +## 2. Backend API + +### New endpoints — Themes CRUD + +- `GET /api/v1/themes` — list user's themes +- `POST /api/v1/themes` — create a new theme +- `PUT /api/v1/themes/:id` — update a theme +- `DELETE /api/v1/themes/:id` — delete a theme (syntheses kept with `theme_id = NULL`) + +### Modified endpoints + +- `GET /api/v1/sources` — add optional `?theme_id=` filter +- `POST /api/v1/sources` — require `theme_id` in request body +- `POST /api/v1/syntheses/generate` — require `theme_id` in request body +- `GET /api/v1/syntheses` — response includes `theme_name`. Add optional `?sort=date|theme` param. + +### Pipeline change + +`run_generation_inner` receives `theme_id` and loads content settings (theme, categories, max_items, max_age, summary_length) from the `themes` table instead of `settings`. Global settings (provider, models, batch_size, rate limits, etc.) still come from `settings`. + +--- + +## 3. Frontend — "Personnaliser les syntheses" page + +### Navigation rename + +"Sources personnalisees" → "Personnaliser les syntheses" + +### Page layout + +1. **Theme selector** — dropdown listing all user themes + "Creer un nouveau theme" button +2. **Content settings** — theme name, search topic, categories (add/remove), max age, max items, summary length slider. Moved from Settings page. +3. **Sources** — existing sources list, filtered by selected theme. Add/delete/bulk import scoped to current theme. +4. **Delete theme** — danger button with confirmation. + +### Settings page changes + +Remove the "Contenu" section. Keep: Sources (pipeline tuning), Intelligence Artificielle, Performance, Import/Export. + +--- + +## 4. Frontend — Home page enhancements + +- **Theme badge** on synthesis cards (below week label). "Theme supprime" for null theme_id. +- **Sort toggle**: "Trier par: Date | Theme". Default: Date. Theme sort groups by theme name. +- **Generate page**: theme dropdown before "Generate" button. Pre-selects last used theme. + +--- + +## 5. Implementation phases + +| Phase | Scope | Dependencies | +|-------|-------|-------------| +| 1 | Data model + backend API (migrations, themes CRUD, pipeline) | None | +| 2 | Theme management page (new page, move content settings) | Phase 1 | +| 3 | Generation with theme (generate page dropdown) | Phase 1 | +| 4 | Home page enhancements (theme badge, sort) | Phase 1 | + +Each phase produces working software. Phases 2-4 can be done in any order after Phase 1. + +--- + +## Files overview + +### Phase 1 (Backend) +- **Create:** `backend/migrations/20260326000028_create_themes.sql` +- **Create:** `backend/src/db/themes.rs` +- **Create:** `backend/src/models/theme.rs` +- **Create:** `backend/src/handlers/themes.rs` +- **Modify:** `backend/src/db/mod.rs`, `backend/src/models/mod.rs`, `backend/src/handlers/mod.rs` +- **Modify:** `backend/src/router.rs` — add theme routes +- **Modify:** `backend/src/db/sources.rs` — add `theme_id` filter +- **Modify:** `backend/src/db/syntheses.rs` — add `theme_id`, `theme_name` to queries +- **Modify:** `backend/src/models/settings.rs` — remove moved fields +- **Modify:** `backend/src/db/settings.rs` — remove moved columns from queries +- **Modify:** `backend/src/services/synthesis.rs` — load content settings from theme +- **Modify:** `backend/src/handlers/generation.rs` — accept `theme_id` + +### Phase 2 (Theme page) +- **Create:** `frontend/src/pages/ThemeManager.tsx` +- **Create:** `frontend/src/api/themes.ts` +- **Modify:** `frontend/src/App.tsx` — routes +- **Modify:** `frontend/src/components/Navbar.tsx` — rename nav item +- **Modify:** `frontend/src/pages/Settings.tsx` — remove Contenu section +- **Modify:** `frontend/src/i18n/fr.ts` — labels + +### Phase 3 (Generate) +- **Modify:** `frontend/src/pages/GenerateSynthesis.tsx` — theme dropdown +- **Modify:** `frontend/src/api/syntheses.ts` — pass theme_id + +### Phase 4 (Home) +- **Modify:** `frontend/src/pages/Home.tsx` — theme badge, sort +- **Modify:** `frontend/src/types.ts` — add theme fields to types