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:
2026-01-31 11:05:24 +00:00
parent c1321c3f0c
commit a9b1994c48
110 changed files with 40788 additions and 0 deletions

View 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;