The backend is a Cloudflare Worker that exposes a tRPC API. It handles authentication, database operations, and business logic.
File: src/server.ts
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response>
}- Handles CORS preflight (
OPTIONS) - Routes
/trpc/*to tRPC handler - Routes
/healthto health check - Returns 404 for unknown routes
export const appRouter = router({
auth: authRouter,
resume: resumeRouter,
section: sectionRouter,
});Created for every request, contains:
db- Drizzle database instanceuser- Clerk user object (or null)userId- User ID string (or null)env- Cloudflare environment bindingsclerkClient- Clerk SDK client
export const authMiddleware = middleware(async ({ ctx, next }) => {
if (!ctx.user || !ctx.userId) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
return next({ ctx });
});publicProcedure- No auth requiredprotectedProcedure- Requires authenticated user
export function createDb(d1: D1Database): Database {
return drizzle(d1, { schema });
}users- User accountsresumes- Resume documentssections- Resume sectionsaccounts,sessions- Auth tables
- SQL migration files generated by Drizzle Kit
- Applied via
wrangler d1 migrations apply
- Returns all resumes for authenticated user
- Excludes archived by default
- Orders by
updatedAtdesc
- Fetches resume with all sections
- Validates user ownership
- Returns sections ordered by
orderfield
- Creates resume with default metadata
- Default metadata includes:
personalInfo- Empty personal detailssettings- Page size, fonts, colors, margins
- Updates resume metadata
- Validates Zod schema
- Updates
updatedAttimestamp
- Soft delete (sets
isArchived = true) - Or hard delete if specified
- Creates or updates section
- Content is JSON blob specific to section type
- Handles ordering
- Updates
orderfield for multiple sections - Transaction-safe
CLERK_SECRET_KEY=sk_test_...
CLERK_PUBLISHABLE_KEY=pk_test_...
tRPC errors are caught and logged:
onError({ path, error }) {
console.error(`Error in tRPC handler on path '${path}':`, error);
}Common error codes:
UNAUTHORIZED- Missing or invalid authNOT_FOUND- Resource doesn't existFORBIDDEN- User doesn't own resourceBAD_REQUEST- Validation failedINTERNAL_SERVER_ERROR- Database or runtime error
cd api-server
npx wrangler dev- Runs on port 4000
- Uses local D1 database (
.wrangler/state/v3/d1/) - Hot reloads on file changes
npx wrangler deploy- Deploys to Cloudflare Workers
- Uses production D1 database
- Requires
CLERK_SECRET_KEYin Cloudflare dashboard