CodeBench: code-rs.md — spawn_server-esimerkki, {id} vahvistus, init_db yksinkertaistus

- Eksplisiittinen spawn_server()-koodi testien promptiin (async move wrappaus)
- {param} reittiohje vahvistettu kahdesti, chaining-ohje
- init_db: .expect() ei Result
- "You MUST generate ALL 6 files"
This commit is contained in:
2026-04-14 17:08:26 +03:00
parent de3e33d46e
commit 088bad7b21

View File

@@ -36,7 +36,8 @@ DOCUMENTATION — every file starts with //! one-line module doc. Structs get //
RULES: RULES:
- Follow the REFERENCE IMPLEMENTATION patterns exactly - Follow the REFERENCE IMPLEMENTATION patterns exactly
- Use axum 0.8 API: Router, Json, Path, State, StatusCode - Use axum 0.8 API: Router, Json, Path, State, StatusCode
- Route paths use {param} syntax: "/items/{id}" — NOT /:id - ROUTING: use {param} NOT :param — e.g. .route("/items/{id}", get(get_item))
- ROUTING: one .route() call per path, chain methods: .route("/items", post(create).get(list))
- State is SqlitePool wrapped in axum::extract::State - State is SqlitePool wrapped in axum::extract::State
- app() takes SqlitePool as argument and calls .with_state(pool) on the Router - app() takes SqlitePool as argument and calls .with_state(pool) on the Router
- Handlers return Result<(StatusCode, Json<T>), StatusCode> or Result<StatusCode, StatusCode> - Handlers return Result<(StatusCode, Json<T>), StatusCode> or Result<StatusCode, StatusCode>
@@ -45,8 +46,28 @@ RULES:
- Use sqlx::query("SQL") for writes (DELETE, etc.), sqlx::query_as::<_, T>("SQL") for reads - Use sqlx::query("SQL") for writes (DELETE, etc.), sqlx::query_as::<_, T>("SQL") for reads
- Use RETURNING clause in INSERT/UPDATE queries to get the created/updated row back - Use RETURNING clause in INSERT/UPDATE queries to get the created/updated row back
- DateTime fields: store as TEXT, use String type in Rust structs - DateTime fields: store as TEXT, use String type in Rust structs
- Tests: each test spawns isolated server with in-memory SQLite ("sqlite::memory:") on random port (127.0.0.1:0) - init_db: use .expect("msg") not Result return — keep it simple
- Tests: unique descriptive data in Finnish, NOT generic "test" strings
- Tests: use reqwest::Client and serde_json::json!() for request bodies
- NO markdown fences inside file content — just raw code - NO markdown fences inside file content — just raw code
- Edition 2024 in Cargo.toml - Edition 2024 in Cargo.toml
- You MUST generate ALL 6 files. Do not stop early.
TESTS — follow this exact spawn_server pattern:
async fn spawn_server() -> (reqwest::Client, String) {
let pool = sqlx::sqlite::SqlitePoolOptions::new()
.max_connections(1)
.connect("sqlite::memory:")
.await
.expect("DB failed");
init_db(&pool).await;
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.expect("Bind failed");
let addr = listener.local_addr().unwrap();
let base_url = format!("http://{addr}");
let router = app(pool);
tokio::spawn(async move { axum::serve(listener, router).await.unwrap() });
(reqwest::Client::new(), base_url)
}
- Each #[tokio::test] calls spawn_server() to get (client, url)
- Unique descriptive data in Finnish, NOT generic "test" strings
- Use serde_json::json!() for request bodies