Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ verify Render separately.
- Do not revert user changes. Inspect `git status` first.
- Prefer scoped changes matching existing Angular/Laravel patterns.

## Parallel AI coordination

When Codex and Antigravity work at the same time, read
`docs/colaboracion-ias.md` and the two files under `docs/handoffs/` before
editing. Never work directly on `main`, never force-push a shared branch and do
not modify a file currently owned by the other agent. The account/profile block
belongs in the topbar; it is intentionally absent from the sidebar.

## Docs to read by task

- Overall project state: `docs/ai-project-context.md`
Expand Down
71 changes: 71 additions & 0 deletions ANTIGRAVITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Instrucciones operativas para Antigravity

Este repositorio es producción real. Antes de editar, lee en este orden:

1. `AGENTS.md`;
2. `docs/colaboracion-ias.md`;
3. `docs/handoffs/codex-to-antigravity.md`;
4. `docs/sistema-visual-portal-alumno.md` y `docs/portal-alumno.md` cuando el
alcance sea el portal estudiante.

## Rama y límites

- Trabaja únicamente en `feature/frontend-design-system` o en una rama
`antigravity/<modulo>` creada desde el `origin/main` indicado en el handoff.
- Nunca hagas commit, merge, push o deploy directamente a `main`.
- No modifiques ramas `codex/*`.
- No mezcles más de un módulo funcional por commit.
- No uses `git reset --hard`, force-push ni descartes cambios ajenos.
- Si un archivo aparece modificado antes de empezar, detente sobre ese archivo
y regístralo en el handoff; no lo sobrescribas.

## Contrato funcional

- Angular presenta; Laravel autoriza y persiste.
- XP es progreso permanente y DAEMONS es saldo gastable.
- Un `401` invalida la sesión; permisos insuficientes deben responder `403`.
- No elimines rutas, botones, estados, IDs de tour, respuestas de error ni
acciones existentes para simplificar una pantalla.
- La ficha redundante de usuario se eliminó intencionalmente del sidebar. El
enlace de navegación `Mi perfil` permanece y el topbar conserva avatar,
cuenta, saldo, notificaciones y cierre de sesión.
- El hamburguesa móvil debe ser visible, tener al menos 40 px, abrir con un solo
toque y cerrar con overlay, Escape o navegación.
- No cambies contratos API, autenticación, telemetría o servicios `core` dentro
de una tarea puramente visual.

## Contrato visual y responsive

- Inter, colores sólidos, tarjetas blancas, borde ligero y radios de 12–16 px.
- Sin degradados, Outfit, glassmorphism, blur decorativo, saltos verticales de
tarjetas ni animación continua.
- Acciones táctiles de al menos 40 px y foco visible.
- Respeta `prefers-reduced-motion`.
- No inventes métricas, niveles, bloqueos, cursos ni estados.
- Implementa y revisa siempre: loading, datos, vacío, error y reintento.
- Verifica 1440×900, 1024×768, 390×844 y 360×800 sin scroll horizontal.

## Entrega obligatoria

Antes de pedir integración ejecuta:

```powershell
cd frontend-angular
npm run check:architecture
npm run check:student-visual
npm run test:ci
npm run build
```

Después actualiza únicamente `docs/handoffs/antigravity-to-codex.md` con:

- rama, commit base y commit entregado;
- objetivo y archivos cambiados;
- comportamiento preservado;
- evidencia de los comandos;
- capturas desktop/móvil o rutas para reproducirlas;
- riesgos, decisiones abiertas y archivos que Codex no debe tocar.

Codex revisará el diff, lo integrará por cherry-pick en su rama y podrá
corregirlo. Un build verde no sustituye la revisión funcional, visual y de
accesibilidad.
3 changes: 3 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ a la tarea.
| `gamificacion-xp-daemons.md` | Separación de XP y DAEMONS, nivel, ranking y canjes. |
| `release-2026-07-14-portal-alumno.md` | Historial completo, commits, archivos y evidencia del release. |
| `frontend-ui-standard.md` | Uso de NG-ZORRO y estándar compartido de componentes. |
| `piloto-visual-cursos-2026-07-19.md` | Contrato visual, iconografía y espacios de imágenes de Cursos. |
| `release-2026-07-19-ciclo-aprendizaje.md` | Reestructuración de Cursos, Misiones, Evaluaciones y Resultados. |
| `plan-evolucion-visual-portal-alumno.md` | Bloques completados y orden vigente de los módulos pendientes. |

## Portal de familias

Expand Down
34 changes: 31 additions & 3 deletions docs/ai-project-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This document is written for future AI agents and developers. It summarizes the
current DAEMON system, the cloud decisions already made, the important files,
and the traps that caused confusion during the migration.

Last updated: 2026-07-15.
Last updated: 2026-07-19.

## 1. What DAEMON is

Expand Down Expand Up @@ -87,11 +87,19 @@ Student portal documentation:
docs/sistema-visual-portal-alumno.md
docs/portal-alumno.md
docs/gamificacion-xp-daemons.md
docs/estados-vacios-daemon.md
docs/plan-evolucion-visual-portal-alumno.md
docs/release-2026-07-14-portal-alumno.md
```

Current student visual direction:

- Continue the current Codex work from `codex/antigravity-integration`; the
branch name is historical and does not authorize importing Antigravity work.
- `feature/frontend-design-system` is explicitly excluded from future work.
- The Courses icon audit and the Missions/Evaluations learning-cycle
restructuring are complete in the active PR branch. The next visual block is
Tools IA: chatbot, bot configuration and conversation states.
- Inter only.
- Solid colors; no gradients in the main student modules.
- Canvas `#f4f7fb`, white surfaces, light borders and restrained shadows.
Expand All @@ -100,6 +108,23 @@ Current student visual direction:
- Existing purple sidebar preserved.
- Compact header that displays XP level and DAEMONS separately.
- Dashboard, profile, missions, ranking and store share one visual language.
- Confirmed empty datasets use the shared NG-ZORRO-based `app-estado-vacio`
with the canonical lossless robot, contextual copy and real actions; loading
and errors remain distinct states.
- Courses (`/alumno/recursos`) is the first catalog/exploration pilot using a
dedicated illustrated hero, real status filters, accent-insensitive search,
course progress, a contextual aside and complete loading/empty/error states.
- Optional course illustrations use the shared `daemon-illustration-slot`,
which preserves aspect ratio and renders a safe fallback when an asset is
pending or fails. See `docs/piloto-visual-cursos-2026-07-19.md`.
- Courses now registers replaceable contracts for its hero, course covers and
progress companion; its confirmed empty state uses the canonical shared
robot. Icons distinguish all, not-started, in-progress and completed states.
- Missions list/detail/delivery and student Evaluations/Results now share a
complete remote-state discipline without becoming one generic page shell.
Pending or approved missions cannot be resubmitted from the UI, rejected
missions can be corrected, and assessments require every answer before
submission. See `docs/release-2026-07-19-ciclo-aprendizaje.md`.

The earlier experimental Bento/glass implementation was corrected. Do not use
that first iteration as the target for new student screens.
Expand Down Expand Up @@ -397,8 +422,11 @@ Backend health: https://daemon-5vo1.onrender.com/api/v1/salud

`npm run build` keeps the initial bundle below the configured 1 MB warning
budget. Heavy NG-ZORRO table, upload and modal styles are loaded with the lazy
student or teacher layout instead of the public shell. Global Sass partials use
`@use`, so a clean build should not emit the former deprecation warning.
student or teacher layout instead of the public shell. The current clean build
still emits four Sass deprecation warnings because `src/styles.scss` imports
`layout`, `components`, `popovers` and `gamification` with `@import`. They are
pre-existing non-blockers, but the future Sass migration should replace them
with `@use`/`@forward` and verify global selector order.

## 15. Verification checklist

Expand Down
75 changes: 75 additions & 0 deletions docs/colaboracion-ias.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Protocolo de colaboración Codex–Antigravity

## Objetivo

Permitir trabajo frontend paralelo sin mezclar cambios incompletos, romper
contratos funcionales ni desplegar directamente una propuesta visual.

## Ramas y responsabilidades

| Superficie | Responsable | Rama |
| --- | --- | --- |
| Implementación visual acotada | Antigravity | `feature/frontend-design-system` o `antigravity/<modulo>` |
| Auditoría, corrección e integración | Codex | `codex/antigravity-integration` |
| Producción | pipeline validado | `main` |

`main` no es una rama de trabajo. Antigravity entrega commits atómicos; Codex
los revisa y los cherry-pickea. Solo una integración con todos los gates en
verde puede proponerse para merge.

## Propiedad temporal de archivos

Cada handoff declara qué archivos posee el agente durante la tarea. El otro
agente no los edita hasta que exista un commit entregado o una liberación
explícita. Los archivos de shell (`layout-*`, `sidebar-portal`, topbars,
interceptores, rutas y estilos globales) requieren propiedad exclusiva porque
afectan muchos módulos.

No se fuerza una sincronización copiando el working tree de la otra IA. Se
intercambian hashes de commit reproducibles.

## Flujo de integración

1. Ambos agentes parten del mismo `origin/main` documentado.
2. Antigravity implementa un solo módulo y ejecuta sus gates.
3. Antigravity actualiza `antigravity-to-codex.md` y entrega un hash.
4. Codex revisa contratos, diff, responsive, accesibilidad y rendimiento.
5. Codex cherry-pickea el commit en `codex/antigravity-integration`.
6. Las correcciones se registran en un commit separado y en
`codex-to-antigravity.md`.
7. Se abre un PR borrador. No se despliega una rama con archivos sin commit ni
con gates incompletos.

## Gates mínimos

```text
npm run check:architecture
npm run check:student-visual
npm run test:ci
npm run build
QA 1440×900, 1024×768, 390×844 y 360×800
loading / datos / vacío / error / reintento
teclado / foco / reduced motion / objetivo táctil >= 40 px
```

Para cambios de autenticación, API o backend también se exige la suite Laravel
y una revisión específica de seguridad. Para producción se añaden CI, E2E y
smoke; nunca se asume que un build local autoriza el deploy.

## Decisiones vigentes

- La ficha redundante de usuario no se muestra dentro del sidebar; el enlace
`Mi perfil` se conserva. La cuenta vive en el topbar.
- El tour del alumno apunta al control `#topbar-perfil`.
- Se conservan el sidebar morado, sus rutas y los IDs de navegación del tour.
- Los `401` de rutas protegidas limpian la sesión; no se silencian para evitar
un logout.
- Los cambios visuales no pueden retirar funciones ni reemplazar skeletons por
una pantalla vacía con spinner cuando existe una estructura conocida.

## Conflictos

Si ambos agentes necesitan el mismo archivo, se detiene ese archivo, se entrega
primero el commit del propietario actual y el segundo agente rebasa su trabajo
sobre el commit aceptado. No se resuelven conflictos eligiendo automáticamente
“ours” o “theirs”.
104 changes: 104 additions & 0 deletions docs/estados-vacios-daemon.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Estados vacíos de DAEMON

Estado vigente desde el 19 de julio de 2026.

DAEMON usa un único contrato visual para representar una colección válida que
todavía no contiene elementos. La implementación canónica es el componente
standalone `app-estado-vacio`, construido sobre `nz-empty` de NG-ZORRO.

## Qué representa

Un estado vacío confirma que la consulta terminó correctamente y devolvió cero
resultados. No reemplaza:

- la carga inicial o una actualización en curso;
- un error de red, permisos o servidor;
- un campo multimedia todavía sin completar;
- una instrucción, bloqueo o logro completado que tenga semántica propia.

Carga, error y vacío deben seguir siendo estados mutuamente excluyentes. Si una
actualización falla pero existen datos anteriores, se conservan esos datos y se
muestra un aviso; no se sustituye el contenido por el robot.

## Implementación canónica

```html
<app-estado-vacio
titulo="Tu próxima misión está en camino"
descripcion="Ahora no hay misiones activas para tu nivel."
>
<button nz-button nzType="primary" type="button">Actualizar misiones</button>
</app-estado-vacio>
```

Contrato disponible:

| Entrada | Uso |
| --- | --- |
| `titulo` | Explica el estado sin culpar al usuario. |
| `descripcion` | Indica por qué está vacío, qué ocurrirá o qué puede hacer. |
| `tamano` | `default`, `compact` o `mini`, según el espacio disponible. |
| `compacto` | Alias heredado de `tamano="compact"`. |
| `imagen` | Excepción documentada; por defecto usa el robot canónico. |
| `anunciar` | Controla `aria-live`; se desactiva en popovers ya anunciados. |

Las acciones se proyectan en el footer de `nz-empty`. Debe existir una sola
acción primaria. Una acción secundaria solo se agrega cuando ofrece una ruta
real y distinta; nunca se inventa una acción para llenar espacio.

## Tamaños

- `default`: páginas y paneles principales.
- `compact`: tarjetas, pestañas, resultados filtrados e inventarios.
- `mini`: popovers y superficies de muy poca altura, como notificaciones.

En móvil las acciones ocupan el ancho disponible y mantienen un área táctil
legible. La tipografía sigue siendo Inter, igual que el resto del portal; los
controles y la estructura accesible provienen de NG-ZORRO.

## Ilustración canónica

```text
frontend-angular/public/img/empty/empty-robot.webp
```

- Fuente entregada: PNG transparente de 1254 × 1254 px.
- Salida: WebP lossless transparente, 288 774 bytes.
- Reducción frente al PNG original: 52,8 %.
- Diferencia de píxeles decodificados: cero.
- SHA-256: `9813FCC986580ACDB395E70B0900A1A8DF8A83ED612857D3D59EC66FED6236CA`.

No se generó un SVG automático. La ilustración tiene volumen 3D, iluminación,
sombras y transparencias; vectorizarla produciría una malla enorme o una
aproximación visual distinta. El WebP lossless conserva exactamente el robot y
reduce de forma material el peso de descarga. Si el recurso falla, el
componente muestra un fallback SVG liviano sin exponer texto alternativo
redundante: el título y la descripción ya comunican el estado.

## Redacción

1. El título describe qué ocurrirá: “Tu primera insignia está por llegar”.
2. La descripción explica el origen o siguiente paso con lenguaje breve.
3. El botón usa un verbo concreto: “Actualizar cursos”, “Ver misiones”.
4. No usar mensajes técnicos, bromas ambiguas ni expresiones que parezcan error.
5. Adaptar pronombres cuando se consulta el perfil de otra persona.

## Decisión sobre configuración global

NG-ZORRO permite configurar una imagen vacía global. DAEMON no lo hace porque
también afectaría vacíos internos de selects, tablas y otros controles compactos,
donde este robot sería desproporcionado. Los vacíos editoriales se declaran con
`app-estado-vacio`; los controles internos conservan el comportamiento estándar
de la librería.

## Verificación mínima

```powershell
cd frontend-angular
npm test -- --runInBand src/app/shared/componentes/estado-vacio/estado-vacio.spec.ts
npm run check:architecture
npm run build
```

La prueba compartida comprueba la imagen canónica, el contenido contextual, la
acción proyectada y el fallback ante un recurso roto.
18 changes: 18 additions & 0 deletions docs/firebase-auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,24 @@ firebase.projectId: 'daemon-a41f8'

La config web de Firebase no es secreto. Las service accounts si son secreto.

### Desarrollo local y cookies

Angular y Laravel deben usar el mismo hostname durante las pruebas locales:

```text
Frontend: http://localhost:4200 o http://localhost:4300
API: http://localhost:8000/api/v1
```

No mezclar `localhost` con `127.0.0.1`. Aunque ambos apunten al mismo equipo,
el navegador los considera sitios distintos. La llamada de login puede
responder HTTP 200, pero la cookie HttpOnly `daemon_access` con `SameSite=Lax`
no queda disponible para la siguiente consulta autenticada y el interceptor
termina limpiando la sesión.

Si se elige `127.0.0.1`, tanto el frontend como el backend deben servirse con
ese mismo hostname.

## Variables backend

Laravel necesita:
Expand Down
5 changes: 5 additions & 0 deletions docs/frontend-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ sesión, la autenticación o la configuración del shell. Los componentes
puramente presentacionales, como la moneda DAEMON y los estados vacíos,
permanecen en `shared`.

`shared/componentes/estado-vacio` es la única abstracción editorial para
colecciones vacías. Encapsula `nz-empty`, no conoce servicios ni rutas y recibe
sus acciones por proyección de contenido. Su contrato visual se documenta en
`docs/estados-vacios-daemon.md`.

## Modelos, configuración, directivas y pipes

- Un modelo utilizado solo por una feature se coloca junto a esa feature.
Expand Down
Loading
Loading