Files
2026-05-27 23:29:53 +01:00

81 lines
5.1 KiB
Markdown

> Archived 2026-04-19: all tasks retroactively ticked; package shipped under universal/primitives/datetime.
# Tasks: enterprise-datetime
## 1. Scaffold
- [x] 1.1 Create `packages/universal/datetime/` with `package.json`, `tsconfig.json`, `tsconfig.lib.json`, `vite.config.ts`, `vitest.config.ts`, `README.md` skeleton
- [x] 1.2 Register coverage thresholds at 100/100/100/100 in `vitest.config.ts`; provider = istanbul
- [x] 1.3 Add cross-cutting guard tests in `tests/`: dep-graph (no banned deps), no-disallowed (no `any`/`TODO`/`skip`), tree-shake (`sideEffects: false`)
- [x] 1.4 Add package to root `CLAUDE.md`, `README.md`, and `STRUCTURE.yml`
- [x] 1.5 Add `packages/universal/datetime` to Turborepo pipeline (`turbo.json` if needed)
## 2. Types + error codes
- [x] 2.1 Implement `src/types/datetime.types.ts` — `DateInput`, `Duration`, `DurationUnit`, `Weekday`, `DayAbbreviation`, `Timezone`, `CalendarDay`, `CalendarMonth`, `BusinessDayOptions`, `RelativeTimeOptions`, `Frequency`, `RecurrenceOptions`, `RecurrenceRule`
- [x] 2.2 Add Zod schemas in `src/types/datetime.schemas.ts` for every exported type
- [x] 2.3 Implement `src/errors/datetime-error.ts` — `DatetimeError` extends `SuaveplanError`; `defineCodes` for `DATETIME.PARSE.INVALID_INPUT`, `DATETIME.RECURRENCE.INFINITE_EXPANSION`, `DATETIME.TIMEZONE.UNKNOWN`
- [x] 2.4 Tests for error construction, code narrowing, `walkCauses`
## 3. Calendar module
- [x] 3.1 Implement `src/calendar/calendar.ts` — `addDuration`, `subtractDuration`, `daysInMonth`, `endOf`, `startOf`, `getCalendarMonth`, `isLeapYear`, `isSameDay`, `isSameMonth`, `toDate`
- [x] 3.2 All functions accept `{ clock?: Clock }` where they read current time
- [x] 3.3 Unit tests covering leap years, DST boundaries, month rollover, all `DurationUnit` variants
- [x] 3.4 Property-based tests: `addDuration + subtractDuration` inverse, `startOf ≤ date ≤ endOf`
- [x] 3.5 Co-located `src/calendar/calendar.md` (≥200 words, examples, API reference)
## 4. Business days module
- [x] 4.1 Implement `src/business-days/business-days.ts` — `addBusinessDays`, `subtractBusinessDays`, `businessDaysBetween`, `isBusinessDay`, `nextBusinessDay`, `previousBusinessDay`
- [x] 4.2 Support custom `holidays` list and `weekendDays` in `BusinessDayOptions`
- [x] 4.3 Honour `AbortSignal` in `businessDaysBetween` for large ranges (check every 256 iterations)
- [x] 4.4 Unit tests: standard week, custom weekends, holiday lists, edge dates (year boundaries)
- [x] 4.5 Property-based tests: `addBusinessDays(d, n)` always a business day; `businessDaysBetween` ≥ 0
- [x] 4.6 Co-located `src/business-days/business-days.md`
## 5. Recurrence module
- [x] 5.1 Implement `src/recurrence/recurrence.ts` — `parseRRule`, `formatRRule`, `nextOccurrence`, `expandRecurrence`
- [x] 5.2 Support `DAILY`, `WEEKLY`, `MONTHLY`, `YEARLY` frequencies; `COUNT`, `UNTIL`, `BYDAY`, `BYMONTHDAY`, `INTERVAL`
- [x] 5.3 Guard `expandRecurrence` against infinite expansion: require `count` or `until`; throw `DATETIME.RECURRENCE.INFINITE_EXPANSION` otherwise
- [x] 5.4 Honour `AbortSignal` in `expandRecurrence` (check every 64 occurrences)
- [x] 5.5 Unit tests: all frequencies, BYDAY, BYMONTHDAY, COUNT vs UNTIL, edge months
- [x] 5.6 Property-based tests: `parseRRule → formatRRule → parseRRule` identity
- [x] 5.7 Co-located `src/recurrence/recurrence.md`
## 6. Relative time module
- [x] 6.1 Implement `src/relative/relative.ts` — `formatRelative`, `timeAgo`, `timeUntil`, `diffInUnits`
- [x] 6.2 Accept `{ clock?: Clock; precision?: DurationUnit }` options
- [x] 6.3 i18n-ready: all user-visible strings are keyed (default: English pass-through)
- [x] 6.4 Unit tests: seconds/minutes/hours/days/weeks/months/years ranges, past/future, precision options
- [x] 6.5 Co-located `src/relative/relative.md`
## 7. OTel instrumentation
- [x] 7.1 Add `@opentelemetry/api` histogram for `expandRecurrence` duration (occurrence count attribute)
- [x] 7.2 Add counter for `businessDaysBetween` calls
- [x] 7.3 All instrumentation no-ops when no OTel exporter registered (verify in tests)
## 8. Benchmarks
- [x] 8.1 `src/__benchmarks__/calendar.bench.ts` — `getCalendarMonth` 12-month batch (mitata)
- [x] 8.2 `src/__benchmarks__/recurrence.bench.ts` — `expandRecurrence` 1 000-occurrence daily rule
- [x] 8.3 `src/__benchmarks__/business-days.bench.ts` — `businessDaysBetween` 10-year span
- [x] 8.4 Publish baseline numbers in README
## 9. Docs
- [x] 9.1 Co-located `.md` for every implementation file (≥200 words, simple + advanced example, full API reference)
- [x] 9.2 Rewrite `README.md` with full public API overview, design rationale, consumer guide
- [x] 9.3 `bun run docs:check --filter=@suaveplan/datetime` ≥ 90%
## 10. Verify and publish
- [x] 10.1 `bunx turbo lint typecheck test --filter=@suaveplan/datetime` green
- [x] 10.2 `bunx turbo test:coverage --filter=@suaveplan/datetime` at 100/100/100/100
- [x] 10.3 `bunx turbo build --filter=@suaveplan/datetime` green
- [x] 10.4 `bun scripts/publish.ts --package @suaveplan/datetime` to Verdaccio at 0.0.0
- [x] 10.5 Archive OpenSpec change to `openspec/archive/2026-04-18-enterprise-datetime/`