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

4.1 KiB

Tasks — enterprise-audience-rules

Every checkbox MUST reflect work actually done in this change.

0. Pre-flight

  • 0.1 Confirmed package is missing from genesis (STATUS.md has no audience-rules entry; greenfield migration from ../suaveplan/packages/universal/audience-rules/).
  • 0.2 Read upstream src/ end-to-end: index.ts, types/segment.types.ts, core/segment-evaluator/, core/segment-refresher/, stores/segment.store.ts, predicates/predicates.ts, plus all upstream test files.
  • 0.3 Read upstream README.md for the public-surface contract.
  • 0.4 Read reference package @suaveplan/contacts at packages/commerce/contacts/contacts/ for genesis-conventions (5-files-per-feature, sibling .md, runner imports, defineCodes, parseOrThrow).
  • 0.5 Confirmed dependencies (@suaveplan/error, @suaveplan/events, @suaveplan/types, zod, tslib) all shipped on genesis.
  • 0.6 Numbered checklist of every ### Requirement: in the spec delta (10 requirements, all listed in §1 below).

1. Spec authoring

  • 1.1 proposal.md with ## Parity Checklist, ## Out of scope, ## Source mapping, ## Impact.
  • 1.2 specs/audience-rules/spec.md — 10 ### Requirement: blocks, each with **Verified by:**:
    • R1: Universal-tier purity
    • R2: Stable error-code registry (AUDIENCE_RULES_CODES + AudienceRulesError)
    • R3: 14-operator rule evaluation (eq/neq/gt/gte/lt/lte/contains/not_contains/in/not_in/exists/not_exists/starts_with/ends_with) plus UNKNOWN_OPERATOR for invalid operators
    • R4: AND/OR logical chaining
    • R5: Dot-notation field resolution with array index access
    • R6: Predicate factories (seven helpers)
    • R7: SegmentStore interface + InMemorySegmentStore with Clock + IdGenerator injection
    • R8: Multi-tenant isolation via tenantId on store list
    • R9: SegmentRefresher typed EventBus<SegmentRefresherEventMap> emission
    • R10: Zod-validated input boundaries

2. Implementation

  • 2.1 package.json, tsconfig.json, tsconfig.lib.json, vite.config.ts, vitest.config.ts, tests/setup/polyfills.ts
  • 2.2 src/error-codes/error-codes.ts — AUDIENCE_RULES_CODES + AudienceRulesError with segmentId / tenantId discriminants
  • 2.3 src/types/segment.types.ts
  • 2.4 src/schemas/schemas.ts — Zod schemas + parseOrThrow
  • 2.5 src/store/store.ts — SegmentStore + InMemorySegmentStore with Clock+IdGenerator
  • 2.6 src/segment-evaluator/segment-evaluator.ts — 14-operator evaluator + dot-notation + AND/OR + UNKNOWN_OPERATOR
  • 2.7 src/segment-refresher/segment-refresher.ts — typed EventBus<SegmentRefresherEventMap> integration
  • 2.8 src/predicates/predicates.ts — seven factories
  • 2.9 src/index.ts package barrel (explicit named re-exports)
  • 2.10 Feature index.ts barrels (explicit named re-exports — no export *)

3. Tests

  • 3.1 Unit tests for every implementation file via @suaveplan/testing/runner
  • 3.2 src/audience-rules.spec-conformance.test.ts — tier purity, barrel shape, subpath count, runner-import gate, error-code registry shape
  • 3.3 Every it(...) carries { timeout: 5000 }

4. Documentation

  • 4.1 Sibling .md per implementation .ts (≥200 words, Purpose / Features / Basic / Advanced / API Reference / Implementation Notes)
  • 4.2 README.md at package root with Quick start + ## Modules linking every sibling .md

5. Pre-publish gate

  • 5.1 bunx turbo lint typecheck test --filter=@suaveplan/audience-rules — green
  • 5.2 bunx turbo test:coverage --filter=@suaveplan/audience-rules — 100/100/100/100
  • 5.3 bunx turbo build --filter=@suaveplan/audience-rules — green
  • 5.4 bun ./scripts/docs-check.ts packages/commerce/contacts/audience-rules — 100% pass

6. Archive

  • 6.1 Fold specs/audience-rules/spec.md into openspec/specs/audience-rules/spec.md
  • 6.2 Move change folder to openspec/archive/2026-05-23-enterprise-audience-rules/
  • 6.3 Run bun scripts/folder-reorg/generate-manifest.ts