mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-19 21:31:46 +00:00
0b218d53b2
Co-hosted NestJS app behind the existing Express server via a strangler-fig dispatcher, sharing the same better-sqlite3 connection and JWT httpOnly cookie. Additive and dormant: default routing stays on Express, Nest only serves its own /api/_nest diagnostics until a module opts in. F1 @trek/shared Zod contract package; F2 Nest bootstrap co-hosted (fall-through, single Dockerfile/port); F3 shared better-sqlite3 provider; F4 JWT cookie auth guard (+ @CurrentUser, admin guard); F5 Zod validation pipe + error-envelope parity; F6 Nest test + coverage gates; F7 per-prefix strangler toggle (env, default Express); F8 CI build/typecheck/test/coverage. Remaining F4/F6/F8 checklist items (trip-access + permission levels + MFA policy, e2e harness/seed + 80% gate, Nest↔Express parity test, Playwright PR-comment workflow) are tracked on the first consuming module cards (L1/A1/C1).
27 lines
994 B
TypeScript
27 lines
994 B
TypeScript
import { ArgumentMetadata, HttpException, Injectable, PipeTransform } from '@nestjs/common';
|
|
import type { ZodType } from 'zod';
|
|
|
|
/**
|
|
* Validates an incoming @Body()/@Query() against a Zod schema (from @trek/shared)
|
|
* and returns the parsed, typed value. On failure it throws TREK's error envelope
|
|
* `{ error: string }` with status 400 — the same shape the legacy routes produce,
|
|
* so the client's error handling is unaffected.
|
|
*
|
|
* Usage: `@Body(new ZodValidationPipe(someSchema)) dto: Dto`.
|
|
*/
|
|
@Injectable()
|
|
export class ZodValidationPipe implements PipeTransform {
|
|
constructor(private readonly schema: ZodType) {}
|
|
|
|
transform(value: unknown, _metadata: ArgumentMetadata): unknown {
|
|
const result = this.schema.safeParse(value);
|
|
if (!result.success) {
|
|
const message = result.error.issues
|
|
.map((i) => `${i.path.join('.') || 'body'}: ${i.message}`)
|
|
.join('; ');
|
|
throw new HttpException({ error: message }, 400);
|
|
}
|
|
return result.data;
|
|
}
|
|
}
|