- docs/kontra-architecture.mmd (mermaid source) + rendered PNG/SVG - docs/kontra-architecture-map.html (interactive Archify, validated + visual-checked) - docs/architecture.md (doc with embedded mermaid) - README.md (showcase: stack, content model, design system, deploy, security) - published docs/ to https://maps.lab.audasmedia.com.au/kontra_day/docs/ [secret-scan: skip - false positive on generated mermaid SVG path data]
3.3 KiB
type, id, title, status, source_of_truth, freshness, last_reviewed, tags
| type | id | title | status | source_of_truth | freshness | last_reviewed | tags | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| action | action.kontra-day.kontra-phase-3-build-goth-app-complete-golang-gotchas | Kontra Phase 3 build — GOTH app complete + golang gotchas | active | false | current | 2026-09-08 |
|
Kontra Phase 3 build — GOTH app complete + golang gotchas
Kontra — Phase 3 build complete (verified local)
What was built (2026-09-08)
GOTH stack app at /home/sam/home_network/web_sites/kontra_day/app:
- golang 1.26.2 (the "Go" in GOTH is golang, NOT Rust-like Go — vgo.mod uses
require (...)blocks,package main,func main()). - templ v0.3.1020 — CLI at
~/go/bin/templ(installed viago install github.com/a-h/templ/cmd/templ@latest, path must be on PATH)..templfiles inapp/src/, generated withtempl generate(writes*_templ.go), build withgo build -o kontra-bin .fromapp/src/. Build script:app/build.sh. - goldmark v1.8.6 markdown + goccy/go-yaml v1.19.2.
- Single static binary ~11.5MB.
PORTandKONTRA_CONTENTandKONTRA_MEDIAenv vars.
Key golang gotchas (learned the hard way)
[start:end]slices PANIC (bounds) if end > len — clamp first! Use helperfirstArticles(a, n)/firstSubjects.- No ternary operator; templ
{}interpolation doesn't support inlineif/else { }expressions — use block-levelifbetween elements, andtempl.KV(" active", cond)for conditional classes. //go:embed webkeeps FULL path in the virtual FS → root =web/, files atweb/assets/kontra.css. Serve withhttp.Handle("/web/", http.FileServerFS(web)). Route patterns need trailing-slash (/web/) plus/catch-all registered LAST.- Route specificity works but registers specific before
/. - go-yaml lowers struct field names for keys by default — use lowercase YAML keys (name/tagline/defaulttemplate/subjects/label/slug).
- log:
log.Printf/log.Fatalf(no log.Errorf). - golang stdlib net/http:
http.Handle(pattern, handler),http.HandleFunc,http.ListenAndServe(":8080", nil),r.URL.Path,r.PathValue("slug"). Patterns:/subjects/{slug}. - All source files
package main; go.modmodule day.
Content model
content/ tree: config/site.yaml, subjects/<slug>/_subject.yaml + *.md, pages/*.md. Front-matter keys lowercase: title/author/date/kicker/template/subject/image/excerpt/featured/published. Shortcodes {{media:name}}→KONTRA_MEDIA base + /name; {{embed:vimeo:ID}}→iframe. Resolved on RAW markdown BEFORE goldmark so links work.
Admin
Decap CMS at app/src/web/admin/ (index.html + config.yml): git-gateway backend → Gitea, collections articles/subjects/pages + editorial workflow. Served at /web/admin/.
Verified routes (local smoke test, PORT=8691)
/, /articles/{slug}, /subjects/{slug}, /web/assets/kontra.css, /web/admin/ → all 200. 404 for missing article/subject.
Git
Committed to local repo (no remote yet): commit 31e9a70. .pi/ memory vault is inside the repo too.
Not done yet (task 7)
Gitea remotes (.35), Obsidian vault, .13 systemd service + 30s git pull timer, Caddy routes (kontra.domain + admin), Decap git-gateway OAuth app.
Evidence
- Confidence: 100%
- Reason: Manual memctx_save