mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-20 17:02:53 -04:00
This is a fresh start for the `artcraft` repo. The old monorepo, which included our web API gateway, job services, SRE tools, various frontends, and more has moved to `artcraft-services` You can find the full git history here: https://github.com/storytold/artcraft-services This change was motivated by the fact that the entire git history was hundreds of gigabytes in size, which is unwieldy for anyone not in the core team that doesn't care about support services outside of the core artcraft app. We wanted to keep this repo in its well-known place since we already have users and activity here. Please update your remotes to either `artcraft-services` or make a fresh clone of this repo. History can be found at the artcraft-services repo.
93 lines
4.9 KiB
Markdown
93 lines
4.9 KiB
Markdown
# Code Style
|
|
|
|
## Rust
|
|
|
|
- Two spaces for indentation (not four)
|
|
- No minimum supported Rust version; use latest stable features freely
|
|
- `#[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: 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)`
|
|
|
|
## File Layout (Top-to-Bottom Reading Order)
|
|
|
|
Organize code so a human reading top-to-bottom encounters the most important things first and
|
|
can drill down into details only when curious. Think of it like a newspaper: headline first,
|
|
then the story, then the fine print.
|
|
|
|
### Ordering within a file
|
|
|
|
1. **Constants** at the top, right after imports.
|
|
2. **The primary public type** (the main struct/enum the file is about) comes next.
|
|
A reader opening this file should immediately see what it defines.
|
|
3. **Supporting/subordinate types** (sub-structs, helper enums, serialization DTOs) go
|
|
below the primary type, not above it. Ask: "Would a reader need to know this type
|
|
exists before seeing the main type?" — if no, push it down.
|
|
4. **Type ordering for API types**: Request, then Response (success), then Error.
|
|
5. **`impl` blocks** after their type definitions.
|
|
|
|
### Ordering within an `impl` block
|
|
|
|
1. **Constructors** (`new`, `from_*`, `builder`) at the top.
|
|
2. **Public methods** next — these are the main entry points a reader cares about.
|
|
3. **Private helper methods** below public methods.
|
|
- Among helpers: place "meaty" helpers (substantial logic, direct continuations of the
|
|
public entry point) above "leaf" helpers (small formatters, simple lookups).
|
|
- A method that calls another method in the same file should appear *above* the method
|
|
it calls. This lets readers follow the call chain downward.
|
|
|
|
### Ordering within test modules
|
|
|
|
Put test cases first, helpers last. A reader opening a test file should immediately see
|
|
*what* is being tested before *how* the test machinery works.
|
|
|
|
1. **Imports**
|
|
2. **Constants** (test IDs, URLs, fixture data) — small context that tests reference
|
|
3. **Test functions** or **sub-modules** grouped by category
|
|
4. **Helper functions** (builders, pipeline runners, assertions)
|
|
|
|
Group related tests into sub-modules (`mod pricing_tests { ... }`) when a category has 2+
|
|
tests. Don't create a sub-module for a single test. Keep nesting to two levels max
|
|
(`mod tests { mod category { ... } }`). Shared helpers go in the parent module so
|
|
sub-modules can reach them via `use super::*`.
|
|
|
|
## Naming
|
|
|
|
- Handler functions: `{verb}_{noun}_handler` (e.g. `get_health_check_handler`, `login_handler`)
|
|
- Error enums: `{Feature}Error` (e.g. `FalWebhookError`, `HealthCheckError`)
|
|
- Request/response structs: `{Action}Request`, `{Action}Response`, `{Action}SuccessResponse`
|
|
- Path params: `{Action}PathInfo`
|
|
- Builder structs: `{Thing}Builder` with `set_` prefixed setters and a `build()` method
|
|
|
|
## Imports
|
|
|
|
- Group imports: std, external crates, internal workspace crates, `crate::` imports
|
|
- Prefer `use` imports over inline fully-qualified paths. Inline qualification is acceptable
|
|
only for genuine one-off references where adding an import would be noise, or for types
|
|
that collide with std prelude names (`Result`, `Option`, `Error`). If you reference a symbol
|
|
more than once, always import it.
|
|
- Prefer specific imports over wildcards, except in `api_doc.rs` and test modules
|
|
- When two crates export a type with the same name, alias with a suffix describing the source crate:
|
|
`use enums::...::CommonResolution as CommonResolutionEnum;`
|
|
`use artcraft_router::...::CommonResolution as CommonResolutionRouter;`
|
|
This avoids long fully-qualified paths in function signatures and bodies.
|
|
|
|
## MySQL
|
|
|
|
- MySQL tables: primary key `id` columns must be `BIGINT(20) UNSIGNED`. Do not use signed IDs.
|
|
- Always create tables with `ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin`.
|
|
|
|
## TypeScript / Frontend
|
|
|
|
- TypeScript with React, Vite, Zustand, Three.js
|
|
- Nx monorepo under `crates/frontend/`
|
|
- Two spaces for indentation
|
|
|