Skip to content

feat(templates): immutable records disable Edit up front - GET /{id}/mutable pre-check + read-only pages - #6526

Merged
delchev merged 1 commit into
masterfrom
feat/immutable-ui-precheck
Aug 5, 2026
Merged

feat(templates): immutable records disable Edit up front - GET /{id}/mutable pre-check + read-only pages#6526
delchev merged 1 commit into
masterfrom
feat/immutable-ui-precheck

Conversation

@delchev

@delchev delchev commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

What

immutable: / immutableWhen: entities used to offer Edit → Save in every generated view and only refuse on the write (PUT/DELETE → 409 "immutable in its current status"). The 409 stays exactly as it was — the authoritative guard — but the generated UI now knows up front:

1. Utility API. Each generated controller — power EntityController, EntityPartnerController, EntityMyController — exposes GET /{id}/mutable{"mutable": true|false}, backed by a shared isMutable(entity) extracted from requireMutable (single source of truth, no duplicated logic). The partner/my variants resolve the record through requireMine(id), so a foreign record stays the same 404. Emitted only when the entity declares immutability.

2. All Harmonia templates consume it (not only the document layout):

  • manage form + document pages ask the pre-check on edit/preview load; an immutable record opened via a directly typed /edit URL is forced into the existing read-only preview mode, a warning Read-only badge appears in the title bar (tooltip: "corrections go through the workflow"), and the preview footer's Edit button hides. The pre-check fails open — an outage must not lock the UI; the server still refuses the write.
  • manage list + master browse views hide row-menu Edit/Delete and disable the details-pane Edit/Delete via a baked isRowImmutable(row) computed from the row's status FK against the generation-time immutable status ids — no per-row API calls, and no drift (generated from the same model attrs as the server gate, the validationSchema precedent). Preview always stays — the record remains readable.
  • partner + my form/document pages wrap their controls in fieldset :disabled, hide Save/Delete, item Add/Edit/Delete and the chat composer, and show the same badge.

Entities without immutability generate byte-identical output (all additions are Velocity-guarded).

Tests

IntentEmissionCoverageIT extended on both layers per the emission-testing contract:

  • tokens: /{id}/mutable + isMutable( in the generated controllers, the pre-check in EntryFormPage.js, isRowImmutable in EntryMasterPage.js;
  • behavior: mutable=false over REST for the POSTED entry and the append-only snapshot, mutable=true while DRAFT.

Docs

engine-intent/CLAUDE.md immutability bullet updated with the pre-check contract. A dirigible.io note (help page for immutableWhen) follows after merge; no intentfile.org change — the DSL grammar is untouched.

🤖 Generated with Claude Code

…nt - GET /{id}/mutable pre-check + read-only pages

The immutable/immutableWhen 409 on PUT/DELETE stays the authoritative
guard, but the generated UI used to offer Edit/Save and only fail on
the write. Each generated controller (power/partner/my) now exposes a
GET /{id}/mutable utility endpoint (shared isMutable extracted from
requireMutable; partner/my scoped through requireMine), and every
Harmonia surface consumes it:

- manage form + document pages ask the pre-check on edit load and
  force the read-only preview mode with a "Read-only" title badge, so
  a directly typed /edit URL opens read-only; the preview footer's
  Edit button hides. The pre-check fails OPEN (an outage must not
  lock the UI - the server still refuses the write).
- manage list + master browse views hide row-menu Edit/Delete and
  disable the details-pane buttons via a baked isRowImmutable(row)
  computed from the row's status FK against the generation-time
  immutable ids - no per-row API calls, and no drift (generated from
  the same model attrs as the server gate).
- partner/my form + document pages disable their controls
  (fieldset :disabled), hide Save/Delete/item actions and the chat
  composer, and show the same badge.

IntentEmissionCoverageIT asserts both layers: the endpoint + page
tokens, and mutable=false over REST for a POSTED/append-only record
vs mutable=true while DRAFT.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@delchev
delchev force-pushed the feat/immutable-ui-precheck branch from 05a95f3 to b8599cf Compare August 5, 2026 09:19
@delchev
delchev merged commit e8f3e35 into master Aug 5, 2026
10 checks passed
@delchev
delchev deleted the feat/immutable-ui-precheck branch August 5, 2026 10:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant