feat: uv config other feats

- add uv configuration for the backend
- update frontend to make auth work
- add new auth endpoints
- add bookmars feat
- add reader feat
This commit is contained in:
2026-06-03 22:06:01 -05:00
parent 730c748f5f
commit 6b4c0c43f8
137 changed files with 20319 additions and 2340 deletions
+83
View File
@@ -0,0 +1,83 @@
# 015 — EPUB bookmarks and notes (physical-book UX)
**Status:** Implemented
**Created:** 2026-06-04
## Objective
Let users select passage text while reading an EPUB, save a bookmark (with optional thought), list markers in chapter order, and jump back to the exact location. Global view groups markers by book in a Reddit-style thread layout.
## Fix: AnnotationsProvider
`AnnotationsProvider` wraps all routes in [`App.tsx`](frontend/src/App.tsx) so `/bookmarks-notes` and the reader can use `useAnnotations()`.
## Data model
`Bookmark` (annotations app) references **`books.EBook`**, not catalog `Book`:
| Field | Purpose |
|-------|---------|
| `ebook` | FK to uploaded ebook |
| `epub_cfi` | EPUB CFI anchor |
| `chapter_index` | Spine index for sort order |
| `chapter_title` | Display label |
| `location_text` | Selected passage quote |
| `content` | Optional user thought (empty = bookmark only) |
| `page` | Legacy display field (`chapter_index + 1`) |
Unique: `(user, ebook, epub_cfi)`.
Default API ordering: `chapter_index`, `epub_cfi`.
Legacy `Note` model remains for old API; new UX uses `Bookmark.content` only.
## Reader flow
```mermaid
sequenceDiagram
participant User
participant EpubView
participant Popover
participant API
User->>EpubView: Select text
EpubView->>Popover: Show near selection
User->>Popover: Save optional thought
Popover->>API: POST /annotations/bookmarks/
```
1. Text selection via epub.js `selected` event and content `mouseup` hook.
2. [`SelectionPopover`](frontend/src/components/reader/SelectionPopover.tsx) — floating UI, optional textarea.
3. Toolbar bookmark icon opens [`BookMarkersPanel`](frontend/src/components/reader/BookMarkersPanel.tsx) (current ebook only).
4. “Go to passage” sets reader `location` to stored CFI (`/read/:id` with router state).
## Global page (`/bookmarks-notes`)
[`MarkerThreadsView`](frontend/src/components/annotations/MarkerThreadsView.tsx):
- Groups markers by ebook (collapsible book rows).
- Within each book: chapter order, passage as blockquote, thought indented below (Reddit-style).
- Optional filter: `/bookmarks-notes/:ebookId`.
## API
- `GET /api/annotations/bookmarks/?ebook={id}`
- `POST /api/annotations/bookmarks/` — body: `ebook`, `epub_cfi`, `chapter_index`, `chapter_title`, `location_text`, `content`
## i18n
New keys under `annotations.*` (EN/ES): `saveMarker`, `thoughtPlaceholder`, `bookmarkOnly`, `selectTextHint`, `goToPassage`, `inBookPanel`, `markerCount`, etc.
## Verification
1. `/bookmarks-notes` loads without provider error.
2. Select text in reader → popover → save with/without thought.
3. Markers appear in reader panel and global page under correct book, in chapter order.
4. “Go to passage” opens the correct location.
See also [016 — Bookmark reading anchor](016-bookmark-reading-anchor.md) for preserving reading position while peeking at bookmarks.
## Out of scope
- PDF selection
- Multiple replies per passage
- Migrating legacy `Note` rows into `Bookmark`