Files
STCourses/docs/superpowers/plans/2026-10-30-v1-1.md
T

93 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# STCourses v1.1 Plan
> **For agentic workers:** each work package below is owned by one agent in its own git worktree (branch `feat/v11-<id>`, created from `main`). The agent writes its own detailed TDD plan at `docs/superpowers/plans/2026-10-30-v11-<id>.md` in the format of `docs/superpowers/plans/2026-10-30-stcourses.md`, then executes it. Spec: `docs/superpowers/specs/2026-10-30-stcourses-design.md`. Project rules: `CLAUDE.md`.
**Goal:** five improvements to v1:
- navigation motion (from user feedback);
- editing imported courses in the studio;
- a smaller first load;
- the deferred AI schema work;
- cleaning up stale dev scripts.
## Global Constraints
- Everything in `CLAUDE.md` "Project rules" applies.
- Motion:
- only light, purposeful motion: 120–220 ms, ease-out;
- opacity and short (≤ 8 px) translate only;
- no bounce, no scale-pop, no parallax;
- `prefers-reduced-motion: reduce` turns all of it off;
- motion must never delay input or block navigation.
- No new colours or fonts.
- Every DB change is a new portable migration that runs on SQLite and Postgres.
- Every change keeps `bun test`, `bun run typecheck` and the Postgres run green.
## Work packages
### M — Navigation motion (branch `feat/v11-motion`)
User feedback: "the navigation between courses, pages and steps could need some light animations and not switch as hard."
Scope:
- route changes in the shell;
- library to course;
- lesson to lesson, including previous/next and the floating action bar;
- module expand/collapse in the sidebar;
- deck slide changes;
- hint/fold open/close;
- progress bar fills;
- toasts and overlays.
Approach:
- Use the View Transitions API (`document.startViewTransition`) where the browser supports it, with a CSS-only fallback (a fade-in of the new content).
- Keep the sidebar and header stable during lesson changes, so they don't flash. Only the lesson column transitions.
- Restore scroll position correctly.
- Lesson content should appear as a quick fade plus a 4–6 px rise.
- `<details>` folds animate their height with the `interpolate-size` / `::details-content` pattern where supported, and open instantly otherwise.
Acceptance:
- headless-Chrome screenshots or recordings of mid-transition frames;
- no layout shift of the sidebar;
- a reduced-motion test shows no animation;
- no added JS dependency over 5 KB.
### S — Edit imported courses in the studio (branch `feat/v11-studio-import`)
Resolves the v1 TODO `TODO(studio): convert imported course to a studio-managed repo` (ruling R9).
Scope:
- Add an owner-only action, "Make editable in the studio", for imported courses under `<dataDir>/courses/<id>`.
- It creates `<dataDir>/studio/repos/<id>.git` from the course folder.
- Large media are NOT committed into git: they stay referenced in place, and the manifest paths keep working.
- Use `.gitignore` plus a media reference, or Git LFS only if it's already available. Document the choice.
- After conversion the course is served from the studio's published worktree. The original import folder is kept read-only as the media source, or moved under `<dataDir>/media/<id>`; pick one and document it.
- The id stays the same, so learners' progress and notes are kept.
- Visibility stays restricted until the owner changes it.
Acceptance: convert a synthetic imported course, edit a lesson title, publish, and confirm the learner sees the change, existing progress and notes survive, and media still play with Range requests.
### P — Smaller first load plus cleanup (branch `feat/v11-perf`)
v1 ships one JS file of about 1.8 MB plus 1.47 MB of CSS and fonts.
Scope:
- Code-split per feature route (lazy chunks for studio, import, AI and admin; the learner reader and library stay in the main chunk).
- Load the heavy libraries only where they are used:
- pdf.js only in the deck viewer;
- sanitize-html only where lesson HTML is rendered.
- Fonts: latin plus latin-ext subsets only, `font-display: swap`, and only the weights actually used.
- Long-cache headers for hashed assets in production.
Targets for the initial library page in a production build: at most 600 KB of JS gzip, and at most 350 KB of fonts and CSS. Measure and report before and after.
Cleanup:
- remove or update the stale per-package dev scripts (`packages/*/dev/serve.ts`, `scripts/dev.ts`), now superseded by `apps/server`;
- update READMEs and `docs/operations.md`.
### A — Deferred AI contract requests 3–5 (branch `feat/v11-ai`)
From `docs/contract-requests/ai.md`:
- (3) Tool calls as structured fields on `ChatMessage`, with providers updated (Anthropic tool_use/tool_result blocks, OpenAI tool_calls).
- (4) A per-course mentor setting stored in its own table instead of the generic `ai_settings` JSON. Migrate existing rows.
- (5) A citations column on `ai_messages`, so the UI renders citations from data rather than re-parsing text.
New migrations go in the AI package's migrations directory and must run on both DBs, with an upgrade test from the v1 schema. Also encrypt MCP `env`/`headers` at rest with the same AES-GCM/HKDF scheme as BYOK keys, never returning them in full to the UI (only masked). This was a v1 deferred minor.
## Order
M, S and A run in parallel. P starts after M is merged, because both touch the web shell and bundling. Each package gets a task review (and fix rounds) before merging, and a final whole-branch review runs on `main` at the end.