steid

@jamesgill /

docs: correct the Topcoat guidance in CLAUDE.md

The gotcha telling you to check Topcoat's docs on GitHub was actively
misleading: the repository has already diverged from the released crate, and
following it is how path_param was got wrong. Points at the vendored
registry source instead, which is the authority for the pinned version.

Adds a "Topcoat, as we use it" section for the working knowledge that is easy
to get wrong and slow to rediscover -- bare component invocation, path_param
as an attribute, query_params needing error=, redirect being an error type
while see_other is a response type, static routes beating parameterised ones,
and forms re-rendering rather than redirecting on failure.

Two operational notes: topcoat asset bundle is required after a manual build
or the CSS is stale, and implementations must precede the mod tests block in
sqlite.rs -- appending to the end of that file landed inside the wrong block
twice.

current.md records the one unanswered question so it survives a context
reset: tempfile vs target/ for DiskGitStorage fixtures.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
JamesPatrickGill authored 24 days agoparentc5b3ff5Browse filesbe4fac5a83c0ace1fc0f7a147367a7c84e348358

2 files changed+34 −2

CLAUDE.md+29 −2View file
@@ -65,6 +65,26 @@ Full detail in `plans/architecture.md`. The short version:
6565 gets someone else's data.
6666 - Safe Rust only. No `unsafe`.
6767
68+## Topcoat, as we use it
69+
70+Working knowledge that is easy to get wrong and slow to rediscover:
71+
72+- **Components are invoked bare inside `view!`** — `label(attrs: …, "Text")`, not
73+ `(label(…)?)`. `if`, `match`, `for` and `let` are native to the macro.
74+- **`#[path_param]` is an attribute on a tuple struct** — `#[path_param] struct
75+ Handle(str);` — and the struct name snake-cased is the URL parameter.
76+- **`#[query_params]` needs `error = …`** to be usable with `?`; otherwise the error
77+ borrows from `cx` and escapes the handler.
78+- **`redirect()` is an error type, `see_other()` is a response type.** A page returning
79+ a view redirects with `Err(redirect(..).into())`.
80+- **Static routes beat parameterised ones**, so `/auth/login` still wins over
81+ `/{handle}`.
82+- **Forms redirect on success and re-render on failure.** Redirecting after a validation
83+ error discards what was typed and hides the reason.
84+- **UI components reference theme tokens, never raw colours** — see `styles.css`. A
85+ hardcoded colour follows neither a palette change nor the colour scheme. Registry
86+ components are copied in by `topcoat ui add`, not depended on.
87+
6888 ## Before saying it's done
6989
7090 ```bash
@@ -83,11 +103,18 @@ browser. Say plainly what was checked and what wasn't.
83103
84104 - **Topcoat 0.5 needs rustc ≥ 1.95.** On older toolchains `cargo add topcoat` silently
85105 resolves to an empty `topcoat v0.0.0` placeholder instead of failing.
86- **Topcoat is very new** (first release 2026-07-22) and expects breaking changes.
87 Check its docs on GitHub rather than assuming an API.
106+- **Read the vendored crate, not GitHub `main`.** Topcoat is very new (first release
107+ 2026-07-22) and its repository has already diverged from the released version. The
108+ authority for the pinned version is
109+ `~/.cargo/registry/src/*/topcoat-0.5.0/docs/` and the sibling `topcoat-*-0.5.0`
110+ crates. Checking `main` is how `path_param` was got wrong.
88111 - **`STEID_INSECURE_COOKIES=true`** is set in a gitignored `.env` for local dev,
89112 because a `Secure` cookie is dropped silently over plain-HTTP localhost. Never
90113 deploy it.
91114 - **The setup token is in memory only**, so every restart — including each `topcoat
92115 dev` rebuild — mints a new one.
93116 - Don't leave background servers running; the user drives the app.
117+- **`topcoat asset bundle` after a manual build**, or the CSS served is stale.
118+ `topcoat dev` does it for you.
119+- In `sqlite.rs` and similar, **every implementation precedes the `mod tests` block**.
120+ Appending to the end of the file otherwise lands inside the wrong block.
plans/current.md+5 −0View file
@@ -52,6 +52,11 @@ milestone 4.
5252 up applying different rules. The cost is that a private repo is briefly in memory
5353 before being filtered, which is fine in-process.
5454
55+### Open
56+
57+- **Test fixtures for `DiskGitStorage`:** `tempfile` as a dev-dependency, or write under
58+ `target/`? Leaning `tempfile` — self-cleaning and parallel-safe. Unanswered.
59+
5560 ### Watch for
5661
5762 - **The database and the filesystem cannot share a transaction.** Creating a repo