From 7b91499c873dc5ba96dd2eba470ad67bef74d6f9 Mon Sep 17 00:00:00 2001 From: Jessica Orozco Date: Mon, 15 Jun 2026 14:52:25 -0400 Subject: [PATCH] feat: initialize monorepo structure with NestJS backend, Angular frontend, and project documentation standards --- .env | 26 +++++++ .env.local.template | 26 +++++++ AGENT.md | 57 ++++++++++++++ INICIO-AQUI.md | 75 ++++++++++++++++++ backend/.env | 26 +++++++ backend/package.json | 29 +++++++ backend/src/app.module.ts | 19 +++++ backend/src/auth/auth.module.ts | 4 + backend/src/cms/cms.module.ts | 4 + backend/src/directory/directory.module.ts | 4 + backend/src/main.ts | 11 +++ backend/src/spaces/spaces.module.ts | 4 + backend/src/ticketing/ticketing.module.ts | 4 + backend/src/workflow/workflow.module.ts | 4 + backend/tsconfig.json | 21 +++++ docker-compose.yml | 30 ++++++++ frontend/angular.json | 75 ++++++++++++++++++ frontend/package.json | 31 ++++++++ frontend/src/app/app.component.ts | 27 +++++++ frontend/src/app/app.config.ts | 10 +++ frontend/src/app/app.routes.ts | 14 ++++ .../features/dashboard/dashboard.component.ts | 25 ++++++ frontend/src/index.html | 13 ++++ frontend/src/main.ts | 6 ++ frontend/src/styles.css | 31 ++++++++ frontend/tsconfig.json | 32 ++++++++ logs/app.log | 0 package.json | 20 +++++ setup.ps1 | 32 ++++++++ setup.sh | 27 +++++++ standards/01-subagents-prompts.md | 60 +++++++++++++++ standards/02-database-schema.md | 76 +++++++++++++++++++ standards/03-active-directory-sso.md | 42 ++++++++++ standards/04-ui-ux-neon.md | 35 +++++++++ 34 files changed, 900 insertions(+) create mode 100644 .env create mode 100644 .env.local.template create mode 100644 AGENT.md create mode 100644 INICIO-AQUI.md create mode 100644 backend/.env create mode 100644 backend/package.json create mode 100644 backend/src/app.module.ts create mode 100644 backend/src/auth/auth.module.ts create mode 100644 backend/src/cms/cms.module.ts create mode 100644 backend/src/directory/directory.module.ts create mode 100644 backend/src/main.ts create mode 100644 backend/src/spaces/spaces.module.ts create mode 100644 backend/src/ticketing/ticketing.module.ts create mode 100644 backend/src/workflow/workflow.module.ts create mode 100644 backend/tsconfig.json create mode 100644 docker-compose.yml create mode 100644 frontend/angular.json create mode 100644 frontend/package.json create mode 100644 frontend/src/app/app.component.ts create mode 100644 frontend/src/app/app.config.ts create mode 100644 frontend/src/app/app.routes.ts create mode 100644 frontend/src/app/features/dashboard/dashboard.component.ts create mode 100644 frontend/src/index.html create mode 100644 frontend/src/main.ts create mode 100644 frontend/src/styles.css create mode 100644 frontend/tsconfig.json create mode 100644 logs/app.log create mode 100644 package.json create mode 100644 setup.ps1 create mode 100644 setup.sh create mode 100644 standards/01-subagents-prompts.md create mode 100644 standards/02-database-schema.md create mode 100644 standards/03-active-directory-sso.md create mode 100644 standards/04-ui-ux-neon.md diff --git a/.env b/.env new file mode 100644 index 0000000..02c4fcc --- /dev/null +++ b/.env @@ -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" diff --git a/.env.local.template b/.env.local.template new file mode 100644 index 0000000..02c4fcc --- /dev/null +++ b/.env.local.template @@ -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" diff --git a/AGENT.md b/AGENT.md new file mode 100644 index 0000000..420d04b --- /dev/null +++ b/AGENT.md @@ -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 `. + - 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). diff --git a/INICIO-AQUI.md b/INICIO-AQUI.md new file mode 100644 index 0000000..5820019 --- /dev/null +++ b/INICIO-AQUI.md @@ -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 `. +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. diff --git a/backend/.env b/backend/.env new file mode 100644 index 0000000..02c4fcc --- /dev/null +++ b/backend/.env @@ -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" diff --git a/backend/package.json b/backend/package.json new file mode 100644 index 0000000..ee90641 --- /dev/null +++ b/backend/package.json @@ -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" + } +} diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts new file mode 100644 index 0000000..e11aa55 --- /dev/null +++ b/backend/src/app.module.ts @@ -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 {} diff --git a/backend/src/auth/auth.module.ts b/backend/src/auth/auth.module.ts new file mode 100644 index 0000000..7459c06 --- /dev/null +++ b/backend/src/auth/auth.module.ts @@ -0,0 +1,4 @@ +import { Module } from '@nestjs/common'; + +@Module({}) +export class AuthModule {} diff --git a/backend/src/cms/cms.module.ts b/backend/src/cms/cms.module.ts new file mode 100644 index 0000000..099cb57 --- /dev/null +++ b/backend/src/cms/cms.module.ts @@ -0,0 +1,4 @@ +import { Module } from '@nestjs/common'; + +@Module({}) +export class CmsModule {} diff --git a/backend/src/directory/directory.module.ts b/backend/src/directory/directory.module.ts new file mode 100644 index 0000000..d7de123 --- /dev/null +++ b/backend/src/directory/directory.module.ts @@ -0,0 +1,4 @@ +import { Module } from '@nestjs/common'; + +@Module({}) +export class DirectoryModule {} diff --git a/backend/src/main.ts b/backend/src/main.ts new file mode 100644 index 0000000..9c2a643 --- /dev/null +++ b/backend/src/main.ts @@ -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(); diff --git a/backend/src/spaces/spaces.module.ts b/backend/src/spaces/spaces.module.ts new file mode 100644 index 0000000..a652a8a --- /dev/null +++ b/backend/src/spaces/spaces.module.ts @@ -0,0 +1,4 @@ +import { Module } from '@nestjs/common'; + +@Module({}) +export class SpacesModule {} diff --git a/backend/src/ticketing/ticketing.module.ts b/backend/src/ticketing/ticketing.module.ts new file mode 100644 index 0000000..3952d7d --- /dev/null +++ b/backend/src/ticketing/ticketing.module.ts @@ -0,0 +1,4 @@ +import { Module } from '@nestjs/common'; + +@Module({}) +export class TicketingModule {} diff --git a/backend/src/workflow/workflow.module.ts b/backend/src/workflow/workflow.module.ts new file mode 100644 index 0000000..f21e9c6 --- /dev/null +++ b/backend/src/workflow/workflow.module.ts @@ -0,0 +1,4 @@ +import { Module } from '@nestjs/common'; + +@Module({}) +export class WorkflowModule {} diff --git a/backend/tsconfig.json b/backend/tsconfig.json new file mode 100644 index 0000000..95f5641 --- /dev/null +++ b/backend/tsconfig.json @@ -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 + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..cc872f5 --- /dev/null +++ b/docker-compose.yml @@ -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: diff --git a/frontend/angular.json b/frontend/angular.json new file mode 100644 index 0000000..840d84c --- /dev/null +++ b/frontend/angular.json @@ -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" + } + } + } + } +} diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..cdde0c8 --- /dev/null +++ b/frontend/package.json @@ -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" + } +} diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts new file mode 100644 index 0000000..b7c958b --- /dev/null +++ b/frontend/src/app/app.component.ts @@ -0,0 +1,27 @@ +import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + selector: 'app-root', + standalone: true, + imports: [RouterOutlet], + template: ` +
+
+

+ KINETIX INTRANET +

+
MODULAR AGENT ARCHITECTURE
+
+ +
+ +
+ +
+ © 2026 Kinetix Corp. All rights reserved. +
+
+ ` +}) +export class AppComponent {} diff --git a/frontend/src/app/app.config.ts b/frontend/src/app/app.config.ts new file mode 100644 index 0000000..336f76b --- /dev/null +++ b/frontend/src/app/app.config.ts @@ -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) + ] +}; diff --git a/frontend/src/app/app.routes.ts b/frontend/src/app/app.routes.ts new file mode 100644 index 0000000..b483ded --- /dev/null +++ b/frontend/src/app/app.routes.ts @@ -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. diff --git a/frontend/src/app/features/dashboard/dashboard.component.ts b/frontend/src/app/features/dashboard/dashboard.component.ts new file mode 100644 index 0000000..9b25dc1 --- /dev/null +++ b/frontend/src/app/features/dashboard/dashboard.component.ts @@ -0,0 +1,25 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-dashboard', + standalone: true, + template: ` +
+
+

CMS & Contenidos

+

Gestiona los blogs corporativos y bases de conocimiento corporativos.

+
+ +
+

Directorio Corporativo

+

Encuentra y visualiza la estructura jerárquica de la empresa.

+
+ +
+

Gestión de Espacios

+

Reserva salas de reuniones, oficinas y estacionamientos de forma ágil.

+
+
+ ` +}) +export class DashboardComponent {} diff --git a/frontend/src/index.html b/frontend/src/index.html new file mode 100644 index 0000000..17d3450 --- /dev/null +++ b/frontend/src/index.html @@ -0,0 +1,13 @@ + + + + + Kinetix Intranet + + + + + + + + diff --git a/frontend/src/main.ts b/frontend/src/main.ts new file mode 100644 index 0000000..35b00f3 --- /dev/null +++ b/frontend/src/main.ts @@ -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)); diff --git a/frontend/src/styles.css b/frontend/src/styles.css new file mode 100644 index 0000000..ee021fc --- /dev/null +++ b/frontend/src/styles.css @@ -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); +} diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json new file mode 100644 index 0000000..886b7ea --- /dev/null +++ b/frontend/tsconfig.json @@ -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 + } +} diff --git a/logs/app.log b/logs/app.log new file mode 100644 index 0000000..e69de29 diff --git a/package.json b/package.json new file mode 100644 index 0000000..210a89c --- /dev/null +++ b/package.json @@ -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" + } +} diff --git a/setup.ps1 b/setup.ps1 new file mode 100644 index 0000000..6968035 --- /dev/null +++ b/setup.ps1 @@ -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." diff --git a/setup.sh b/setup.sh new file mode 100644 index 0000000..8fb9b1a --- /dev/null +++ b/setup.sh @@ -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." diff --git a/standards/01-subagents-prompts.md b/standards/01-subagents-prompts.md new file mode 100644 index 0000000..5e119a9 --- /dev/null +++ b/standards/01-subagents-prompts.md @@ -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. diff --git a/standards/02-database-schema.md b/standards/02-database-schema.md new file mode 100644 index 0000000..2e938b1 --- /dev/null +++ b/standards/02-database-schema.md @@ -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 +} +``` diff --git a/standards/03-active-directory-sso.md b/standards/03-active-directory-sso.md new file mode 100644 index 0000000..ec233ef --- /dev/null +++ b/standards/03-active-directory-sso.md @@ -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. diff --git a/standards/04-ui-ux-neon.md b/standards/04-ui-ux-neon.md new file mode 100644 index 0000000..7533539 --- /dev/null +++ b/standards/04-ui-ux-neon.md @@ -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.