Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 8 additions & 22 deletions apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
OrchestrationProposedPlanId,
OrchestrationReadModel,
OrchestrationThreadSearchSource,
OrchestrationShellSnapshot,
type OrchestrationShellSnapshot,
OrchestrationThread,
OrchestrationThreadDetailSnapshot,
ProjectScript,
Expand Down Expand Up @@ -82,7 +82,6 @@ import {
} from "../Services/ProjectionSnapshotQuery.ts";

const decodeReadModel = Schema.decodeUnknownEffect(OrchestrationReadModel);
const decodeShellSnapshot = Schema.decodeUnknownEffect(OrchestrationShellSnapshot);
const decodeThread = Schema.decodeUnknownEffect(OrchestrationThread);
const decodeImportedTranscriptsPayload = Schema.decodeUnknownOption(
Schema.fromJsonString(
Expand Down Expand Up @@ -2746,7 +2745,10 @@ pending_approval_requests AS (
);
const pullRequestsByThread = groupPullRequestRowsByThread(pullRequestRows);

const snapshot = {
// Built from schema-decoded rows, so no second decode here. The HTTP
// and RPC layers encode it against OrchestrationShellSnapshot on the
// way out, like the per-item shells from getThreadShellById.
return {
snapshotSequence: computeSnapshotSequence(stateRows),
projects: Arr.filterMap(projectRows, (row) =>
row.deletedAt === null
Expand Down Expand Up @@ -2800,15 +2802,7 @@ pending_approval_requests AS (
: Result.failVoid,
),
updatedAt: updatedAt ?? "1970-01-01T00:00:00.000Z",
};

return yield* decodeShellSnapshot(snapshot).pipe(
Effect.mapError(
toPersistenceDecodeError(
"ProjectionSnapshotQuery.getShellSnapshot:decodeShellSnapshot",
),
),
);
} satisfies OrchestrationShellSnapshot;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Removing the decode changes the service's returned values for rows whose titles contain surrounding whitespace: row titles use Schema.String, while the shell contract's TrimmedNonEmptyString previously trimmed them (and rejected blank titles). Could you add focused tests for both snapshot methods with such persisted rows and preserve the intended normalization/validation at the appropriate boundary? The existing tests only use already-trimmed titles.

Posted via Macroscope — Effect Service Conventions

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Persisted titles are always trimmed and non-empty. The projector only writes title from event payloads (apps/server/src/orchestration/Layers/ProjectionPipeline.ts:506, 529, 616, 825), and those payloads decode it with TrimmedNonEmptyString (packages/contracts/src/orchestration.ts:1733, 1747, 1767, 1856). The wire path still encodes against OrchestrationShellSnapshot, and that encode also trims (packages/contracts/src/baseSchemas.ts:11), so tests for untrimmed rows would cover data the server cannot write.

}),
),
Effect.mapError((error) => {
Expand Down Expand Up @@ -2941,7 +2935,7 @@ pending_approval_requests AS (
sessionRows.map((row) => [row.threadId, mapSessionRow(row)] as const),
);

const snapshot = {
return {
snapshotSequence: computeSnapshotSequence(stateRows),
projects: Arr.filterMap(projectRows, (row) =>
row.deletedAt === null && activeProjectIds.has(row.projectId)
Expand Down Expand Up @@ -2991,15 +2985,7 @@ pending_approval_requests AS (
planProgress: threadPlanProgress.getThreadPlanProgress(row.threadId),
})),
updatedAt: updatedAt ?? "1970-01-01T00:00:00.000Z",
};

return yield* decodeShellSnapshot(snapshot).pipe(
Effect.mapError(
toPersistenceDecodeError(
"ProjectionSnapshotQuery.getArchivedShellSnapshot:decodeShellSnapshot",
),
),
);
} satisfies OrchestrationShellSnapshot;
}),
),
Effect.mapError((error) => {
Expand Down
Loading