# Third-Party Services (Integrations)

## Purpose
Document how site-level integrations are modeled and exposed via API, including WordPress connection testing, sync, and metadata updates.

## Code Locations (exact paths)
- Models: `backend/igny8_core/business/integration/models.py` (`SiteIntegration`, `SyncEvent`)
- Services: `backend/igny8_core/business/integration/services/integration_service.py`, `sync_service.py`, `sync_metadata_service.py`, `sync_health_service.py`, `content_sync_service.py`
- API views and routing: `backend/igny8_core/modules/integration/views.py`, `backend/igny8_core/modules/integration/urls.py`
- Webhooks: `backend/igny8_core/modules/integration/webhooks.py`

## High-Level Responsibilities
- Store per-site integration configs and credentials for platforms (WordPress, Shopify, custom).
- Provide CRUD, test-connection, sync, sync-status, and structure-update endpoints for integrations.
- Track sync events for debugging/monitoring.
- Enforce tenant/site scoping and role-based permissions on integration APIs.

## Detailed Behavior
- Model behavior:
  - `SiteIntegration`: site+account scoped; fields for platform, platform_type, config_json (content types, sync settings), credentials_json (API keys, etc.), active/sync flags, sync status, last_sync_at, sync_error; unique per site+platform.
  - `SyncEvent`: per-integration/site event log with event_type/action, success flag, optional content_id/external_id, details JSON, error_message, duration, timestamps.
  - `SiteIntegration.get_credentials` / `set_credentials` currently store JSON as-is (encryption to be added).
- Service behavior (`IntegrationService`):
  - `create_integration` sets account from site and saves config/credentials with platform/platform_type.
  - `update_integration` updates config/credentials/is_active; `delete_integration` removes the record.
  - `get_integration`/`list_integrations`/`get_integrations_for_site` fetch active integrations by site/platform.
  - `test_connection` delegates to platform-specific testers (WordPress/Shopify implemented; others raise `NotImplementedError`).
- API (`IntegrationViewSet`, router `/api/v1/integration/integrations/`):
  - Inherits `SiteSectorModelViewSet` but overrides `get_queryset` to filter by site_id (no sector field).
  - Permissions: `IsAuthenticatedAndActive` + `IsEditorOrAbove`; throttle scope `integration`.
  - Serializer exposes derived `api_key` for WordPress; validates that WordPress integrations include an API key.
  - Actions:
    - `test_connection` (detail): calls `IntegrationService.test_connection` for the existing integration.
    - `test_connection_collection` (AllowAny, no throttle): accepts site_id/api_key/site_url; validates site ownership or matching `Site.wp_api_key`; creates WordPress integration if missing, tests via `_test_wordpress_connection`, deletes if test fails, returns integration_id on success.
    - `sync`: calls `SyncService.sync` (direction metadata/both/to_external/from_external); metadata-only uses `SyncMetadataService.sync_wordpress_structure`.
    - `sync_status`: returns sync status via `SyncService.get_sync_status`.
    - `update_site_structure`: updates `config_json.content_types` from WordPress push (post_types, taxonomies, plugin flags, timestamp).
    - `get_content_types`: returns content type config.
    - `debug_status`: uses `SyncHealthService` for debug data.
    - `sync_wordpress_content`: calls `ContentSyncService.sync_from_wordpress` for a specific content_id.
- Webhooks:
  - Registered under `/api/v1/integration/webhooks/wordpress/status/` and `/metadata/` for incoming WordPress callbacks (handling in `webhooks.py`).

## Data Structures / Models Involved (no code)
- `SiteIntegration` config/credentials/sync flags/status/error.
- `SyncEvent` event logs.
- Site/account context from `auth.models.Site` and `Account`.

## Execution Flow
- CRUD/test/sync requests → DRF auth → site-filtered queryset → service calls (integration/sync/health/content-sync) → model updates or sync actions.
- Collection-level test may create integration, run test, and delete on failure.
- Webhooks ingest external events; service handlers update integrations/sync events (implementation-specific).

## Cross-Module Interactions
- Integrations reference sites and are consumed by publishing/sync flows when pushing/pulling content.
- WordPress API key path relies on `Site.wp_api_key` and integration credentials during connection tests.
- Sync services interact with planner/writer content when syncing content or structure.

## State Transitions
- `SiteIntegration.sync_status/last_sync_at` update during sync; `is_active`/`sync_enabled` toggled via API.
- `SyncEvent` records per-action success/failure with timestamps and optional IDs.

## Error Handling
- Unsupported platforms raise `NotImplementedError`; connection tests return structured success/message; newly created integrations are deleted if test fails in collection endpoint.
- API returns 403/404/400 for invalid site/auth/API key; sync errors surface in responses and may populate `sync_error`.

## Tenancy Rules
- All integrations are site- and account-scoped; viewsets filter by site_id and require authenticated user with editor-or-above, or matching API key for collection-level WordPress test.

## Billing Rules
- None; integration operations do not alter credits.

## Background Tasks / Schedulers
- None dedicated; syncs run inline in service calls unless delegated inside sync services.

## Key Design Considerations
- Unique integration per site+platform avoids duplication.
- Collection-level test supports plugin onboarding without prior authenticated session while still requiring site ownership or API key.
- Credentials are currently stored plain JSON—add encryption before production use.

## How Developers Should Work With This Module
- Use `IntegrationService` for CRUD/test; avoid direct credential mutation outside service helpers.
- Extend platform support by adding platform-specific test logic and serializer validation.
- When adding new sync flows, use `SyncService`/`SyncMetadataService`/`ContentSyncService` and keep site/account scoping intact.

