@@ -41,66 +41,72 @@ reviews:
4141 - path : " src/routes/**/*.rs"
4242 instructions : |
4343 - Route handlers are HTTP-only: delegate all business logic to services
44- - Verify correct HTTP status codes: 200 OK, 201 Created, 204 No Content, 404 Not Found, 409 Conflict, 422 Unprocessable Entity
45- - Ensure `#[get]`/`#[post]`/`#[put]`/`#[patch]`/`#[delete]` attributes appear directly above `fn`, with doc comment above the attribute
46- - Check that state is accessed via `&State<PlayerCollection>` and locked with `.lock().map_err(|_| Status::InternalServerError)?`
47- - Surrogate key (UUID) is used only for `GET /players/{id}`; all mutation routes use `squad_number` as the natural key
48- - Verify each route module exposes a `pub fn routes() -> Vec<rocket::Route>` function
44+ - Verify HTTP status codes: 200 OK, 201 Created, 204 No Content,
45+ 404 Not Found, 409 Conflict, 422 Unprocessable Entity
46+ - Only #[get], #[post], #[put], #[delete] attributes are valid.
47+ This API does NOT implement PATCH — flag any #[patch] handler.
48+ - State is an r2d2 connection pool injected as
49+ &State<Pool<ConnectionManager<SqliteConnection>>>; no manual Mutex locking
50+ - Surrogate key (UUID) is used only for GET /players/{id};
51+ all mutation routes use squad_number as the natural key
4952
5053 - path : " src/services/**/*.rs"
5154 instructions : |
52- - Services must be pure business logic with no HTTP knowledge
53- - All fallible functions return `Result<T, CustomError>` with domain-specific error variants
54- - Verify `squad_number` uniqueness is enforced on create
55- - On update, UUID and squad_number are always preserved from the existing record — request body values for these fields are ignored
56- - Functions should accept `&[Player]` or `&mut Vec<Player>` (not `&Vec<Player>`) when a slice suffices
55+ - Pure business logic only: no HTTP knowledge, no Diesel or SQL imports
56+ - All fallible functions return Result<T, CustomError>
57+ - squad_number uniqueness is enforced on create
58+ - On update, UUID and squad_number are always preserved from the stored
59+ record — request body values for these fields are ignored
60+
61+ - path : " src/repositories/**/*.rs"
62+ instructions : |
63+ - All Diesel DSL queries live here; services must not import Diesel directly
64+ - Functions return Result<T, CustomError> and propagate errors with ?
65+ - Minimize .clone(); prefer references where lifetimes allow
5766
5867 - path : " src/models/**/*.rs"
5968 instructions : |
6069 - Maintain three distinct types: `Player` (storage), `PlayerRequest` (input), `PlayerResponse` (output)
6170 - Verify `serde` derive macros and camelCase JSON field naming (`#[serde(rename_all = "camelCase")]`)
6271 - `id` (UUID) and `squad_number` are immutable once set — validate that no model allows changing them after creation
63- - `PlayerRequest` fields should all be required except where explicitly optional (e.g. `PATCH` payloads)
72+ - All `PlayerRequest` fields are required; this API has no partial-update endpoint
6473
6574 - path : " src/state/**/*.rs"
6675 instructions : |
67- - `PlayerCollection` is `Mutex<Vec<Player>>` — verify no blocking operations hold the lock longer than needed
68- - Seed data in `initialize_players()` must not be modified without discussion
69- - Check that the module exposes only what is needed for external use
76+ - This module initializes the r2d2 connection pool
77+ (Pool<ConnectionManager<SqliteConnection>>)
78+ - embed_migrations!() must be called on startup to run all pending Diesel
79+ migrations before any route is served
80+ - No business logic or HTTP knowledge belongs here
7081
7182 - path : " src/main.rs"
7283 instructions : |
73- - Verify ` #[launch]` macro is used to generate ` main()`
74- - Check all route modules are mounted at "/"
75- - Ensure state is initialized with `PlayerCollection::new(initialize_players())`
84+ - #[launch] macro generates main()
85+ - All route modules are mounted at "/"
86+ - State must be the r2d2 pool returned by the state initializer
7687 - Port must remain 9000 (configured in Rocket.toml)
7788
7889 - path : " src/lib.rs"
7990 instructions : |
80- - Verify all modules (`models`, `routes`, `services`, `state`) are re-exported as `pub mod`
81- - This file exists solely to expose modules to integration tests — keep it minimal
91+ - Re-exports all modules as pub mod: models, repositories, routes,
92+ schema, services, state
93+ - Keep minimal — this file exists only to expose modules to integration tests
8294
83- - path : " tests/player_routes_tests .rs"
95+ - path : " tests/**/* .rs"
8496 instructions : |
85- - Integration tests only — import from the library crate (`rust_samples_rocket_restful::`)
86- - Follow AAA pattern with `// Arrange`, `// Act`, `// Assert` section comments
87- - Naming convention: `test_request_{method}_{endpoint}_{condition}_response_{verification}`
88- (e.g. `test_request_get_player_by_id_existing_response_status_ok`)
89- - Use `setup_client()` (full 26-player seed) for all tests except POST creation
90- - Use `setup_client_for_post()` (25-player seed, squad 16 excluded) for POST creation tests
91- - Use `player_request_for_creation_json()` and `player_request_for_update_json()` fixtures — no ad-hoc JSON payloads
92- - Use `common::SEED_MESSI_ID` constant for UUID-based GET tests — never hardcode UUID strings inline
93- - PUT tests must capture the original UUID via GET before calling PUT, then assert the response preserves it
97+ - Integration tests only; import from the library crate (`rust_samples_rocket_restful::`)
98+ - Follow AAA pattern with // Arrange, // Act, // Assert section comments
99+ - Naming: test_request_{method}_{endpoint}_{condition}_response_{verification}
100+ - Use initialize_test_database() (full seeded pool) for most tests;
101+ imported from the library crate (state::player_collection), NOT from tests/common
102+ - Use initialize_empty_test_database() (schema only, no seed rows) where needed;
103+ also imported from the library crate
104+ - Use player_request_for_creation() and player_request_for_update() from
105+ tests/common for request bodies
106+ - Use EXISTING_PLAYER_ID from tests/common for UUID-based GET tests —
107+ never hardcode UUID strings inline
94108 - Verify complete response objects (all fields), not just status codes
95109
96- - path : " tests/concurrency_tests.rs"
97- instructions : |
98- - Tests the `Mutex<Vec<Player>>` state layer directly — do NOT use `rocket::local::blocking::Client`
99- - `blocking::Client` is not `Sync` and cannot be shared across threads via `Arc`
100- - Use `Arc<PlayerCollection>` + `std::thread` for all concurrency scenarios
101- - Use `common::player_request_for_creation()` as the base fixture and override `squad_number` per thread
102- - Cover: concurrent reads, concurrent unique creates, concurrent duplicate creates, mixed reads/writes
103-
104110 path_filters :
105111 - " !**/target/**"
106112 - " !**/*.db"
@@ -144,10 +150,10 @@ reviews:
144150 If so, update the relevant sections of README.md to reflect the current state.
145151 Do not rewrite sections unrelated to the changes.
146152
147- ## 3. .github/copilot-instructions .md
153+ ## 3. CLAUDE .md
148154 If the PR introduces patterns, conventions, or architectural decisions that
149155 should guide future AI-assisted contributions, add or update the relevant
150- instructions in .github/copilot-instructions .md.
156+ instructions in CLAUDE .md.
151157 Focus on things a developer (or AI assistant) unfamiliar with this specific
152158 Rust/Rocket implementation should know before writing code here.
153159
@@ -181,7 +187,7 @@ reviews:
181187 contract. Check the README or any spec/contract file in the repo for reference.
182188 Pay special attention to the surrogate vs. natural key design:
183189 - UUID (`id`) is used only for `GET /players/{uuid}`
184- - `squad_number` is used for all mutation routes (PUT, DELETE, PATCH )
190+ - `squad_number` is used for all mutation routes (PUT, DELETE)
185191 Flag any deviations — missing fields, wrong status codes, inconsistent naming.
186192 Do not make changes; only report findings as a comment.
187193
@@ -315,7 +321,7 @@ knowledge_base:
315321 code_guidelines :
316322 enabled : true
317323 filePatterns :
318- - " .github/copilot-instructions .md"
324+ - " CLAUDE .md"
319325 learnings :
320326 scope : auto
321327 issues :
@@ -345,9 +351,11 @@ code_generation:
345351 - Follow AAA pattern with `// Arrange`, `// Act`, `// Assert` comments
346352 - Naming: `test_request_{method}_{endpoint}_{condition}_response_{verification}`
347353 - Use fixture functions for test data — no inline magic values
348- - Use `SEED_MESSI_ID` constant for UUID-based GET tests
349- - HTTP tests use `rocket::local::blocking::Client` via a `setup_client()` helper
350- - Concurrency tests use `Arc<PlayerCollection>` + `std::thread`
354+ - Use initialize_test_database() from the library crate (state::player_collection)
355+ for the full seeded pool; use initialize_empty_test_database() for schema-only
356+ - Use EXISTING_PLAYER_ID from tests/common for UUID-based GET tests —
357+ never hardcode UUID strings inline
358+ - Concurrency tests clone the r2d2 pool across threads via Pool::clone()
351359
352360issue_enrichment :
353361 auto_enrich :
0 commit comments