refactor: migrate backend to pnpm monorepo with Hono module architecture
- Replace Bun with pnpm 9 + Turborepo + tsx; apps/api renamed to apps/backend - Split backend into http/, modules/, lib/ layers mirroring tai-specguard - Add use-case + Result pattern, Problem Details RFC 7807, basePath /api/v1 - Mount Better Auth at /api/v1/auth, keep session-auth whitelist - Split Prisma schema into prisma/models/*, generate into generated/ - Rework packages/shared into lib/ + schemas/ with pagination DTOs - Implement health, groups, students, payments, waitlist modules - Add vitest suite with prisma mocks (21 tests), biome lint - Point web client to /api/v1/auth and /api/v1/groups/from-organization
This commit is contained in:
49
apps/backend/src/app.ts
Normal file
49
apps/backend/src/app.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Hono } from 'hono';
|
||||
import type { BackendEnv } from '@/http/env';
|
||||
import {
|
||||
internalServerErrorProblem,
|
||||
notFoundProblem,
|
||||
problemJson,
|
||||
} from '@/http/problem-details';
|
||||
import { requestIdMiddleware } from '@/http/request-id';
|
||||
import { requestLoggerMiddleware } from '@/http/request-logger';
|
||||
import { corsMiddleware, securityHeadersMiddleware } from '@/http/security-headers';
|
||||
import { sessionAuthMiddleware } from '@/http/session-auth';
|
||||
import { logger } from '@/logger';
|
||||
import { authRoutes } from './modules/auth';
|
||||
import { groupsRoutes } from './modules/groups';
|
||||
import { healthCheckRoutes } from './modules/health-check';
|
||||
import { paymentsRoutes } from './modules/payments';
|
||||
import { studentsRoutes } from './modules/students';
|
||||
import { waitlistRoutes } from './modules/waitlist';
|
||||
|
||||
const app = new Hono<BackendEnv>();
|
||||
|
||||
app.use('*', corsMiddleware);
|
||||
app.use('*', securityHeadersMiddleware);
|
||||
app.use('*', requestIdMiddleware);
|
||||
app.use('*', requestLoggerMiddleware);
|
||||
|
||||
app.get('/', (c) => c.json({ name: 'Gruperly API', status: 'ok' }));
|
||||
|
||||
const api = app.basePath('/api/v1');
|
||||
|
||||
api.use('*', sessionAuthMiddleware);
|
||||
|
||||
api.route('/auth', authRoutes);
|
||||
api.route('/health', healthCheckRoutes);
|
||||
api.route('/groups', groupsRoutes);
|
||||
api.route('/students', studentsRoutes);
|
||||
api.route('/payments', paymentsRoutes);
|
||||
api.route('/waitlist', waitlistRoutes);
|
||||
|
||||
app.notFound((c) => {
|
||||
return problemJson(c, notFoundProblem(c.req.path));
|
||||
});
|
||||
|
||||
app.onError((error, c) => {
|
||||
logger.error({ error, path: c.req.path }, 'Unhandled request error');
|
||||
return problemJson(c, internalServerErrorProblem(c.req.path));
|
||||
});
|
||||
|
||||
export default app;
|
||||
Reference in New Issue
Block a user