v9.4.0 — Composition Mode (#128) #143

Merged
claude-bot merged 4 commits from feat/v10-composition into main 2026-07-18 19:21:49 +00:00
Contributor

A motif becomes an authored artifact: manually order its entries and interleave prose/heading blocks so the published page and Markdown export read as an essay with evidence, not a reverse-chron dump.

Model

  • Migration 056: entry_motifs.position INTEGER (nullable) + a motif_blocks table (position, content, content_format). Entries and prose blocks share one ordered sequence.
  • All renderers switch to ORDER BY position NULLS LAST, created_at DESC and interleave blocks — an uncurated motif renders exactly as before (all-NULL positions → created_at DESC, no blocks).

Backend

  • Motif detail returns entries[].position + a blocks array.
  • PUT /api/motifs/:id/composition (transactional reorder of the mixed list), POST/PATCH/DELETE /api/motifs/:id/blocks (sanitized on write). Writes gate on ACCESSIBLE_PROJECTS_SQL.
  • Public page JSON, motif Atom feed, and Markdown export all honor curated order; the public page + export interleave prose blocks.

Frontend

  • "Compose" mode on the motif page: native HTML5 drag-to-reorder (with ▲/▼ fallback for touch), add/edit/delete prose blocks.
  • The read view and the public motif page render entries + blocks interleaved by position.

Validation (dev server)

  • API suite: 52 files / 373 tests (new: composition.test.ts — reorder persistence, uncurated-unchanged, block CRUD + sanitize, Markdown interleave).
  • App suite: 14 files / 76 tests green. api tsc + app build green.

Closes #128.

🤖 Generated with Claude Code

A motif becomes an authored artifact: manually order its entries and interleave prose/heading blocks so the published page and Markdown export read as an essay with evidence, not a reverse-chron dump. ## Model - Migration 056: `entry_motifs.position INTEGER` (nullable) + a `motif_blocks` table (`position`, `content`, `content_format`). Entries and prose blocks share **one ordered sequence**. - All renderers switch to `ORDER BY position NULLS LAST, created_at DESC` and interleave blocks — **an uncurated motif renders exactly as before** (all-NULL positions → created_at DESC, no blocks). ## Backend - Motif detail returns `entries[].position` + a `blocks` array. - `PUT /api/motifs/:id/composition` (transactional reorder of the mixed list), `POST/PATCH/DELETE /api/motifs/:id/blocks` (sanitized on write). Writes gate on `ACCESSIBLE_PROJECTS_SQL`. - Public page JSON, motif Atom feed, and Markdown export all honor curated order; the public page + export interleave prose blocks. ## Frontend - "Compose" mode on the motif page: native HTML5 drag-to-reorder (with ▲/▼ fallback for touch), add/edit/delete prose blocks. - The read view and the public motif page render entries + blocks interleaved by position. ## Validation (dev server) - API suite: **52 files / 373 tests** (new: `composition.test.ts` — reorder persistence, uncurated-unchanged, block CRUD + sanitize, Markdown interleave). - App suite: 14 files / 76 tests green. `api` tsc + `app` build green. Closes #128. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(p128): Composition Mode backend — ordered entries + prose blocks
All checks were successful
CI / Images — production build (push) Successful in 40s
CI / App — typecheck, test & build (push) Successful in 2m44s
CI / API — typecheck & tests (push) Successful in 3m41s
f8390c07da
migration 056 (entry_motifs.position + motif_blocks); motif detail returns
position + blocks; PUT /composition (transactional reorder), POST/PATCH/DELETE
/blocks (sanitized). public.ts page JSON + Atom feed and export.ts Markdown all
honor 'position NULLS LAST, created_at DESC' and interleave blocks — uncurated
motifs render exactly as before.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(p128): Composition Mode frontend + public position select fix
Some checks failed
CI / App — typecheck, test & build (push) Successful in 1m31s
CI / Images — production build (push) Successful in 1m9s
CI / API — typecheck & tests (push) Has been cancelled
2f1a4a5d01
Curate mode on MotifDetailPage (native DnD reorder + up/down fallback,
add/edit/delete prose blocks), interleaved rendering on the read + public
views. Fix: public page entries query now selects em.position (was in
GROUP BY/ORDER BY only, so entries lacked position on the public page).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
chore(release): v9.4.0 — Composition Mode
Some checks failed
CI / API — typecheck & tests (push) Has been cancelled
CI / App — typecheck, test & build (push) Has been cancelled
CI / Images — production build (push) Has been cancelled
af0088f2b7
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
chore(release): sync lockfile versions to 9.4.0
All checks were successful
CI / App — typecheck, test & build (push) Successful in 2m18s
CI / App — typecheck, test & build (pull_request) Successful in 2m18s
CI / Images — production build (pull_request) Successful in 1m21s
CI / Images — production build (push) Successful in 3m37s
CI / API — typecheck & tests (push) Successful in 4m27s
CI / API — typecheck & tests (pull_request) Successful in 6m28s
656faed303
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude-bot deleted branch feat/v10-composition 2026-07-18 19:21:49 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/TeaLeaves!143
No description provided.