docs: add remove cover page design

This commit is contained in:
2026-06-16 06:54:01 -06:00
parent 979a70439b
commit 478e002068

View File

@@ -0,0 +1,108 @@
# Remove Cover Page Design
## Goal
Remove the cover page feature completely from the teaching book workflow, including UI entry points, editable cover state, and legacy saved `cover` data in book JSON.
## Scope
In scope:
- Remove `TeachingBook.cover` from the domain model.
- Change `TeachingBook.selectedId` from `'cover' | DesignId` to `DesignId | null`.
- Make newly created books start with no selected page.
- Migrate existing stored book JSON by deleting `cover`.
- Migrate existing `selectedId: 'cover'` to the first lesson id, or `null` when the book has no lessons.
- Remove the sidebar "封面" navigation item.
- Remove cover rendering and cover update events from the A4 workspace.
- Stop passing cover state through `WorkspaceView.vue`.
- Delete the unused `CoverPage.vue` component and cover-specific CSS.
- Update tests for the domain model, store behavior, sidebar, workspace, DB migration, and route persistence.
Out of scope:
- Removing book names from the book list. `BookRecord.name` remains the management/display name for each saved book.
- Changing lesson rendering, print layout, Markdown export, ZIP export, or generated lesson content.
- Creating a user-facing migration screen.
## Data Model
`TeachingBook` becomes lesson-only:
```ts
export interface TeachingBook {
schemaVersion: typeof BOOK_SCHEMA_VERSION
designs: TeachingDesign[]
selectedId: DesignId | null
updatedAt: string
}
```
`createEmptyBook()` returns an empty `designs` array and `selectedId: null`.
The schema version can stay at `1` because the server migration normalizes stored JSON at load/open time. The app does not need to preserve old cover data.
## Legacy Data Migration
The server will normalize every stored book when opening the SQLite database:
- Parse `books.data`.
- Delete `data.cover` when present.
- If `data.selectedId === 'cover'`, set it to `data.designs[0].id` when a first lesson exists, otherwise `null`.
- If `data.selectedId` points to a missing lesson id, set it to the first lesson id or `null`.
- Persist the normalized JSON back into the row only when it changed.
This ensures old database rows no longer contain `cover` after the app starts, not just after a user edits the book.
## UI Behavior
The workspace has no cover page:
- `LessonSidebar.vue` lists lessons only.
- Empty books continue to show the upload dropzone instead of an A4 page.
- `A4Workspace.vue` renders `TeachingDesignPage` only when there is a selected lesson.
- `WorkspaceView.vue` no longer passes cover props or listens for cover update events.
Selection behavior becomes:
- Importing lessons into an empty book selects the first imported/sorted lesson.
- Generating a lesson selects the generated lesson.
- Deleting the selected lesson selects the next lesson, then previous lesson, then `null`.
- Clearing all lessons sets `selectedId` to `null`.
## Removed Code
Delete:
- `src/components/CoverPage.vue`
- Cover-specific CSS rules in `src/style.css`
Keep:
- Book list names and backend book metadata.
- Existing print/export behavior, which already renders lessons without a cover page.
## Testing
Domain tests verify:
- New books do not have `cover`.
- New books start with `selectedId: null`.
- Independent book creation still produces independent lesson arrays.
DB tests verify:
- Opening a database migrates old `cover` data out of saved book JSON.
- Old `selectedId: 'cover'` becomes the first lesson id when lessons exist.
- Old `selectedId: 'cover'` becomes `null` when no lessons exist.
- Invalid selected ids are normalized.
Store/component tests verify:
- `useTeachingBook` no longer exposes `updateCover`.
- Clear/delete/import/generate selection behavior uses `null` or lesson ids only.
- `LessonSidebar` does not render a cover button.
- `A4Workspace` does not import or render `CoverPage`.
- `WorkspaceView` does not pass cover props.
Verification will run the frontend tests, backend tests, and production build.