Integrations overview¶
Status: Placeholder — to be developed. Last reviewed: — Reference structural sibling:
guidelines/i18n/translation-rules.md(rule + workflow style — establishes the shared connector contract).
Scope (when this guideline lands)¶
Shared patterns for any external integration: where credentials live (env vars, secret stores), retry/backoff, cursor/pagination handling, rate-limit handling, idempotent fetch (resume on partial failure), how raw responses are persisted (audit trail vs ephemeral), how a sync becomes a Celery task, error surfacing (Sentry, ImportRow, dataquality flag).
The per-connector files (doctolib.md, pennylane.md, logosw.md, inpi.md) document the connector-specific quirks; this file documents what they all share.
Out of scope (cross-refs)¶
- Connector-specific quirks (auth model, schema, schedule) →
guidelines/integrations/{doctolib,pennylane,logosw,inpi}.md(placeholders). - Celery task shape (naming, idempotency, retry/backoff configuration) →
guidelines/celery/task-conventions.md(placeholder). This file references the task shape; that file owns it. - Importer pattern (for file-based ingestion like Logosw) →
guidelines/imports/abstract-importer.md(placeholder). - Logging and PII redaction in connector output →
guidelines/security/pii-and-logging.md(placeholder). - Multi-tenant scoping of synced data →
guidelines/security/multi-tenant-isolation.md(placeholder).
Sources to mine when writing this¶
- Compare existing connectors side-by-side:
apps/sync/(Doctolib),apps/pennylane_sync/,apps/imports/(Logosw viaapps/collection/),apps/annuaire/(INPI). The shared patterns and the divergences both teach. - The reusable Pennylane bundle (referenced in
roadmap/done/meta-finance-captable-planning-session.md) — was an early attempt at extracting shared patterns. Salvage what's good. roadmap/done/agent-csv-writer-migration.md,roadmap/done/imports-encoding-fixes.md— agent (Logosw upload) hardening lessons.apps/collection/models.py—CollectionAgent, upload pipeline. The remote-agent pattern is a separate kind of integration worth documenting.
Starter hard rules to investigate¶
- Credentials in env vars, never in code. Per-connector env vars prefixed by connector name (
DOCTOLIB_API_KEY,PENNYLANE_TOKEN_<COMPANY>, …). - Retry/backoff via decorator (Celery's
retry_kwargsor a shared decorator) — never hand-rolledfor i in range(N): try:loops. - Raw responses persisted with hash for idempotent re-fetch detection — the importers do this with
ImportRow; non-importer connectors should mirror. - Sync = Celery task for anything > 1s of work. Don't run sync inline in a view.
- Errors surface via Sentry + structured log + (where applicable)
ImportRow.status='failed'— three channels, not silent.
Decision points to settle¶
- Shared base class vs duplication: should there be an
apps/core/integrations/BaseConnector? Tried with the Pennylane reusable bundle — verify whether it survived. - Rate-limit handling: do connectors share a rate-limiter? Or per-connector handling? Pick.
- When to make a sync a Celery task vs a management command vs an inline view operation. Define the cutover (e.g. > 1s).
- Raw response retention: how long to keep raw API responses for replay? Storage cost vs debugging value.
- Connector versioning: what happens when a third-party API gates its v2 endpoint behind a flag? Do we maintain dual paths?
Known deviations to look for during writing¶
- Connectors with credentials in code or settings.py (security risk).
- Hand-rolled retry loops without exponential backoff.
- Connectors that swallow API errors silently.
- Inline-in-view API calls with no Celery wrapper (latency risk).
If found, file as roadmap/backlog/integrations-overview-drift-2026-MM.md.