nexus/.planning/phases/42-wallpapers-social-format-conversion-voice/42-06-SUMMARY.md

6.6 KiB

phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
42-wallpapers-social-format-conversion-voice 06 ui
react
typescript
drag-drop
format-conversion
deep-link
SSE
FormData
multipart
shadcn
lucide
phase plan provides
42-wallpapers-social-format-conversion-voice 03 POST /api/companies/:companyId/convert (multipart), GET /api/system/converters, ConvertBundle type
phase provides
40-content-job-infra useContentJob hook, getContentJobAsset, SSE job tracking pattern
ui/src/api/convert.ts — submitConvertJob (multipart) and getConverterCapabilities API client
ui/src/components/ConvertPanel.tsx — drag-drop + grouped format chips + AI fallback notice + download
ui/src/pages/ConvertPage.tsx — /convert route with deep-link URL param reading
ui/src/App.tsx — three route variants /convert, /convert/:src, /convert/:src/:tgt
Any future phase adding nav links to /convert
added patterns
Direct fetch (not api.post) for multipart submissions that need per-status-code inspection (422 vs 202)
Direct EventSource connection for pre-submitted jobs (bypasses useContentJob.submit which re-submits)
FORMAT_GROUPS constant exported from ConvertPanel for reuse in ConvertPage validation
normalizeFormatParam helper
toLowerCase + allowlist check, silently returns undefined for invalid params
created modified
ui/src/api/convert.ts
ui/src/components/ConvertPanel.tsx
ui/src/pages/ConvertPage.tsx
ui/src/App.tsx
Direct fetch used in submitConvertJob (not api.postForm) to inspect 422 vs 202 status before throwing — api.request() throws on !res.ok, but 422 is a valid business response with MIME error body
Direct EventSource in ConvertPanel for already-submitted jobs — useContentJob.submit() calls submitContentJob internally and cannot track an existing jobId without re-submitting
FORMAT_GROUPS exported from ConvertPanel so ConvertPage can import the same constant for allowlist validation without duplicating the list
AI fallback notice shown per target format group (Images/AV/Docs/Data) based on capabilities, not per individual format pair — matches CONV-08 spec that all paths fall to AI bridge when direct converter unavailable
Format chip role=radio within role=radiogroup — matches accessibility spec from 42-UI-SPEC.md
Drop zone uses motion-safe: Tailwind variant to disable transition for prefers-reduced-motion
CONV-01
CONV-02
CONV-03
CONV-04
CONV-05
CONV-06
CONV-07
CONV-08
CONV-09
12min 2026-04-04

Phase 42 Plan 06: Format Conversion UI Summary

Drag-drop ConvertPanel with grouped format chips, AI fallback notice, MIME error display, SSE job tracking, and deep-link /convert/:src/:tgt routing

Performance

  • Duration: 12 min
  • Started: 2026-04-04T22:17:33Z
  • Completed: 2026-04-04T22:29:00Z
  • Tasks: 2
  • Files modified: 4 (3 created, 1 modified)

Accomplishments

  • Created convert.ts API client: submitConvertJob with direct fetch for 422/202 status differentiation; getConverterCapabilities for startup capability probe
  • Built ConvertPanel with all three visual zones: ConvertSourceZone (drag-drop with idle/dragover/error states), ConvertTargetSelector (grouped chips with AI fallback notice), ConvertActionBar (disabled until ready, download after done)
  • FORMAT_GROUPS constant drives chip rendering and is exported for ConvertPage format validation
  • ConvertPage reads URL params, normalizes to lowercase, silently ignores invalid format strings
  • Three route variants wired in App.tsx: /convert, /convert/:sourceFormat, /convert/:sourceFormat/:targetFormat

Task Commits

  1. Task 1: Create convert API client and ConvertPanel component - c0040f66 (feat)
  2. Task 2: Create ConvertPage and wire routes in App.tsx - b5587c03 (feat)

Files Created/Modified

  • ui/src/api/convert.ts - submitConvertJob (multipart POST, 422/202 handling), getConverterCapabilities
  • ui/src/components/ConvertPanel.tsx - Full ConvertPanel: drag-drop zone, FORMAT_GROUPS chips, AI fallback notice, SSE progress, download
  • ui/src/pages/ConvertPage.tsx - Route page reading sourceFormat/targetFormat URL params with case-insensitive normalization
  • ui/src/App.tsx - Added ConvertPage lazy import and three /convert route variants inside boardRoutes()

Decisions Made

  • Direct fetch in submitConvertJob — api.request() throws on any !res.ok response, but 422 is a valid business response carrying the MIME mismatch error body. Using raw fetch lets us return it as a ConvertMimeError value instead of catching and re-parsing an ApiError.
  • Direct EventSource for pre-submitted jobs — useContentJob.submit() calls submitContentJob internally; it has no "track existing job" API. Since submitConvertJob already dispatched the convert job via the multipart route (not contentJobs route), a standalone EventSource connection is used to track progress.
  • FORMAT_GROUPS exported from ConvertPanel — ConvertPage needs the same allowlist for normalizeFormatParam validation. Exporting from ConvertPanel avoids duplication and keeps them in sync.
  • AI fallback notice per group — The capabilities object returns converter availability per category (imageConverter, audioVideoConverter, docConverter, dataConverter), not per format pair. Showing the notice at group level matches the granularity available from /api/system/converters.

Deviations from Plan

None — plan executed exactly as written.

Known Stubs

None — all conversion flows are fully wired to real backend endpoints.

Issues Encountered

None — tsc compiles cleanly for all new/modified files. 17 pre-existing errors in unrelated files (AgentConfigForm, useKeyboardShortcuts, useNexusMode, usePiperTts, useVadRecorder, ContentStudio, PersonalAssistant) were present before this plan and not introduced here.

User Setup Required

None — no external service configuration required.

Next Phase Readiness

  • All CONV requirements fulfilled (CONV-01 through CONV-09)
  • /convert, /convert/:src, and /convert/:src/:tgt routes live and navigable
  • Phase 42 is complete — all 6 plans executed

Phase: 42-wallpapers-social-format-conversion-voice Completed: 2026-04-04

Self-Check: PASSED

  • ui/src/api/convert.ts — FOUND
  • ui/src/components/ConvertPanel.tsx — FOUND
  • ui/src/pages/ConvertPage.tsx — FOUND
  • .planning/phases/42-wallpapers-social-format-conversion-voice/42-06-SUMMARY.md — FOUND
  • Task 1 commit c0040f66 — FOUND
  • Task 2 commit b5587c03 — FOUND