create-substrat 0.11.9 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -36,12 +36,12 @@ const TEMPLATE = join(HERE, 'template');
36
36
  // The runtime packages release together off one version line (the changesets `fixed`
37
37
  // group), so one constant is right for all of them. Engines do NOT share a line —
38
38
  // each versions on its own, so one pin per engine, deliberately.
39
- const SUBSTRAT = '^0.149.0';
40
- const ENGINE_WORKORDER = '^0.12.33';
41
- const ENGINE_INVOICING = '^0.11.33';
39
+ const SUBSTRAT = '^0.151.0';
40
+ const ENGINE_WORKORDER = '^0.12.35';
41
+ const ENGINE_INVOICING = '^0.11.35';
42
42
  const BOUNDARY_LINT = '^0.8.0';
43
- const DEV_ISSUER = '^0.2.31';
44
- const ATTACHMENT_EXTRACTORS = '^0.2.10';
43
+ const DEV_ISSUER = '^0.2.33';
44
+ const ATTACHMENT_EXTRACTORS = '^0.2.12';
45
45
 
46
46
  const DOCS = 'https://substrat.net';
47
47
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-substrat",
3
- "version": "0.11.9",
3
+ "version": "0.12.1",
4
4
  "description": "Scaffold a Substrat vertical — `npm create substrat <dir>`.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -163,7 +163,7 @@ stop. Do not scaffold.
163
163
  ## Step 3 — Write the design document
164
164
 
165
165
  **This is the deliverable.** Everything before now was learning; this is where it lands
166
- somewhere the user can hold. Write a **checked-in `spec/concept.md`** — beside
166
+ somewhere the user can hold. Fill in the **checked-in `spec/concept.md`** (the scaffold ships it) — beside
167
167
  `spec/model.ts`, which is this same design one rung more concrete — in the user's own
168
168
  vocabulary — no Substrat internals, no decision refs, no cross-references to
169
169
  platform docs. Someone who has never heard of Substrat must be able to read it and recognise
@@ -175,6 +175,12 @@ their own business.
175
175
  Status: draft v0.1 · Last updated: <date> · For review before any code
176
176
  ```
177
177
 
178
+ **The layout is fixed by the scaffold**: keep its seven headings and the `substrat:` markers —
179
+ purpose and users, roles and permissions, entity model, processes, screens and dashboard,
180
+ decisions log, open questions. Roles, entities and processes are generated from the code
181
+ (Step 5); what follows describes the authored parts, and the denials preview below is prose that
182
+ sits beside the generated roles table, not instead of it.
183
+
178
184
  **The template** — the coverage map (Step 2) is sections 3–4, already done; the rest is the
179
185
  interview written down. Two sections deliberately *preview* the code checkpoints of Step 7 in
180
186
  plain language, so nothing there is a surprise:
@@ -248,6 +254,19 @@ say so rather than letting them wave it through — a design nobody understands
248
254
  reproduces exactly the failure Substrat exists to prevent. Iterate the document until they
249
255
  can, and only then take explicit approval.
250
256
 
257
+ **A change to a vertical that already has a `model.json`** goes through this same gate, and what
258
+ the gate shows is the **concept delta**, not prose. Declare the change in `spec/model.ts` and
259
+ its roles only — no handler, no screen — re-emit the artifacts, and run `substrat plan`. It
260
+ prints the entities added, changed and removed (the model before and after), the lifecycle
261
+ changes with the operation that triggers each transition, the permission-diff table, the
262
+ spec-version impact (patch / minor / major, from the same classifier `substrat changeset`
263
+ uses), and the decisions-log entry approval would write. Show it to the user as printed, walk
264
+ them through it in their vocabulary, and **stop**. Only once they approve, run the
265
+ `substrat plan --approve <digest> --by "<their name>" --why "<their reason>"` line it printed:
266
+ that records the approval in the Decisions log of `spec/concept.md`. Never run `--approve`
267
+ on your own judgement, and if the model moves after they read it, show the delta again — the
268
+ old digest is refused.
269
+
251
270
  Approval of the design is what unlocks Step 5. Until you have it, you are still in design.
252
271
 
253
272
  ---
@@ -312,6 +331,19 @@ and event subjects all need one id, so naming such an entity in `parents`,
312
331
  compile error. It is still a full model member with migrations and a row type. A
313
332
  single-column key that is not called `id` stays fully pointable.
314
333
 
334
+ **Run `substrat concept sync` after every change to the model.** It reads `model.json` beside
335
+ `package.json`, which a scaffold does not write for you: write the exported model there
336
+ (`JSON.stringify(<your emitModel result>, null, 2)`) first. Sync then rewrites the entity and
337
+ process regions of `spec/concept.md` between the `<!-- substrat:entities -->` and
338
+ `<!-- substrat:processes -->` markers (a Mermaid ER diagram, and one state diagram per lifecycle).
339
+ The roles region is filled from a `PERMISSIONS.md` beside `model.json`; a scaffold has no command
340
+ that writes one, so until it does the region says so and the roles live in your own prose. Never
341
+ edit between the markers by hand, and run `substrat concept sync --check` before you hand the
342
+ design over: it exits 1 while a region is stale. **Write the decisions-log entry yourself**, in
343
+ the document's *Decisions log* section on every change to the model or a permission: the date,
344
+ what changed, and why. No tool in a scaffold enforces it, so the reviewer reading the diff is the
345
+ gate.
346
+
315
347
  Behaviour stays prose in `spec/concept.md`. Inventing a way to declare a state *transition*
316
348
  means the boundary slipped.
317
349
 
@@ -0,0 +1,40 @@
1
+ Status: draft v0.1 · Last updated: <date> · For review before any code
2
+
3
+ # <The name of the thing you are building>
4
+
5
+ This is the readable description of the app, for the people who own it. Three sections are
6
+ written by `substrat concept sync` from the code (entity model and processes from `model.json`;
7
+ roles from a `PERMISSIONS.md` beside it, when there is one) and the rest by hand. Do not edit
8
+ between the `substrat:` markers: the next sync overwrites it, and `substrat concept sync --check`
9
+ exits 1 while one is stale.
10
+
11
+ ## 1. Purpose and users
12
+
13
+ _Authored. Who this is for, what it does, in their words._
14
+
15
+ ## 2. Roles and permissions
16
+
17
+ <!-- substrat:roles -->
18
+ <!-- /substrat:roles -->
19
+
20
+ ## 3. Entity model
21
+
22
+ <!-- substrat:entities -->
23
+ <!-- /substrat:entities -->
24
+
25
+ ## 4. Processes
26
+
27
+ <!-- substrat:processes -->
28
+ <!-- /substrat:processes -->
29
+
30
+ ## 5. Screens and dashboard
31
+
32
+ _Authored. What each person sees first, and what the dashboard answers._
33
+
34
+ ## 6. Decisions log
35
+
36
+ _Authored, appended on every change to the model or to a permission: the date, what changed, and why._
37
+
38
+ ## 7. Open questions
39
+
40
+ _Authored. What is not decided yet, and who decides it._
@@ -3,6 +3,7 @@ import { dirname, join } from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  import { serve } from '@hono/node-server';
5
5
  import { Hono } from 'hono';
6
+ import { invocationLog } from '@substrat-run/vertical-host';
6
7
  import type { Context } from 'hono';
7
8
  import { HTTPException } from 'hono/http-exception';
8
9
  import { platformActorId } from '@substrat-run/contracts';
@@ -71,6 +72,10 @@ const login = devLogin({
71
72
  });
72
73
 
73
74
  const app = new Hono();
75
+ // The request's stamp: an id on every response (`x-substrat-request-id`) and, under
76
+ // `substrat dev`, the HTTP half of its trace. FIRST, so it wraps every route below. Bare on
77
+ // purpose: no router fronts this server, so there is nothing to verify and no line to write.
78
+ app.use('*', invocationLog());
74
79
 
75
80
  // Login, callback, logout. Accounts and passwords live at the issuer; this vertical
76
81
  // runs no credential store of its own.