| | @@ -65,6 +65,26 @@ Full detail in `plans/architecture.md`. The short version: |
| 65 | 65 | gets someone else's data. |
| 66 | 66 | - Safe Rust only. No `unsafe`. |
| 67 | 67 | |
| 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 | + |
| 68 | 88 | ## Before saying it's done |
| 69 | 89 | |
| 70 | 90 | ```bash |
| | @@ -83,11 +103,18 @@ browser. Say plainly what was checked and what wasn't. |
| 83 | 103 | |
| 84 | 104 | - **Topcoat 0.5 needs rustc ≥ 1.95.** On older toolchains `cargo add topcoat` silently |
| 85 | 105 | 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. |
| 88 | 111 | - **`STEID_INSECURE_COOKIES=true`** is set in a gitignored `.env` for local dev, |
| 89 | 112 | because a `Secure` cookie is dropped silently over plain-HTTP localhost. Never |
| 90 | 113 | deploy it. |
| 91 | 114 | - **The setup token is in memory only**, so every restart — including each `topcoat |
| 92 | 115 | dev` rebuild — mints a new one. |
| 93 | 116 | - 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. |