@clipboard-health/ai-rules 2.8.6 → 2.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -94,9 +94,26 @@ throw new ServiceError({
|
|
|
94
94
|
|
|
95
95
|
- Use `@clipboard-health/date-time` for all user-facing date formatting and all timezone-dependent operations (start-of-day-in-timezone, business hours, `setHours`, etc.) with an explicit `timeZone` parameter
|
|
96
96
|
- Use `date-fns` only for timezone-agnostic timestamp math and parsing
|
|
97
|
+
- Use `date-fns` comparison functions (`isBefore`, `isAfter`, `isEqual`, `isSameDay`, `compareAsc`, `compareDesc`) for all date comparisons — never use raw JS comparison operators (`>`, `<`, `===`, `>=`, `<=`) or `.getTime()` for equality/inequality checks
|
|
97
98
|
- Never import `date-fns-tz`, `@date-fns/tz`, `moment`, or `moment-timezone`
|
|
98
99
|
- In contracts, use `dateTimeSchema()` from `contract-core` for date fields — not `z.coerce.date()`, `z.string().datetime()`, or `z.date()`
|
|
99
100
|
|
|
101
|
+
```typescript
|
|
102
|
+
import { isBefore, isAfter, isSameDay } from "date-fns";
|
|
103
|
+
|
|
104
|
+
// ✅ Good — explicit, readable, handles edge cases
|
|
105
|
+
if (isBefore(shiftStart, now)) {
|
|
106
|
+
}
|
|
107
|
+
if (isSameDay(createdAt, today)) {
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// ❌ Bad — raw JS comparison, implicit coercion risks
|
|
111
|
+
if (shiftStart < now) {
|
|
112
|
+
}
|
|
113
|
+
if (shiftStart.getTime() === today.getTime()) {
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
100
117
|
## Internal Libraries
|
|
101
118
|
|
|
102
119
|
- Use object arguments and object return types in library APIs; wrap exported responses in `ServiceResult`; prefer `ServiceResult` for expected errors and reserve throwing for unexpected/unrecoverable failures
|
|
@@ -25,6 +25,14 @@ await expect(page.getByText("Submit")).toBeVisible();
|
|
|
25
25
|
await expect(page.getByText("Submit")).toBeAttached();
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
## E2E vs Component Test Decision
|
|
29
|
+
|
|
30
|
+
Before adding an E2E test:
|
|
31
|
+
|
|
32
|
+
1. Check if existing E2E tests already cover the API calls and flows being tested — avoid duplicating coverage
|
|
33
|
+
2. Confirm the flow is a core user journey (auth, payments, onboarding, multi-page navigation) — non-core flows belong in component tests even if they call backend APIs or touch API contracts
|
|
34
|
+
3. Verify the test requires real cross-service integration or multi-page navigation — if it can be asserted with `render()` + `screen.getByRole()` or mocked API responses, write a component test instead
|
|
35
|
+
|
|
28
36
|
## Avoid
|
|
29
37
|
|
|
30
38
|
- Hard-coded timeouts (`page.waitForTimeout`)
|
|
@@ -86,3 +86,13 @@ return <Input onChange={(e) => setValue(e.target.value)} />;
|
|
|
86
86
|
const handleSave = useCallback(async () => { ... }, [deps]);
|
|
87
87
|
return <MemoizedChild onSave={handleSave} />;
|
|
88
88
|
```
|
|
89
|
+
|
|
90
|
+
## Component Reuse
|
|
91
|
+
|
|
92
|
+
Before creating a new component, search for existing ones in this order:
|
|
93
|
+
|
|
94
|
+
1. **Shared UI libraries**: `@clipboard-health/ui-components`, `@clipboard-health/ui-react`, MUI
|
|
95
|
+
2. **App-level shared directories**: e.g., `src/appV2/lib/`, `src/lib/components/`, `src/shared/`
|
|
96
|
+
3. **Sibling features**: search for `*Card`, `*Modal`, `*Form`, `*EmptyState`, `*Page` patterns in other features
|
|
97
|
+
|
|
98
|
+
If an existing component covers >70% of the need, extend it (prefer composition over boolean flags). Only create a new component when behavior is fundamentally different — document why in the PR.
|
|
@@ -32,20 +32,16 @@ Then, for EVERY comment (both `unresolvedComments` AND `nitpickComments`):
|
|
|
32
32
|
|
|
33
33
|
1. Group comments by file path and read each file once (not per-comment)
|
|
34
34
|
2. If a file no longer exists, note that the comment may be outdated
|
|
35
|
-
3. Assess
|
|
36
|
-
|
|
37
|
-
- **Disagree**: Explain why the current code is acceptable
|
|
38
|
-
- **Already fixed**: Note that the code already addresses this concern
|
|
39
|
-
4. When multiple comments appear at the same file and line, they are part of the same review thread — read them together as a conversation and assess the original feedback
|
|
40
|
-
5. Present your assessment in list format (renders reliably in terminals):
|
|
35
|
+
3. Assess each comment against the current code. When multiple comments appear at the same file and line, they are part of the same review thread — read them together as a conversation
|
|
36
|
+
4. Group your assessment as follows:
|
|
41
37
|
|
|
42
|
-
**
|
|
43
|
-
|
|
38
|
+
**Should address**
|
|
39
|
+
- Description of the comment with file path(s)
|
|
40
|
+
- Why it's a real issue (bug, a11y, UX, etc.)
|
|
44
41
|
|
|
45
|
-
**
|
|
46
|
-
|
|
42
|
+
**Can ignore**
|
|
43
|
+
- Description of the comment with file path(s)
|
|
44
|
+
- Why: already fixed, not actionable, not worth addressing in this PR, etc.
|
|
47
45
|
|
|
48
|
-
**
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
Then, offer to fix any issues where you agreed.
|
|
46
|
+
**Net**
|
|
47
|
+
Summary of how many are worth fixing and what kind of issues they are. Offer to fix, but **do NOT start until the user confirms**.
|