You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .claude/rules/coding-style.md
+36-6Lines changed: 36 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ Before writing new logic, decide which layer it belongs to. Run this check at pl
11
11
| DB schema |`prisma/`| Migrations are immutable after apply |
12
12
| DB access |`src/lib/server/`| Server-only; never import in client code |
13
13
| Validation |`src/**/zod/`|`z.number().int()` for Int fields; comment dual-enforcement with SQL CHECK |
14
-
| Domain types |`src/**/types/` (`_types/` inside `src/routes/`) | Plural aliases; TSDoc on every export; no`any`|
14
+
| Domain types |`src/**/types/` (`_types/` inside `src/routes/`) | Plural aliases; TSDoc on every export; avoid`any`; see alternatives|
15
15
| Test data |`src/**/fixtures/` (`_fixtures/` inside `src/routes/`) | Write before implementation (TDD); use realistic values |
16
16
| Business logic |`src/**/services/`| Return pure values or `null`; no `Response`/`json()`|
17
17
| Pure utilities |`src/**/utils/` (`_utils/` inside `src/routes/`) | No side effects; adjacent unit test required |
@@ -26,7 +26,16 @@ Before writing new logic, decide which layer it belongs to. Run this check at pl
26
26
-**Abbreviations**: avoid non-standard abbreviations (`res` → `response`, `btn` → `button`). When in doubt, spell it out.
27
27
-**Lambda parameters**: no single-character names (e.g., use `placement`, `workbook`). Iterator index `i` is the only exception.
28
28
-**`upsert`**: only use when the implementation performs both insert and update. For insert-only, use `initialize`, `seed`, or another accurate verb.
29
-
-**`any`**: before using `any`, check the value's origin — adding a missing `@types/*` or `devDependency` often provides the correct type.
29
+
-**`any`**: before using `any`, check the value's origin — adding a missing `@types/*` or `devDependency` often provides the correct type. When `any` seems unavoidable, use the narrowest alternative:
| Assign to a property not on the type |`obj as T & { prop: U }` (intersection cast) |
34
+
| Return type too complex to write manually |`ReturnType<typeof fn>`|
35
+
| Partial mock: only specific properties matter |`Partial<T>`, `Pick<T, 'a' \| 'b'>`, or `satisfies` — prefer these first |
36
+
| Partial mock: none of the above narrow the type far enough |`as unknown as T` — last resort; bypasses type checking entirely |
37
+
| Inline `: any` annotation where inference reaches | Delete the annotation |
38
+
30
39
-**UI labels**: if a label does not match actual behavior, update it or add an inline comment explaining the intentional mismatch.
31
40
-**Constant names**: reflect what the value IS (content), not what it is used for (purpose). e.g., a set holding all enum tab values is `EXISTING_TABS`, not `VALID_TABS`.
32
41
-**New files**: before naming a new file or directory, grep the relevant `src/` directory to confirm existing conventions. Confirm at plan time, not during implementation:
@@ -39,23 +48,44 @@ Before writing new logic, decide which layer it belongs to. Run this check at pl
39
48
40
49
-**Braces**: always use braces for single-statement `if` blocks. Never `if () return;` — write `if () { return; }`.
41
50
-**Plural type aliases**: define `type Placements = Placement[]` instead of using `Placement[]` directly in signatures and variables.
51
+
-**Empty `catch` blocks**: never use `catch { }` or `catch (_e)` to silence errors. Every `catch` must re-throw, log, or contain an explanatory comment justifying the suppression. Silent swallowing hides bugs and makes failures untraceable.
52
+
53
+
```typescript
54
+
// Bad: silently discards the error
55
+
try { ... } catch { }
56
+
try { ... } catch (_e) { }
57
+
58
+
// Good: log and re-throw (adds context before propagating)
59
+
try { ... } catch (error) {
60
+
console.error('Operation failed:', error);
61
+
throwerror;
62
+
}
63
+
64
+
// Good: intentional suppression with explanation
65
+
try {
66
+
localStorage.setItem(key, value);
67
+
} catch {
68
+
// localStorage may be unavailable (private browsing) — fall back to in-memory store
69
+
}
70
+
```
42
71
43
72
### No Hard-Coded Values
44
73
45
74
Extract magic numbers and strings to named constants. Never embed literal values whose meaning is not self-evident from the type or immediate context.
-**Tests**: Write tests before implementation (TDD). Use `@quramy/prisma-fabbrica` for factories only in `prisma/seed.ts`. For service-layer unit tests, mock the DB with `vi.mock('$lib/server/database', ...)` — do not use fabbrica there. Use Nock for HTTP mocking
0 commit comments