critical priority medium complexity backend pending backend specialist Tier 2

Acceptance Criteria

OrganizationIntegration class has fields matching all database columns: id (String/UUID), organizationId (String), integrationType (IntegrationType enum), displayName (String), isEnabled (bool), credentialVaultId (String?), fieldMappings (List<FieldMapping>), syncSchedule (SyncSchedule?), lastSyncAt (DateTime?), createdAt (DateTime), updatedAt (DateTime)
fromJson() correctly parses all fields from a Supabase row Map<String, dynamic>
toJson() produces a Map<String, dynamic> that can be passed directly to Supabase insert/update — JSONB fields are encoded as nested maps, not strings
field_mappings JSONB column is deserialized into List<FieldMapping> — an empty JSON array produces an empty list, null produces an empty list
SyncSchedule model represents cron expression or interval with a human-readable label
copyWith() returns a new instance with only specified fields changed; all other fields are unchanged
== and hashCode are implemented using all fields (use Equatable or manual override)
toString() returns a readable representation useful for debugging
DateTime fields correctly parse ISO 8601 strings including timezone offset from Supabase
Model round-trips correctly: OrganizationIntegration.fromJson(model.toJson()) == model

Technical Requirements

frameworks
Dart
Flutter
apis
Supabase Dart client (for row type compatibility)
data models
OrganizationIntegration
FieldMapping
SyncSchedule
IntegrationType
performance requirements
fromJson and toJson must complete synchronously
List<FieldMapping> deserialization must handle up to 100 mappings without performance issues
security requirements
credentialVaultId must be nullable String — never embed actual credential values in the model
toJson() must exclude credentialVaultId from update payloads by default (use a separate toUpdateJson() or toInsertJson() variant)

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Integration Task

Handles integration between different epics or system components. Requires coordination across multiple development streams.

Implementation Notes

Place models in lib/domain/integrations/models/. Use @immutable annotation. For equality, consider using the equatable package if already in pubspec.yaml — otherwise implement == and hashCode manually. For the JSONB field: in fromJson, cast the raw value as List?

and map each element through FieldMapping.fromJson(). In toJson, encode fieldMappings as a List> (not a JSON string) — Supabase handles JSONB natively. Align field names with database column names using snake_case keys in fromJson/toJson (e.g., 'organization_id', 'field_mappings'). Do NOT use code generation (json_serializable) unless it is already a project dependency.

Testing Requirements

Write unit tests using flutter_test. Test: (1) fromJson round-trip with a complete fixture row; (2) fromJson handles null optional fields (credentialVaultId, syncSchedule, lastSyncAt) without throwing; (3) fromJson correctly decodes JSONB field_mappings array; (4) toJson produces correct structure for Supabase; (5) copyWith changes only the specified field; (6) equality check — two models with identical fields are equal; (7) DateTime parsing from ISO 8601 string with UTC offset; (8) empty/null field_mappings produces empty list. Use hardcoded fixture maps as inputs — no Supabase calls needed.

Component
Organization Integration Repository
data medium
Epic Risks (3)
high impact medium prob technical

Supabase Vault API has limited documentation for Dart/Flutter clients; wrapping it correctly for credential rotation and secret reference management may require significant trial and error, delaying the vault component and blocking all downstream credential-dependent work.

Mitigation & Contingency

Mitigation: Spike the Vault integration in the first sprint using a minimal proof-of-concept (store, retrieve, rotate one secret). Document the API surface before building the full vault client. Identify any missing Dart SDK bindings early.

Contingency: If Supabase Vault is too complex, fall back to Supabase's encrypted column approach (pgcrypto) for credential storage as a temporary measure, with a planned migration path to Vault once the API is understood.

high impact low prob security

Incorrect RLS policy configuration on organization_integrations could allow org admins of one organization to read or modify another organization's integration credentials, creating a serious data breach and compliance violation.

Mitigation & Contingency

Mitigation: Write integration tests that explicitly attempt cross-org data access using different JWT tokens and assert 0 rows returned. Include RLS policy review in PR checklist. Use Supabase's local development stack for policy validation before deployment.

Contingency: If a breach is discovered post-deployment, immediately revoke all integration credentials, rotate vault secrets, notify affected organizations, and apply emergency RLS patches.

medium impact medium prob technical

JSONB columns for field_mappings and sync_schedule lack database-level schema enforcement; AI-generated or malformed JSON could silently corrupt integration configurations, causing export failures that are hard to diagnose.

Mitigation & Contingency

Mitigation: Define TypeScript/Dart model classes with strict deserialization and validation. Add database check constraints or triggers that validate JSONB structure at write time. Version the JSONB schema to enable forward-compatible migrations.

Contingency: Build a repair script that scans organization_integrations for invalid JSONB and resets corrupted records to a safe default state, alerting the admin of the affected organization.