Files
oO/services/integrations/README.md
alvis cba3f1a184 docs(services): update integrations + recommender READMEs for signal abstraction (#78)
integrations/README — replace stale Connector interface and fictional
libsodium vault with the actual SignalSource pattern, SQLite token table,
and real OAuth routes.

recommender/README — document the SignalAggregator pipeline, current
policy registry, and actual /recommend + /feedback contract shapes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 17:17:38 +00:00

51 lines
2.0 KiB
Markdown

# integrations
Third-party connectors and the token vault.
## Signal source interface
Each connector implements `SignalSource` from `@oo/shared-types`:
```ts
interface SignalSource {
readonly id: string // e.g. "todoist"
fetchSignals(userId: string): Promise<Signal[]> // returns normalized Signal[]
act?(userId: string, signalId: string, action: string): Promise<void> // optional write-back
}
```
`SignalAggregator` (`services/api/src/signals/aggregator.ts`) fans out to all registered sources in parallel, isolating per-source failures.
## Token vault
OAuth tokens stored in the `integration_tokens` SQLite table (`services/api/src/db/schema.ts`):
| Column | Description |
|--------|-------------|
| `userId` | owner |
| `provider` | e.g. `todoist` |
| `accessToken` | OAuth access token (plain in dev; encrypted in prod via server secret store) |
| `tokenStatus` | `active` \| `needs_reconnect` |
On a 401 from the upstream API, the connector marks the token `needs_reconnect` and publishes `signals.integration.token_expired` so the client can prompt re-auth.
## Routes
| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/api/integrations` | List connected integrations for current user |
| `GET` | `/api/integrations/todoist/connect` | Start Todoist OAuth flow |
| `GET` | `/api/integrations/todoist/callback` | OAuth callback — exchange code, store token |
| `DELETE` | `/api/integrations/:provider` | Disconnect + delete token |
## Connectors
| Connector | Status | Signals produced |
|-----------|--------|-----------------|
| Todoist | Phase 1 — active | `task` signals (today + overdue); `done` write-back |
| Google Calendar | Phase 2 — planned | `event` signals |
## Extraction criteria
Extract to its own process when credential blast-radius isolation requires it (e.g. token vault with KMS-backed encryption needs to run in a hardened sidecar) or when connector volume justifies separate scaling.