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.
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>