Skip to content

feat(sync,schema,db): unify primary keys on String/UUID format, revert casting bypasses, and add pull-sync conflict protection - #18

Merged
kjxcodez merged 8 commits into
mainfrom
feat/unified-string-ids
Aug 5, 2026
Merged

feat(sync,schema,db): unify primary keys on String/UUID format, revert casting bypasses, and add pull-sync conflict protection#18
kjxcodez merged 8 commits into
mainfrom
feat/unified-string-ids

Conversation

@kjxcodez

@kjxcodez kjxcodez commented Aug 5, 2026

Copy link
Copy Markdown
Owner

📝 Summary of Changes

This PR unifies the primary key format across the hybrid architecture of LeadForge OS. By transitioning all MongoDB collections from binary ObjectId identifiers to client-authoritative String (UUID/ObjectId-string) values, we align the cloud schemas with the local SQLite schemas, removing the need for query-casting bypasses and preventing key mismatches during bi-directional synchronization.

Additionally, this PR upgrades the local SQLite repository to protect un-synced client-side modifications from being discarded, and introduces client-side casing translation for campaign statuses to conform to API specifications.


🛠️ Key Technical Details

1. Database Schema Overrides

  • Mongoose Schema Overrides: Customized the global workspacePlugin and system-level schemas (User, Workspace, BetaApplicant) to map _id: { type: String } with standard default generators.
  • TypeScript Type Alignment: Declared _id: string on Mongoose document interfaces utilizing mongoose.Document<any> constraints. This allows Mongoose to accept string IDs while preserving compile-time type-safety.
  • Zod Validation Relaxed: Updated the shared objectIdField and objectIdFieldNullable schemas in @leadforge/schema to support any string input, ensuring client-generated UUIDs do not fail server-side validation.

2. Cleaned Up Repository Code

  • Bypasses Reverted: Reverted the collection-based raw driver workarounds in BaseRepository (apps/api/src/repositories/base/base.repository.ts) and OutreachService (apps/api/src/services/outreach/outreach.service.ts) back to standard, typed Mongoose helper methods (findOne, findOneAndUpdate, deleteOne), as Mongoose now natively handles string query filters correctly.

3. Sync Conflict Protection

  • SQLite Update Guard: Modified LocalCRMRepository.saveMany to check for existing.syncStatus === 'pending'. If a local record contains un-synced mutations, the sync engine will skip overwriting it during a remote pull, protecting local offline edits.

4. Client-First Status Casing Mapper

  • Sync Casing Conversion: Updated SyncEngine (apps/desktop/src/main/services/sync-engine.ts) to handle campaign status formatting differences:
    • Converts local capitalized format ('Draft' | 'Active') to API-required uppercase ('DRAFT' | 'ACTIVE') on push.
    • Converts server uppercase format back to capitalized strings when pulling from the API to fit SQLite and React UI specifications.

🧪 Verification & Evidence

  • Monorepo Build: Ran turbo run build across all workspace modules successfully with zero compilation errors.
  • Clean Database Reset: MongoDB dropped and purged the old database leadforge-os. All SQLite workspace database tables were successfully wiped. Both databases migrated cleanly on server startup.

@vercel

vercel Bot commented Aug 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
leadforge-os-api Ready Ready Preview Aug 5, 2026 11:47am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
leadforge-os-marketing Skipped Skipped Aug 5, 2026 11:47am

@kjxcodez
kjxcodez merged commit 742ac0b into main Aug 5, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant