All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 1m22s
157 lines
5.0 KiB
Markdown
157 lines
5.0 KiB
Markdown
# Account Sync Drafts Implementation Plan
|
||
|
||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||
|
||
**Goal:** Add lightweight account/password auth, cloud draft persistence, cross-device restore, resumable episode conversion, and full-regenerate controls.
|
||
|
||
**Architecture:** Keep the current Vite frontend, add a minimal Express + SQLite backend under `server/`, and let the frontend auto-save/load the current draft for the logged-in account. Continue using the existing conversion UI, but persist the generated episode results and resume state remotely.
|
||
|
||
**Tech Stack:** React 19, TypeScript, Vite, Express, better-sqlite3, Node crypto, SQLite
|
||
|
||
---
|
||
|
||
### Task 1: Create backend skeleton and shared storage model
|
||
|
||
**Files:**
|
||
- Create: `server/index.ts`
|
||
- Create: `server/db.ts`
|
||
- Create: `server/auth.ts`
|
||
- Modify: `package.json`
|
||
- Modify: `vite.config.ts`
|
||
|
||
**Step 1: Add a backend run script**
|
||
- Add `dev:server` and `dev:full` scripts.
|
||
- Keep existing frontend scripts unchanged.
|
||
|
||
**Step 2: Create SQLite schema helpers**
|
||
- Add `users`, `sessions`, and `drafts` tables.
|
||
- Store one current draft JSON blob per user for now.
|
||
|
||
**Step 3: Add Express server bootstrap**
|
||
- Enable JSON body parsing.
|
||
- Mount auth and draft endpoints under `/api`.
|
||
|
||
**Step 4: Add Vite proxy for local development**
|
||
- Proxy `/api` to the local backend server.
|
||
|
||
**Step 5: Verify backend compiles under TypeScript**
|
||
- Run `npm run lint`.
|
||
|
||
### Task 2: Implement lightweight account/password authentication
|
||
|
||
**Files:**
|
||
- Modify: `server/db.ts`
|
||
- Modify: `server/auth.ts`
|
||
- Modify: `server/index.ts`
|
||
|
||
**Step 1: Implement password hashing with Node crypto**
|
||
- Use `scryptSync` + random salt.
|
||
|
||
**Step 2: Add register endpoint**
|
||
- Accept `username` and `password`.
|
||
- Reject duplicate usernames and invalid payloads.
|
||
|
||
**Step 3: Add login endpoint**
|
||
- Verify password.
|
||
- Create a random session token and persist it.
|
||
|
||
**Step 4: Add auth middleware**
|
||
- Read bearer token.
|
||
- Resolve current user from `sessions`.
|
||
|
||
**Step 5: Add session restore endpoint**
|
||
- Return current user info when token is valid.
|
||
|
||
### Task 3: Add cloud draft persistence endpoints
|
||
|
||
**Files:**
|
||
- Modify: `server/db.ts`
|
||
- Modify: `server/index.ts`
|
||
- Create: `server/types.ts`
|
||
|
||
**Step 1: Define draft payload shape**
|
||
- Include conversion settings, extracted episodes, conversion episode results, finalized selections, and source metadata.
|
||
|
||
**Step 2: Add load current draft endpoint**
|
||
- Return the saved draft JSON for the authenticated user.
|
||
|
||
**Step 3: Add save current draft endpoint**
|
||
- Upsert the latest draft JSON and update timestamp.
|
||
|
||
**Step 4: Add reset/restart endpoint if needed**
|
||
- Allow frontend to intentionally replace cloud draft on full regeneration.
|
||
|
||
### Task 4: Add frontend auth state and draft synchronization
|
||
|
||
**Files:**
|
||
- Create: `src/services/api.ts`
|
||
- Modify: `src/App.tsx`
|
||
- Modify: `src/main.tsx` if needed
|
||
|
||
**Step 1: Add auth modal/panel UI**
|
||
- Support register and login with username/password.
|
||
|
||
**Step 2: Add token persistence**
|
||
- Save token locally and restore session on app load.
|
||
|
||
**Step 3: Load remote draft on login/app restore**
|
||
- Hydrate the conversion state from the server.
|
||
|
||
**Step 4: Auto-save remote draft**
|
||
- Debounce save calls when relevant conversion state changes.
|
||
- Save generated content and manual edits.
|
||
|
||
### Task 5: Strengthen resumable conversion workflow
|
||
|
||
**Files:**
|
||
- Modify: `src/App.tsx`
|
||
- Modify: `src/services/ai.ts`
|
||
- Modify: `src/lib/conversionWorkflow.ts`
|
||
- Modify: `tests/conversionWorkflow.test.ts`
|
||
|
||
**Step 1: Preserve current stop/resume behavior**
|
||
- Keep paused episode/version state intact.
|
||
|
||
**Step 2: Add `<60><><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>` control**
|
||
- When a resumable state exists, show both `<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>` and `<60><><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>`.
|
||
- Full regenerate clears existing generated episode results before starting from episode 1.
|
||
|
||
**Step 3: Ensure manual edits persist**
|
||
- Save edited episode version content into draft state and remote storage.
|
||
|
||
### Task 6: Enforce continuity and scope constraints in generation
|
||
|
||
**Files:**
|
||
- Modify: `src/App.tsx`
|
||
- Modify: `src/services/ai.ts`
|
||
|
||
**Step 1: Build previous-episode continuity context**
|
||
- For episode N, pass episode N-1 selected final version, or current active version if not finalized.
|
||
|
||
**Step 2: Restrict generation scope**
|
||
- Explicitly tell the model to only generate within the current episode outline shown on the left.
|
||
|
||
**Step 3: Reassert global constraints**
|
||
- Require adherence to worldview, story outline, and core character settings.
|
||
|
||
**Step 4: Keep resume continuation safe**
|
||
- Continue from already generated content without rewriting earlier text.
|
||
|
||
### Task 7: Verification
|
||
|
||
**Files:**
|
||
- Test: `tests/conversionWorkflow.test.ts`
|
||
- Test: backend endpoint smoke verification via local commands
|
||
|
||
**Step 1: Run draft workflow unit test**
|
||
- Run `node --experimental-strip-types tests/conversionWorkflow.test.ts`
|
||
|
||
**Step 2: Run type-check**
|
||
- Run `npm run lint`
|
||
|
||
**Step 3: Run production build**
|
||
- Run `npm run build`
|
||
|
||
**Step 4: Smoke-test backend boot if possible**
|
||
- Start local backend and verify auth/draft endpoints respond.
|