@clipboard-health/ai-rules 2.8.6 → 2.9.0
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.
|