Line

You are reading the unreleased docs (next). See latest (v0.9)

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

NotesStoreError

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#

const MAX_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#

const NOTE_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.