misc cleanup, update claude docs (#1657)

This commit is contained in:
Brandon Thomas
2026-06-16 01:34:50 -04:00
committed by GitHub
parent de538ba94c
commit ebe1287182
6 changed files with 35 additions and 12 deletions
+12 -3
View File
@@ -19,9 +19,18 @@ Handlers in `storyteller_web` follow this structure:
### Session/Auth
- `require_user_session_using_connection()` reuses an open DB connection (preferred)
- `require_user_session()` acquires its own connection (deprecated)
- `require_moderator()` for admin-only endpoints
Helpers live in `storyteller_web` under `http_server/web_utils/user_session/`. Each takes a
generic `mysql_executor: E` (any `sqlx::Executor`), so whether it reuses a connection or acquires
its own depends on the **argument you pass**:
- `require_user_session(http_request, session_checker, mysql_executor)` — require a logged-in user.
- `require_user_session_extended(...)` — same, with extra session detail.
- `require_moderator(http_request, session_checker, mysql_executor)` — admin-only endpoints.
PREFER passing an already-open connection (`&mut *conn`) so the helper reuses it. Passing
`&server_state.mysql_pool` makes it acquire a fresh connection — avoid that when the handler
already holds one (the double-acquire adds pool pressure; this crate has had pool-timeout
incidents). There is no `*_using_connection` variant — the reuse/acquire choice is the argument.
### API Type Definitions
+5 -4
View File
@@ -7,10 +7,11 @@
- `#[macro_use] extern crate serde_derive;` is used in binary crates; library crates use `use serde_derive::{Serialize, Deserialize};`
- Never use `println!` or `eprintln!` outside of tests; use `log` crate macros (`info!`, `warn!`, `error!`, `debug!`, `trace!`) instead
- Use `anyhow::Result` / `AnyhowResult` for fallible functions in application code; new database queries should use `Result<T, sqlx::Error>` instead
- SQLx queries: prefer `sqlx::query!` and `sqlx::query_as!` compile-time checked macros over
runtime `sqlx::query()` / `sqlx::query_as()`. The macros catch SQL typos, column mismatches,
and type errors at build time. Use runtime queries only when assembling complicated
dynamic/branching queries that cannot be expressed as a compile-time macro.
- SQLx: MySQL queries belong in the `mysql_queries` crate. Do NOT write `sqlx::query!` /
`sqlx::query()` in application/service crates (e.g. `storyteller-web`, which has zero direct
SQLx queries) — add or reuse a function in `mysql_queries` and call it. The compile-time
`query!` / `query_as!` macro conventions for that crate are documented in
`crates/schema/database/mysql_queries/CLAUDE.md`.
- Enum Display/Debug: use `impl_enum_display_and_debug_using_to_str!` macro, not `derive_more::Display` (CLion doesn't understand it)
- Fields that are optional use the `maybe_` prefix: `maybe_creator_user_token`, `maybe_prompt_token`
- When implementing `fmt::Display` for error types, use the pattern: `write!(f, "{:?}", self)`
+1 -1
View File
@@ -58,7 +58,7 @@ artcraft/
- Rust with no minimum supported version
- Actix-web for HTTP services
- SQLx for MySQL and SQLite; prefer `sqlx::query!` / `sqlx::query_as!` compile-time checked macros over runtime `sqlx::query()` whenever possible
- SQLx for MySQL and SQLite. MySQL queries belong in the `mysql_queries` crate, not in application/service crates like `storyteller-web` — call those query functions instead of embedding `sqlx::query!` / `sqlx::query()` in handlers. (Query-writing conventions live in `crates/schema/database/mysql_queries/CLAUDE.md`.)
- A mix of wreq and reqwest for Rust HTTP clients
- Never use `println!` or `eprintln!` outside of tests; use `log` crate macros instead
- When two crates export the same type name, alias imports with a suffix: `use foo::Bar as BarFoo;`
+15 -2
View File
@@ -28,8 +28,21 @@ deprecated or only used when setting other HTTP headers, like cookies.
Prefer `CommonWebError` for new handlers unless you need custom error variants.
When a handler uses `require_user_session`, prefer `require_user_session_using_connection`
which reuses an existing DB connection.
The session helpers (`require_user_session`, `require_user_session_extended`, `require_moderator`
in `http_server/web_utils/user_session/`) take a generic `mysql_executor` argument. Pass an
already-open connection (`&mut *conn`) so the helper reuses it; do NOT pass
`&server_state.mysql_pool` when the handler already holds a connection, since that self-acquires a
second one and adds pool pressure (this crate has had pool-timeout incidents). There is no
`require_user_session_using_connection` / `require_moderator_using_connection` — the
reuse-vs-acquire behavior is determined by the argument.
## Database Access
Do NOT write SQLx queries in this crate. `storyteller-web` contains **zero** direct SQLx queries —
all MySQL access goes through the `mysql_queries` crate. Add a function there (or reuse an existing
one) and call it from the handler; never embed `sqlx::query!` / `sqlx::query()` in a handler or
helper here. See `crates/schema/database/mysql_queries/CLAUDE.md` for the query-writing conventions
(compile-time `query!` / `query_as!` macros, offline cache, the `Args`/`Executor` pattern, etc.).
## api_doc.rs
@@ -25,6 +25,6 @@ pub fn to_simple_json_error(
};
HttpResponseBuilder::new(status_code)
.set_header(CONTENT_TYPE, "application/json")
.insert_header((CONTENT_TYPE, "application/json"))
.body(body)
}
@@ -16,6 +16,6 @@ pub fn serialize_as_json_error<T>(
};
HttpResponseBuilder::new(error_payload.status_code())
.set_header(CONTENT_TYPE, "application/json")
.insert_header((CONTENT_TYPE, "application/json"))
.body(body)
}