feat: initialize monorepo structure with NestJS backend, Angular frontend, and project documentation standards
This commit is contained in:
commit
7b91499c87
26
.env
Normal file
26
.env
Normal 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
26
.env.local.template
Normal 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
57
AGENT.md
Normal 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
75
INICIO-AQUI.md
Normal 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
26
backend/.env
Normal 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
29
backend/package.json
Normal 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
19
backend/src/app.module.ts
Normal 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 {}
|
||||||
4
backend/src/auth/auth.module.ts
Normal file
4
backend/src/auth/auth.module.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Module({})
|
||||||
|
export class AuthModule {}
|
||||||
4
backend/src/cms/cms.module.ts
Normal file
4
backend/src/cms/cms.module.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Module({})
|
||||||
|
export class CmsModule {}
|
||||||
4
backend/src/directory/directory.module.ts
Normal file
4
backend/src/directory/directory.module.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Module({})
|
||||||
|
export class DirectoryModule {}
|
||||||
11
backend/src/main.ts
Normal file
11
backend/src/main.ts
Normal 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();
|
||||||
4
backend/src/spaces/spaces.module.ts
Normal file
4
backend/src/spaces/spaces.module.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Module({})
|
||||||
|
export class SpacesModule {}
|
||||||
4
backend/src/ticketing/ticketing.module.ts
Normal file
4
backend/src/ticketing/ticketing.module.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Module({})
|
||||||
|
export class TicketingModule {}
|
||||||
4
backend/src/workflow/workflow.module.ts
Normal file
4
backend/src/workflow/workflow.module.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Module({})
|
||||||
|
export class WorkflowModule {}
|
||||||
21
backend/tsconfig.json
Normal file
21
backend/tsconfig.json
Normal 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
30
docker-compose.yml
Normal 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
75
frontend/angular.json
Normal 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
31
frontend/package.json
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
||||||
27
frontend/src/app/app.component.ts
Normal file
27
frontend/src/app/app.component.ts
Normal 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 {}
|
||||||
10
frontend/src/app/app.config.ts
Normal file
10
frontend/src/app/app.config.ts
Normal 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)
|
||||||
|
]
|
||||||
|
};
|
||||||
14
frontend/src/app/app.routes.ts
Normal file
14
frontend/src/app/app.routes.ts
Normal 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.
|
||||||
25
frontend/src/app/features/dashboard/dashboard.component.ts
Normal file
25
frontend/src/app/features/dashboard/dashboard.component.ts
Normal 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
13
frontend/src/index.html
Normal 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
6
frontend/src/main.ts
Normal 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
31
frontend/src/styles.css
Normal 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
32
frontend/tsconfig.json
Normal 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
0
logs/app.log
Normal file
20
package.json
Normal file
20
package.json
Normal 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
32
setup.ps1
Normal 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
27
setup.sh
Normal 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."
|
||||||
60
standards/01-subagents-prompts.md
Normal file
60
standards/01-subagents-prompts.md
Normal 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.
|
||||||
76
standards/02-database-schema.md
Normal file
76
standards/02-database-schema.md
Normal 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
|
||||||
|
}
|
||||||
|
```
|
||||||
42
standards/03-active-directory-sso.md
Normal file
42
standards/03-active-directory-sso.md
Normal 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.
|
||||||
35
standards/04-ui-ux-neon.md
Normal file
35
standards/04-ui-ux-neon.md
Normal 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.
|
||||||
Loading…
x
Reference in New Issue
Block a user