ui/server/src/notesStore
(part of , drives story ) — durable, per-project Notes.
Cockpit server, next. Source: ui/server/src/notesStore.mjs.
Classes#
NotesStoreError#
Defined in: ui/server/src/notesStore.mjs:55
Extends#
Error
Constructors#
Constructor
new NotesStoreError(
message,opts?):NotesStoreError
Defined in: ui/server/src/notesStore.mjs:57
Parameters
message
string
opts?
code?
string
status?
number = 400
Returns
Overrides
Error.constructor
Properties#
code
code:
string
Defined in: ui/server/src/notesStore.mjs:61
name
name:
string
Defined in: ui/server/src/notesStore.mjs:59
Inherited from
Error.name
status
status:
number
Defined in: ui/server/src/notesStore.mjs:60
Variables#
MAX_NOTE_BODY_BYTES#
constMAX_NOTE_BODY_BYTES:number
Defined in: ui/server/src/notesStore.mjs:47
Note body cap: a note's content is capped at 256 KiB. Enforced on both create and
update, so a note can never be saved over the cap by either path.
NOTE_STATUSES#
constNOTE_STATUSES:Set<string>
Defined in: ui/server/src/notesStore.mjs:53
The known status values a note may carry (design: docs/design/ia-five-screens.md section 7,
issue's "Notes storage" note). draft (default) -> plan-ready (a plan was generated for
it, not attempted in this slice) -> ran (Run copied it into a process record). Validated here so
a route layer built on top of this store cannot persist a typo'd status silently.
Functions#
notesDir()#
notesDir(
projectRoot,__namedParameters?):any
Defined in: ui/server/src/notesStore.mjs:66
Absolute directory holding one project's note records: <stateDir>/notes/<projectKey>.
Parameters#
projectRoot
any
__namedParameters?
stateDir?
string = ...
Returns#
any
openNotesStore()#
openNotesStore(
projectRoot,options?):object
Defined in: ui/server/src/notesStore.mjs:119
Open the store for one project, mirroring openProcessStore's shape: a small bound object rather
than free functions, so a caller passes the project root and the state directory once. A second
openNotesStore() call against the same projectRoot/stateDir (e.g. after a simulated server
restart) reads back exactly what an earlier instance wrote — there is no in-memory cache here, the
directory listing on disk IS the store.
Parameters#
projectRoot
string
The project the notes belong to.
options?
now?
() => string = ...
Clock (ISO string) — a test seam.
stateDir?
string = ...
Base state directory (defaults to resolveStateDir()).
Returns#
dir
dir:
any
projectRoot
projectRoot:
any
create()
create(
__namedParameters?):object
Create a note. Assigns a fresh id and rev: 1; status defaults to draft, plan to
null (whatever shape the caller hands in for plan is stored as-is — no plan-generation
logic lives here). Throws NotesStoreError (413 TOO_LARGE, 400 INVALID_STATUS) rather
than silently truncating or coercing.
Parameters
__namedParameters?
anchor?
any = null
body?
string = ''
plan?
any = null
processId?
any = null
status?
string = 'draft'
title?
string = ''
Returns
object
anchor
anchor:
any
body
body:
string
createdAt
createdAt:
string
id
id:
any
plan
plan:
any
planStale
planStale:
boolean=false
processId
processId:
any
rev
rev:
number=1
status
status:
string
title
title:
string
updatedAt
updatedAt:
string=createdAt
get()
get(
id):any
One note by id, or null if there is no such record. Throws NotesStoreError (500
UNREADABLE) if the file exists but is not valid JSON — a caller asking for one specific note
wants to know it is broken, unlike list().
Parameters
id
any
Returns
any
list()
list():
object
Every note for this project, newest-updated first. problems lists files that could not be
read, so one corrupt record cannot hide the rest of the list.
Returns
object
notes
notes:
any[]
problems
problems:
any[]
markRan()
markRan(
id,__namedParameters):any
Run marks the note ran: the plan that started and the process it became are copied onto the note, which
is read-only history from then on. Server-side only (status: 'ran' is not settable from a client), so it takes
no rev: Run reads the note as it is on disk, and the text that ran is the plan's own ticket text.
Parameters
id
any
__namedParameters
plan
any
processId
any
Returns
any
Throws
404 NOT_FOUND; 409 NOTE_RAN (it already ran: one note, one run).
remove()
remove(
id):boolean
Remove a note. Returns true if there was one, false otherwise (mirrors
processStore.mjs's remove).
Parameters
id
any
Returns
boolean
update()
update(
id,__namedParameters?):any
Update a note with optimistic-concurrency: the caller's rev must equal the record's current
rev on disk, or the write is refused (this is the server half of the "409, Keep mine / Load
theirs" contract; picking between them is the client UI's job, not this slice's).
Parameters
id
any
__namedParameters?
Returns
any
Throws
404 NOT_FOUND — no such note.
Throws
400 REV_REQUIRED — rev missing (a client bug: it never loaded, or
forgot to resend, the rev it saved against — distinct from a routine stale write).
Throws
409 STALE_REV — rev present but does not match the note on disk
(someone/something else saved first — routine, "reload and try again").
Throws
413 TOO_LARGE / 400 INVALID_STATUS — same validation as create.