Sistek Pro
Sistema full stack corporativo + gestión técnica (Astro + NestJS)
Sistema completo para la empresa Sistek: sitio corporativo en Astro 6 + React 19 con SEO avanzado, páginas por servicio, blog, seguimiento público por QR; más API REST propia en NestJS 11 con TypeORM y PostgreSQL para usuarios, fichas técnicas de equipos, órdenes de servicio, clientes, empleados y leads. Desplegado en Vercel (frontend) y Render (backend).
Contexto y propósito
Sistek Pro es ahora un sistema full stack, no solo un sitio. El frontend (repo systekpro) es la presencia profesional de Sistek —infraestructura tecnológica y redes en Cali— y el backend (repo sistekpro-backend, NestJS 11) es la herramienta operativa: usuarios por roles, fichas técnicas (hojas de vida de equipos), órdenes de servicio con timeline y seguimiento público por QR.
Verificado en READMEs y código: frontend Astro 6 + React 19 + Tailwind 4 con SEO completo; backend NestJS 11 con TypeORM, PostgreSQL/MySQL, auth API Key + JWT, Helmet, Throttler y documentación API.md para el frontend. Incluye database.drawio con el ERD.
Propósito declarado: Dar presencia web profesional a una empresa de infraestructura y redes, y digitalizar su operación interna: hojas de vida de equipos, órdenes de servicio con timeline y seguimiento público por QR.
Arquitectura
Frontend: sitio estático/híbrido Astro 6 con islas React 19, Tailwind 4, JSON-LD y sitemap. Backend: API REST modular NestJS 11 (auth, users, ficha_tecnica, ordenes, clientes, empleados, leads, departamentos) con TypeORM + PostgreSQL, auth API Key + JWT por roles (admin/mantenimiento), Helmet + Throttler + class-validator.
Visitantes / Clientes Técnicos / Admin
│ │
▼ ▼
Astro 6 SSG + Islas React 19 NestJS 11 API REST (Render)
(SEO, blog, servicios, seguimiento) ──fetch──▶ auth │ users │ ficha_tecnica
│ │ ordenes │ clientes │ empleados
│ │ leads │ departamentos
▼ ▼
Vercel (sistekpro.vercel.app) PostgreSQL (+ MySQL compat.)
QR público ──▶ /seguimiento?code=XXX ──▶ endpoint público con x-api-key - Frontend: Astro 6 con contenido en src/content (blog), layouts con SEO, páginas por servicio en src/pages/servicios, sistema de seguimiento en /seguimiento y formularios backendless vía FormSubmit + GA4.
- Backend: módulos NestJS con patrón controller/service/module + dto/entities/enums por feature; transversal en src/common (seguridad, errores, metadata) y config validada con class-validator (src/config/env.validation.ts). Falla al arrancar si falta env obligatoria.
- Flujo de petición: Helmet → CORS → Throttler (100/60s global + 10/min login) → ApiKeyGuard → JwtGuard por roles → ValidationPipe → servicio → TypeORM → respuesta uniforme + log de lentas (>5s).
Stack detallado
| Capa | Tecnología | Detalle |
|---|---|---|
| Frontend | Astro 6 + React 19 + Tailwind 4 | SSG + islas; Tabler Icons; react-hook-form; qrcode.react |
| SEO | JSON-LD + sitemap + robots | LocalBusiness, Organization, Service, FAQPage, BreadcrumbList; hreflang, canonical, OG/Twitter |
| Backend | NestJS 11 + TypeScript ES2023 | @nestjs/config, @nestjs/jwt + bcrypt, @nestjs/throttler, helmet, class-validator |
| ORM / BD | TypeORM + PostgreSQL (pg) / MySQL (mysql2) | synchronize:true solo dev; seed interno sin registro público |
| Package mgmt | pnpm (backend) / npm (frontend) | Node 20+ / 22+; PG 14+ |
| Deploy | Vercel (front) + Render (back) | Backend vivo en sistekpro-backend.onrender.com |
Módulos / servicios
- auth: POST /auth/login (10 req/min) → { token 10h, user:{id,name,role} }; GET /auth/profile. Sin registro público.
- users: GET/PATCH/DELETE /users solo admin; password nunca se devuelve, se re-hashea al actualizar.
- ficha_tecnica: CRUD hojas de vida de equipos: cliente, servicio, marca/modelo/serial único, CPU/RAM/disco, garantía, fechas.
- ordenes: Órdenes con estados + timeline de eventos + código de seguimiento público (QR → TRACKING_URL_BASE).
- clientes / empleados / departamentos / leads: Gestión operativa y comercial conectada a fichas y órdenes.
Endpoints principales
| Método | Ruta | Qué hace | Auth |
|---|---|---|---|
GET | / | Health "Hola Mundo!" | x-api-key |
POST | /auth/login {name,password} | Emite JWT 10h + rol | x-api-key |
GET | /users · /users/:id | Listar / detalle (UUID) | JWT admin |
PATCH/DELETE | /users/:id | Actualizar (re-hash) / eliminar | JWT admin |
CRUD | /ficha-tecnica | Hojas de vida; serial único (409 si duplica) | JWT cualquier rol |
CRUD + público | /ordenes · /seguimiento/:code | Gestión interna + consulta pública por QR | JWT / solo x-api-key |
Datos y conexiones
users (id UUID, name UNIQUE, password_hash, role admin|mantenimiento) │ 1──* ficha_tecnica (serialEquipo UNIQUE, cliente, hardware, garantía) │ 1──* ordenes (estado, timeline eventos) ── código seguimiento ──▶ QR clientes · empleados · departamentos · leads ──▶ relacionan fichas/órdenes Ver database.drawio en el repo para el ERD exacto.
- Seed crea admin + mantenimiento (pnpm run seed); no hay endpoint de registro.
- Formato de error uniforme {statusCode, error, message, path, method, timestamp} con 400/401/403/404/409/429 documentados.
Autenticación y seguridad
- Doble capa: header x-api-key global en TODAS las rutas + Bearer JWT en protegidas; rol viaja en el token.
- Validación .env al boot; Helmet, Throttler global 100/60s, CORS por env, DTOs estrictos anti-inyección.
- Nunca commitear .env: JWT_SECRET y API_KEY con openssl rand -hex 32.
Frontend y rutas
/ (home)/servicios/* (redes, cableado CAT6, WiFi, soporte)/sistema (acceso operativo)/seguimiento (consulta pública por código/QR)/blog/*, /nosotros, /contacto, /políticas
- SEO como feature: meta OG/Twitter, hreflang, canonical, sitemap dinámico, breadcrumbs semánticos.
- Formularios con FormSubmit (sin backend propio en el front) + QR con qrcode.react para órdenes.
Despliegue
Dónde: Frontend Vercel (sistekpro.vercel.app) · Backend Render (sistekpro-backend.onrender.com) · PostgreSQL gestionado
- Frontend: npm run build → Astro SSG a Vercel
- Backend: pnpm build && pnpm start:prod (o start:dev con watch); seed previo
- CORS_ORIGIN y TRACKING_URL_BASE apuntando al dominio Vercel
- DB_SSL=true en gestionados; synchronize:false en producción + migraciones
Variables de entorno clave (.env — tú pones los valores):
PORT, CORS_ORIGIN DB_HOST/PORT/USER/PASS/NAME, DB_SSL JWT_SECRET, JWT_EXPIRATION=10h, API_KEY THROTTLE_TTL/LIMIT, TRACKING_URL_BASE SEED_ADMIN_PASSWORD, SEED_MANTENIMIENTO_PASSWORD
Metodología y decisiones
- API-first con API.md como contrato: el frontend se programa contra tablas de endpoints y ejemplos, no contra prueba-error.
- Guías internas de integración y troubleshooting para resolver errores de integración y 401 de forma sistemática.
- Orden de estudio recomendado en README (del main.ts → capas → flujos) para onboarding rápido de reclutadores/devs.
Retos y soluciones
Qué aprendí
- Construir un sistema empresa-real: marketing + operación en dos repos coordinados.
- Auth por roles con doble llave y seed seguro.
- SEO técnico + Deploy desacoplado Vercel/Render.
Ejecutar en local
Frontend: git clone https://github.com/xenoxf/systekpro && npm install && npm run dev (→ :4321) Backend: git clone https://github.com/xenoxf/sistekpro-backend && pnpm install Crear .env según README §3 (DB + JWT_SECRET + API_KEY) createdb sistekpro_db && pnpm run seed && pnpm run start:dev (→ :3000)
Próximos pasos
- Migraciones TypeORM y CI con tests Jest + e2e.
- Adjuntos/fotos de equipos en fichas (S3/Cloudinary).
- Notificaciones por estado de orden (email/WhatsApp).