diff --git a/apps/editor/src/app/App.tsx b/apps/editor/src/app/App.tsx index cb69939..f9dc9e3 100644 --- a/apps/editor/src/app/App.tsx +++ b/apps/editor/src/app/App.tsx @@ -618,7 +618,7 @@ function AppInner() { try { const alignmentDocs = await api.listAlignmentFrameworks({ tenantId, participantId: sourceId }) return alignmentDocs.flatMap((doc) => { - const participants = doc.alignmentParticipants ?? [] + const participants = doc.extensions?.['ext:opencase']?.alignmentParticipants ?? [] const other = participants.find((p) => p.identifier !== sourceId) // No distinct "other" participant means this is a self (intra-framework) alignment doc. const targetIdentifier = other?.identifier ?? (participants.some((p) => p.identifier === sourceId) ? sourceId : undefined) @@ -646,7 +646,7 @@ function AppInner() { // for a self-alignment (targetId === activeFrameworkId) matching "any participant === targetId" // would match the first cross-framework doc too — instead require ALL participants to be self. const matchingDoc = alignmentDocs.find((doc) => { - const participants = doc.alignmentParticipants ?? [] + const participants = doc.extensions?.['ext:opencase']?.alignmentParticipants ?? [] if (targetId === activeFrameworkId) { return participants.length > 0 && participants.every((p) => p.identifier === activeFrameworkId) } diff --git a/apps/editor/src/infrastructure/caseApi/CaseApiClient.ts b/apps/editor/src/infrastructure/caseApi/CaseApiClient.ts index 8aaa014..8eeebf1 100644 --- a/apps/editor/src/infrastructure/caseApi/CaseApiClient.ts +++ b/apps/editor/src/infrastructure/caseApi/CaseApiClient.ts @@ -3,13 +3,25 @@ import type { HttpClient } from './http' export type OpenCaseCfPackageResponse = { CFPackage: CFPackage } +/** + * Shape of the `extensions['ext:opencase']` object as served by the CFDocuments list endpoint + * and the management "list frameworks" endpoint (only present when the request sends + * X-CASE-EDITOR). Server-side, this object is passed through verbatim — it may contain other + * frontend-only keys too (e.g. layout), but these are the ones the editor currently reads here. + */ +export type OpenCaseListExtensions = { + sourcePackageURI?: string + isModifiedFromSource?: boolean + alignmentParticipants?: Array<{ identifier?: string; uri: string }> +} + export type AlignmentFrameworkSummary = { sourcedId: string title: string caseVersion: string frameworkType?: string - alignmentParticipants?: Array<{ identifier?: string; uri: string }> lastChangeDateTime?: string + extensions?: { 'ext:opencase'?: OpenCaseListExtensions } } export type OpenCaseManagementCfPackageSummary = { @@ -37,12 +49,10 @@ export type CfDocumentSummary = { adoptionStatus?: string lastChangeDateTime?: string caseVersion?: string - /** URL the framework was imported from, if known (set during import via backend). */ - sourcePackageURI?: string - /** Set (true or false) once a framework has been imported/mirrored; true once it's been locally modified (forked). */ - isModifiedFromSource?: boolean /** Server-level archive flag — independent of CASE adoptionStatus */ archived?: boolean + /** OpenCASE-proprietary data (e.g. sourcePackageURI/isModifiedFromSource for the mirror/fork badge) — only present when the request sends X-CASE-EDITOR. */ + extensions?: { 'ext:opencase'?: OpenCaseListExtensions } } export class CaseApiClient { diff --git a/apps/editor/src/ui/home/HomeScreen.tsx b/apps/editor/src/ui/home/HomeScreen.tsx index 2082f9b..32dc22a 100644 --- a/apps/editor/src/ui/home/HomeScreen.tsx +++ b/apps/editor/src/ui/home/HomeScreen.tsx @@ -792,8 +792,8 @@ export default function HomeScreen({ frameworkType: doc.frameworkType, adoptionStatus: doc.adoptionStatus, }} - sourcePackageURI={doc.sourcePackageURI} - isModifiedFromSource={doc.isModifiedFromSource} + sourcePackageURI={doc.extensions?.['ext:opencase']?.sourcePackageURI} + isModifiedFromSource={doc.extensions?.['ext:opencase']?.isModifiedFromSource} rightHint={isArchiving ? 'Archiving' : hint} lastChanged={doc.lastChangeDateTime} onClick={() => openRemote(doc.identifier)} @@ -843,8 +843,8 @@ export default function HomeScreen({ frameworkType: doc.frameworkType, adoptionStatus: doc.adoptionStatus, }} - sourcePackageURI={doc.sourcePackageURI} - isModifiedFromSource={doc.isModifiedFromSource} + sourcePackageURI={doc.extensions?.['ext:opencase']?.sourcePackageURI} + isModifiedFromSource={doc.extensions?.['ext:opencase']?.isModifiedFromSource} rightHint={isDeleting ? 'Deleting' : (isRestoring ? 'Restoring' : undefined)} lastChanged={doc.lastChangeDateTime} onDelete={tenantId ? () => handleHardDeleteRequest(doc.identifier, title) : undefined}