carlos / movement Public

Clone
git clone https://amadan.net/carlos/movement

Plain git — no account needed to clone.

Download

Download this file

1# movement
2
3A [rastrillo](https://github.com/rastrilloorg/rastrillo) app. Read the
4framework's own SKILL.md (repo root, or in the module cache) before
5writing app code — it is the whole app story in ~15KB. The conventions
6below are load-bearing; the framework enforces most of them
7mechanically.
8
9## Layout
10
11- `internal/<app>/` — the app: `models.go` (plain GORM structs
12 + Models), `migrations.go` + `migrations/` (Schema, BootSchema),
13 `app.go` (migrate.Apply + chi router), `handlers.go`,
14 `render.go` + `templates/`. This is SKILL.md's five-file shape.
15- `manifest/` — the declarative path, optional and equal: TOML or .go
16 Resource manifests, each generating a full screen set under `gen/`
17 (see manifest/README.md for the mounting recipe). A hand-written
18 action file at a generated path (carrying `//go:build rastrillo_actions`)
19 takes that one screen over, by existence.
20- `gen/` — generated when manifests are used; never edit. Regenerate
21 with `rastrillo generate`.
22
23## Rules the family holds hard
24
25- Every query touching user-owned rows goes through `scope.Owned` —
26 reads AND writes, transactions included. A row that isn't yours 404s,
27 never 403s.
28- Never bind a request body onto a GORM model: explicit
29 `map[string]any` + `.Select` allowlist.
30- Migrations apply at boot, once each, and are never re-run or reversed.
31- Schema changes: edit models.go, then run `rastrillo migration generate`
32 and read the SQL it writes — it may be a full table rebuild, not just
33 an `ADD COLUMN`. Never edit a migration that has shipped.
34 Renames are hand-written (`rastrillo migration new rename_x`) because
35 a rename is indistinguishable from a drop plus an add.
36- Money is integer cents. A float never touches a value a person will
37 be held to.
38- Screens work with JavaScript disabled; destructive actions get their
39 own confirm-page URL.
40- The gate is `make ci` (vet + gofmt + tests) — the same definition
41 CI runs. Run it before every push. `CGO_ENABLED=0` throughout: the
42 stack is cgo-free by design.
43
44## Serving
45
46`rastrillo.Resolve` + `Serve` speak the CARLOS activation contract
47(socket/addr/db argv, LISTEN_FDS, $STATE_DIRECTORY, `sidecar run`) —
48the golden deployment target, not a requirement: `./app -addr :8080`
49serves anywhere. `GET /healthz` and `GET /api/version` are answered
50by the framework, outside app middleware.
51
52## UX conventions (seeded from profile: considered)
53
54Accessible by construction, progressively enhanced, and never dependent on JavaScript to be usable.
55
56These are rastrillo's own conventions, and the profile is named for what it does rather than after anyone else's work. For wider reading on interface quality, impeccable.style, the WAI-ARIA Authoring Practices and Inclusive Components are all worth your time — none of them is endorsed by, or authoritative for, this framework.
57
58- [x] Icons — lucide, inline — `internal/<app>/icons`
59- [x] Fields — label, hint, help and error in one envelope, wired with aria-describedby — `ui/field, ui/field-select, ui/field-text`
60- [x] Destructive actions — their own confirm-page URL, never a modal — `ui/confirm-form`
61- [x] State — never colour alone — always a text label too — `ui/status-pill, ui/badge`
62- [ ] Dates — relative, with the absolute date in a title attribute
63- [ ] Errors — server-rendered beside the field, in plain language
64- [x] Empty states — say what the screen is for, not just that it is empty — `ui/empty-state`
65
66`[x]` is enforced by a vendored component: use it, do not hand-roll an
67equivalent. `[ ]` is guidance to apply by hand. A convention absent from
68this list is one rastrillo has no opinion about.
69
70Edit any line. **This file is the source of truth, not the profile name.**
71The profile only seeded this list at scaffold time; nothing re-reads it, so
72changing a line here changes what the app does. A convention deleted from
73this file is not a convention to reinstate.
74