User rows have a FK constraint to CwMember (User_cwMemberId_fkey). Syncing
Users first caused all 140 User upserts to fail since the CwMember table was
empty. This cascade failure then caused all Opportunity upserts to fail because
Opportunity.primarySalesRepId is FK-constrained to User.cwIdentifier.
Fix: reorder steps so CW Members syncs first, then Users.
- Add ownerLevelRecId -> locationId mapping to opportunity translation
- Include soOppStatus in opportunity query and derive closedFlag from
status.closedFlag (with fallback to legacy oldCloseFlag field)
- Add locationId sanitization guard in both sync.ts and sync-by-table.ts
Note: departmentId is not available in CW SO_Opportunity table and
remains null for synced records.
When no User accounts have cwMemberId linked, the context map was empty
and all opportunities got primarySalesRepId = null. Now also populate
the map from CwMember rows directly (User-linked entries take precedence),
so rep identifiers resolve correctly regardless of user account linkage.
Prisma MSSQL adapter keeps connections open after the sync finishes,
preventing the process from exiting naturally. The k8s job was staying
in Running state indefinitely. Call process.exit(0) on success so the
job completes and the GH workflow step passes.
Full initial sync has 500k+ rows across all tables and exceeded the
30-minute activeDeadlineSeconds. Bump both the k8s job deadline and
the kubectl wait timeout to 7200s (2 hours).
envFrom was loading api-env-secret but CW_DATABASE_URL was absent from the
deployed secret, causing sync.ts to fall back to DATABASE_URL (Postgres) as
the MSSQL connection string -> 'Invalid port number: //optima'.
- Replaced envFrom with explicit CW_DATABASE_URL and API_DATABASE_URL env
entries so the mapping is unambiguous
- Patched api-env-secret in cluster to add CW_DATABASE_URL
The CW MSSQL and API Postgres addresses are internal to the cluster and
unreachable from GitHub-hosted runners, so the sync must run inside k8s.
- Add dalpuri-sync Docker stage to api/Dockerfile: installs deps,
generates both Prisma clients, and runs dalpuri/src/sync.ts
- Add dalpuri/kubernetes/sync-job.yaml: mounts api-env-secret (which
already contains CW_DATABASE_URL) and maps DATABASE_URL -> API_DATABASE_URL
- build-api job now also pushes optima-dalpuri-sync:TAG image
- sync-cw-to-api CI job replaced with kubectl apply/wait pattern,
needs [build-api, build-worker], blocks deploy-api and deploy-worker
Fixed field name mismatches for tables with lastUpdatedUTC (all-caps):
- IV_Product: lastUpdateUtc → lastUpdatedUTC
- Department: lastUpdateUtc → lastUpdatedUTC
These field names must match the Prisma schema exactly (case-sensitive).
Ensures smart sync decision logic can correctly probe for record updates.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>