Convex Backend Restructuring Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Reorganize packages/backend/convex/ into a clean, predictable structure with clear domain boundaries, consistent naming, and separation of concerns.
Architecture: Flat function files grouped by domain into subdirectories. HTTP handlers consolidated. Lib utilities consolidated with consistent naming. Tests co-located with source files.
Tech Stack: Convex 1.37.0, TypeScript
Critical Rule: Verify-After-Every-Commit
After every commit, you MUST verify the backend builds and deploys correctly.
cd packages/backend && npm run build
npx convex deploy --build-onlyIf either fails, STOP and fix before proceeding. Do not compound errors across tasks.
Target File Structure
convex/
├── schema.ts # Database schema (single source of truth)
├── convex.json # Convex project config
├── tsconfig.json
├── vitest.config.ts
├── crons.ts # Cron job definitions
├── auth.config.ts # Auth provider configuration
│
├── lib/ # Shared utilities
│ ├── index.ts # Re-exports for convenience
│ ├── auth.ts # Auth helpers
│ ├── errors.ts # Custom error classes
│ ├── env.ts # Environment variable accessors
│ ├── relationships.ts # Relationship helpers
│ ├── zod.ts # Zod builder setup
│ └── onepay/ # OnePay integration
│ ├── index.ts
│ ├── utils.ts # (renamed from onepay-utils.ts)
│ └── api.ts # (renamed from api_client.ts)
│
├── http.ts # Root HTTP router (minimal)
├── http/ # HTTP handler implementations
│ ├── index.ts
│ ├── onepay.ts # OnePay return + webhook handlers
│ ├── tickets.ts # Ticket HTTP handlers
│ └── booking.ts # Booking HTTP handlers
│
├── domains/ # Domain modules (one per business domain)
│ ├── shows/
│ ├── reservations/
│ ├── crm/
│ ├── notifications/
│ ├── minigames/
│ │ └── schemas/
│ ├── forms/
│ ├── payments/
│ ├── checkins/
│ ├── profiles/
│ └── analytics/
└── _generated/ # Auto-generated (DO NOT EDIT)Task Breakdown
Each task is atomic: it modifies files, commits, and verifies. No task should break the build.
Task 1: Checkpoint Current State
Files:
-
Modify:
packages/backend/convex/.gitignore -
Step 1: Ensure .gitignore is correct
Verify .gitignore includes:
node_modules/
.env
*.bak- Step 2: Create checkpoint commit
cd packages/backend/convex
git add -A
git commit -m "chore: checkpoint before backend restructure"- Step 3: Verify build still works
cd packages/backend && npm run buildTask 2: Create Domain Directory Structure
Files:
-
Create:
packages/backend/convex/domains/(all subdirectories) -
Create:
packages/backend/convex/http/ -
Step 1: Create all domain directories
cd packages/backend/convex
mkdir -p domains/shows domains/reservations domains/crm domains/notifications
mkdir -p domains/minigames/schemas domains/forms domains/payments
mkdir -p domains/checkins domains/profiles domains/analytics
mkdir -p http- Step 2: Commit
git add domains/ http/ && git commit -m "chore: create domain directory structure"- Step 3: Verify build
cd packages/backend && npm run buildTask 3: Consolidate Lib/onepay
Files:
-
Create:
lib/onepay/ -
Move:
lib/onepay-utils.ts→lib/onepay/utils.ts -
Move:
lib/zoho/api_client.ts→lib/onepay/api.ts -
Move:
lib/__tests__/onepay-utils.test.ts→lib/onepay/utils.test.ts -
Delete:
lib/__tests__/,lib/zoho/,lib/schemas/ -
Step 1: Create lib/onepay and move files
cd packages/backend/convex
mkdir -p lib/onepay
mv lib/__tests__/onepay-utils.test.ts lib/onepay/utils.test.ts
mv lib/onepay-utils.ts lib/onepay/utils.ts
mv lib/zoho/api_client.ts lib/onepay/api.ts
rmdir lib/__tests__ lib/zoho lib/schemas 2>/dev/null || true- Step 2: Update imports in utils.ts
Check the file for imports from ../zoho/api_client and update to ./api.
- Step 3: Update lib/index.ts to re-export onepay
// lib/index.ts
export * from "./auth";
export * from "./errors";
export * from "./env";
export * from "./relationships";
export * from "./zod";
export * from "./onepay/utils";
export * from "./onepay/api";- Step 4: Commit and verify
git add -A && git commit -m "refactor: consolidate lib/onepay utilities"
cd packages/backend && npm run buildTask 4: Remove auth.config.ts.bak
Files:
-
Delete:
packages/backend/convex/auth.config.ts.bak -
Step 1: Remove .bak file
cd packages/backend/convex
rm -f auth.config.ts.bak
git add -A && git commit -m "chore: remove auth.config.ts.bak"
cd packages/backend && npm run buildTask 5: Move Minigames Domain
Files:
-
Create:
domains/minigames/index.ts -
Create:
domains/minigames/schemas/ -
Move:
functions/challenges.ts→domains/minigames/challenges.ts -
Move:
functions/liveViewers.ts→domains/minigames/live-viewers.ts -
Move:
functions/menu.ts→domains/minigames/menu.ts -
Move:
lib/schemas/minigames.ts→domains/minigames/schemas/minigames.ts -
Step 1: Move minigames files
cd packages/backend/convex
mv functions/challenges.ts domains/minigames/challenges.ts
mv functions/liveViewers.ts domains/minigames/live-viewers.ts
mv functions/menu.ts domains/minigames/menu.ts
mv lib/schemas/minigames.ts domains/minigames/schemas/minigames.ts 2>/dev/null || true- Step 2: Rename recurrence.ts if it exists in functions
Check if recurrence.ts exists and move it:
[ -f functions/recurrence.ts ] && mv functions/recurrence.ts domains/minigames/recurrence.ts- Step 3: Update import paths in moved files
In each moved file, update relative paths:
// From:
import { staffMutation } from "../../lib/auth";
import schema from "../schema";
// To:
import { staffMutation } from "../../../lib/auth";
import schema from "../../../schema";- Step 4: Create domains/minigames/index.ts
export * from "./challenges";
export * from "./live-viewers";
export * from "./menu";
export * from "./recurrence";
export * from "./schemas/minigames";- Step 5: Commit and verify
git add -A && git commit -m "refactor: move minigames domain to domains/minigames"
cd packages/backend && npm run buildTask 6: Move Notifications Domain
Files:
-
Create:
domains/notifications/index.ts -
Move:
functions/notifications.ts→domains/notifications/notifications.ts -
Move:
functions/notifications_internal.ts→domains/notifications/notifications-internal.ts -
Step 1: Move files
cd packages/backend/convex
mv functions/notifications.ts domains/notifications/notifications.ts
mv functions/notifications_internal.ts domains/notifications/notifications-internal.ts-
Step 2: Update import paths
-
Step 3: Create index.ts and commit
git add -A && git commit -m "refactor: move notifications domain"
cd packages/backend && npm run buildTask 7: Move CRM Domain
Files:
-
Create:
domains/crm/index.ts -
Move:
functions/crm.ts→domains/crm/crm.ts -
Move:
functions/crm_sync.ts→domains/crm/sync.ts -
Move:
functions/crm_sync_internal.ts→domains/crm/sync-internal.ts -
Step 1: Move files
cd packages/backend/convex
mv functions/crm.ts domains/crm/crm.ts
mv functions/crm_sync.ts domains/crm/sync.ts
mv functions/crm_sync_internal.ts domains/crm/sync-internal.ts-
Step 2: Update import paths and create index.ts
-
Step 3: Commit and verify
git add -A && git commit -m "refactor: move crm domain"
cd packages/backend && npm run buildTask 8: Move Profiles Domain
Files:
-
Create:
domains/profiles/index.ts -
Move:
functions/profiles.ts→domains/profiles/profiles.ts -
Step 1: Move and commit
cd packages/backend/convex
mv functions/profiles.ts domains/profiles/profiles.ts
git add -A && git commit -m "refactor: move profiles domain"
cd packages/backend && npm run buildTask 9: Move Forms Domain
Files:
-
Create:
domains/forms/index.ts -
Move:
functions/contact_form.ts→domains/forms/contact-form.ts -
Move:
functions/form_sessions.ts→domains/forms/form-sessions.ts -
Move:
functions/proposal_forms.ts→domains/forms/proposal-forms.ts -
Step 1: Move files
cd packages/backend/convex
mv functions/contact_form.ts domains/forms/contact-form.ts
mv functions/form_sessions.ts domains/forms/form-sessions.ts
mv functions/proposal_forms.ts domains/forms/proposal-forms.ts-
Step 2: Update paths and create index.ts
-
Step 3: Commit and verify
git add -A && git commit -m "refactor: move forms domain"
cd packages/backend && npm run buildTask 10: Move Analytics Domain
Files:
-
Create:
domains/analytics/index.ts -
Move:
functions/analytics.ts→domains/analytics/analytics.ts -
Move:
functions/scheduled.ts→domains/analytics/scheduled.ts -
Move:
analytics.test.ts→domains/analytics/analytics.test.ts(if exists) -
Move:
scheduled.test.ts→domains/analytics/scheduled.test.ts(if exists) -
Step 1: Move files
cd packages/backend/convex
mv functions/analytics.ts domains/analytics/analytics.ts
mv functions/scheduled.ts domains/analytics/scheduled.ts
mv analytics.test.ts domains/analytics/ 2>/dev/null || true
mv scheduled.test.ts domains/analytics/ 2>/dev/null || true-
Step 2: Update paths and create index.ts
-
Step 3: Commit and verify
git add -A && git commit -m "refactor: move analytics domain"
cd packages/backend && npm run buildTask 11: Move Checkins Domain
Files:
-
Create:
domains/checkins/index.ts -
Move:
functions/checkIns.ts→domains/checkins/checkins.ts -
Step 1: Move and commit
cd packages/backend/convex
mv functions/checkIns.ts domains/checkins/checkins.ts
git add -A && git commit -m "refactor: move checkins domain"
cd packages/backend && npm run buildTask 12: Move Payments Domain
Files:
-
Create:
domains/payments/index.ts -
Move:
functions/payments.ts→domains/payments/payments.ts -
Move:
functions/orders.ts→domains/payments/orders.ts -
Move:
functions/addons.ts→domains/payments/addons.ts -
Move:
functions/pricing.ts→domains/payments/pricing.ts -
Move:
functions/tables.ts→domains/payments/tables.ts -
Step 1: Move files
cd packages/backend/convex
mv functions/payments.ts domains/payments/payments.ts
mv functions/orders.ts domains/payments/orders.ts
mv functions/addons.ts domains/payments/addons.ts
mv functions/pricing.ts domains/payments/pricing.ts
mv functions/tables.ts domains/payments/tables.ts-
Step 2: Update paths and create index.ts
-
Step 3: Commit and verify
git add -A && git commit -m "refactor: move payments domain"
cd packages/backend && npm run buildTask 13: Move Shows Domain
Files:
-
Create:
domains/shows/index.ts -
Move:
functions/shows.ts→domains/shows/shows.ts -
Move:
functions/occurrences.ts→domains/shows/occurrences.ts -
Move:
functions/shows.http.ts→domains/shows/shows.http.ts -
Step 1: Move files
cd packages/backend/convex
mv functions/shows.ts domains/shows/shows.ts
mv functions/occurrences.ts domains/shows/occurrences.ts
mv functions/shows.http.ts domains/shows/shows.http.ts-
Step 2: Update paths and create index.ts
-
Step 3: Commit and verify
git add -A && git commit -m "refactor: move shows domain"
cd packages/backend && npm run buildTask 14: Move Reservations Domain
Files:
-
Create:
domains/reservations/index.ts -
Move:
functions/reservations.ts→domains/reservations/reservations.ts -
Move:
functions/booking_drafts.ts→domains/reservations/booking-drafts.ts -
Move:
functions/booking.http.ts→domains/reservations/booking.http.ts -
Move:
functions/reservations/createOnePayOrderForReservation.ts→domains/reservations/create-order.ts -
Step 1: Move files
cd packages/backend/convex
mv functions/reservations.ts domains/reservations/reservations.ts
mv functions/booking_drafts.ts domains/reservations/booking-drafts.ts
mv functions/booking.http.ts domains/reservations/booking.http.ts
mv functions/reservations/createOnePayOrderForReservation.ts domains/reservations/create-order.ts-
Step 2: Update paths and create index.ts
-
Step 3: Commit and verify
git add -A && git commit -m "refactor: move reservations domain"
cd packages/backend && npm run buildTask 15: Consolidate HTTP Handlers
Files:
-
Create:
http/index.ts -
Move:
functions/onePay.http.ts→http/onepay.ts -
Move:
functions/tickets.http.ts→http/tickets.ts -
Move:
http/onepay.ts→http/onepay.ts(already there, may need merging) -
Step 1: Check existing http/ directory
ls -la http/- Step 2: If http/onepay.ts exists, merge with functions/onePay.http.ts
# Compare files and merge unique handlers
cat functions/onePay.http.ts >> http/onepay.ts
rm functions/onePay.http.ts
mv functions/tickets.http.ts http/tickets.ts- Step 3: Update http.ts root router
// http.ts (root)
import { httpRouter } from "convex/server";
import { onepay } from "./http/onepay";
import { tickets } from "./http/tickets";
const http = httpRouter();
http.route({ path: "/onepay/return", method: "GET", handler: onepay.return });
http.route({
path: "/onepay/webhook",
method: "POST",
handler: onepay.webhook,
});
http.route({
path: "/tickets/verify",
method: "POST",
handler: tickets.verify,
});
export default http;- Step 4: Create http/index.ts
export * from "./onepay";
export * from "./tickets";- Step 5: Commit and verify
git add -A && git commit -m "refactor: consolidate http handlers"
cd packages/backend && npm run buildTask 16: Remove Empty functions/ Directory
Files:
-
Delete:
packages/backend/convex/functions/ -
Step 1: Verify functions/ is empty then remove
cd packages/backend/convex
ls functions/ # Should be empty or show only hidden files
rmdir functions 2>/dev/null || rmdir functions/* 2>/dev/null; rmdir functions
git add -A && git commit -m "chore: remove empty functions directory"
cd packages/backend && npm run buildTask 17: Final Verification
- Step 1: Run full build
cd packages/backend && npm run build- Step 2: Verify deployment
npx convex deploy --build-only- Step 3: Check git status
git statusExpected: Clean diff showing only the restructure changes.
Verification Checklist
After each task:
-
npm run buildsucceeds -
git commitcreated with descriptive message - No unexpected files modified
Final state:
- All function files in domain directories
- Each domain has
index.tsre-exporting functions -
lib/onepay/consolidated with consistent naming -
http/consolidated with all HTTP handlers -
functions/directory removed - No
.bakfiles remain - Build succeeds
- Deploy succeeds
Rollback Plan
If something goes wrong after a commit:
cd packages/backend/convex
git reset --soft HEAD~1 # Undo last commit, keep changes
# Fix the issue
# Then recommit with fixOr for full rollback to checkpoint:
cd packages/backend/convex
git checkout HEAD~1 -- .