Compare commits

..

40 Commits

Author SHA1 Message Date
840ef44670 fix: add image names to docker-compose and update CI pipeline with login-action
All checks were successful
CI/CD Pipeline / backend-build (push) Successful in 2m3s
CI/CD Pipeline / frontend-build (push) Successful in 43s
CI/CD Pipeline / docker-build (push) Successful in 1m18s
2026-04-04 19:25:52 -03:00
42cb6e0d67 Fix: CI Version
All checks were successful
CI/CD Pipeline / backend-build (push) Successful in 2m14s
CI/CD Pipeline / frontend-build (push) Successful in 41s
CI/CD Pipeline / docker-build (push) Successful in 1m43s
2026-04-04 19:08:58 -03:00
6de2518a72 Fix: Label para Relacion Paquete Repositorio
All checks were successful
CI/CD Pipeline / backend-build (push) Successful in 2m20s
CI/CD Pipeline / frontend-build (push) Successful in 52s
CI/CD Pipeline / docker-build (push) Successful in 1m29s
2026-04-04 18:55:17 -03:00
6a4b16bb8b Retry CI Login con Usuario
All checks were successful
CI/CD Pipeline / backend-build (push) Successful in 2m10s
CI/CD Pipeline / frontend-build (push) Successful in 35s
CI/CD Pipeline / docker-build (push) Successful in 2m4s
2026-04-04 18:37:47 -03:00
f70ecaeeb5 Retry Ci Login
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 2m9s
CI/CD Pipeline / frontend-build (push) Successful in 40s
CI/CD Pipeline / docker-build (push) Failing after 48s
2026-04-04 18:29:00 -03:00
8459327d8b Retry ci Login
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 2m9s
CI/CD Pipeline / frontend-build (push) Successful in 45s
CI/CD Pipeline / docker-build (push) Failing after 16s
2026-04-04 18:24:29 -03:00
29b497468e Fix Login CI.yml
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 2m31s
CI/CD Pipeline / frontend-build (push) Successful in 1m17s
CI/CD Pipeline / docker-build (push) Failing after 18s
2026-04-04 18:14:57 -03:00
c33b186098 Repush 2 2026-04-03 21:03:19 -03:00
56e7b8b0a8 Repush 1 2026-04-03 21:00:15 -03:00
11638026d9 Repush 2026-04-03 20:57:38 -03:00
e3db9eb87f Fix: Login con Secret Token en CI 2026-04-03 20:55:50 -03:00
3a85201154 Fix: ci.yml con login previo a steps
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 2m6s
CI/CD Pipeline / frontend-build (push) Successful in 36s
CI/CD Pipeline / docker-build (push) Failing after 13s
2026-04-03 20:46:41 -03:00
865cf9b3e8 test ci.yml runner
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 2m18s
CI/CD Pipeline / frontend-build (push) Successful in 1m8s
CI/CD Pipeline / docker-build (push) Failing after 1m11s
2026-04-03 20:39:29 -03:00
eb5f04e5e2 docs: add README.md 2026-04-03 20:35:27 -03:00
ca15833526 chore: trigger pipeline with empty commit 2026-04-03 20:25:19 -03:00
67b56c1c9b fix: improve docker-build job with login, compose push, and correct image names 2026-04-03 20:23:13 -03:00
ed7586f950 fix: add DOCKER_API_VERSION env to job for API compatibility
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 2m15s
CI/CD Pipeline / frontend-build (push) Successful in 51s
CI/CD Pipeline / docker-build (push) Failing after 1m52s
2026-04-03 20:05:40 -03:00
361be0eb9e fix: use lowercase repo name and add image cleanup step
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 2m53s
CI/CD Pipeline / frontend-build (push) Successful in 1m20s
CI/CD Pipeline / docker-build (push) Failing after 2m0s
2026-04-03 19:42:16 -03:00
667b01c2a0 feat: push Docker images to Gitea registry after build
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 2m36s
CI/CD Pipeline / frontend-build (push) Successful in 54s
CI/CD Pipeline / docker-build (push) Failing after 2m3s
2026-04-03 19:34:42 -03:00
d3e77ad9a5 fix: correct paths in Backend Dockerfile for docker compose build context
All checks were successful
CI/CD Pipeline / backend-build (push) Successful in 2m15s
CI/CD Pipeline / frontend-build (push) Successful in 53s
CI/CD Pipeline / docker-build (push) Successful in 7m14s
The docker-compose.yml uses 'context: .' (root), so paths must include 'Backend/' prefix.
2026-04-03 19:15:29 -03:00
fd52352b21 fix: use docker label for build job (runner has docker-cli)
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 2m53s
CI/CD Pipeline / frontend-build (push) Successful in 1m19s
CI/CD Pipeline / docker-build (push) Failing after 39s
2026-04-01 21:25:44 -03:00
86a4b7cc1d fix: use docker compose v2 (plugin) in CI
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 2m58s
CI/CD Pipeline / frontend-build (push) Successful in 1m4s
CI/CD Pipeline / docker-build (push) Failing after 23s
2026-04-01 21:15:01 -03:00
5fed217818 fix: use docker build instead of docker-compose in CI
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 3m19s
CI/CD Pipeline / docker-build (push) Has been cancelled
CI/CD Pipeline / frontend-build (push) Has been cancelled
2026-04-01 21:11:18 -03:00
03c2cbf90b fix: install Docker CLI in CI step before docker-compose build
Some checks failed
CI/CD Pipeline / frontend-build (push) Has been cancelled
CI/CD Pipeline / backend-build (push) Has been cancelled
CI/CD Pipeline / docker-build (push) Has been cancelled
Each CI step runs in a separate container (node:18-bullseye).
Docker CLI must be installed within that container to use docker-compose.
2026-04-01 21:07:42 -03:00
2061ea5c0e revert: use docker-compose v1 in CI (runner now has docker-cli-compose)
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 3m14s
CI/CD Pipeline / frontend-build (push) Successful in 1m20s
CI/CD Pipeline / docker-build (push) Failing after 23s
2026-04-01 21:01:01 -03:00
8729de88a7 fix: use docker compose v2 instead of docker-compose in CI
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 3m4s
CI/CD Pipeline / frontend-build (push) Successful in 57s
CI/CD Pipeline / docker-build (push) Failing after 30s
docker-compose (v1) not available in gitea/act_runner container.
Docker Compose v2 is available as a plugin via 'docker compose'.
2026-04-01 20:31:41 -03:00
caf6d492ca fix: TypeScript build errors in frontend pipeline
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 2m41s
CI/CD Pipeline / frontend-build (push) Successful in 58s
CI/CD Pipeline / docker-build (push) Failing after 28s
- Remove unused ReactNode import in useAuth.test.tsx
- Use vitest/config for defineConfig to recognize test property
- Add vitest/globals to tsconfig types for test runner globals
2026-04-01 20:17:56 -03:00
653d3e7670 feat: agregar componente TestEcosistemaComponent para validación de ecosistema OpenCode 2026-04-01 19:14:34 -03:00
77c5f5419f chore: Simplify post-restart protocol - only Telegram when user is remote
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 3m9s
CI/CD Pipeline / frontend-build (push) Failing after 52s
CI/CD Pipeline / docker-build (push) Has been skipped
2026-04-01 18:43:29 -03:00
86e656d593 chore: Remove restart wrapper references, clean up protocol
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 3m32s
CI/CD Pipeline / frontend-build (push) Failing after 1m1s
CI/CD Pipeline / docker-build (push) Has been skipped
2026-04-01 18:33:53 -03:00
afac617b3f chore: Update restart protocol with wrapper flow
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 3m3s
CI/CD Pipeline / frontend-build (push) Failing after 50s
CI/CD Pipeline / docker-build (push) Has been skipped
2026-04-01 18:21:47 -03:00
1585339dee chore: Add post-restart remote notification protocol
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 3m10s
CI/CD Pipeline / frontend-build (push) Failing after 1m10s
CI/CD Pipeline / docker-build (push) Has been skipped
2026-04-01 17:21:12 -03:00
39469ad121 chore: Add Gitea labels, issue templates and PR template
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 3m37s
CI/CD Pipeline / frontend-build (push) Failing after 1m18s
CI/CD Pipeline / docker-build (push) Has been skipped
2026-04-01 16:45:02 -03:00
f8e5060278 test: Add Vitest + React Testing Library setup (Refs #2)
Some checks failed
CI/CD Pipeline / backend-build (push) Successful in 2m30s
CI/CD Pipeline / frontend-build (push) Failing after 2m0s
CI/CD Pipeline / docker-build (push) Has been skipped
2026-04-01 16:14:06 -03:00
d7481323f9 ci: Add Gitea Actions workflow for CI/CD (Refs #2)
Some checks failed
CI/CD Pipeline / frontend-build (push) Has been cancelled
CI/CD Pipeline / docker-build (push) Has been cancelled
CI/CD Pipeline / backend-build (push) Has been cancelled
2026-04-01 16:11:33 -03:00
c91ee30c1b chore: Environment improvements - delegation rules, GGA config, skill audit 2026-04-01 15:51:17 -03:00
552d1305f8 fix: Configure GGA to use AGENT.md instead of AGENTS.md 2026-04-01 15:50:15 -03:00
48aaaa798c fix: Update proxy target to backend port 5082 (Refs #2) 2026-04-01 15:10:15 -03:00
08cd32ba85 fix: Move AuthProvider to main.tsx to fix context error (Refs #2) 2026-04-01 14:58:27 -03:00
869cc66a2f Merge pull request 'feat: Sistema de autenticación frontend (Login + Register + Dashboard)' (#3) from feat/autenticacion-frontend into main
feat: Sistema de autenticación frontend (Login + Register + Dashboard)

Closes #2
2026-04-01 17:38:48 +00:00
22 changed files with 1690 additions and 43 deletions

2
.gga
View File

@@ -34,7 +34,7 @@ EXCLUDE_PATTERNS="*.test.ts,*.spec.ts,*.test.tsx,*.spec.tsx,*.d.ts"
# File containing code review rules # File containing code review rules
# Default: AGENTS.md # Default: AGENTS.md
RULES_FILE="AGENTS.md" RULES_FILE="AGENT.md"
# Strict mode: fail if AI response is ambiguous # Strict mode: fail if AI response is ambiguous
# Default: true # Default: true

View File

@@ -0,0 +1,29 @@
---
name: Bug Report
about: Reportar un bug o problema
title: "[BUG] "
labels: bug
---
## Descripción del Bug
Descripción clara del problema.
## Pasos para Reproducir
1. Ir a '...'
2. Hacer click en '...'
3. Ver error
## Comportamiento Esperado
Describir lo que debería pasar.
## Comportamiento Actual
Describir lo que realmente pasa.
## Screenshots
Si aplica, agregar screenshots.
## Entorno
- OS: [ej. Windows 11]
- Browser: [ej. Chrome 120]
- .NET Version: [ej. 10.0]
- Node Version: [ej. 22.x]

View File

@@ -0,0 +1,24 @@
---
name: Feature Request
about: Solicitar una nueva funcionalidad
title: "[FEATURE] "
labels: feature
---
## Descripción de la Feature
Descripción clara de lo que se quiere.
## Problema que Resuelve
¿Qué problema tiene el usuario actualmente?
## Solución Propuesta
Describir la solución deseada.
## Alternativas Consideradas
Otras soluciones que se consideraron.
## Área
- [ ] Backend
- [ ] Frontend
- [ ] DevOps
- [ ] Base de Datos

View File

@@ -0,0 +1,21 @@
---
name: Technical Task
about: Tarea técnica o refactor
title: "[TASK] "
labels: task
---
## Descripción
Descripción de la tarea técnica.
## Objetivo
Qué se quiere lograr.
## Alcance
- [ ] Archivos/carpetas afectados
- [ ] Dependencias
- [ ] Tests necesarios
## Criterios de Aceptación
- [ ] Criterio 1
- [ ] Criterio 2

View File

@@ -0,0 +1,21 @@
## Descripción
Breve descripción de los cambios.
## Tipo de Cambio
- [ ] Bug fix (change that fixes an issue)
- [ ] New feature (change that adds functionality)
- [ ] Breaking change (change that would cause existing functionality to not work as expected)
- [ ] Documentation update
## Issue Relacionada
Closes #
## Checklist
- [ ] Mi código sigue las convenciones del proyecto (AGENT.md)
- [ ] He hecho self-review de mi código
- [ ] He agregado tests que prueban mi cambio (si aplica)
- [ ] Los tests pasan localmente
- [ ] He actualizado la documentación (si aplica)
## Screenshots (si aplica)
Agregar screenshots de los cambios visuales.

88
.gitea/workflows/ci.yml Normal file
View File

@@ -0,0 +1,88 @@
name: CI/CD Pipeline
# Triggers: push to main and pull requests to main
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
# Backend build job
backend-build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET 10
uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.x
- name: Restore dependencies
run: dotnet restore Backend/PruebaGentle.slnx
- name: Build backend
run: dotnet build Backend/PruebaGentle.slnx --configuration Release
# Frontend build job
frontend-build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js 22
uses: actions/setup-node@v4
with:
node-version: 22.x
- name: Install dependencies
run: npm ci
working-directory: Frontend
- name: Build frontend
run: npm run build
working-directory: Frontend
- name: Run tests
run: npm run test:run
working-directory: Frontend
docker-build:
needs: [backend-build, frontend-build]
runs-on: docker
if: github.ref == 'refs/heads/main'
env:
DOCKER_API_VERSION: "1.41"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Login to Gitea Registry
uses: docker/login-action@v3
with:
registry: repo.eldiaservicios.com
username: dmolinari
password: ${{ secrets.TOKEN_REGISTRY }}
- name: Build Docker images
run: docker compose build
- name: Tag versioned images
run: |
docker tag repo.eldiaservicios.com/dmolinari/pruebagentle/backend:latest repo.eldiaservicios.com/dmolinari/pruebagentle/backend:${{ github.run_number }}
docker tag repo.eldiaservicios.com/dmolinari/pruebagentle/frontend:latest repo.eldiaservicios.com/dmolinari/pruebagentle/frontend:${{ github.run_number }}
- name: Push to registry
run: |
docker compose push
docker push repo.eldiaservicios.com/dmolinari/pruebagentle/backend:${{ github.run_number }}
docker push repo.eldiaservicios.com/dmolinari/pruebagentle/frontend:${{ github.run_number }}
- name: Clean up old images
run: |
docker images --format '{{.Repository}}:{{.Tag}}' | grep 'repo.eldiaservicios.com/dmolinari/pruebagentle' | tail -n +3 | xargs -r docker rmi || true

View File

@@ -2,6 +2,33 @@
> **IMPORTANTE:** El idioma oficial de este proyecto es el ESPAÑOL. Todas las respuestas, explicaciones, comentarios de código y logs deben ser exclusivamente en español. > **IMPORTANTE:** El idioma oficial de este proyecto es el ESPAÑOL. Todas las respuestas, explicaciones, comentarios de código y logs deben ser exclusivamente en español.
## 🚨 REGLA DE ORO: DELEGAR SIEMPRE
**NUNCA escribas código inline como orquestador.** Tu rol es COORDINAR, no ejecutar.
### Auto-pregunta ANTES de cada acción:
> *"¿Esto infla mi contexto sin necesidad?"*
> - Si SÍ → **DELEGA** a sub-agente
> - Si NO → hazlo inline
### DELEGAR (siempre):
- ❌ Escribir o editar CUALQUIER archivo de código
- ❌ Leer 4+ archivos para entender
- ❌ Ejecutar tests, builds, installs
- ❌ Crear branches, commits complejos
- ❌ Cualquier tarea de implementación
### INLINE (solo esto):
- ✅ git status / diff / log (solo lectura)
- ✅ Leer 1-3 archivos para DECIDIR (no para escribir)
- ✅ mem_search / mem_save
- ✅ Responder al usuario / hacer preguntas
### Anti-patrones que NUNCA debes repetir:
1. Leer archivos como "preparación" y luego editarlos → DELEGA la lectura + edición juntos
2. Escribir un fix "rápido" de 2 líneas → DELEGA igual
3. Ejecutar `npm run build` o `dotnet build` → DELEGA
Este proyecto utiliza C# (.NET Web API), React (TypeScript + Vite + Tailwind CSS), SQL Server, Docker y Gitea. Este proyecto utiliza C# (.NET Web API), React (TypeScript + Vite + Tailwind CSS), SQL Server, Docker y Gitea.
DEBES cumplir estrictamente estas reglas en TODAS las fases del SDD (Spec, Design, Apply, Verify). DEBES cumplir estrictamente estas reglas en TODAS las fases del SDD (Spec, Design, Apply, Verify).
@@ -63,3 +90,14 @@ Para cualquier aprobación, pregunta o decisión que requieras del usuario, DEBE
1. Pasa tu pregunta SIEMPRE entre comillas dobles. 1. Pasa tu pregunta SIEMPRE entre comillas dobles.
2. Al ejecutar este comando, la terminal se pausará automáticamente (pueden ser minutos u horas). NO ENTRES EN PÁNICO, solo espera. 2. Al ejecutar este comando, la terminal se pausará automáticamente (pueden ser minutos u horas). NO ENTRES EN PÁNICO, solo espera.
3. Cuando el comando termine, capturará la salida estándar (stdout) donde estará la respuesta exacta del usuario. Usa esa respuesta para continuar tu trabajo. 3. Cuando el comando termine, capturará la salida estándar (stdout) donde estará la respuesta exacta del usuario. Usa esa respuesta para continuar tu trabajo.
### 🔄 Protocolo Post-Reinicio (OBLIGATORIO)
Si OpenCode se reinició:
1. **PRIMERA ACCIÓN**: Buscar en engram `mem_search(query: "remote-communication-protocol")`
2. **Si el usuario está EN EL CHAT** (mensajes directos en esta ventana):
- Continuar normalmente, NO enviar Telegram
3. **Si el usuario NO está** (último mensaje fue "salgo de la pc" o "modo remoto"):
- Ejecutar: `node E:/telegram-mcp/index.js "Reinicio completado. Estoy de vuelta y a la espera de tu mensaje."`
- Esperar respuesta antes de continuar

View File

@@ -4,12 +4,12 @@ EXPOSE 8080
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src WORKDIR /src
COPY PruebaGentle.Core/PruebaGentle.Core.csproj PruebaGentle.Core/ COPY Backend/PruebaGentle.Core/PruebaGentle.Core.csproj Backend/PruebaGentle.Core/
COPY PruebaGentle.Infrastructure/PruebaGentle.Infrastructure.csproj PruebaGentle.Infrastructure/ COPY Backend/PruebaGentle.Infrastructure/PruebaGentle.Infrastructure.csproj Backend/PruebaGentle.Infrastructure/
COPY PruebaGentle.API/PruebaGentle.API.csproj PruebaGentle.API/ COPY Backend/PruebaGentle.API/PruebaGentle.API.csproj Backend/PruebaGentle.API/
RUN dotnet restore PruebaGentle.API/PruebaGentle.API.csproj RUN dotnet restore Backend/PruebaGentle.API/PruebaGentle.API.csproj
COPY . . COPY . .
WORKDIR /src/PruebaGentle.API WORKDIR /src/Backend/PruebaGentle.API
RUN dotnet build -c Release -o /app/build RUN dotnet build -c Release -o /app/build
FROM build AS publish FROM build AS publish

View File

@@ -1,6 +1,6 @@
{ {
"ConnectionStrings": { "ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=PruebaGentle;User Id=sa;Password=YourStrong@Password123;TrustServerCertificate=true;" "DefaultConnection": "Server=localhost;Database=Desarrollo;User Id=desarrollo;Password=desarrollo2026;TrustServerCertificate=true;"
}, },
"JwtSettings": { "JwtSettings": {
"Secret": "ThisIsA32CharacterLongSecretKey!!", "Secret": "ThisIsA32CharacterLongSecretKey!!",

167
Bitacora-CICD-Gitea.md Normal file
View File

@@ -0,0 +1,167 @@
# 📖 Bitácora de Configuración CI/CD en Gitea
## Fase 1: Configuración del Gitea Act-Runner
**Objetivo:** Levantar el contenedor que ejecutará los pipelines de Gitea (el "runner").
* **Problema 1:** El contenedor del runner no iniciaba y arrojaba el error `accepts at most 0 arg(s), received 1`.
* **Causa:** Un espacio en blanco después de la coma en la variable de entorno `GITEA_RUNNER_LABELS` que Bash interpretaba como un argumento adicional.
* **Solución:** Eliminar el espacio y encerrar toda la declaración entre comillas dobles en el `docker-compose.yml` de Gitea:
`- "GITEA_RUNNER_LABELS=ubuntu-latest:docker://node:18-bullseye,docker:docker://repo.eldiaservicios.com/dmolinari/act-runner:latest"`
## Fase 2: Preparación del Proyecto y Docker Compose
**Objetivo:** Que el código fuente (Backend y Frontend) se construya correctamente dentro de Docker.
* **Problema 2:** Error al construir la imagen del backend: `ERROR: "/PruebaGentle.API.csproj" not found`.
* **Causa:** El "contexto" de construcción (`context`) estaba mal referenciado; Docker buscaba el archivo en la raíz cuando en realidad estaba dentro de la carpeta `Backend/`.
* **Solución:** Se ajustó el `docker-compose.yml` del proyecto definiendo explícitamente los contextos (`context: ./Backend` y `context: ./Frontend`).
* **Problema 3:** Gitea no mostraba los paquetes en la pestaña "Paquetes" del repositorio.
* **Causa:** Las imágenes no tenían metadatos que le dijeran a Gitea a qué repositorio pertenecían.
* **Solución:** Se agregaron etiquetas OCI (`labels`) al `docker-compose.yml` del proyecto.
* **Problema 4:** Docker Compose no sabía cómo llamar a las imágenes, dando errores al intentar etiquetarlas con `docker tag backend`.
* **Solución:** Declarar el nombre exacto de la imagen en la propiedad `image:` de cada servicio.
**✅ Resultado final de `docker-compose.yml` (Proyecto):**
```yaml
services:
backend:
image: repo.eldiaservicios.com/dmolinari/pruebagentle/backend:latest
build:
context: ./Backend
dockerfile: Dockerfile
labels:
- "org.opencontainers.image.source=https://repo.eldiaservicios.com/dmolinari/PruebaGentle"
frontend:
image: repo.eldiaservicios.com/dmolinari/pruebagentle/frontend:latest
build:
context: ./Frontend
dockerfile: Dockerfile
labels:
- "org.opencontainers.image.source=https://repo.eldiaservicios.com/dmolinari/PruebaGentle"
```
## Fase 3: Solución de Problemas en el Pipeline (Errores de Gitea Actions)
**Objetivo:** Que el Action compile, inicie sesión y suba las imágenes a Gitea Registry.
* **Problema 5:** Error `client version 1.52 is too new. Maximum supported API version is 1.41`.
* **Causa:** El Docker Engine del servidor host es más antiguo que el cliente instalado en el runner. Las variables de entorno del `Dockerfile` se borraban al iniciar el job.
* **Solución:** Forzar la compatibilidad inyectando `env: DOCKER_API_VERSION: "1.41"` directamente a nivel del Job en el archivo `ci.yml`.
* **Problema 6:** Errores de Autenticación (`unauthorized`, `cannot perform an interactive login from a non TTY device` y `Password required`).
* **Causa:** Faltaba el paso para iniciar sesión en el Registry. Al intentar pasarlo por consola, si una variable estaba vacía, Docker pedía la clave por teclado, colgando el proceso (non TTY). Además, el token por defecto de Gitea no tenía permisos de escritura para paquetes.
* **Solución:**
1. Se generó un **Token de Acceso Personal (PAT)** desde el perfil del usuario con permisos de lectura/escritura en *Packages*.
2. Se guardó este token en **Configuración del Repositorio -> Acciones -> Secretos** bajo el nombre `TOKEN_REGISTRY`.
3. Se implementó la acción oficial `docker/login-action@v3` para manejar el login de forma segura.
* **Problema 7:** Las imágenes subidas sobreescribían el historial (todo era `latest`).
* **Causa:** La etiqueta `latest` reemplaza a la anterior sin guardar historial.
* **Solución:** Implementar doble etiquetado. Subir `:latest` (para producción) y subir `:${{ github.run_number }}` (para mantener un registro de versiones atado a la ejecución del Action).
## Fase 4: El Archivo Pipeline Final (`ci.yml`)
Este es el archivo definitivo, pulido y profesional que logró integrar todo el proceso:
```yaml
name: CI/CD Pipeline
# Triggers: push to main and pull requests to main
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
# Backend build job
backend-build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET 10
uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.x
- name: Restore dependencies
run: dotnet restore Backend/PruebaGentle.slnx
- name: Build backend
run: dotnet build Backend/PruebaGentle.slnx --configuration Release
# Frontend build job
frontend-build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js 22
uses: actions/setup-node@v4
with:
node-version: 22.x
- name: Install dependencies
run: npm ci
working-directory: Frontend
- name: Build frontend
run: npm run build
working-directory: Frontend
- name: Run tests
run: npm run test:run
working-directory: Frontend
docker-build:
needs: [backend-build, frontend-build]
runs-on: docker
if: github.ref == 'refs/heads/main'
env:
DOCKER_API_VERSION: "1.41"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Login to Gitea Registry
uses: docker/login-action@v3
with:
registry: repo.eldiaservicios.com
username: dmolinari
password: ${{ secrets.TOKEN_REGISTRY }}
- name: Build Docker images
run: docker compose build
- name: Tag versioned images
run: |
docker tag repo.eldiaservicios.com/dmolinari/pruebagentle/backend:latest repo.eldiaservicios.com/dmolinari/pruebagentle/backend:${{ github.run_number }}
docker tag repo.eldiaservicios.com/dmolinari/pruebagentle/frontend:latest repo.eldiaservicios.com/dmolinari/pruebagentle/frontend:${{ github.run_number }}
- name: Push to registry
run: |
docker compose push
docker push repo.eldiaservicios.com/dmolinari/pruebagentle/backend:${{ github.run_number }}
docker push repo.eldiaservicios.com/dmolinari/pruebagentle/frontend:${{ github.run_number }}
- name: Clean up old images
run: |
docker images --format '{{.Repository}}:{{.Tag}}' | grep 'repo.eldiaservicios.com/dmolinari/pruebagentle' | tail -n +3 | xargs -r docker rmi || true
```
## Fase 5: Mantenimiento y Retención del Servidor
**Objetivo:** Evitar que el disco del servidor colapse por acumular cientos de versiones de imágenes.
* **Acción tomada:** Se configuró una regla de limpieza automática desde la cuenta de **Administrador del sitio** de Gitea (`/admin/packages`).
* **Regla implementada:**
* Tipo: `Container`
* Mantener el más reciente: `5 versiones por paquete` (Esto actúa como escudo de seguridad mínimo).
* Eliminar versiones anteriores a: `X días` (Para limpiar la basura antigua periódicamente).
* **Aclaración de Interfaz:** Se aprendió que Gitea agrupa los paquetes en la vista del repositorio (hay que hacer clic para ver las versiones), mientras que en la vista de administración muestra todas las etiquetas desagrupadas.
---

View File

@@ -1 +1 @@
VITE_API_URL=http://localhost:5000/api VITE_API_URL=http://localhost:5082/api

File diff suppressed because it is too large Load Diff

View File

@@ -3,12 +3,14 @@
"private": true, "private": true,
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "tsc -b && vite build", "build": "tsc -b && vite build",
"lint": "eslint .", "lint": "eslint .",
"preview": "vite preview" "preview": "vite preview",
}, "test": "vitest",
"test:run": "vitest run"
},
"dependencies": { "dependencies": {
"react": "^19.2.4", "react": "^19.2.4",
"react-dom": "^19.2.4", "react-dom": "^19.2.4",
@@ -17,6 +19,9 @@
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.39.4", "@eslint/js": "^9.39.4",
"@tailwindcss/vite": "^4.2.2", "@tailwindcss/vite": "^4.2.2",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
"@types/node": "^24.12.0", "@types/node": "^24.12.0",
"@types/react": "^19.2.14", "@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3", "@types/react-dom": "^19.2.3",
@@ -25,9 +30,11 @@
"eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.5.2", "eslint-plugin-react-refresh": "^0.5.2",
"globals": "^17.4.0", "globals": "^17.4.0",
"jsdom": "^29.0.1",
"tailwindcss": "^4.2.2", "tailwindcss": "^4.2.2",
"typescript": "~5.9.3", "typescript": "~5.9.3",
"typescript-eslint": "^8.57.0", "typescript-eslint": "^8.57.0",
"vite": "^8.0.1" "vite": "^8.0.1",
"vitest": "^4.1.2"
} }
} }

View File

@@ -1,5 +1,5 @@
import { Routes, Route, Navigate } from 'react-router-dom'; import { Routes, Route, Navigate } from 'react-router-dom';
import { AuthProvider, useAuth } from './hooks/useAuth'; import { useAuth } from './hooks/useAuth';
import ProtectedRoute from './components/ProtectedRoute'; import ProtectedRoute from './components/ProtectedRoute';
import LoginPage from './pages/LoginPage'; import LoginPage from './pages/LoginPage';
import RegisterPage from './pages/RegisterPage'; import RegisterPage from './pages/RegisterPage';
@@ -9,7 +9,6 @@ function App() {
const { isAuthenticated } = useAuth(); const { isAuthenticated } = useAuth();
return ( return (
<AuthProvider>
<Routes> <Routes>
<Route path="/" element={ <Route path="/" element={
<Navigate to={isAuthenticated ? '/dashboard' : '/login'} replace /> <Navigate to={isAuthenticated ? '/dashboard' : '/login'} replace />
@@ -25,7 +24,6 @@ function App() {
} }
/> />
</Routes> </Routes>
</AuthProvider>
); );
} }

View File

@@ -0,0 +1,21 @@
import React from 'react';
const TestEcosistemaComponent: React.FC = () => {
return (
<div>
<h2>Test Ecosistema OpenCode</h2>
<p>Componente creado para completar la fase apply del flujo SDD</p>
<ul>
<li>MCP engram: Funcional</li>
<li>MCP mssql: Sin conexión</li>
<li>MCP convention-checker: Funcional</li>
<li>MCP release-mcp: Funcional</li>
<li>MCP coordinator-mcp: Funcional</li>
<li>MCP context7: Funcional</li>
<li>MCP sdd-mcp: Parcial/Stub</li>
</ul>
</div>
);
};
export default TestEcosistemaComponent;

View File

@@ -0,0 +1,32 @@
import { render, screen } from '@testing-library/react';
import { AuthProvider } from '../useAuth';
import { useAuth } from '../useAuth';
// Test component that uses useAuth hook
const TestComponent = () => {
const auth = useAuth();
return <div data-testid="auth-user">{auth.user?.username ?? 'null'}</div>;
};
describe('useAuth hook', () => {
test('throws error when used outside AuthProvider', () => {
// Render component without AuthProvider wrapper
const renderTestComponent = () => render(<TestComponent />);
// Expect it to throw an error
expect(renderTestComponent).toThrow('useAuth must be used within an AuthProvider');
});
test('provides context through AuthProvider', () => {
// Render component with AuthProvider wrapper
render(
<AuthProvider>
<TestComponent />
</AuthProvider>
);
// Should initially show null since no user is set
const authContextElement = screen.getByTestId('auth-user');
expect(authContextElement).toHaveTextContent('null');
});
});

View File

@@ -3,11 +3,14 @@ import { createRoot } from 'react-dom/client'
import './index.css' import './index.css'
import App from './App.tsx' import App from './App.tsx'
import { BrowserRouter } from 'react-router-dom' import { BrowserRouter } from 'react-router-dom'
import { AuthProvider } from './hooks/useAuth'
createRoot(document.getElementById('root')!).render( createRoot(document.getElementById('root')!).render(
<StrictMode> <StrictMode>
<BrowserRouter> <BrowserRouter>
<AuthProvider>
<App /> <App />
</AuthProvider>
</BrowserRouter> </BrowserRouter>
</StrictMode>, </StrictMode>,
) )

View File

@@ -0,0 +1,2 @@
// Setup file for Vitest with React Testing Library
import '@testing-library/jest-dom'

View File

@@ -5,7 +5,7 @@
"useDefineForClassFields": true, "useDefineForClassFields": true,
"lib": ["ES2023", "DOM", "DOM.Iterable"], "lib": ["ES2023", "DOM", "DOM.Iterable"],
"module": "ESNext", "module": "ESNext",
"types": ["vite/client"], "types": ["vite/client", "vitest/globals"],
"skipLibCheck": true, "skipLibCheck": true,
/* Bundler mode */ /* Bundler mode */

View File

@@ -1,4 +1,4 @@
import { defineConfig } from 'vite' import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react' import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite' import tailwindcss from '@tailwindcss/vite'
@@ -8,9 +8,14 @@ export default defineConfig({
port: 8181, port: 8181,
proxy: { proxy: {
'/api': { '/api': {
target: 'http://localhost:5000', target: 'http://localhost:5082',
changeOrigin: true, changeOrigin: true,
}, },
}, },
}, },
test: {
environment: 'jsdom',
setupFiles: './src/test/setup.ts',
globals: true,
},
}) })

41
README.md Normal file
View File

@@ -0,0 +1,41 @@
# PruebaGentle
Proyecto de prueba con backend .NET y frontend React.
## Tech Stack
- **Backend**: .NET 10 + Dapper + SQL Server
- **Frontend**: React 19 + Vite + Tailwind CSS
- **Database**: SQL Server (Docker)
- **CI/CD**: Gitea Actions
## Desarrollo Local
### Requisitos
- .NET 10 SDK
- Node.js 22+
- Docker Desktop
### Comandos
```bash
# Frontend
cd Frontend
npm install
npm run dev
# Backend
cd Backend
dotnet restore
dotnet run
# Docker (todo)
docker compose up -d
```
## Pipeline
El pipeline de CI/CD corre en Gitea Actions y construye:
1. Backend (.NET)
2. Frontend (React + Vite)
3. Imágenes Docker (push al registry de Gitea)

View File

@@ -1,5 +1,3 @@
version: '3.8'
services: services:
sqlserver: sqlserver:
image: mcr.microsoft.com/mssql/server:2022-latest image: mcr.microsoft.com/mssql/server:2022-latest
@@ -20,9 +18,13 @@ services:
start_period: 30s start_period: 30s
backend: backend:
# 1. AÑADIMOS EL NOMBRE DE LA IMAGEN AQUÍ
image: repo.eldiaservicios.com/dmolinari/pruebagentle/backend:latest
build: build:
context: . context: .
dockerfile: Backend/Dockerfile dockerfile: Backend/Dockerfile
labels:
- "org.opencontainers.image.source=https://repo.eldiaservicios.com/dmolinari/PruebaGentle"
ports: ports:
- "5000:8080" - "5000:8080"
environment: environment:
@@ -35,9 +37,13 @@ services:
condition: service_healthy condition: service_healthy
frontend: frontend:
# 2. AÑADIMOS EL NOMBRE DE LA IMAGEN AQUÍ
image: repo.eldiaservicios.com/dmolinari/pruebagentle/frontend:latest
build: build:
context: ./Frontend context: ./Frontend
dockerfile: Dockerfile dockerfile: Dockerfile
labels:
- "org.opencontainers.image.source=https://repo.eldiaservicios.com/dmolinari/PruebaGentle"
ports: ports:
- "8181:80" - "8181:80"
depends_on: depends_on: