- 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
49 lines
1.6 KiB
TypeScript
49 lines
1.6 KiB
TypeScript
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; |