oficina / calendar Public

Clone
git clone https://amadan.net/oficina/calendar

Plain git — no account needed to clone.

Download

Download this file

manifest/ — the declarative path

Manifest-driven and code-driven are equal, optional paths: declare the resources that are pure CRUD, hand-write the ones that aren't, per resource, in one app. One TOML file here declares a whole screen set — List → Show → Edit/New plus the confirm-page delete flow — generated as real committed code under gen/ by rastrillo generate:

name = "tickettypes" route = "/admin/tickettypes"

[list] columns = [{ field = "Name", kind = "text" }, { field = "Price", kind = "money" }] search = true

[form] basics = [{ name = "Name", required = true }, { name = "Price", kind = "money" }]

The vocabulary covers one flat table per resource, three field kinds, no relations. Add scope = "user" and every generated query is owner-filtered by the session subject — someone else's row answers 404 — for resources a user owns; mount those routes behind sessions.Require. Add store = "mergeable" and the resource lives as event-log streams (tombstone deletes, derive-on-read) instead of a sqlc table — it needs no sqlc tool. Relations or a custom flow: hand-write it.

Adding the first manifest to this app:

  1. go get -tool github.com/sqlc-dev/sqlc/cmd/sqlc (once — the generated store is sqlc input).
  2. rastrillo generate writes gen/ — committed, never hand-edited.
  3. Mount the generated router beside the chi router in internal/calendar/app.go, and wire its Ctx (the generated actions render through Ctx.Render — examples/blog's internal/blog/genrender.go in the rastrillo repo is the adapter to copy):

gmux := gen.Router(func(http.Request) rastrillo.Ctx { writer, _ := d.G.DB() return &rastrillo.Ctx{DB: writer, Logger: logger, Actor: rastrillo.Actor{Human: true}, Render: render} }) mux.Handle("/admin/", gmux)

  1. Append the generated migrations to the schema step, and add rastrillo generate --check to the Makefile's ci target.

Drop to a .go manifest in this directory (package manifest, a var X = rastrillo.Resource{...}) the moment you need a function value — a custom Column.Render, say. To take any single generated screen over by hand, write your own action file at the same computed path under actions/ — the generator skips that one from then on.