/**
* modules/notes.ts — Notes as the first Papyrus-native registered module
* (step 5 of the incremental refactor in reducing-papyrus-consumer-change-amplification-with-modules--pvdo,
* combined with step 1 for a real proof-of-shape rather than an empty abstraction).
*
* Notes was chosen first because it owns no bespoke schema (it reuses the generic doc
* table via NOTE_SUBTYPE) and has exactly six operations — the smallest real module to
* prove the OperationRegistry shape against before extracting Tasks or Docs.
*
* This module does not import another module's infrastructure (src/task/task-service.ts,
* src/docs/docs-service.ts, etc.) — only its own src/note/note-service.ts and the shared
* OperationInput parsing helpers, matching the "module code does not import another
* module's infrastructure" constraint.
*/
import type { OperationDefinition } from "../module-registry.ts";
import type { NoteEventDirection } from "../note/note-event.ts";
import type { NoteDisposition, Notes } from "../note/note-service.ts";
import { type OperationInput, optionalNumber, optionalString, string } from "./operation-input.ts";
const MODULE_ID = "notes";
/** This module's own operation names, the single source of truth src/service.ts's EXPECTED_OPERATION_NAMES spreads in rather than re-listing by hand. */
export const NOTES_OPERATION_NAMES = [
"notes.capture",
"notes.list",
"notes.list_page",
"notes.show",
"notes.history",
"notes.consume",
"notes.promote",
"notes.archive",
] as const;
/** Registers every notes.* operation against one Notes instance. Behavior is unchanged from the prior inline handlers in src/service.ts. */
export function notesOperations(notes: Notes): OperationDefinition[] {
const define = (name: string, execute: (input: Input) => Output): OperationDefinition => ({
name,
moduleId: MODULE_ID,
execute,
});
return [
define("notes.capture", (input: OperationInput) =>
notes.capture({
body: string(input, "body"),
title: optionalString(input, "title"),
projectRoot: string(input, "project_root"),
actor: optionalString(input, "actor"),
source: optionalString(input, "source"),
sessionId: optionalString(input, "session_id"),
}),
),
define("notes.list", (input: OperationInput) =>
notes.list({
projectRoot: string(input, "project_root"),
status: optionalString(input, "status") as "draft" | "active" | "archived" | undefined,
text: optionalString(input, "text"),
limit: optionalNumber(input, "limit"),
}),
),
define("notes.list_page", (input: OperationInput) =>
notes.listPage({
projectRoot: optionalString(input, "project_root"),
status: optionalString(input, "status") as "draft" | "active" | "archived" | undefined,
text: optionalString(input, "text"),
limit: optionalNumber(input, "limit"),
cursor: optionalString(input, "cursor"),
}),
),
define("notes.show", (input: OperationInput) => notes.show(string(input, "id"), string(input, "project_root"))),
define("notes.history", (input: OperationInput) =>
notes.history(string(input, "id"), string(input, "project_root"), {
limit: optionalNumber(input, "limit"),
cursor: optionalNumber(input, "cursor"),
direction: optionalString(input, "direction") as NoteEventDirection | undefined,
}),
),
define("notes.consume", (input: OperationInput) =>
notes.consume(string(input, "id"), {
projectRoot: string(input, "project_root"),
actor: optionalString(input, "actor"),
source: optionalString(input, "source"),
sessionId: optionalString(input, "session_id"),
reason: optionalString(input, "reason"),
}),
),
define("notes.promote", (input: OperationInput) =>
notes.promote(string(input, "id"), string(input, "target_id"), {
projectRoot: string(input, "project_root"),
actor: optionalString(input, "actor"),
source: optionalString(input, "source"),
sessionId: optionalString(input, "session_id"),
reason: optionalString(input, "reason"),
}),
),
define("notes.archive", (input: OperationInput) =>
notes.archive(string(input, "id"), {
projectRoot: string(input, "project_root"),
disposition: string(input, "disposition") as NoteDisposition,
actor: optionalString(input, "actor"),
source: optionalString(input, "source"),
sessionId: optionalString(input, "session_id"),
reason: optionalString(input, "reason"),
}),
),
];
}