Files
agent/docs/superpowers/plans/2026-09-14-editor-cms-connection.md
T

5.9 KiB

Editor CMS Connection Implementation Plan

For agentic workers: Use superpowers:executing-plans inline. The user requests direct execution; do not pause for another execution-mode choice.

Goal: Let the web app load the real editor Skill and authenticate its own CMS session, then read genuine drama inventory and subtitles without exposing credentials. Architecture: First implement the CMS/auth boundary as a separately testable milestone. It does not claim render readiness; the subsequent media milestone requires an authenticated source and explicit model/footage authorization. Original Skill and CMS code remain unchanged. Tech Stack: Existing Fastify, React, Pi, Zod, pinned official Supabase JS client. Spec: docs/superpowers/specs/2026-09-10-short-drama-web-design.md.

2026-09-14 execution checkpoint: Auth/API/UI/read-only tools are implemented. Full suite: 146 passed, lint/typecheck/build passed. Real login, 30-item catalog, Skill + CMS contract reads and status tool passed through the Vite/API/real-Qwen chain. Browser login/catalog also passed. Detailed evidence and remaining limitations: docs/editor-cms-web.md. Checklists below retain unverified cases (including explicit expiry, busy API mutation and browser content approval); do not interpret this milestone as full video acceptance.

Global Constraints

  • localhost single-user app; no CMS writes, RLS changes, service_role, arbitrary shell or uploads.
  • Authentication is a separate UI form; no password/token in chat, model tools, SSE or disk. Session reset clears only this app's CMS connection.
  • Fixed Supabase project and CMS origin; reject redirects. Only verified app_metadata.role=admin is accepted, matching actual backend checks.
  • Skill source is read-only; copy only explicitly enumerated references and script dependencies.
  • Do not equate readable Skill/catalog with a finished video pipeline.

Task 1: Authenticated CMS boundary

Files: packages/harness/src/cms/cms-connection.ts, packages/harness/tests/cms-connection.test.ts. Interface: CmsConnection({publishableKey,fetch?}): login(email,password), status(), clear(), listDramas(query,offset), inventory(dramaId), subtitle(dramaId,episodeId,locale).

  • RED: create real service tests with injected external HTTP responses. Assert no data query before login; fail non-admin even with user_metadata.admin; status omits passwords/tokens; subtitle rejects an episode not in the requested drama; inventory completeness preserves missing sources. Example: await expect(cms.listDramas('',0)).rejects.toMatchObject({code:'CMS_LOGIN_REQUIRED'}).
  • Run ../../node_modules/.bin/vitest run tests/cms-connection.test.ts in harness and observe missing implementation failure.
  • GREEN: use official createClient(url,key,{auth:{persistSession:false,autoRefreshToken:false,detectSessionInUrl:false}}). Call signInWithPassword then getUser and verify role. Fetch only known tables/selects, validate all returns with Zod; fixed CMS subtitle route and bounded responses. Never return raw SDK errors.
  • Verify tests and TypeScript, including expiry and disconnect; review credential lifecycle and request destinations.

Task 2: Session API and login UI

Files: apps/server/src/routes/cms.ts, apps/server/src/app.ts, apps/server/src/index.ts, apps/web/src/components/cms/CmsPanel.tsx, apps/web/src/App.tsx, corresponding route/component tests. Interface: GET/POST/DELETE /api/sessions/:sessionId/cms/connection; GET /api/sessions/:sessionId/cms/dramas?q=&offset=. All authenticated CMS objects are mapped by Session; dispose clears them.

  • RED: API rejects unknown Session, cross-origin mutation, concurrent login, busy mutation; private fields never appear in status. UI password empties on submission/failure/close; authenticated catalog selection fills an exact drama ID in Chat.
  • Run test files and observe failures before implementation.
  • GREEN: fixed-origin backend API, JSON-only login body, same-origin/fetch metadata guard, bounded login attempts, no-store. Status communicates connected and expiresAt; no user email or credentials to model. UI accessible labels, pending/error states and an explicit notice of the destination receiving credentials.
  • Verify route and UI tests; unchanged report flow passes.

Task 3: Real Skill and read-only tools

Files: packages/harness/src/cms/editor-tools.ts, apps/server/src/index.ts, tool policy, Skill and web tests. Interfaces: cms_connection_status, cms_list_dramas, cms_drama_inventory, cms_read_subtitle. Model never calls login or changes the connection. Inventory and subtitle access require page approval because they can disclose licensed/nonpublic content to the configured model.

  • RED: Skill snapshot reads full reference hierarchy; tools reject data access before login; policy asks for content reads; discovery alone does not claim rendering ready.
  • GREEN: enumerate trusted Skill resources, register tools only with that Skill, strict tool argument schemas, inject runtime instruction to report missing media/vision/research capability honestly and never use demo data.
  • Run all tests, lint, typecheck, build, then restart only the local Agent Studio service with secrets via hidden stdin.
  • Browser verify Skill entry, original instructions, login form and capability/status tools; request the user to authenticate through the form for the real CMS flow. Stop at a genuine missing login instead of inventing an admin session.

Remaining full-workflow milestones (not claimed by this plan)

After real CMS login is available: approved bounded HLS download; vision evidence and analysis v2 gate; configured reference research and scoring; immutable plan approval; fixed Python/FFmpeg worker with cancellation/quota; machine QA; human sound/viewing review; versioned downloads/export. Each requires its own test-first plan against the full spec. The task remains incomplete until these are verified on user-selected licensed footage.