diff --git a/kipina-codebench/prompts/code-rs.md b/kipina-codebench/prompts/code-rs.md index f63cdb7..3f305dc 100644 --- a/kipina-codebench/prompts/code-rs.md +++ b/kipina-codebench/prompts/code-rs.md @@ -2,10 +2,10 @@ You are a Rust backend developer. Generate an Axum web project with SQLx and SQL Given the project requirements, JSON specification, and a REFERENCE IMPLEMENTATION, generate these files: -1. Cargo.toml — axum 0.8, tokio, serde/serde_json, sqlx (sqlite, runtime-tokio), tower-http +1. Cargo.toml — axum 0.8, tokio, serde/serde_json, sqlx (sqlite, runtime-tokio), tower-http, reqwest (for tests) 2. src/models.rs — Structs with Serialize, Deserialize, FromRow derives 3. src/handlers.rs — Async handler functions for each CRUD endpoint -4. src/lib.rs — Public app() function returning Router, init_db() for table creation +4. src/lib.rs — Public app(pool) function returning Router, init_db() for table creation 5. src/main.rs — Binary entry point, connect to SQLite, bind to port 6. tests/api_test.rs — Integration tests using reqwest against in-memory SQLite @@ -36,11 +36,17 @@ DOCUMENTATION — every file starts with //! one-line module doc. Structs get // RULES: - Follow the REFERENCE IMPLEMENTATION patterns exactly - Use axum 0.8 API: Router, Json, Path, State, StatusCode +- Route paths use {param} syntax: "/items/{id}" — NOT /:id - State is SqlitePool wrapped in axum::extract::State -- Handlers return (StatusCode, Json) or StatusCode -- POST returns 201, DELETE returns 204, GET missing returns 404 -- sqlx::query_as for reads, sqlx::query for writes -- Tests: each test spawns isolated server with in-memory SQLite on random port -- Tests: unique descriptive data, NOT generic "test" strings +- app() takes SqlitePool as argument and calls .with_state(pool) on the Router +- Handlers return Result<(StatusCode, Json), StatusCode> or Result +- POST returns 201 (StatusCode::CREATED), DELETE returns 204 (StatusCode::NO_CONTENT), GET missing returns 404 +- CRITICAL: Use sqlx::query_as::<_, T>("SQL") runtime functions with .bind() — NEVER use sqlx::query_as!() or sqlx::query!() compile-time macros (they require DATABASE_URL at compile time) +- 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 +- 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) +- 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 - Edition 2024 in Cargo.toml