Five things a building authority needed and portal could not say,
found by building one and replaying its cases through the engine.
The one that mattered: a submitter could only ever act on a record
nobody had touched. `access.rs` pinned a self_transition's from-state
to `open`, though the runtime had always passed the real state and
asked. So the applicant written to for a missing drawing could not
send it, and nobody could withdraw once anything had happened.
`self_transition` now takes `from: [state, ...]` and compiles one rule
per state; omitted it still means the initial state alone, which is
what every unsubscribe link already meant.
Then the four beside it. A record can belong to another record
(`type: record`, `of:`), with `where: { field, equals }` on a listing
as the other half, so an application's page lists the objections that
name it. A public view can be narrowed to the states worth showing,
so a register that is public by law is public about what was decided
and not about what was withdrawn. A state can grant a group, so an
approval that means membership needs no second step. And a state can
be moved by a clock (`after: { days, to }`, src/deadlines.rs) - held
to the same declared edge as a desk button, firing the same mail,
publishing the same event.
Also: the README is a README again, and everything that was crowding
it is in docs/ - architecture, content reference, state machines,
access, operations.
95 tests, up from 82.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
23 lines
1.2 KiB
Markdown
23 lines
1.2 KiB
Markdown
# portal documentation
|
|
|
|
Portal turns a Git repo of YAML into a running site. Almost everything
|
|
here is about that YAML: what a content repo may say, and what the
|
|
engine does with it.
|
|
|
|
| | |
|
|
|---|---|
|
|
| [Architecture](architecture.md) | What the engine is made of and where each piece lives in the source. |
|
|
| [Content reference](content-reference.md) | Every key a content repo may write, and what it does. |
|
|
| [State machines](state-machines.md) | `aggregates.yaml`: stages, who moves a case, mail, deadlines, memberships. |
|
|
| [Access](access.md) | How the Cedar policy is compiled from content, and who may ask it what. |
|
|
| [Operations](operations.md) | Releasing, deploying, adding a site, environment variables. |
|
|
| [Filesystem routes](design/filesystem-routes.md) | Why the `questions/` tree is the router. |
|
|
|
|
Two repos in the same family carry their own docs:
|
|
|
|
- [uhhm/iris](https://project.uhhm.no/uhhm/iris) — the lint. Versioned
|
|
as portal and released by portal's publish job; it is the thing a
|
|
content repo's CI runs before anything reaches a site.
|
|
- [uhhm/gdo](https://project.uhhm.no/uhhm/gdo) — the mailer. Delivers
|
|
what content asked to be sent, and carries replies back.
|