131 lines
7.0 KiB
Markdown
131 lines
7.0 KiB
Markdown
# VoxBlog Admin Project Plan
|
||
|
||
## Vision
|
||
Voice-first authoring tool for single-user Ghost blog. Capture audio, refine with AI, manage rich media, and publish seamlessly via a secure admin dashboard.
|
||
|
||
## Architecture Snapshot
|
||
- **Frontend**: `apps/admin` – React + TypeScript, Vite, Material UI, authenticated single-user dashboard.
|
||
- **Backend**: `apps/api` – Node.js (Express) providing auth, media upload, OpenAI & Ghost integrations, leveraging shared utilities.
|
||
- **Storage**: **MinIO (S3-compatible)** running on VPS (S3 API at `http://<vps>:9000`), with local dev fallback as needed.
|
||
- **Shared**: `packages/` for shared TypeScript types, client SDK, and utility modules.
|
||
|
||
## Milestones & Tasks
|
||
- **M1 · Access & Shell** (Scope: Goals 1 + infrastructure)
|
||
- [x] Scaffold workspace structure (frontend, backend, shared packages).
|
||
- [x] Implement .env management & secrets handling guidelines.
|
||
- [x] Build password gate (frontend form + backend verification).
|
||
- [x] Connect FE<->BE via Vite proxy and enable CORS.
|
||
- [x] Load .env in API with explicit path.
|
||
- [x] Bootstrap base admin layout with navigation placeholders.
|
||
- [ ] Document manual test checklist for auth flow.
|
||
- **M2 · Voice Capture Pipeline** (Scope: Goal 2)
|
||
- [x] Add browser audio recorder UI & permissions handling.
|
||
- [x] Stream/upload audio blobs to backend endpoint.
|
||
- [x] Persist raw audio (S3/local) with metadata.
|
||
- **M3 · Speech-to-Text Integration** (Scope: Goal 3)
|
||
- [x] Invoke OpenAI STT API server-side.
|
||
- [x] Surface transcript in rich editor state with status feedback.
|
||
- [x] Log conversion lifecycle for debug.
|
||
- **M4 · Rich Editor Enhancements** (Scope: Goal 4)
|
||
- [x] Integrate block-based editor (e.g., TipTap/Rich text) with custom nodes.
|
||
- [x] Implement file/image upload widget wired to storage.
|
||
- [ ] Support color picker, code blocks, and metadata fields.
|
||
- **M5 · AI Editing Tools** (Scope: Goal 5)
|
||
- [ ] Prompt templates for tone/style suggestions via OpenAI.
|
||
- [ ] Inline improvement workflow with diff/revert capabilities.
|
||
- **M6 · Ghost Publication Flow** (Scope: Goal 6)
|
||
- [ ] Map editor content (HTML) to Ghost post payload (title, html, tags[], feature_image, canonical_url)
|
||
- [ ] Backend: `/api/ghost/post` create/update (draft or published) using Ghost Admin API
|
||
- Body: `{ id?, title, html, tags: string[], feature_image?, canonical_url?, status: 'draft'|'published' }`
|
||
- Returns: `{ id, url, status }`
|
||
- [ ] Frontend: Metadata panel (title, tags input, feature image picker, canonical URL)
|
||
- [ ] Frontend: Buttons — "Save as Draft" and "Publish" (calls `/api/ghost/post`)
|
||
- [ ] Show status toast and link to view post
|
||
- [ ] ENV: `GHOST_ADMIN_API_URL`, `GHOST_ADMIN_API_KEY`, `GHOST_PUBLIC_URL`
|
||
- **M7 · Media Management** (Scope: Goal 7)
|
||
- [x] Centralize media library view with reuse.
|
||
- [ ] Background cleanup/retention policies.
|
||
- **M8 · UX Polish & Hardening** (Scope: Goal 8)
|
||
- [ ] Redesign admin layout (persistent sidebar navigation + header actions)
|
||
- [x] RichEditor toolbar (bold/italic/underline, headings, links, lists, code)
|
||
- [x] Insert images at cursor from MediaLibrary (use editor ref instead of appending)
|
||
- [ ] Snackbar toasts for upload/transcribe/save success & errors
|
||
- [ ] Loading skeletons/placeholders for MediaLibrary and Drafts
|
||
- [ ] Responsive layout tuning & accessibility audit
|
||
- [ ] Smoke test scripts for manual verification
|
||
- [x] Recorder playback compatibility (MediaRecorder mime selection, webm/mp4)
|
||
|
||
## Environment & Tooling TODOs
|
||
- **Core tooling**
|
||
- [ ] Configure PNPM workspaces (or Nx/Turbo) for multi-app repo.
|
||
- [ ] ESLint + Prettier shared config.
|
||
- [ ] Commit hooks (lint-staged, Husky) optional.
|
||
- **Secrets**
|
||
- [x] `.env.example` for common keys (ADMIN_PASSWORD_HASH, OPENAI_API_KEY, GHOST_ADMIN_API_KEY, S3 credentials).
|
||
- [ ] Instructions for local secret population.
|
||
|
||
## Tooling Decisions
|
||
- **Dependency manager**: Adopt PNPM with workspace support for mono-repo friendliness and fast installs.
|
||
- **Task runner**: Use Turborepo for orchestrating build/test scripts across apps/packages.
|
||
- **Package structure**: Maintain `apps/` for runtime targets and `packages/` for shared libraries.
|
||
|
||
## Immediate Next Actions
|
||
- [x] Create admin layout shell (header/sidebar, container)
|
||
- [x] Persist auth state (cookie/localStorage flag after success)
|
||
- [x] Add simple health route `/api/health` and error handler
|
||
- [x] Begin audio capture UI (mic permission + basic recorder)
|
||
- [x] Add concise request logging (morgan) and S3 op logs for visibility
|
||
|
||
## Upcoming Next Actions
|
||
- [x] Backend endpoint for audio upload `/api/media/audio` (accept WebM/PCM) — implemented with MinIO via AWS SDK v3
|
||
- [x] S3-compatible adapter using MinIO (`S3_ENDPOINT`, `S3_ACCESS_KEY`, `S3_SECRET_KEY`)
|
||
- [x] Backend STT endpoint `/api/stt` (download from MinIO, call OpenAI STT, return transcript)
|
||
- [x] Add STT trigger in UI: call `/api/stt` with `{ bucket, key }` and render transcript
|
||
|
||
## Next Priorities
|
||
- [x] Save transcript into an editor document (draft state) and display in editor.
|
||
- [x] Add simple document persistence API (filesystem) at `/api/drafts` (list/get/save).
|
||
- [x] Wire editor to use `/api/drafts` (load/save) instead of only localStorage.
|
||
- [ ] List uploaded media items and allow re-use/deletion.
|
||
|
||
## Verification Steps
|
||
- [ ] Start API: `pnpm run dev -C apps/api`
|
||
- [ ] Start Admin: `pnpm run dev -C apps/admin`
|
||
- [ ] Record → Stop → Upload → Transcribe; see transcript populate Draft.
|
||
- [ ] Save Draft (local) and verify persistence on reload.
|
||
|
||
## MinIO Integration Checklist
|
||
- [ ] Deploy MinIO on VPS (console `:9001`, API `:9000`).
|
||
- [ ] Create bucket `voxblog` and access keys.
|
||
- [ ] Configure `.env` with:
|
||
- `S3_ENDPOINT=http://<vps>:9000`
|
||
- `S3_BUCKET=voxblog`
|
||
- `S3_REGION=us-east-1`
|
||
- `S3_ACCESS_KEY=...`
|
||
- `S3_SECRET_KEY=...`
|
||
- [ ] Optional: Set bucket policy to allow public reads for media.
|
||
|
||
## Scaffolding Plan (Draft)
|
||
- **Frontend (`apps/admin`)**
|
||
- `pnpm create vite apps/admin --template react-ts`
|
||
- Add Material UI (`pnpm add @mui/material @mui/icons-material @emotion/react @emotion/styled -C apps/admin`).
|
||
- **Backend (`apps/api`)**
|
||
- `pnpm dlx degit expressjs/express apps/api`
|
||
- Install TypeScript + tooling (`pnpm add -D typescript ts-node-dev @types/node @types/express -C apps/api`).
|
||
- **Shared packages**
|
||
- `pnpm create @tsconfig/bases packages/config-ts` (or manual `tsconfig` shared file).
|
||
- Create `packages/types` for shared TypeScript definitions.
|
||
- **Workspace root**
|
||
- Initialize PNPM workspace: `pnpm init`, add `pnpm-workspace.yaml` with `apps/**` and `packages/**`.
|
||
- Configure Turborepo: `pnpm add -D turbo`, add `turbo.json` with build/dev/lint pipelines.
|
||
|
||
## Risks & Assumptions
|
||
- **OpenAI & Ghost API access** available with required scopes.
|
||
- **Single admin user** requirement simplifies auth; if multi-user emerges, revisit architecture.
|
||
- **Browser recording support** assumed for target browsers (Chrome/Edge latest).
|
||
|
||
## References
|
||
- Ghost Admin API docs
|
||
- OpenAI Whisper/Speech-to-Text API docs
|
||
- AWS S3 SDK for Node.js
|