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.
92 lines
4.4 KiB
Markdown
92 lines
4.4 KiB
Markdown
---
|
||
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 2–4 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.
|