Skip to content

CMS-67: Wire environment-specific field badges in editor UI#42

Merged
iipanda merged 12 commits into
mainfrom
codex/cms-67-environment-field-badges
Apr 10, 2026
Merged

CMS-67: Wire environment-specific field badges in editor UI#42
iipanda merged 12 commits into
mainfrom
codex/cms-67-environment-field-badges

Conversation

@iipanda
Copy link
Copy Markdown
Collaborator

@iipanda iipanda commented Apr 10, 2026

Summary

  • derive and forward environment-specific document-route metadata, including per-environment schema hashes and field target environments
  • render environment-specific field badges in the Studio document sidebar and keep route write metadata aligned with the active environment switcher
  • align the studio example/review apps and review fixtures with the new contract and badge behavior

Test Plan

  • bun test packages/studio/src/lib/document-route-schema.test.ts packages/shared/src/lib/contracts/extensibility.test.ts packages/studio/src/lib/studio-loader.test.ts packages/studio/src/lib/runtime-ui/pages/content-document-page.test.tsx apps/studio-review/review/scenarios.test.ts
  • bun run check

Notes

  • bun run format:check still fails because of a pre-existing unrelated formatting issue in packages/studio/src/lib/runtime-ui/app/admin/environments-page.tsx.

Summary by CodeRabbit

  • New Features
    • Environment-aware document editor: per-environment schema hashes & write gating, environment-targeted fields, full frontmatter editing, new Info sidebar tab, and inline environment badges.
  • Bug Fixes
    • Prevents stale UI updates and mismatched save/publish behavior when switching routes or environments.
  • Documentation
    • Specs updated to detail editor behaviors, frontmatter persistence, and environment-field rules.
  • Tests
    • Added tests covering metadata resolution, schema-hashes, environment badges, frontmatter flows, and post fields.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 10, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9ef68ca1-f797-4612-aec8-59e6d7927e9f

📥 Commits

Reviewing files that changed from the base of the PR and between 3cdc550 and dd5c940.

📒 Files selected for processing (1)
  • packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx

📝 Walkthrough

Walkthrough

Propagates prepared document-route metadata from server-side config into client Studio init; computes per-environment schema hashes and environment→field mappings; extends mount context with environment-aware write info; updates loader, runtime UI, tests, and docs to surface environment-specific field badges and prevent stale async updates.

Changes

Cohort / File(s) Summary
AdminStudioClient propagation
apps/studio-example/app/admin/[[...path]]/page.tsx, apps/studio-example/app/admin/admin-studio-client.tsx, apps/studio-review/app/review/[scenario]/admin/[[...path]]/page.tsx, apps/studio-review/app/review/[scenario]/admin/admin-studio-client.tsx
Added optional documentRouteMetadata prop to AdminStudioClient and threaded it from server pages into client config initialization.
Client studio-config API
apps/studio-example/app/admin/studio-config.ts, apps/studio-review/app/review/[scenario]/admin/studio-config.ts
createClientStudioConfig accepts optional documentRouteMetadata and conditionally injects _documentRouteMetadata into returned MdcmsConfig; introduced a prepared-document-metadata type alias.
Content schema & scenarios
apps/studio-review/mdcms.config.ts, apps/studio-review/review/scenarios.ts, apps/studio-review/review/scenarios.test.ts, apps/studio-example/mdcms.config.ts, apps/studio-example/mdcms.config.test.ts
Added featured (and abTestVariant in example) fields targeted to staging; updated scenarios and tests to include assertions for environment-targeted fields.
Shared contract extensions
packages/shared/src/lib/contracts/extensibility.ts, packages/shared/src/lib/contracts/extensibility.test.ts
Extended StudioDocumentRouteMountContext with optional writeByEnvironment and environmentFieldTargets and added corresponding Zod schema/tests.
Document-route metadata resolution
packages/studio/src/lib/document-route-schema.ts, packages/studio/src/lib/document-route-schema.test.ts
Added StudioDocumentRoutePreparedMetadata, helpers to compute schemaHashesByEnvironment and environmentFieldTargets, and resolveStudioDocumentRoutePreparedMetadata() with tests.
Studio loader & validation
packages/studio/src/lib/studio-loader.ts, packages/studio/src/lib/studio-loader.test.ts
Added isPreparedDocumentRouteMetadata, readPreparedDocumentRouteMetadata, toWriteByEnvironment; updated createDocumentRouteMountContext to prefer prepared write info and include writeByEnvironment/environmentFieldTargets; added tests.
Core studio config embedding
packages/studio/src/lib/studio.ts
prepareStudioConfig attempts to resolve prepared document-route metadata and conditionally embeds it as _documentRouteMetadata; MdcmsConfig extended with optional _documentRouteMetadata and _schemaHash.
Runtime UI: environment-aware editor
packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx, packages/studio/src/lib/runtime-ui/pages/content-document-page.test.tsx
Added frontmatter editing, request-token helpers to avoid stale async updates, resolveActiveDocumentRouteContext, environment-specific field badges, new sidebar Info tab, and many related tests.
Document shell & loader tests
packages/studio/src/lib/document-shell.ts, packages/studio/src/lib/document-shell.test.ts
Document shell now includes format and frontmatter; load test added to assert preservation of format/frontmatter/body.
Docs & specs
packages/studio/README.md, docs/specs/SPEC-006-studio-runtime-and-ui.md, docs/specs/SPEC-007-editor-mdx-and-collaboration.md
Documented writeByEnvironment and environmentFieldTargets, editor behavior changes, frontmatter save/publish semantics, and stale-update protections.
Misc tests & adjustments
packages/studio/src/lib/studio-loader.test.ts, packages/studio/src/lib/document-route-schema.test.ts, packages/shared/.../extensibility.test.ts
New and extended tests validating prepared metadata shape, loader behavior, contract changes, and runtime UI behavior.

Sequence Diagram

sequenceDiagram
    participant Server as Server Config
    participant Resolver as DocumentRouteResolver
    participant Client as AdminStudioClient
    participant Loader as StudioLoader
    participant UI as ContentDocumentPage

    Server->>Resolver: resolveStudioDocumentRoutePreparedMetadata(config)
    Resolver->>Resolver: compute schemaHashesByEnvironment
    Resolver->>Resolver: compute environmentFieldTargets
    Resolver-->>Server: StudioDocumentRoutePreparedMetadata

    Server->>Client: pass documentRouteMetadata prop
    Client->>Client: createClientStudioConfig(documentRouteMetadata)
    Client-->>Server: MdcmsConfig (with _documentRouteMetadata)

    Server->>Loader: mount studio with config
    Loader->>Loader: readPreparedDocumentRouteMetadata(config)
    Loader->>Loader: toWriteByEnvironment(schemaHashesByEnvironment)
    Loader-->>UI: mount context with writeByEnvironment & environmentFieldTargets

    UI->>UI: resolveActiveDocumentRouteContext(selectedEnvironment)
    UI->>UI: getEnvironmentSpecificFieldBadges(environmentFieldTargets)
    UI-->>UI: render badges ("staging only", etc.)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐇 I hopped through configs and hashes bright,

Staging fields donned badges soft and light,
Routes now carry per-env keys and write,
Editors learn which fields to show by sight,
I stitched metadata through day and night.

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly references the primary change (environment-specific field badges) and accurately reflects the main focus of wiring these badges in the editor UI sidebar across multiple files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/cms-67-environment-field-badges

Comment @coderabbitai help to get the list of available commands and usage tips.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
mdcms-studio-review Ready Ready Preview, Comment Apr 10, 2026 11:31pm

Request Review

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx`:
- Around line 1986-2005: The async-result guards that now only compare document
identity (documentId) must also validate the environment/revision token so
late-arriving staging responses cannot overwrite a switched environment; update
the guards in saveDraft, publishDocument and all version-loading flows to
compare route.initialEnvironment (or a route revision token) in addition to
documentId, and ensure activeContext/route (from
resolveActiveDocumentRouteContext) is passed into those async callbacks so they
bail when the environment token differs from the one captured when the request
was started.

In `@packages/studio/src/lib/studio-loader.ts`:
- Around line 244-274: isPreparedDocumentRouteMetadata currently accepts
loosely-shaped nested values which lets malformed _documentRouteMetadata slip
through and fail later in assertStudioMountContext; update
isPreparedDocumentRouteMetadata to strictly validate the nested structure:
verify value.schemaHashesByEnvironment is a record whose keys are non-empty
strings and values are non-empty trimmed strings; verify
value.environmentFieldTargets is a record whose keys are the same non-empty
environment keys (or at least a subset) and whose values are records mapping
non-empty type-name strings to non-empty string arrays; for each typeFields
ensure every key is a string and every entry in each array is a trimmed
non-empty string (use existing helpers isRecord and isStringArray as part of the
checks), and return false if any of these stricter invariants fail so malformed
metadata fails fast instead of later in assertStudioMountContext.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7a5c9b6d-37a2-48a2-92c3-8d65e57e6ba5

📥 Commits

Reviewing files that changed from the base of the PR and between 5ebbe86 and 237f146.

📒 Files selected for processing (19)
  • apps/studio-example/app/admin/[[...path]]/page.tsx
  • apps/studio-example/app/admin/admin-studio-client.tsx
  • apps/studio-example/app/admin/studio-config.ts
  • apps/studio-review/app/review/[scenario]/admin/[[...path]]/page.tsx
  • apps/studio-review/app/review/[scenario]/admin/admin-studio-client.tsx
  • apps/studio-review/app/review/[scenario]/admin/studio-config.ts
  • apps/studio-review/mdcms.config.ts
  • apps/studio-review/review/scenarios.test.ts
  • apps/studio-review/review/scenarios.ts
  • packages/shared/src/lib/contracts/extensibility.test.ts
  • packages/shared/src/lib/contracts/extensibility.ts
  • packages/studio/README.md
  • packages/studio/src/lib/document-route-schema.test.ts
  • packages/studio/src/lib/document-route-schema.ts
  • packages/studio/src/lib/runtime-ui/pages/content-document-page.test.tsx
  • packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx
  • packages/studio/src/lib/studio-loader.test.ts
  • packages/studio/src/lib/studio-loader.ts
  • packages/studio/src/lib/studio.ts

Comment thread packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx
Comment thread packages/studio/src/lib/studio-loader.ts Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (2)
packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx (1)

198-278: ⚠️ Potential issue | 🔴 Critical

Apply the route token to syncSchema() and variant creation too.

Now that initialEnvironment is part of the active route, two async paths still commit stale results after an environment switch: syncSchema() only checks document identity on Line 2291, and handleCreateVariant() still unconditionally navigates / sets errors after its awaits on Lines 2570-2585. A staging response can still overwrite production write state or redirect the user from the wrong environment.

Also applies to: 2015-2034

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx` around
lines 198 - 278, syncSchema() and handleCreateVariant() are still vulnerable to
stale results after an environment switch; generate and pass a
ContentDocumentRouteRequestToken (use createContentDocumentRouteRequestToken)
for the current request and, after each await in syncSchema() and in
handleCreateVariant() before committing state, navigation or setting errors,
validate the token with matchesContentDocumentRouteRequestToken using the
current documentId and route.initialEnvironment—if it doesn't match, abort
applying the response (no state changes, navigation or error updates).
packages/studio/src/lib/studio-loader.ts (1)

240-245: ⚠️ Potential issue | 🟠 Major

Exclude arrays from prepared-metadata validation.

isRecord() still accepts arrays, so malformed _documentRouteMetadata like schemaHashesByEnvironment: ["hash"] can pass here as environment "0" instead of being rejected and falling back cleanly.

Proposed fix
 function isRecord(value: unknown): value is Record<string, unknown> {
-  return typeof value === "object" && value !== null;
+  return (
+    typeof value === "object" &&
+    value !== null &&
+    !Array.isArray(value)
+  );
 }

Also applies to: 249-304

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/studio/src/lib/studio-loader.ts` around lines 240 - 245, The
isRecord type guard currently treats arrays as objects, allowing arrays like
schemaHashesByEnvironment to pass validation; update isRecord (and any related
checks around prepared-metadata handling) to explicitly exclude arrays (e.g.,
add a check like !Array.isArray(value)) so that arrays are not considered
records and will be rejected/fall back cleanly; also review the surrounding
prepared-metadata logic referenced in the diff (functions/blocks around isRecord
and isStringArray between lines ~249-304) to ensure arrays are handled
consistently and that isStringArray remains the correct predicate for
string-array fields.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx`:
- Around line 198-278: syncSchema() and handleCreateVariant() are still
vulnerable to stale results after an environment switch; generate and pass a
ContentDocumentRouteRequestToken (use createContentDocumentRouteRequestToken)
for the current request and, after each await in syncSchema() and in
handleCreateVariant() before committing state, navigation or setting errors,
validate the token with matchesContentDocumentRouteRequestToken using the
current documentId and route.initialEnvironment—if it doesn't match, abort
applying the response (no state changes, navigation or error updates).

In `@packages/studio/src/lib/studio-loader.ts`:
- Around line 240-245: The isRecord type guard currently treats arrays as
objects, allowing arrays like schemaHashesByEnvironment to pass validation;
update isRecord (and any related checks around prepared-metadata handling) to
explicitly exclude arrays (e.g., add a check like !Array.isArray(value)) so that
arrays are not considered records and will be rejected/fall back cleanly; also
review the surrounding prepared-metadata logic referenced in the diff
(functions/blocks around isRecord and isStringArray between lines ~249-304) to
ensure arrays are handled consistently and that isStringArray remains the
correct predicate for string-array fields.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 45115eb3-0acb-41b9-91a3-8b1765f1300c

📥 Commits

Reviewing files that changed from the base of the PR and between 237f146 and 0b68f68.

📒 Files selected for processing (4)
  • packages/studio/src/lib/runtime-ui/pages/content-document-page.test.tsx
  • packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx
  • packages/studio/src/lib/studio-loader.test.ts
  • packages/studio/src/lib/studio-loader.ts

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx (1)

1612-1630: Add nullable-environment test coverage for route resolution.

Line 1614 accepts string | null | undefined, but behavior for null/undefined and unknown environments should be explicitly locked in tests (especially fallback at Line 1625-Line 1628).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx` around
lines 1612 - 1630, The function resolveActiveDocumentRouteContext accepts
environment: string | null | undefined but tests are missing for null/undefined
and unknown environments; add unit tests for resolveActiveDocumentRouteContext
that call it with environment = null, environment = undefined, and with an
unknown environment string (not present in route.writeByEnvironment) to assert
that when environment is null/undefined it returns the original route
(route.initialEnvironment unchanged) and when environment is unknown it returns
a route with initialEnvironment set to the trimmed unknown value and write equal
to the fallback object (canWrite: false and the message containing the unknown
environment); reference resolveActiveDocumentRouteContext,
route.initialEnvironment and route.writeByEnvironment in your test to locate the
behaviour to validate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx`:
- Around line 1612-1630: The function resolveActiveDocumentRouteContext accepts
environment: string | null | undefined but tests are missing for null/undefined
and unknown environments; add unit tests for resolveActiveDocumentRouteContext
that call it with environment = null, environment = undefined, and with an
unknown environment string (not present in route.writeByEnvironment) to assert
that when environment is null/undefined it returns the original route
(route.initialEnvironment unchanged) and when environment is unknown it returns
a route with initialEnvironment set to the trimmed unknown value and write equal
to the fallback object (canWrite: false and the message containing the unknown
environment); reference resolveActiveDocumentRouteContext,
route.initialEnvironment and route.writeByEnvironment in your test to locate the
behaviour to validate.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9e37819b-62d7-4e31-8adb-ba31575930b5

📥 Commits

Reviewing files that changed from the base of the PR and between 0b68f68 and 0ea3465.

📒 Files selected for processing (3)
  • packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx
  • packages/studio/src/lib/studio-loader.test.ts
  • packages/studio/src/lib/studio-loader.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/studio/src/lib/studio-loader.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/studio/src/lib/studio-loader.ts

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/studio-example/mdcms.config.test.ts (1)

63-71: Consider narrowing assertion scope to reduce fixture brittleness.

Line 64 currently asserts the entire environmentFieldTargets object. If future demo fields are added for other types/environments, this test can fail even when the post contract still works.

Proposed tweak
-  assert.deepEqual(
-    preparedConfig._documentRouteMetadata?.environmentFieldTargets,
-    {
-      post: {
-        abTestVariant: ["staging"],
-        featured: ["staging"],
-      },
-    },
-  );
+  assert.deepEqual(
+    preparedConfig._documentRouteMetadata?.environmentFieldTargets?.post,
+    {
+      abTestVariant: ["staging"],
+      featured: ["staging"],
+    },
+  );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/studio-example/mdcms.config.test.ts` around lines 63 - 71, The test is
asserting the entire
preparedConfig._documentRouteMetadata?.environmentFieldTargets object, making it
brittle; narrow the assertion to only the 'post' entry by changing the assertion
to check preparedConfig._documentRouteMetadata?.environmentFieldTargets?.post
equals the expected object (abTestVariant and featured arrays) so other future
keys won't break the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/studio-example/mdcms.config.test.ts`:
- Around line 63-71: The test is asserting the entire
preparedConfig._documentRouteMetadata?.environmentFieldTargets object, making it
brittle; narrow the assertion to only the 'post' entry by changing the assertion
to check preparedConfig._documentRouteMetadata?.environmentFieldTargets?.post
equals the expected object (abTestVariant and featured arrays) so other future
keys won't break the test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 388d113a-4142-4297-b024-3f95088a6031

📥 Commits

Reviewing files that changed from the base of the PR and between 0ea3465 and 2b7bd4a.

📒 Files selected for processing (2)
  • apps/studio-example/mdcms.config.test.ts
  • apps/studio-example/mdcms.config.ts

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/specs/SPEC-006-studio-runtime-and-ui.md`:
- Line 329: The current doc line for GET /api/v1/content/:documentId?draft=true
is ambiguous; change the wording to state that the draft=true query parameter is
an authorization/read-model switch that returns the mutable head content
(subject to caller authorization) and explicitly warn that it is not a
server-side status filter for "show unpublished" or "draft-only" documents;
update the description around the GET /api/v1/content/:documentId?draft=true
entry to use that precise phrasing and add a short note that authorization
controls access to the mutable head snapshot.

In `@docs/specs/SPEC-007-editor-mdx-and-collaboration.md`:
- Around line 103-104: The draftChanged reducer in content-document-page.tsx
currently only updates body via event.body and state.draftBody; update it to
also detect and update frontmatter/property changes by comparing
event.properties with state.draftProperties and setting state.draftProperties
(and corresponding unsaved flag) so frontmatter-only edits enter the same
unsaved/saving/saved flow; ensure the same saveDraft/save pipeline (the existing
draft save handlers) reads state.draftProperties as well as state.draftBody so
frontmatter edits are persisted through the same state machine and triggers.
- Around line 98-99: The spec says auto-save should persist frontmatter but the
implementation's updateDraft call in content-document-page.tsx currently only
sends { body: input.state.draftBody }; update the client-side auto-save to
include the current frontmatter draft (e.g., include
input.state.draftFrontmatter or the Properties tab state) in the payload sent to
updateDraft, and ensure the updateDraft API handler/endpoint accepts and
persists that frontmatter field as well; alternatively, if you intend not to
persist frontmatter on auto-save, update the SPEC-007 text to remove the claim
about persisting frontmatter so the spec matches the current updateDraft
behavior.
- Around line 109-110: The spec claims Publish "copies the current draft body
and frontmatter into a new immutable row in document_versions" but the publish
handler in content-document-page.tsx (the function that sends { documentId,
locale, changeSummary }) does not include frontmatter or draft body; either
update the spec to state that frontmatter is captured server-side from draft
state, or change the publish handler to explicitly collect the current draft
body and frontmatter and include them in the API payload (alongside documentId,
locale, changeSummary) so the server can write the immutable row to
document_versions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a417a003-68d4-4fb8-86c7-ecfbac7515fa

📥 Commits

Reviewing files that changed from the base of the PR and between 2b7bd4a and 348c69c.

📒 Files selected for processing (2)
  • docs/specs/SPEC-006-studio-runtime-and-ui.md
  • docs/specs/SPEC-007-editor-mdx-and-collaboration.md

Comment thread docs/specs/SPEC-006-studio-runtime-and-ui.md
Comment thread docs/specs/SPEC-007-editor-mdx-and-collaboration.md
Comment thread docs/specs/SPEC-007-editor-mdx-and-collaboration.md
Comment thread docs/specs/SPEC-007-editor-mdx-and-collaboration.md Outdated
@iipanda
Copy link
Copy Markdown
Collaborator Author

iipanda commented Apr 10, 2026

@coderabbitai pause

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 10, 2026

✅ Actions performed

Reviews paused.

Replace bordered cards with flat divider-separated rows, demote type
labels to right-aligned monospace hints, use red * for required fields
instead of Optional badges, render environment badges as colored amber
pills, inline boolean toggle controls, and dim unsupported fields.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx`:
- Around line 433-449: The function mapErrorToFrontmatterField currently maps
any string in RuntimeError.details.field to a frontmatter property; change it so
it only returns a field name when the candidate explicitly starts with
"frontmatter." — check mapErrorToFrontmatterField, the local variable candidate,
and the normalized logic and bail out (return undefined) if candidate does not
startWith("frontmatter."); apply the same change to the other identical mapping
occurrence (the second implementation around the 1593-1604 region) so
non-frontmatter paths (e.g., body-level validation) are not treated as
frontmatter errors.
- Around line 2921-2934: The mutation paths (publishDocument, saveDraft,
handleCreateVariant) are creating an API using the current activeContext/route
while using a stale document snapshot from stateRef.current, allowing writes to
be sent to the wrong route; fix by capturing the relevant snapshot-bound
routing/context at the start of each mutation (e.g., read const snapshot =
stateRef.current; const requestContext = snapshot.context || activeContext;
const requestRoute = snapshot.route || route) and then call createRouteApi with
those snapshot-bound requestContext/requestRoute before performing any mutation
so the API route always matches the document snapshot being mutated (apply same
pattern in publishDocument, saveDraft, handleCreateVariant and the other
indicated blocks).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b83c0449-2edc-4a64-a541-7ce4f3f98cab

📥 Commits

Reviewing files that changed from the base of the PR and between 2b7bd4a and 3cdc550.

📒 Files selected for processing (6)
  • docs/specs/SPEC-006-studio-runtime-and-ui.md
  • docs/specs/SPEC-007-editor-mdx-and-collaboration.md
  • packages/studio/src/lib/document-shell.test.ts
  • packages/studio/src/lib/document-shell.ts
  • packages/studio/src/lib/runtime-ui/pages/content-document-page.test.tsx
  • packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx
✅ Files skipped from review due to trivial changes (1)
  • docs/specs/SPEC-006-studio-runtime-and-ui.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/studio/src/lib/runtime-ui/pages/content-document-page.test.tsx

Comment thread packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx
Comment thread packages/studio/src/lib/runtime-ui/pages/content-document-page.tsx
Bail out early when the error field path does not start with
"frontmatter." so non-frontmatter paths (e.g. body-level validation)
are not incorrectly mapped as frontmatter field errors.
@iipanda iipanda merged commit d239e4e into main Apr 10, 2026
5 of 6 checks passed
@iipanda iipanda deleted the codex/cms-67-environment-field-badges branch April 14, 2026 15:55
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