wulf-pulse/.planning/seeds/SEED-002-pax8-integration.md
lorentz 4f7e9be059 docs: capture exploration — PAX8 integration scope
Plant two seeds (PAX8 sync + Autotask mapping, general Pulse data
assistant) and one research question (PAX8 company identifier
alternatives to fuzzy name matching), surfaced while scoping a
future PAX8 integration.
2026-07-10 11:45:11 -04:00

92 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: SEED-002
status: dormant
planted: 2026-07-10
planted_during: v1.0 milestone (Pulse Mobile Shell Redesign), Phase 9.1 in flight
trigger_when: Whenever the developer is ready to start this as its own milestone — surface during the next /gsd-new-milestone scan
scope: Medium
---
# SEED-002: PAX8 Integration
A read-only integration syncing PAX8 (vendor licensing/distribution marketplace)
data into Pulse — companies, subscriptions, product catalog, and orders/invoices —
mapped to existing Autotask companies, surfaced on a new `/pax8` page.
## Why This Matters
Three overlapping needs, all satisfied by the same underlying data sync:
1. **Cost reconciliation** — compare what PAX8 bills per client/subscription
against what's actually provisioned or invoiced.
2. **License visibility** — see subscription/seat counts per company alongside
other Pulse company data.
3. **Autotask cost mapping** — tie PAX8 companies and subscription costs to
Autotask companies/contracts for margin/profitability reporting.
The developer already has a PAX8 client ID + client secret provisioned, so auth
setup is not a blocker — this seed is purely about scope/sequencing, not
credential access.
## When to Surface
**Trigger:** Whenever the developer wants to start this — not gated on any other
milestone closing, but naturally lands after the current Mobile Shell Redesign
wraps. Also surface if a future milestone's scope mentions: "PAX8", "license
reconciliation", "vendor subscription costs", "seat count audit", or "Autotask
contract margin".
## Scope Estimate
**Medium** — roughly 24 phases. New external client integration (auth, 4
entities), a sync service, a new migration, a company-matching pass with manual
review for exceptions, and one new UI page. Follows an existing, well-worn
pattern in this codebase (autotask-factory, veeam-sync-service, etc.) — no new
architectural concepts, just new surface area.
## Breadcrumbs
- Auth: PAX8 REST API at `https://api.pax8.com/v1`, OAuth2 client-credentials.
Client ID + secret already provisioned by the developer.
- Pattern to follow: `lib/services/<name>-client.ts` + `<name>-factory.ts`
(`is<Name>Configured()`) — see `lib/services/veeam-client.ts` /
`veeam-factory.ts` or `lib/services/msgraph-client.ts` / `msgraph-factory.ts`
for the shape.
- Sync pattern: `lib/services/entity-sync.ts` (Autotask) and
`lib/services/engagement-sync-service.ts` — incremental-if-supported, else
full upsert via `postgresClient.bulkUpsert()`.
- Env vars: `PAX8_*` (add to the integrations table in `CLAUDE.md` /
`INTEGRATIONS.md` once built).
- Scheduler: new `pax8-daily` schedule via `lib/services/sync-scheduler.ts`,
matching cadence of other integrations (see `engagement-daily`).
- Admin disable: wire into `/admin/integrations` (`integration_settings` table,
migration 081) like other integrations, so it can be toggled without a
container restart.
- UI: new top-level page (like `/engagement`) — company list, subscriptions,
cost breakdown. Not folded into the existing company detail modal.
- This is explicitly the first planned data source for [[SEED-003]] (General
Pulse Data Assistant) — build the Postgres schema with that eventual consumer
in mind (clean, well-typed tables; avoid PAX8-API-shaped blobs).
## Notes
### Entities in scope (v1)
- Companies (join key to Autotask companies)
- Subscriptions (product, seat count, billing term — current state)
- Products/Catalog (SKUs, categories — needed to make subscriptions readable)
- Orders/Invoices (historical line items — needed for actual cost reconciliation,
not just current-state seats)
### Key design forks (decided during exploration)
- **Read-only** — no write-back to PAX8 (no seat adjustments, no orders) in v1.
- **Company matching: fuzzy name match at sync time** — auto-match by name
similarity, flag unmatched/ambiguous companies for manual review. See
[[RESEARCH-pax8-company-identifiers]] — worth checking whether PAX8 exposes a
more stable identifier (domain, external ID) before committing to fuzzy
matching as the permanent strategy.
- **New dedicated `/pax8` page**, not folded into company detail — daily sync
via the scheduler, not on-demand-only.
### Anti-goals
- Not building write access (seat changes, placing orders) in v1.
- Not building the chatbot/NL query layer here — that's [[SEED-003]], a
separate initiative that consumes this data once it exists.