You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
2.7 KiB
Markdown
73 lines
2.7 KiB
Markdown
# 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
|