docs: add spec for preferred sources feature
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>master
parent
78844c4ebe
commit
48b5e77e7e
@ -0,0 +1,72 @@
|
||||
# Design: Preferred Sources
|
||||
|
||||
**Date**: 2026-03-27
|
||||
**Scope**: Allow users to mark sources as preferred so they are processed first during synthesis generation.
|
||||
|
||||
---
|
||||
|
||||
## 1. Data Model
|
||||
|
||||
Add `is_preferred BOOLEAN NOT NULL DEFAULT false` to the `sources` table. All existing sources default to non-preferred.
|
||||
|
||||
**Bulk update endpoint:** `PUT /api/v1/sources/preferred` with body `{ "source_ids": ["uuid1", "uuid2"] }`. Sets the listed sources to `preferred = true` and all others (for the same user) to `false`. This is an idempotent "set the full list" operation.
|
||||
|
||||
---
|
||||
|
||||
## 2. Pipeline Shuffle
|
||||
|
||||
### Source ordering (before wave chunking)
|
||||
|
||||
After `rotate_sources`, split into preferred and non-preferred, preserving rotation order within each group:
|
||||
|
||||
```
|
||||
rotated = rotate_sources(all_sources)
|
||||
preferred = rotated.filter(is_preferred)
|
||||
non_preferred = rotated.filter(!is_preferred)
|
||||
ordered = preferred ++ non_preferred
|
||||
waves = ordered.chunks(window_size)
|
||||
```
|
||||
|
||||
Preferred sources are processed in earlier waves, maximizing their chance of filling the synthesis.
|
||||
|
||||
### URL shuffle (within each wave)
|
||||
|
||||
After extracting links from a wave's sources, split candidate URLs by whether their source was preferred:
|
||||
|
||||
```
|
||||
preferred_urls = wave_urls.filter(source is preferred)
|
||||
other_urls = wave_urls.filter(source is not preferred)
|
||||
shuffle(preferred_urls)
|
||||
shuffle(other_urls)
|
||||
final = preferred_urls ++ other_urls
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Frontend
|
||||
|
||||
### ThemeManager source list
|
||||
|
||||
- Checkbox on each source row (left side)
|
||||
- Preferred sources get a star icon or subtle highlight
|
||||
- Counter at bottom: "X source(s) prioritaire(s)"
|
||||
- Auto-save: on check/uncheck, immediately call `PUT /api/v1/sources/preferred` with updated ID list
|
||||
|
||||
---
|
||||
|
||||
## 4. Files
|
||||
|
||||
- **Create:** `backend/migrations/20260327000029_add_source_preferred.sql`
|
||||
- **Create:** `backend/tests/api_sources_preferred_test.rs`
|
||||
- **Modify:** `backend/src/models/source.rs` — add `is_preferred: bool` to `Source`
|
||||
- **Modify:** `backend/src/db/sources.rs` — add to queries, add `update_preferred` function
|
||||
- **Modify:** `backend/src/handlers/sources.rs` — add `update_preferred` handler
|
||||
- **Modify:** `backend/src/router.rs` — add route
|
||||
- **Modify:** `backend/src/services/synthesis.rs` — preferred-first ordering + shuffle
|
||||
- **Modify:** `backend/tests/pipeline_test.rs` — test preferred ordering
|
||||
- **Modify:** `frontend/src/pages/ThemeManager.tsx` — checkboxes, counter, auto-save
|
||||
- **Modify:** `frontend/src/api/sources.ts` — add `updatePreferred`
|
||||
- **Modify:** `frontend/src/types.ts` — add `is_preferred` to `Source`
|
||||
- **Modify:** `frontend/src/i18n/fr.ts` — labels
|
||||
- **Modify:** `e2e/tests/sources.spec.ts` — add preferred test
|
||||
- **Modify:** `CLAUDE.md` — migration count
|
||||
Loading…
Reference in New Issue