Appearance
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/:
| File | Source | Notes |
|---|---|---|
users.ts | legacy/base44/entities/User.jsonc | Add role column (member/admin/owner), migrate subscription fields |
journalEntries.ts | legacy/base44/entities/JournalEntry.jsonc | Same structure, add userId FK |
compatibilityResults.ts | legacy/base44/entities/CompatibilityResult.jsonc | Add userId FK, replace stripeSessionId with paymentId |
consentRecords.ts | legacy/base44/entities/ConsentRecord.jsonc | GDPR tracking |
deepInsightsPurchases.ts | legacy/base44/entities/DeepInsightsPurchase.jsonc | One-time purchase tracking |
better-auth tables (managed by better-auth Drizzle adapter):
user(extended with our custom fields)sessionaccountverification
Rules to follow: .agents/rules/database.md
0.2 Auth Setup (packages/auth)
- Configure
better-authwith Drizzle adapter - Enable Google OAuth plugin
- Enable Email/Password plugin with scrypt hasher (
node:crypto.scrypt) - Add
rolefield to user table viaadditionalFields - 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-authhandler at/api/auth/* - Implement
whoamioRPC route - Set up
OpenAPIHandlerwith 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 profileupdate-profile.ts— Update user profileget-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.jsx→apps/web/src/pages/ProfileSettings.tsxMemberDashboard.jsx→apps/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.js→apps/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 trackingget-entry.ts— Get single entrylist-entries.ts— List user's entries with paginationget-today-prompt.ts— Generate daily prompt
2.2 Frontend Components
Migrate from legacy/src/components/journal/:
JournalTodayTab.jsxJournalHistoryTab.jsxJournalProfileTab.jsxJournalGrowthTab.jsxJournalPaywall.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 calculationsapps/web/src/lib/numerologyEngine.ts— Number calculationsapps/web/src/lib/baziEngine.ts— BaZi calculationsapps/web/src/lib/primbonEngine.ts— Javanese calculationsapps/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.jsxNumerology.jsxBaZi.jsxPrimbon.jsxHumanDesign.jsxComprehensiveOutput.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 resultget-result.ts— Get result (with ownership check)list-results.ts— List user's resultsunlock-deep-insights.ts— Unlock paid insights
Key logic to migrate:
legacy/src/lib/compatibilityEngine.jslegacy/src/lib/compatibilityResultHelper.jslegacy/src/lib/compatibilityI18n.js
4.2 Frontend Components
Migrate from legacy/src/components/compatibility/:
CompatibilityForm.jsxCompatibilityResult.jsxInsightSection.jsxLockedSection.jsxScoreRing.jsxSubScoreCard.jsxSystemTabs.jsxUnlockModal.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 checkoutverify-payment.ts— Verify payment statusprocess-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 routesetUserPremiumPlus→ admin route- Usage analytics
7.2 Consent & Privacy
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.jsxTermsOfService.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
- Export users from base44
- Transform: base44
role: "user"→ newrole: "member" - Hash passwords: If base44 used plaintext or weak hashing, require password reset on first login
- Import via Drizzle seed script or D1 import
Journal Entries
- Export entries with user references
- Transform user IDs to match new better-auth user IDs
- Import via seed script
Compatibility Results
- Export results
- Replace
stripeSessionIdwith null or new payment reference - Import via seed script
Purchases
- Export purchase history
- Mark as migrated, create new purchase records in
deepInsightsPurchasestable
Frontend Migration Pattern
For each page/component migration:
- Copy the
.jsxfile toapps/web/src/as.tsx - Fix TypeScript types (add interfaces, fix prop types)
- Replace data fetching:
- Remove base44 imports
- Add oRPC client hooks
- Replace
useQueryfrom legacy with TanStack Query + oRPC
- Replace auth:
- Remove
AuthContextusage - Use new auth hooks from
@packages/auth
- Remove
- Update routing:
- Convert React Router v6 routes if needed
- Test the migrated component in isolation
Service Implementation Pattern
For each backend function migration:
- Identify the base44 function in
legacy/base44/functions/ - Create service mixin in
apps/api/src/services/<domain>/- Define params schema (Zod)
- Define result schema (Zod)
- Implement business logic
- Create contract in
apps/api/src/contract/<domain>.ts - Create route handler in
apps/api/src/routes/<domain>/<operation>.ts - Add to router in
apps/api/src/routes/<domain>/index.ts - Test via API client or curl
Risk Mitigation
| Risk | Mitigation |
|---|---|
| Data loss during migration | Export everything before migration. Keep legacy DB read-only during transition. |
| Auth migration complexity | Require password reset for email users. OAuth users seamless via Google. |
| Payment interruption | Keep Stripe active during Doku integration. Switch over only after testing. |
| Feature parity gaps | Phase-by-phase delivery ensures each feature is fully working before moving on. |
| Performance regression | Cloudflare 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
| Phase | Duration | Deliverable |
|---|---|---|
| 0. Foundation | Week 1 | Working infra, auth, DB |
| 1. User Domain | Week 2 | Profile, settings, plans |
| 2. Journal Domain | Week 3 | Full journal feature |
| 3. Destiny Analysis | Week 4 | Astrology, Numerology, BaZi, etc. |
| 4. Compatibility | Week 5 | Compatibility tests + deep insights |
| 5. Payment | Week 6 | Doku integration |
| 6. AI Features | Week 7 | AI synthesis + chat |
| 7. Admin + Polish | Week 8 | Admin, consent, final polish |
Total: 8 weeks (can be parallelized where dependencies allow)
Docs Updates Required
After each phase, update these docs:
| Phase | Doc updates |
|---|---|
| 0 | technical/architecture.md, technical/database.md, technical/authentication.md |
| 1 | technical/user-flow.md (user profile flow) |
| 2 | technical/user-flow.md (journal flow), overview/product.md |
| 3 | technical/user-flow.md (analysis flows) |
| 4 | technical/user-flow.md (compatibility flow) |
| 5 | technical/deployment.md (payment config) |
| 6 | overview/product.md (AI features) |
| 7 | technical/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