Skip to content

Migration Plan: Legacy → New Monorepo

Overview

Migrate the legacy Soul Map Atlas codebase (React + base44.com backend) to the new monorepo architecture (React + oRPC + Cloudflare D1 + better-auth).

Scope:

  • Frontend: legacy/src/apps/web/
  • Backend: legacy/base44/apps/api/
  • Data: legacy/base44/entities/packages/db/
  • Auth: base44 auth → better-auth (Google OAuth + Email/Password)
  • Payment: Stripe → Doku

Approach: Phased migration. Each phase produces a working increment. No big-bang.


Phase 0: Foundation (Week 1)

Goal: Working infrastructure with auth and database.

0.1 Database Schema (packages/db)

Create Drizzle schema files in packages/db/src/schema/:

FileSourceNotes
users.tslegacy/base44/entities/User.jsoncAdd role column (member/admin/owner), migrate subscription fields
journalEntries.tslegacy/base44/entities/JournalEntry.jsoncSame structure, add userId FK
compatibilityResults.tslegacy/base44/entities/CompatibilityResult.jsoncAdd userId FK, replace stripeSessionId with paymentId
consentRecords.tslegacy/base44/entities/ConsentRecord.jsoncGDPR tracking
deepInsightsPurchases.tslegacy/base44/entities/DeepInsightsPurchase.jsoncOne-time purchase tracking

better-auth tables (managed by better-auth Drizzle adapter):

  • user (extended with our custom fields)
  • session
  • account
  • verification

Rules to follow: .agents/rules/database.md

0.2 Auth Setup (packages/auth)

  • Configure better-auth with Drizzle adapter
  • Enable Google OAuth plugin
  • Enable Email/Password plugin with scrypt hasher (node:crypto.scrypt)
  • Add role field to user table via additionalFields
  • Migrate existing user data (if any) preserving IDs

Rules to follow: .agents/rules/api.md (Auth Setup section)

0.3 API Entrypoint (apps/api)

  • Wire better-auth handler at /api/auth/*
  • Implement whoami oRPC route
  • Set up OpenAPIHandler with proper spec generation
  • Add CORS middleware for frontend communication
  • Health check at /api/health

Rules to follow: .agents/rules/api.md

0.4 Frontend Shell (apps/web)

  • Set up React 19 + Vite + Tailwind + shadcn/ui
  • Configure TanStack Query client
  • Set up React Router with route structure matching legacy
  • Create basic layout shell (header, nav, footer)

Deliverable: A working dev environment where you can sign in (via better-auth) and hit /api/health.


Phase 1: User Domain (Week 2)

Goal: User profile, settings, and plan management working end-to-end.

1.1 User Service (apps/api/src/services/users/)

Implement service mixins:

  • get-profile.ts — Get current user profile
  • update-profile.ts — Update user profile
  • get-plan-and-usage.ts — Get subscription plan and usage counters

Route handlers:

  • GET /api/v1/getProfile (memberProcedure)
  • POST /api/v1/updateProfile (memberProcedure)
  • GET /api/v1/getPlanAndUsage (memberProcedure)

1.2 Frontend Pages

Migrate from legacy/src/pages/:

  • ProfileSettings.jsxapps/web/src/pages/ProfileSettings.tsx
  • MemberDashboard.jsxapps/web/src/pages/MemberDashboard.tsx

Update data fetching:

  • Replace base44 client calls with oRPC client calls
  • Replace legacy auth context with new auth hooks

1.3 Plan & Usage System

Migrate usage tracking logic:

  • legacy/src/hooks/useUserPlanAndUsage.jsapps/web/src/hooks/usePlanAndUsage.ts
  • Implement usage increment service
  • Implement plan limit enforcement

Deliverable: Users can sign in, view profile, see plan/usage, update settings.


Phase 2: Journal Domain (Week 3)

Goal: Inner Growth Journal fully working.

2.1 Journal Service (apps/api/src/services/journal/)

  • create-entry.ts — Create journal entry with mood tracking
  • get-entry.ts — Get single entry
  • list-entries.ts — List user's entries with pagination
  • get-today-prompt.ts — Generate daily prompt

2.2 Frontend Components

Migrate from legacy/src/components/journal/:

  • JournalTodayTab.jsx
  • JournalHistoryTab.jsx
  • JournalProfileTab.jsx
  • JournalGrowthTab.jsx
  • JournalPaywall.jsx

2.3 Prompt Engine

Migrate legacy/src/lib/journalPromptEngine.js to apps/web/src/lib/journalPromptEngine.ts.

Deliverable: Users can write journal entries, view history, see mood trends, get daily prompts.


Phase 3: Destiny Analysis (Week 4)

Goal: Astrology, Numerology, BaZi, Primbon, Human Design working.

3.1 Analysis Engine Services

These are primarily calculation engines — no persistent data beyond user inputs:

  • apps/web/src/lib/astrologyEngine.ts — Birth chart calculations
  • apps/web/src/lib/numerologyEngine.ts — Number calculations
  • apps/web/src/lib/baziEngine.ts — BaZi calculations
  • apps/web/src/lib/primbonEngine.ts — Javanese calculations
  • apps/web/src/lib/humanDesignEngine.ts — Human Design calculations

Note: Most calculation logic can be ported directly from legacy. These run client-side.

3.2 Frontend Pages

Migrate from legacy/src/pages/:

  • Astrology.jsx / AstrologyCalculator.jsx / AstrologyComparison.jsx
  • Numerology.jsx
  • BaZi.jsx
  • Primbon.jsx
  • HumanDesign.jsx
  • ComprehensiveOutput.jsx

3.3 Soul Map Context

Migrate legacy/src/components/SoulMapContext.jsx to manage analysis state.

Deliverable: Users can input birth data and get all analysis results.


Phase 4: Compatibility Domain (Week 5)

Goal: Compatibility testing with free/lite and paid deep insights.

4.1 Compatibility Service (apps/api/src/services/compatibility/)

  • create-result.ts — Create compatibility result
  • get-result.ts — Get result (with ownership check)
  • list-results.ts — List user's results
  • unlock-deep-insights.ts — Unlock paid insights

Key logic to migrate:

  • legacy/src/lib/compatibilityEngine.js
  • legacy/src/lib/compatibilityResultHelper.js
  • legacy/src/lib/compatibilityI18n.js

4.2 Frontend Components

Migrate from legacy/src/components/compatibility/:

  • CompatibilityForm.jsx
  • CompatibilityResult.jsx
  • InsightSection.jsx
  • LockedSection.jsx
  • ScoreRing.jsx
  • SubScoreCard.jsx
  • SystemTabs.jsx
  • UnlockModal.jsx

4.3 Result Detail Page

Migrate legacy/src/pages/CompatibilityResultDetail.jsx.

Deliverable: Users can create compatibility tests, view lite results, and unlock deep insights.


Phase 5: Payment & Purchases (Week 6)

Goal: Doku payment integration replacing Stripe.

5.1 Payment Package (packages/payment)

  • Doku client configuration
  • Checkout session creation
  • Webhook handling
  • Payment verification

5.2 Payment Service (apps/api/src/services/payment/)

  • create-checkout.ts — Create Doku checkout
  • verify-payment.ts — Verify payment status
  • process-webhook.ts — Handle Doku webhook

5.3 Purchase Flow

Migrate purchase logic:

  • One-time deep insights purchases
  • Subscription plan upgrades
  • Usage credit purchases

Frontend:

  • Migrate legacy/src/pages/Pricing.jsx
  • Migrate legacy/src/components/PricingSection.jsx
  • Migrate legacy/src/pages/PaymentSuccess.jsx

Deliverable: Users can purchase plans and one-time credits via Doku.


Phase 6: AI Features (Week 7)

Goal: AI synthesis and chat features.

6.1 AI Integration

Migrate legacy/src/pages/AISynthesisCore.jsx.

Note: AI features may still call base44.com directly as per architecture decision. The migration here is minimal — mostly frontend wiring.

6.2 Chat Components

Migrate legacy/src/components/chat/SoulMapGuide.jsx.

Deliverable: AI chat and synthesis features working.


Phase 7: Admin & Utilities (Week 8)

Goal: Admin functions, consent management, final polish.

7.1 Admin Routes

Migrate admin functions from legacy/base44/functions/:

  • makeUserAdmin → admin route
  • setUserPremiumPlus → admin route
  • Usage analytics

Migrate legacy/src/components/ConsentGate.jsx.

  • GDPR consent tracking
  • Privacy policy / Terms of service pages

7.3 Static Pages

Migrate from legacy/src/pages/:

  • PrivacyPolicy.jsx
  • TermsOfService.jsx

7.4 Final Polish

  • Error boundaries (legacy/src/components/ErrorBoundary.jsx)
  • Loading states
  • Toast notifications
  • Mobile responsiveness

Deliverable: Feature-complete application ready for production.


Data Migration Strategy

User Data

  1. Export users from base44
  2. Transform: base44 role: "user" → new role: "member"
  3. Hash passwords: If base44 used plaintext or weak hashing, require password reset on first login
  4. Import via Drizzle seed script or D1 import

Journal Entries

  1. Export entries with user references
  2. Transform user IDs to match new better-auth user IDs
  3. Import via seed script

Compatibility Results

  1. Export results
  2. Replace stripeSessionId with null or new payment reference
  3. Import via seed script

Purchases

  1. Export purchase history
  2. Mark as migrated, create new purchase records in deepInsightsPurchases table

Frontend Migration Pattern

For each page/component migration:

  1. Copy the .jsx file to apps/web/src/ as .tsx
  2. Fix TypeScript types (add interfaces, fix prop types)
  3. Replace data fetching:
    • Remove base44 imports
    • Add oRPC client hooks
    • Replace useQuery from legacy with TanStack Query + oRPC
  4. Replace auth:
    • Remove AuthContext usage
    • Use new auth hooks from @packages/auth
  5. Update routing:
    • Convert React Router v6 routes if needed
  6. Test the migrated component in isolation

Service Implementation Pattern

For each backend function migration:

  1. Identify the base44 function in legacy/base44/functions/
  2. Create service mixin in apps/api/src/services/<domain>/
    • Define params schema (Zod)
    • Define result schema (Zod)
    • Implement business logic
  3. Create contract in apps/api/src/contract/<domain>.ts
  4. Create route handler in apps/api/src/routes/<domain>/<operation>.ts
  5. Add to router in apps/api/src/routes/<domain>/index.ts
  6. Test via API client or curl

Risk Mitigation

RiskMitigation
Data loss during migrationExport everything before migration. Keep legacy DB read-only during transition.
Auth migration complexityRequire password reset for email users. OAuth users seamless via Google.
Payment interruptionKeep Stripe active during Doku integration. Switch over only after testing.
Feature parity gapsPhase-by-phase delivery ensures each feature is fully working before moving on.
Performance regressionCloudflare D1 + Workers should be faster than base44. Monitor latency.

Success Criteria

  • [ ] All legacy pages render in new app
  • [ ] All legacy API functions have oRPC equivalents
  • [ ] User data migrated successfully
  • [ ] Auth works (Google OAuth + Email/Password)
  • [ ] Payment works (Doku)
  • [ ] OpenAPI docs generated correctly
  • [ ] All docs updated and deployed
  • [ ] No sensitive data in code or docs
  • [ ] legacy/ folder can be deleted

Timeline Summary

PhaseDurationDeliverable
0. FoundationWeek 1Working infra, auth, DB
1. User DomainWeek 2Profile, settings, plans
2. Journal DomainWeek 3Full journal feature
3. Destiny AnalysisWeek 4Astrology, Numerology, BaZi, etc.
4. CompatibilityWeek 5Compatibility tests + deep insights
5. PaymentWeek 6Doku integration
6. AI FeaturesWeek 7AI synthesis + chat
7. Admin + PolishWeek 8Admin, consent, final polish

Total: 8 weeks (can be parallelized where dependencies allow)


Docs Updates Required

After each phase, update these docs:

PhaseDoc updates
0technical/architecture.md, technical/database.md, technical/authentication.md
1technical/user-flow.md (user profile flow)
2technical/user-flow.md (journal flow), overview/product.md
3technical/user-flow.md (analysis flows)
4technical/user-flow.md (compatibility flow)
5technical/deployment.md (payment config)
6overview/product.md (AI features)
7technical/authentication.md (admin), overview/product.md

See .agents/rules/docs.md for full docs conventions.


Appendix: Legacy Code Inventory

Frontend Pages (26 pages)

  • Home, Spiritual, Astrology, AstrologyCalculator, AstrologyComparison
  • Numerology, BaZi, Primbon, HumanDesign
  • CompatibilityTest, CompatibilityResultDetail
  • InnerGrowthJournal, MemberDashboard, MoodAndGrowthCharts
  • Pricing, PaymentSuccess, ProfileSettings
  • PrivacyPolicy, TermsOfService, ComprehensiveOutput
  • AISynthesisCore, DestinyStudio, SoulMapAtlas
  • Psychology, UserJourney

Frontend Components

  • UI components (shadcn/ui) — reusable, port as-is
  • Journal components (4 tabs + paywall)
  • Compatibility components (8 components)
  • Destiny components (3 components)
  • Chat component (SoulMapGuide)

Backend Functions (22 functions)

  • Auth: makeUserAdmin, setUserPremiumPlus
  • Payment: createCheckoutSession, verifyCheckoutSession, stripeWebhook
  • Deep Insights: createDeepInsightsCheckout, verifyDeepInsightsPayment, processDeepInsightsPayment, consumeDeepInsightUsage, getDeepInsightsUsage, syncDeepInsightsCredits, syncDeepInsightsUnlock, migrateDeepInsightsUsage, resetDeepInsightsUsage, startDeepInsightsTest
  • Usage: incrementUsage, trackUsage, getPersonalityTestsUsage
  • Compatibility: saveCompatibilityResult
  • Subscription: syncSubscription, syncPaymentForResult

Entities (5 entities)

  • User, JournalEntry, CompatibilityResult, ConsentRecord, DeepInsightsPurchase