feat: initialize monorepo structure with NestJS backend, Angular frontend, and project documentation standards

This commit is contained in:
Jessica Orozco 2026-06-15 14:52:25 -04:00
commit 7b91499c87
34 changed files with 900 additions and 0 deletions

26
.env Normal file
View File

@ -0,0 +1,26 @@
# Kinetix Intranet - Environment Variables Template
# ==========================================
# BACKEND (NestJS) CONFIGURATION
# ==========================================
PORT=3000
NODE_ENV=development
# Database Settings (PostgreSQL / Supabase)
DATABASE_URL="postgresql://admin:supersecretpassword123@localhost:5432/kinetix_db?schema=public"
# SUPABASE_URL="https://your-project.supabase.co"
# SUPABASE_KEY="your-anon-key"
# Active Directory / Azure AD SSO Config
AD_TENANT_ID="your-azure-tenant-id"
AD_CLIENT_ID="your-azure-client-id"
AD_CLIENT_SECRET="your-azure-client-secret"
AD_REDIRECT_URI="http://localhost:3000/api/auth/callback"
JWT_SECRET="kinetix-super-jwt-secret-key-2026"
# ==========================================
# FRONTEND (Angular) CONFIGURATION
# ==========================================
NG_APP_API_URL="http://localhost:3000/api"
NG_APP_AD_CLIENT_ID="your-azure-client-id"
NG_APP_AD_TENANT_ID="your-azure-tenant-id"

26
.env.local.template Normal file
View File

@ -0,0 +1,26 @@
# Kinetix Intranet - Environment Variables Template
# ==========================================
# BACKEND (NestJS) CONFIGURATION
# ==========================================
PORT=3000
NODE_ENV=development
# Database Settings (PostgreSQL / Supabase)
DATABASE_URL="postgresql://admin:supersecretpassword123@localhost:5432/kinetix_db?schema=public"
# SUPABASE_URL="https://your-project.supabase.co"
# SUPABASE_KEY="your-anon-key"
# Active Directory / Azure AD SSO Config
AD_TENANT_ID="your-azure-tenant-id"
AD_CLIENT_ID="your-azure-client-id"
AD_CLIENT_SECRET="your-azure-client-secret"
AD_REDIRECT_URI="http://localhost:3000/api/auth/callback"
JWT_SECRET="kinetix-super-jwt-secret-key-2026"
# ==========================================
# FRONTEND (Angular) CONFIGURATION
# ==========================================
NG_APP_API_URL="http://localhost:3000/api"
NG_APP_AD_CLIENT_ID="your-azure-client-id"
NG_APP_AD_TENANT_ID="your-azure-tenant-id"

57
AGENT.md Normal file
View File

@ -0,0 +1,57 @@
# AGENT.md — Intranet Architect Agent
## Sistema Cognitivo Modular · NestJS (Backend) + Angular 17+ (Frontend) + Active Directory SSO + PostgreSQL
> Este archivo es el system prompt principal del agente para Kinetix.
> Se carga automáticamente en cada sesión de IA para proveer guías y convenciones arquitectónicas.
---
## Rol del Agente Principal
**Senior Intranet Architect & Full-Stack Engineer** (Experto en NestJS, Angular Standalone, Signals, Active Directory/SSO y diseño de bases de datos relacionales).
---
## Stack Técnico del Monorepo
```
Backend: NestJS (TypeScript) + Prisma (u ORM) + Passport.js (SSO Active Directory)
Frontend: Angular 17+ (Signals, Standalone components, `@for` flow control)
Estilos: Vanilla CSS / TailwindCSS + daisyUI (estilo Vercel/Neon/Cyberpunk)
Database: PostgreSQL / Supabase (Reservas, Workflow, Organigramas)
SSO: OAuth2 / Azure AD (Entra ID) con Tokens JWT intercambiados en cabeceras HTTP
```
---
## Arquitectura de Subagentes Especializados
Para este desarrollo, el Agente Principal coordina a 5 subagentes especializados, cada uno mapeado a un módulo específico en backend (`backend/src/...`) y frontend (`frontend/src/app/features/...`):
1. **Agente de Gestión de Contenidos (CMS)**
- *Dominio:* Editor de artículos corporativos (WYSIWYG/Markdown), taxonomías y buscador indexado.
2. **Agente de Directorios Corporativos (IAM/HR)**
- *Dominio:* Perfiles de empleados, cargos, departamentos, e integración LDAP/Active Directory para lecturas de organigrama.
3. **Agente de Workflow de Aprobación y Publicación (BPM & Redes)**
- *Dominio:* Gestión de estados de aprobación de contenidos, publicación automática y APIs de redes sociales (LinkedIn, X).
4. **Agente de Gestión de Espacios (PMS)**
- *Dominio:* Reservas y disponibilidad de salas de reuniones, oficinas y parqueo mediante calendarios dinámicos.
5. **Agente de Requerimientos e Incidencias (Ticketing)**
- *Dominio:* Creación, flujo y asignación de tickets internos, gestión de SLAs y prioridades de soporte.
---
## Directrices de Desarrollo & Seguridad (Reglas de Oro)
1. **Seguridad y Autenticación SSO:**
- La autenticación se delega a Active Directory. El frontend Angular redirige al SSO y obtiene el token JWT de ID.
- El token JWT se envía al backend NestJS en el header `Authorization: Bearer <token>`.
- El backend valida el JWT con `passport-azure-ad` / `passport-jwt` y extrae el perfil del empleado (`user.email`, `user.roles`).
2. **Modularidad en NestJS:**
- Cada subagente debe tener su propio módulo aislado (ej: `CmsModule`, `WorkflowModule`) en `backend/src/`.
- Utilizar inyección de dependencias limpia y evitar acoplamientos innecesarios.
3. **Reactividad en Angular:**
- Utilizar **Signals** (`signal`, `computed`, `effect`) para estados locales e interactividad del cliente.
- Emplear el nuevo flujo de control declarativo (`@for`, `@if`, `@switch`).
- Todos los componentes nuevos deben ser **Standalone**.
4. **Alineación de Base de Datos:**
- Diseñar y ejecutar migraciones de PostgreSQL con Prisma para asegurar transaccionalidad robusta (especialmente en reservas de espacios para evitar overbooking).

75
INICIO-AQUI.md Normal file
View File

@ -0,0 +1,75 @@
# INICIO-AQUI.md — Guía de Onboarding Kinetix Intranet
## La guía técnica única para desarrolladores y agentes de IA
**Para:** Cualquier desarrollador o agente de IA que trabaje en el monorepo Kinetix.
**Stack Principal:** Angular 17+ & NestJS + PostgreSQL.
---
## Estructura del Monorepo
```
Kinetix/
├── AGENT.md ← System Prompt principal de la IA (no borrar)
├── INICIO-AQUI.md ← Este archivo
├── package.json ← Scripts del monorepo
├── docker-compose.yml ← Contenedor de base de datos PostgreSQL local
├── setup.ps1 / setup.sh ← Scripts de aprovisionamiento de entorno
├── backend/ ← API REST en NestJS
│ ├── src/
│ │ ├── auth/ ← Módulo de SSO Active Directory / JWT
│ │ ├── cms/ ← Módulo de Gestión de Contenidos
│ │ ├── directory/ ← Módulo de Directorios Corporativos
│ │ ├── workflow/ ← Módulo de Workflow de Aprobación
│ │ ├── spaces/ ← Módulo de Reservas de Espacios
│ │ └── ticketing/ ← Módulo de Incidencias (Ticketing)
│ └── package.json
├── frontend/ ← SPA en Angular 17+
│ ├── src/app/
│ │ ├── core/ ← Guardias de SSO, interceptores HTTP, auth services
│ │ ├── shared/ ← Componentes comunes estilo Neon/Cyberpunk
│ │ └── features/ ← Módulos visuales correspondientes a cada subagente
│ └── package.json
└── standards/ ← Estándares del proyecto
├── 01-subagents-prompts.md ← Prompts e instrucciones para cada subagente
├── 02-database-schema.md ← Modelado e integridad PostgreSQL
├── 03-active-directory-sso.md ← Flujo de autenticación detallado
└── 04-ui-ux-neon.md ← Directrices de diseño Neon/Cyberpunk/Vercel
```
---
## Paso 1: Configurar el Entorno
Ejecuta el script de configuración correspondiente a tu sistema operativo en la raíz del proyecto para copiar la plantilla de variables de entorno y preparar el workspace:
```bash
# Windows (PowerShell):
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process; .\setup.ps1
# Linux / macOS (Bash):
chmod +x setup.sh && ./setup.sh
```
---
## Paso 2: Iniciar Base de Datos Local
Levanta el contenedor de PostgreSQL para desarrollo local:
```bash
docker-compose up -d
```
Esto creará la base de datos `kinetix_db` expuesta en `localhost:5432` y pgAdmin en `http://localhost:5050` con las credenciales configuradas en el archivo `.env`.
---
## Paso 3: Flujo de Autenticación Integrado (Active Directory SSO)
1. El cliente entra en la app Angular. Si no está autenticado, el guardia de SSO lo redirige al portal institucional de Microsoft Entra ID.
2. Al ingresar sus credenciales institucionales, se le retorna un JWT.
3. El frontend Angular intercepta las llamadas HTTP e inyecta el JWT en la cabecera `Authorization: Bearer <JWT>`.
4. El backend NestJS valida el token en el módulo `auth` y le da acceso a los endpoints correspondientes según su rol en la organización.

26
backend/.env Normal file
View File

@ -0,0 +1,26 @@
# Kinetix Intranet - Environment Variables Template
# ==========================================
# BACKEND (NestJS) CONFIGURATION
# ==========================================
PORT=3000
NODE_ENV=development
# Database Settings (PostgreSQL / Supabase)
DATABASE_URL="postgresql://admin:supersecretpassword123@localhost:5432/kinetix_db?schema=public"
# SUPABASE_URL="https://your-project.supabase.co"
# SUPABASE_KEY="your-anon-key"
# Active Directory / Azure AD SSO Config
AD_TENANT_ID="your-azure-tenant-id"
AD_CLIENT_ID="your-azure-client-id"
AD_CLIENT_SECRET="your-azure-client-secret"
AD_REDIRECT_URI="http://localhost:3000/api/auth/callback"
JWT_SECRET="kinetix-super-jwt-secret-key-2026"
# ==========================================
# FRONTEND (Angular) CONFIGURATION
# ==========================================
NG_APP_API_URL="http://localhost:3000/api"
NG_APP_AD_CLIENT_ID="your-azure-client-id"
NG_APP_AD_TENANT_ID="your-azure-tenant-id"

29
backend/package.json Normal file
View File

@ -0,0 +1,29 @@
{
"name": "kinetix-backend",
"version": "1.0.0",
"private": true,
"scripts": {
"build": "nest build",
"start": "nest start",
"start:dev": "nest start --watch",
"start:prod": "node dist/main"
},
"dependencies": {
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
"@nestjs/jwt": "^10.0.0",
"@nestjs/passport": "^10.0.0",
"@nestjs/platform-express": "^10.0.0",
"passport": "^0.7.0",
"passport-jwt": "^4.0.1",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1"
},
"devDependencies": {
"@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0",
"@types/node": "^20.0.0",
"@types/passport-jwt": "^4.0.0",
"typescript": "^5.0.0"
}
}

19
backend/src/app.module.ts Normal file
View File

@ -0,0 +1,19 @@
import { Module } from '@nestjs/common';
import { AuthModule } from './auth/auth.module';
import { CmsModule } from './cms/cms.module';
import { DirectoryModule } from './directory/directory.module';
import { WorkflowModule } from './workflow/workflow.module';
import { SpacesModule } from './spaces/spaces.module';
import { TicketingModule } from './ticketing/ticketing.module';
@Module({
imports: [
AuthModule,
CmsModule,
DirectoryModule,
WorkflowModule,
SpacesModule,
TicketingModule,
],
})
export class AppModule {}

View File

@ -0,0 +1,4 @@
import { Module } from '@nestjs/common';
@Module({})
export class AuthModule {}

View File

@ -0,0 +1,4 @@
import { Module } from '@nestjs/common';
@Module({})
export class CmsModule {}

View File

@ -0,0 +1,4 @@
import { Module } from '@nestjs/common';
@Module({})
export class DirectoryModule {}

11
backend/src/main.ts Normal file
View File

@ -0,0 +1,11 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('api');
app.enableCors();
await app.listen(process.env.PORT || 3000);
console.log(`Backend server running on: ${await app.getUrl()}`);
}
bootstrap();

View File

@ -0,0 +1,4 @@
import { Module } from '@nestjs/common';
@Module({})
export class SpacesModule {}

View File

@ -0,0 +1,4 @@
import { Module } from '@nestjs/common';
@Module({})
export class TicketingModule {}

View File

@ -0,0 +1,4 @@
import { Module } from '@nestjs/common';
@Module({})
export class WorkflowModule {}

21
backend/tsconfig.json Normal file
View File

@ -0,0 +1,21 @@
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "ES2021",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": false,
"noImplicitAny": false,
"strictBindCallApply": false,
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false
}
}

30
docker-compose.yml Normal file
View File

@ -0,0 +1,30 @@
version: '3.8'
services:
postgres:
image: postgres:15-alpine
container_name: kinetix-postgres
restart: always
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: supersecretpassword123
POSTGRES_DB: kinetix_db
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
pgadmin:
image: dpage/pgadmin4
container_name: kinetix-pgadmin
restart: always
environment:
PGADMIN_DEFAULT_EMAIL: admin@kinetix.com
PGADMIN_DEFAULT_PASSWORD: adminpassword123
ports:
- "5050:80"
depends_on:
- postgres
volumes:
postgres_data:

75
frontend/angular.json Normal file
View File

@ -0,0 +1,75 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"kinetix-frontend": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"standalone": true
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"options": {
"outputPath": "dist/kinetix-frontend",
"index": "src/index.html",
"browser": "src/main.ts",
"polyfills": [
"zone.js"
],
"tsConfig": "tsconfig.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"outputHashing": "all"
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"buildTarget": "kinetix-frontend:build:production"
},
"development": {
"buildTarget": "kinetix-frontend:build:development"
}
},
"defaultConfiguration": "development"
}
}
}
}
}

31
frontend/package.json Normal file
View File

@ -0,0 +1,31 @@
{
"name": "kinetix-frontend",
"version": "1.0.0",
"private": true,
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development"
},
"dependencies": {
"@angular/animations": "^18.0.0",
"@angular/common": "^18.0.0",
"@angular/compiler": "^18.0.0",
"@angular/core": "^18.0.0",
"@angular/forms": "^18.0.0",
"@angular/platform-browser": "^18.0.0",
"@angular/platform-browser-dynamic": "^18.0.0",
"@angular/router": "^18.0.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"
},
"devDependencies": {
"@angular-devkit/build-angular": "^18.0.0",
"@angular/cli": "^18.0.0",
"@angular/compiler-cli": "^18.0.0",
"@types/node": "^18.11.12",
"typescript": "~5.4.2"
}
}

View File

@ -0,0 +1,27 @@
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet],
template: `
<main class="min-h-screen flex flex-col justify-between p-6 bg-[#0a0a0c]">
<header class="flex justify-between items-center border-b border-white/10 pb-4 mb-6">
<h1 class="text-2xl font-extrabold tracking-wider text-transparent bg-clip-text bg-gradient-to-r from-cyan-400 to-blue-500">
KINETIX INTRANET
</h1>
<div class="text-xs text-white/50">MODULAR AGENT ARCHITECTURE</div>
</header>
<section class="flex-grow">
<router-outlet></router-outlet>
</section>
<footer class="border-t border-white/5 pt-4 mt-6 text-center text-xs text-white/30">
© 2026 Kinetix Corp. All rights reserved.
</footer>
</main>
`
})
export class AppComponent {}

View File

@ -0,0 +1,10 @@
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes)
]
};

View File

@ -0,0 +1,14 @@
import { Routes } from '@angular/router';
export const routes: Routes = [
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
},
{
path: 'dashboard',
loadComponent: () => import('./features/dashboard/dashboard.component').then(m => m.DashboardComponent)
}
];
// Modules for each subagent will be lazily loaded here.

View File

@ -0,0 +1,25 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-dashboard',
standalone: true,
template: `
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 p-6">
<div class="glass-panel p-6 rounded-xl neon-border">
<h2 class="text-lg font-bold text-cyan-400 mb-2">CMS & Contenidos</h2>
<p class="text-sm text-white/70">Gestiona los blogs corporativos y bases de conocimiento corporativos.</p>
</div>
<div class="glass-panel p-6 rounded-xl neon-border">
<h2 class="text-lg font-bold text-magenta-400 mb-2">Directorio Corporativo</h2>
<p class="text-sm text-white/70">Encuentra y visualiza la estructura jerárquica de la empresa.</p>
</div>
<div class="glass-panel p-6 rounded-xl neon-border">
<h2 class="text-lg font-bold text-green-400 mb-2">Gestión de Espacios</h2>
<p class="text-sm text-white/70">Reserva salas de reuniones, oficinas y estacionamientos de forma ágil.</p>
</div>
</div>
`
})
export class DashboardComponent {}

13
frontend/src/index.html Normal file
View File

@ -0,0 +1,13 @@
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Kinetix Intranet</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body class="bg-black text-white antialiased">
<app-root></app-root>
</body>
</html>

6
frontend/src/main.ts Normal file
View File

@ -0,0 +1,6 @@
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, appConfig)
.catch((err) => console.error(err));

31
frontend/src/styles.css Normal file
View File

@ -0,0 +1,31 @@
/* Root Styles for Kinetix Neon Theme */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;800&display=swap');
:root {
font-family: 'Inter', sans-serif;
color-scheme: dark;
}
body {
margin: 0;
background-color: #0a0a0c;
color: #f3f4f6;
overflow-x: hidden;
}
/* Custom Neon Accents and Vercel-style card system */
.neon-border {
border: 1px solid rgba(255, 255, 255, 0.08);
transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.neon-border:hover {
border-color: #00f2fe;
box-shadow: 0 0 15px rgba(0, 242, 254, 0.15);
}
.glass-panel {
background: rgba(15, 15, 20, 0.7);
backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.08);
}

32
frontend/tsconfig.json Normal file
View File

@ -0,0 +1,32 @@
{
"compileOnSave": false,
"compilerOptions": {
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"skipLibCheck": true,
"eslint.enable": true,
"sourceMap": true,
"declaration": false,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "ES2022",
"module": "ES2022",
"useDefineForClassFields": false,
"lib": [
"ES2022",
"dom"
]
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}

0
logs/app.log Normal file
View File

20
package.json Normal file
View File

@ -0,0 +1,20 @@
{
"name": "kinetix-monorepo",
"version": "1.0.0",
"private": true,
"workspaces": [
"frontend",
"backend"
],
"scripts": {
"setup": "powershell -ExecutionPolicy Bypass -File ./setup.ps1",
"dev:frontend": "cd frontend && npm run start",
"dev:backend": "cd backend && npm run start:dev",
"build:all": "npm run build --workspaces",
"docker:up": "docker-compose up -d",
"docker:down": "docker-compose down"
},
"devDependencies": {
"concurrently": "^8.2.2"
}
}

32
setup.ps1 Normal file
View File

@ -0,0 +1,32 @@
# setup.ps1
Write-Output "=== Iniciando configuración de Kinetix Intranet Monorepo ==="
# 1. Copiar archivo de entorno si no existe
if (!(Test-Path ".env")) {
Write-Output "[SETUP] Creando .env desde plantilla..."
Copy-Item ".env.local.template" ".env"
} else {
Write-Output "[SETUP] .env ya existe."
}
# Copiar al backend y frontend si lo requieren
if (!(Test-Path "backend/.env")) {
if (Test-Path "backend") {
Copy-Item ".env.local.template" "backend/.env"
}
}
# 2. Crear carpetas de logs
if (!(Test-Path "logs")) {
$null = New-Item -ItemType Directory -Path "logs" -Force
}
if (!(Test-Path "logs/app.log")) {
$null = New-Item -ItemType File -Path "logs/app.log" -Force
}
# 3. Instalar dependencias en raíz
Write-Output "[SETUP] Instalando dependencias de monorepo..."
npm install --no-audit
Write-Output "=== Configuración básica completa! ==="
Write-Output "Ejecuta 'docker-compose up -d' para levantar la Base de Datos."

27
setup.sh Normal file
View File

@ -0,0 +1,27 @@
#!/bin/bash
# setup.sh
echo "=== Iniciando configuración de Kinetix Intranet Monorepo ==="
# 1. Copiar archivo de entorno si no existe
if [ ! -f .env ]; then
echo "[SETUP] Creando .env desde plantilla..."
cp .env.local.template .env
else
echo "[SETUP] .env ya existe."
fi
# Copiar al backend y frontend si lo requieren
if [ -d backend ] && [ ! -f backend/.env ]; then
cp .env.local.template backend/.env
fi
# 2. Crear carpetas de logs
mkdir -p logs
touch logs/app.log
# 3. Instalar dependencias en raíz
echo "[SETUP] Instalando dependencias de monorepo..."
npm install --no-audit
echo "=== Configuración básica completa! ==="
echo "Ejecuta 'docker-compose up -d' para levantar la Base de Datos."

View File

@ -0,0 +1,60 @@
# Estándares - Prompts de Subagentes Especializados
Este documento define el rol, contexto y tareas específicas para cada subagente. Al delegar trabajo, pasa este prompt directamente al subagente.
---
## 1. Agente de Gestión de Contenidos (CMS / Blog)
- **Rol:** CMS & Knowledge Management Specialist.
- **Contexto:** Encargado del "Block de Información" de la intranet. Este módulo almacena noticias, políticas internas y guías del conocimiento corporativo.
- **Backend (NestJS):** `CmsModule`
- Crear endpoints para CRUD de artículos, categorías y etiquetas.
- Implementar historial de versiones de artículos.
- **Frontend (Angular):** `/features/cms`
- Crear un visor de artículos en Markdown / WYSIWYG.
- Diseñar una interfaz de categorías y taxonomías para filtrado rápido.
---
## 2. Agente de Directorios Corporativos (IAM / HR)
- **Rol:** Identity & Access Management (IAM) Specialist.
- **Contexto:** Diseña y gestiona el directorio de empleados, organigramas y detalles de contacto.
- **Backend (NestJS):** `DirectoryModule`
- Conexión LDAP / Active Directory para consultar perfiles de empleados.
- APIs para exponer datos del perfil (nombre, cargo, departamento, contacto, jefe directo).
- **Frontend (Angular):** `/features/directory`
- Buscador inteligente de empleados con autocompletado y filtros de departamento.
- Renderizador dinámico del organigrama jerárquico corporativo usando CSS o componentes SVG interactivos.
---
## 3. Agente de Workflow de Aprobación y Publicación (BPM & Redes)
- **Rol:** Business Process Management & Integration Specialist.
- **Contexto:** El motor que controla los estados de los contenidos creados en el CMS (Borrador -> Pendiente -> Aprobado -> Publicado). Una vez aprobado, gestiona la publicación automatizada en redes configuradas (LinkedIn, X, etc.).
- **Backend (NestJS):** `WorkflowModule`
- Lógica de estados con transiciones seguras.
- Integración con colas de mensajería o temporizadores para posts en redes externas.
- **Frontend (Angular):** `/features/workflow`
- Panel de aprobación multinivel para gerentes con botones de Aprobar/Rechazar y registro de notas de revisión.
---
## 4. Agente de Gestión de Espacios (PMS / Reservas)
- **Rol:** Property Management System (PMS) & Calendar Specialist.
- **Contexto:** Autogestión de alquiler y reserva de salas de reuniones, oficinas temporales y parqueos corporativos.
- **Backend (NestJS):** `SpacesModule`
- APIs para disponibilidad por fecha y rango de horas.
- Transacciones atómicas en PostgreSQL para evitar solapamiento de reservas en el mismo horario.
- **Frontend (Angular):** `/features/spaces`
- Calendario interactivo (mensual/semanal/diario) para visualización en tiempo real y reserva de espacios en un par de clics.
---
## 5. Agente de Requerimientos e Incidencias (Ticketing)
- **Rol:** IT Service Management (ITSM) Specialist.
- **Contexto:** Service Desk para que los usuarios reporten fallas técnicas, solicitudes de recursos humanos u otras incidencias corporativas.
- **Backend (NestJS):** `TicketingModule`
- Gestión de prioridades (Alta, Media, Baja) y cálculo automático del SLA de resolución.
- Lógica de asignación automática de tickets al equipo de soporte adecuado.
- **Frontend (Angular):** `/features/ticketing`
- Formulario de creación de incidencias y dashboard de seguimiento con líneas de tiempo del estado del ticket.

View File

@ -0,0 +1,76 @@
# Estándares - Modelado e Integridad PostgreSQL (Prisma)
El proyecto utiliza **PostgreSQL** para persistencia estructurada y transaccionalidad. A continuación se detallan las directrices y los esquemas clave.
---
## 1. Reglas Generales de Base de Datos
- **Transacciones de Reservas:** Las reservas de espacios deben usar exclusión mutua en consultas o bloqueos optimistas para asegurar que no ocurran solapamientos de reservas.
- **Relaciones Claras:** Los artículos del CMS se relacionan con el perfil de usuario del Directorio.
- **Trazabilidad:** Cada cambio de estado de un ticket o workflow de publicación debe registrar una fila en una tabla de auditoría (`StateHistory`).
---
## 2. Esquema Conceptual (Prisma Schema Reference)
```prisma
// Esquema de Base de Datos Kinetix Intranet
model User {
id String @id @default(uuid())
email String @unique
name String
role String // 'EMPLOYEE', 'MANAGER', 'ADMIN'
department String
position String
phoneNumber String?
managerId String?
manager User? @relation("Hierarchy", fields: [managerId], references: [id])
subordinates User[] @relation("Hierarchy")
articles Article[]
reservations Reservation[]
tickets Ticket[] @relation("UserTickets")
assignedTickets Ticket[] @relation("AgentTickets")
createdAt DateTime @default(now())
}
model Article {
id String @id @default(uuid())
title String
content String @db.Text
status String // 'DRAFT', 'PENDING', 'APPROVED', 'PUBLISHED'
authorId String
author User @relation(fields: [authorId], references: [id])
category String
tags String[]
version Int @default(1)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Reservation {
id String @id @default(uuid())
spaceName String // 'SALA_A', 'OFICINA_3', 'PARQUEO_12'
spaceType String // 'MEETING_ROOM', 'OFFICE', 'PARKING'
userId String
user User @relation(fields: [userId], references: [id])
startTime DateTime
endTime DateTime
createdAt DateTime @default(now())
}
model Ticket {
id String @id @default(uuid())
title String
description String @db.Text
priority String // 'LOW', 'MEDIUM', 'HIGH', 'CRITICAL'
status String // 'OPEN', 'ASSIGNED', 'RESOLVED', 'CLOSED'
creatorId String
creator User @relation("UserTickets", fields: [creatorId], references: [id])
assigneeId String?
assignee User? @relation("AgentTickets", fields: [assigneeId], references: [id])
slaLimit DateTime
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
```

View File

@ -0,0 +1,42 @@
# Estándares - Autenticación SSO Active Directory & JWT
Este documento detalla el flujo de identidad corporativa entre Angular, NestJS y Active Directory (Azure AD / Entra ID).
---
## 1. Diagrama de Secuencia SSO
```
[ Angular (Cliente) ] ----(1) Iniciar Sesión ----> [ Azure AD SSO Portal ]
[ Angular (Cliente) ] <---(2) Retorna JWT Token --- [ Azure AD SSO Portal ]
[ Angular (Cliente) ] ----(3) GET /api/tickets ----> [ NestJS (Backend) ]
(Authorization Header)
[ NestJS (Backend) ] ----(4) Valida Firma JWT ---> [ Azure AD Keys (JWKS) ]
[ NestJS (Backend) ] <---(5) Token Válido --------- [ Azure AD Keys (JWKS) ]
[ Angular (Cliente) ] <---(6) Respuesta JSON ------- [ NestJS (Backend) ]
```
---
## 2. Contrato de Cabeceras
Toda solicitud HTTP realizada por el frontend hacia los endpoints protegidos del backend debe incluir la cabecera `Authorization`:
```http
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IiJ9...
```
---
## 3. Configuración en NestJS (Passport)
El backend utiliza `passport-jwt` o `passport-azure-ad` para descifrar y validar el token.
### Claims esperados en el JWT decodificado:
- `sub` (Identificador único de usuario)
- `email` (Correo electrónico corporativo, ej: `jess@kinetix.com`)
- `name` (Nombre del empleado)
- `roles` (Roles asignados, ej: `['Employee', 'Manager']`)
- `department` (Departamento de la organización)
---
## 4. Frontend Angular AuthGuard
El interceptor HTTP de Angular inyecta automáticamente el token JWT obtenido desde el store de autenticación en todas las llamadas salientes hacia el backend.

View File

@ -0,0 +1,35 @@
# Estándares - UI/UX Diseño Cyberpunk / Neon / Vercel
Este documento establece la guía de estilos visuales de la intranet corporativa Kinetix.
---
## 1. Paleta de Colores (Estilo Neón)
Para lograr el estilo neón premium e interactivo, la interfaz debe utilizar un fondo oscuro profundo con bordes y brillos acentuados en colores cian, magenta y verde neón.
- **Fondo Principal (Deep Dark):** HSL(240, 10%, 4%)
- **Fondo Secundario (Card Background):** HSL(240, 10%, 9%)
- **Acento Primario (Cian Neón):** HSL(180, 100%, 50%)
- **Acento Secundario (Magenta Neón):** HSL(320, 100%, 50%)
- **Acento de Éxito (Verde Neón):** HSL(140, 100%, 50%)
---
## 2. Efecto Glassmorphism (Vercel Style)
Utilizar bordes ultra finos semitransparentes combinados con desenfoque de fondo (`backdrop-filter`) para crear profundidad tridimensional en los paneles:
```css
.glass-panel {
background: rgba(15, 15, 20, 0.7);
backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.08);
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
}
```
---
## 3. Micro-animaciones e Interactividad
- **Hover Glow:** Los botones interactivos y tarjetas deben tener transiciones suaves (`transition: all 0.3s ease`) que agreguen un brillo sutil al pasar el cursor.
- **Transición de Rutas:** Usar animaciones fluidas en Angular al alternar vistas.
- **Efectos de Foco:** Utilizar anillos de foco cian neón en entradas de texto y controles interactivos para garantizar accesibilidad.