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

4.5 KiB

Tasks: enterprise-network-registry

Change ID: enterprise-network-registry Package: @suaveplan/network-registry Target path: universal/network/network-registry Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/types, @suaveplan/events, @suaveplan/logger


1. Scaffold

  • Create universal/network/network-registry/ with src/, tests/, and all feature subdirectories.
  • Write package.json at version 0.1.0: "sideEffects": false, exports map, deps per proposal.md.
  • Write tsconfig.json, vitest.config.ts, scripts.

2. Types and error codes

  • Define all public types in src/types/common.ts: RegistryEntry, HealthStatus, RegistrationHandle, RegistryQuery, RegistryFilter, RegistryChangeHandler, RegistryChange, NetworkRegistryOptions.
  • Write src/types/common.md (≥200 words, simple + advanced examples).
  • Define error codes in src/error-codes.ts.
  • Write Zod schemas in src/types/schemas.ts + src/types/schemas.md.

3. TTL manager (src/core/ttl-manager/)

  • Implement createTtlManager(clock):
    • Tracks expiresAt per entry.
    • isExpired(entry) — compare against clock.now().
    • purge(entries) — returns list of expired entry IDs.
    • Runs GC on gcIntervalMs interval via injectable timer.
  • Write ttl-manager.test.ts + ttl-manager.md.

4. Query engine (src/core/query-engine/)

  • Implement evaluateQuery(entry: RegistryEntry, query: RegistryQuery): boolean:
    • type: match entry type (array = OR, string = exact).
    • capabilities (AND): entry must have ALL capabilities.
    • anyCapabilities (OR): entry must have AT LEAST ONE.
    • tags: all key/value pairs must match.
    • region: exact match.
    • healthyOnly: entry.health.healthy must be true.
  • Implement runQuery(entries: RegistryEntry[], query: RegistryQuery): RegistryEntry[]:
    • Filter via evaluateQuery, sort by latency (lowest first), apply limit.
  • Write query-engine.test.ts (≤500 lines): each filter type, AND/OR capabilities, limit.
  • Write query-engine.md (≥200 words).

5. Network registry (src/core/registry/)

  • Implement createNetworkRegistry(options?):
    • Validates options with Zod.
    • Stores entries in Map<string, RegistryEntry>.
    • Wires TTL manager for expiry.
    • Stores subscriptions as Array<{ query: RegistryQuery; handler: RegistryChangeHandler }>.
  • Implement registry.register(entry):
    • Validate with Zod; throw REGISTRY_INVALID_ENTRY on schema failure.
    • Throw REGISTRY_DUPLICATE_ID if already registered.
    • Check maxEntries; throw REGISTRY_CAPACITY_EXCEEDED if at limit.
    • Compute expiresAt = clock.now() + (entry.ttlMs ?? options.ttlDefaultMs).
    • Return RegistrationHandle with renew() and deregister().
    • Emit event-bus registry.registered event; notify matching subscriptions.
    • OTel: counter registry.register_total.
  • Implement registry.deregister(id) — remove; emit registry.deregistered; notify subscriptions.
  • Implement registry.lookup(query) — delegates to query engine; OTel counter registry.lookup_total, histogram registry.lookup_results.
  • Implement registry.get(id) — direct lookup; throws REGISTRY_EXPIRED if TTL elapsed.
  • Implement registry.list(filter?) — returns all non-expired entries matching optional filter.
  • Implement registry.updateHealth(id, status) — updates health; emits health-changed.
  • Implement registry.subscribe(query, handler) — returns unsubscribe.
  • Implement registry.purgeExpired() — delegates to TTL manager; emits expired for each.
  • Write registry.test.ts (≤500 lines): register, lookup, health update, TTL expiry, subscription notification, capacity exceeded.
  • Write registry.md (≥200 words).

6. Property-based tests (tests/property.test.ts)

  • lookup(q) results are always a subset of list().
  • After purgeExpired(), no expired entries remain in list().
  • capabilities AND: result set is always subset of result with only one capability filter.

7. Docs and verify

  • All per-file .md files per layout in proposal.md.
  • universal/network/network-registry/README.md.
  • bunx turbo lint typecheck test test:coverage --filter=@suaveplan/network-registry — all green, 100%.
  • bun scripts/publish.ts --package @suaveplan/network-registry.
  • Update CLAUDE.md. Archive change folder.