Conventions¶
Coding standards enforced across the project. See also CLAUDE.md at the repository root for the complete AI-enforced rules.
Naming Conventions¶
| Context | Convention | Example |
|---|---|---|
| Database columns | snake_case |
created_at, office_id |
| API JSON fields | camelCase |
createdAt, officeId |
| Rust structs | PascalCase |
CaseStatus, DeedType |
| Rust fields | snake_case |
office_id, created_at |
| TypeScript types | PascalCase |
CaseStatus, DeedType |
| TypeScript fields | camelCase |
officeId, createdAt |
| Svelte files | PascalCase.svelte |
CaseDetail.svelte |
| SQL migrations | NNN_description.sql |
001_initial_schema.sql |
| Route segments | kebab-case |
/donnees-reference |
| CSS classes | Semantic tokens | text-muted-foreground |
Rust ↔ JSON Mapping¶
All API structs use #[serde(rename_all = "camelCase")]:
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CaseResponse {
pub id: Uuid,
pub office_id: Uuid, // → "officeId" in JSON
pub created_at: DateTime, // → "createdAt" in JSON
}
TypeScript types must exactly match the serialized field names.
Language Rules¶
| Context | Language |
|---|---|
| Code, comments, logs | English |
| User-facing validation errors | French |
| Breadcrumb labels | French (with accents: Étude, Données) |
| UI text, button labels | French |
Indentation¶
| File Type | Style |
|---|---|
.svelte |
Tabs |
.ts, .js |
Tabs |
.rs |
4 spaces (rustfmt) |
.sql |
4 spaces |
When editing existing files, always match the indentation style already present.
UUID Generation¶
Always use Uuid::now_v7() in Rust code. Never use Uuid::new_v4().
UUID v7 is time-ordered, providing better database index performance and natural chronological sorting.
Optimistic Locking¶
Every mutable table has version INTEGER NOT NULL DEFAULT 0.
Update Pattern¶
UPDATE cases
SET name = $1, version = version + 1
WHERE id = $2 AND version = $3
When rows_affected() == 0, distinguish NotFound from VersionConflict via SELECT EXISTS.
API Pattern¶
- Response DTOs include
version - Update request DTOs require
version - 409 Conflict handled globally with a toast on the client
Validation¶
- Dual validation mandatory: every field validated both frontend (TypeScript) AND backend (Rust)
- No browser native validation: always
novalidateon<form>elements - Instant error display: validate on blur, show inline errors immediately
- French error messages: inline below the field, in red
Navigation¶
- Use
<a href>for all navigation links (SvelteKit intercepts automatically) - Use
goto()only for programmatic navigation (after form submit, delete, etc.) - Never use
stopPropagation()on<a>elements (breaks SvelteKit router) prerender = falsein+layout.ts(Tauri SPA)
PR Checklist¶
Before submitting a pull request:
- [ ]
cargo build— 0 errors, 0 warnings - [ ]
cargo test— All tests pass - [ ]
npm run check— Svelte/TypeScript checks pass - [ ] No dead code left (imports, unused variables, removed components)
- [ ] Indentation matches file type conventions
- [ ] API types match between backend serde and frontend TypeScript
- [ ] User-facing messages in French
- [ ]
versioncolumn on new mutable tables - [ ]
covers:frontmatter on new doc files