feat: Implement Phase 1 & 2 - Full monorepo architecture
## Backend API (apps/api) - Express.js server with TypeScript - JWT authentication with access/refresh tokens - Multi-tenant middleware (schema per tenant) - Complete CRUD routes: auth, cfdis, transactions, contacts, categories, metrics, alerts - SAT integration: CFDI 4.0 XML parser, FIEL authentication - Metrics engine: 50+ financial metrics (Core, Startup, Enterprise) - Rate limiting, CORS, Helmet security ## Frontend Web (apps/web) - Next.js 14 with App Router - Authentication pages: login, register, forgot-password - Dashboard layout with Sidebar and Header - Dashboard pages: overview, cash-flow, revenue, expenses, metrics - Zustand stores for auth and UI state - Theme support with flash prevention ## Database Package (packages/database) - PostgreSQL migrations with multi-tenant architecture - Public schema: plans, tenants, users, sessions, subscriptions - Tenant schema: sat_credentials, cfdis, transactions, contacts, accounts, alerts - Tenant management functions - Seed data for plans and super admin ## Shared Package (packages/shared) - TypeScript types: auth, tenant, financial, metrics, reports - Zod validation schemas for all entities - Utility functions for formatting ## UI Package (packages/ui) - Chart components: LineChart, BarChart, AreaChart, PieChart - Data components: DataTable, MetricCard, KPICard, AlertBadge - PeriodSelector and Skeleton components ## Infrastructure - Docker Compose: PostgreSQL 15, Redis 7, MinIO, Mailhog - Makefile with 25+ development commands - Development scripts: dev-setup.sh, dev-down.sh - Complete .env.example template Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
70
apps/api/src/middleware/validate.middleware.ts
Normal file
70
apps/api/src/middleware/validate.middleware.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Validation Middleware
|
||||
*
|
||||
* Validates request body, query, and params using Zod schemas
|
||||
*/
|
||||
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
import { ZodSchema, ZodError } from 'zod';
|
||||
import { ValidationError } from '../types';
|
||||
|
||||
export interface ValidateOptions {
|
||||
body?: ZodSchema;
|
||||
query?: ZodSchema;
|
||||
params?: ZodSchema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate request against Zod schemas
|
||||
*/
|
||||
export const validate = (schemas: ValidateOptions) => {
|
||||
return async (req: Request, _res: Response, next: NextFunction): Promise<void> => {
|
||||
try {
|
||||
if (schemas.body) {
|
||||
req.body = schemas.body.parse(req.body);
|
||||
}
|
||||
|
||||
if (schemas.query) {
|
||||
req.query = schemas.query.parse(req.query);
|
||||
}
|
||||
|
||||
if (schemas.params) {
|
||||
req.params = schemas.params.parse(req.params);
|
||||
}
|
||||
|
||||
next();
|
||||
} catch (error) {
|
||||
if (error instanceof ZodError) {
|
||||
const details = error.errors.reduce(
|
||||
(acc, err) => {
|
||||
const path = err.path.join('.');
|
||||
acc[path] = err.message;
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, string>
|
||||
);
|
||||
|
||||
next(new ValidationError('Datos de entrada invalidos', details));
|
||||
} else {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Validate only request body
|
||||
*/
|
||||
export const validateBody = (schema: ZodSchema) => validate({ body: schema });
|
||||
|
||||
/**
|
||||
* Validate only query parameters
|
||||
*/
|
||||
export const validateQuery = (schema: ZodSchema) => validate({ query: schema });
|
||||
|
||||
/**
|
||||
* Validate only path parameters
|
||||
*/
|
||||
export const validateParams = (schema: ZodSchema) => validate({ params: schema });
|
||||
|
||||
export default validate;
|
||||
Reference in New Issue
Block a user