The plan and its versions
On this page
The plan as a working copy, the versions a person freezes, what changed between them, and the plan’s document. Part of the architecture, the contract every change follows.
Versions (D52)
plan.json is always the working copy; plan-versions/V<n>.json its versions, frozen copies made by a person (their number, day, content hash and plan never change; their sends and their validation are added), and plan-versions/notes.json the author’s notes for the client on the changes in no version yet. loadProject reads them into Project.planVersions and Project.planNotes; no package carries them, archives and backups do.
- State and references (
@elabora/coreproject/plan-versions.ts):usableVersions(those whose plan gives their hash),planState(draftwithout a validated version,approvedwhen the working copy is the latest validated version,modifiedotherwise),planVersionsView(every version made, sent and validated; the two references of the app: the changes since the latest validated version, its marks, and those in no version yet, its pill’s count; what an export shows by default and how many changes it would not show; the verbatim texts changed since the validation),planDiffBetween(project, { from, to }),notesFor,describePlanVersions(a line for agents and the command line). - The diff (
project/plan-diff.tsplanDiff(base, current, course?)): elements of two plans matched by their ids (objectives, items, texts and questions wherever they are, sources, and the plan’s own fields), each added, removed or changed, moved (from its position: the elements around it that kept their order did not move, the longest common subsequence), an item’s part changed (the part it belongs to,effectivePartsinproject/plan-order.ts: its own, else the one before it, and in a plan without parts the title of its section in the course,planCourse(project), which every caller with a project gives; an item whose part was only written down, from none to the part it was in, did not change part, so a drag counts once; a base with no parts and no course has none to compare), each field changed with its texts word by word (diffRich),verbatimfor a text the base kept « à l’identique ». Every change has a key (item:ITEM-3) that notes andrevertPlanChange(« Revenir à la V2 ») use. - Rules (
validate/plan.ts,validate/structure.ts):W_PLAN_DRAFT,E_PLAN_NOT_APPROVEDfor release builds without a validated version,W_PLAN_MODIFIED_SINCE_VALIDATION,W_PLAN_VERBATIM_CHANGED,E_PLAN_VERSION_INVALID. The build report’splan.validatedandplan.changesSince, and the proof dossier, say the version a release is built against and the changes delivered since.
The plan’s document (D48, D52)
What the client reads, comments and signs: one version of the plan, the latest by default, or its working copy, as one document: its properties at its head (status, version, validated by, the module’s duration and delivery, the history of the versions up to it) and six sections (framing, objectives, sequence, validated texts, assessments, sources), in the module’s language (French, else English).
- The model (
@elabora/coreplan-document/model.tsplanDocument(project, { date, version }), formatelabora/plan-document/2;planDocumentTargetsays what a version option shows): data without layout, read by every renderer (the exports, the app’s Document view, later a review link that shows the plan alone). Its texts are the plan’s Markdown and the same as rich-text data (plan-document/rich.ts: paragraphs, lists, tables, quotes, code, maths, with marks), so no renderer parses Markdown. What changed since the latest validated version up to the one shown reads in place: a changed text as one text whose words are marked deleted or inserted (diffRich,diffPlainfor titles), an element added (all inserted) or removed (in its old place, all deleted), each with itsmark(« Modifié · déplacé, c’était le point 4 ») and the author’s note for the client. It never says who wrote the plan or a change. - HTML (
plan-document/html.ts): one page, its sections in<details>that fold on screen; an element changed is marked in the margin’s blue, a verbatim text changed in amber, the notes for the client in the margin on a wide screen and under their element in print; an@pagerule gives A4, margins and a footer (the title, « Page n / N »), so a print needs no header or footer template.@elabora/nodeplan-document.tsadds the fonts inline (Inter and JetBrains Mono from@elabora/fonts, WOFF2 data URIs): the same page prints the same everywhere. - PDF: that page printed by Chromium: with
PLAN_PDF_ELECTRONby Electron’swebContents.printToPDFin an offscreen window ofPLAN_PDF_WINDOW(the app, and the command line when the app is installed:printPlanDocumentthrough a browser worker,emulator/electron.tsprintWithElectron, since Electron’s DevTools protocol has noPage.printToPDF), else withPLAN_PDF_PLAYWRIGHTby Chrome, Edge or Playwright’s Chromium: tagged, with an outline from the headings;finishPlanPdfsets its dates to the document’s day, so the same Chromium gives the same bytes (the app’s and the command line’s files are the same). - Word (
plan-document/docx.ts,omml.ts): WordprocessingML written by hand, zipped bycreateZip(D8). Word’s own styles (Title, Heading 1 to 3) and named styles of its own (Elabora …), no direct formatting but the plan’s own emphasis; tables for the properties and the plan’s own tables only; maths as Word equations (OMML, from temml’s MathML); the changes since the validated version as tracked changes (author « Depuis la V2 validée », no date), the notes for the client as comments (word/comments.xml, author « Note pour le client ») on the range of their element; a bookmark around every objective, item, validated text, question and source,wordBookmarkName(id)(el_then the id, « - » as « _ », « _ » as « _u »), read back byplanIdOfBookmark. - Where.
elabora plan export [dir] [--version Vn|current] [--format pdf|docx|html] [--out] [--date](defaultdist/<course id>-plan.<format>), MCPelabora_export_plan_document { format, version },@elabora/node/plan-documentexportPlanDocument(which records the send on the version it shows, one change:record_plan_send),writePlanDocument(the file only: the engine records the send through its queue),readPlanDocument,planDocumentPage,planDocumentWord,printPlanDocument, and the engine’s requests above. Exporting never makes a version.