Hoja de trabajo semana 1 PF2 - martin-hendricks/MISO-PROYECTO-FINAL-SOLVENTA GitHub Wiki
| Proyecto | Solventa — Aseguradora digital |
| Elaboración | Juan Acevedo, John Guerrero, Mauricio Rodriguez, Martin Romero |
| Versión | 0.2 |
| Insumos | Plan de trabajo PF2 (semana 7) · Lecciones aprendidas PF1 · Documento final de arquitectura (semana 8) |
Estado: borrador. Esta página recoge el esqueleto de entregables de la semana 1 del Proyecto Final 2 según la rúbrica. Cada sección se completa a medida que el equipo avanza en la construcción.
-
Hoja de trabajo semana 1 — Proyecto Final 2
- Índice
-
1. Configuración del ambiente de trabajo DevOps
-
1.1 Parametrización de integración continua / despliegue continuo
- 1.1.1 Herramienta y alcance
- 1.1.2 Pipelines por componente
- 1.1.3 Etapas del pipeline
- 1.1.4 Parámetros de configuración
- 1.1.5 Puertas de calidad
- 1.1.6 Infraestructura como código (Terraform)
- 1.1.7 Contenedores (Docker) y registro de imágenes (ECR)
- 1.1.8 Despliegue continuo: estado y plan
- 1.1.9 Manejo de secretos
- 1.2 Sprint Backlog y asignación por integrante (10 puntos)
- 1.3 Commits / pull requests (15 puntos)
- 1.4 Flujo de trabajo y estrategia de versionamiento (10 puntos)
- 1.6 Peer review (opcional)
- 1.7 Revisión automática de código (opcional)
-
1.1 Parametrización de integración continua / despliegue continuo
- 2. Evidencias de avance semanal (15 puntos)
- 3. Tablero del Proyecto (15 puntos)
- 4. Video con evidencias (15 puntos)
- Control de versiones
Descripción general del ambiente DevOps montado para el Sprint 1 del PF2: repositorios, pipelines, ramas y responsables.
| Criterio | Estado al cierre de la semana 1 |
|---|---|
| Herramienta de CI/CD seleccionada | ✅ GitHub Actions + Codecov |
| Pipelines por componente (web, móvil, backend/BFF) | ✅ Siete workflows en .github/workflows/
|
| Etapas: build, pruebas, cobertura, empaquetado | ✅ Automatizadas en cada Pull Request |
| Etapas: análisis estático y despliegue | ⏳ Planeadas; ver 1.1.8 |
| Contenedores y registro de imágenes | ✅ Imágenes Docker por componente y repositorios ECR definidos; ver 1.1.7 |
| Manejo de secretos | ✅ Secrets Manager, KMS y External Secrets definidos como código; ver 1.1.9 |
| Infraestructura como código | ✅ Terraform y Helm versionados; ver 1.1.6 |
| Evidencia de ejecuciones exitosas | ✅ Ver la pestaña Actions del repositorio |
El equipo usa GitHub Actions como motor de integración continua y Codecov como servicio de cobertura. Se eligió GitHub Actions porque el código, los Pull Requests y las reglas de rama ya viven en GitHub, lo que permite que el resultado del pipeline sea una condición de fusión sin integrar otra herramienta.
Todo el código está en un monorepo (MISO-PROYECTO-FINAL-SOLVENTA) con tres componentes: apps/web (Angular), apps/mobile/Solventa (Android) y apps/backend (microservicios y BFF en FastAPI). Cada componente tiene su propio pipeline y cada pipeline se dispara solo cuando cambian archivos de su carpeta (filtro paths), de modo que un cambio en web no ejecuta las pruebas de móvil ni de backend.
Los siete workflows se agrupan por propósito: políticas del repositorio, pruebas y empaquetado.
Workflows de políticas
| Workflow | Componente | Se dispara con | Qué hace |
|---|---|---|---|
branch-flow-policy.yml |
Todo el repositorio | PR hacia develop, main o release/**
|
Valida que la rama origen sea la permitida para la rama destino (GitFlow, 1.4) |
Workflows de pruebas
| Workflow | Componente | Se dispara con | Qué hace |
|---|---|---|---|
backend-unit-tests.yml |
Backend y BFF | Push a develop, main, feature/**, release/**, hotfix/** y PR, con cambios en apps/backend/**
|
Selecciona los servicios modificados, instala cada uno en su entorno, ejecuta PyTest con cobertura y publica JUnit y cobertura |
web-pr.yml |
Web | PR (apertura, nuevos commits y fusión) con cambios en apps/web/**
|
Pruebas unitarias con cobertura; luego construye la imagen nginx del portal y ejecuta las pruebas E2E contra ella |
mobile-pr.yml |
Móvil | PR con cambios en apps/mobile/Solventa/**
|
Compila y ejecuta las pruebas unitarias con cobertura JaCoCo |
mobile-e2e.yml |
Móvil | PR fusionado en develop
|
Pruebas instrumentadas en un emulador Android (API 34) |
Workflows de empaquetado
| Workflow | Componente | Se dispara con | Qué hace |
|---|---|---|---|
docker-images.yml |
Backend (arquetipos) | Push y PR con cambios en ms-arquetipo o bff-arquetipo
|
Construye la imagen de pruebas, ejecuta las pruebas dentro del contenedor y construye la imagen de ejecución |
mobile-apk.yml |
Móvil | Push a develop o main
|
Compila el APK de depuración y lo publica como artefacto descargable |
flowchart LR
PR[Pull Request] --> POL[Política de ramas]
PR --> BE[Backend: selección de servicios]
PR --> WEB[Web: pruebas unitarias]
PR --> MOB[Móvil: pruebas unitarias]
BE --> BET[PyTest + cobertura]
BET --> COV[Codecov ≥ 80 %]
WEB --> WEBE[Imagen nginx + E2E]
WEB --> COV
MOB --> COV
POL --> GATE{Checks requeridos + 1 aprobación}
COV --> GATE
GATE --> DEV[Fusión en develop]
DEV --> APK[APK de depuración]
DEV --> ME2E[E2E móvil en emulador]
| Etapa | Backend / BFF | Web | Móvil |
|---|---|---|---|
| Preparación | Python 3.12; entorno virtual por servicio | Node 22.22.3, pnpm con --frozen-lockfile, Chrome |
JDK 25 (Temurin), caché de Gradle, licencias del SDK |
| Build | Instalación del paquete e importación de app.main
|
ng build dentro de la imagen Docker del portal |
Compilación Gradle del módulo app
|
| Pruebas unitarias | PyTest, excluyendo los marcadores integration y contract
|
Karma + Jasmine en Chrome sin interfaz | JUnit (createDebugUnitTestCoverageReport) |
| Cobertura |
pytest-cov → Codecov, bandera backend
|
lcov → Codecov, bandera web
|
JaCoCo → Codecov, bandera mobile
|
| Pruebas E2E | — | Cucumber + Playwright contra la imagen nginx | Pruebas instrumentadas en emulador, después de la fusión |
| Empaquetado | Imágenes Docker de los arquetipos (prueba y ejecución) | Imagen nginx con el build de producción | APK de depuración |
| Artefactos | Reportes JUnit y de cobertura | Reporte de cobertura | Reporte de cobertura (14 días) y APK (14 días) |
| Parámetro | Valor | Dónde se define |
|---|---|---|
| Ejecutor |
ubuntu-latest (ejecutores de GitHub) |
Cada workflow |
| Filtro por carpeta |
apps/backend/**, apps/web/**, apps/mobile/Solventa/**
|
Clave paths de cada workflow |
| Selección de servicios backend | Solo los servicios con cambios; bff-web y bff-movil se ejecutan siempre en cada push a develop, main, release/** y hotfix/**
|
apps/backend/scripts/select_services.py |
| Regla de pruebas backend | No se permite sleep() en pruebas unitarias; el job falla si lo detecta |
backend-unit-tests.yml |
| Cobertura mínima | 80 % por proyecto, por componente y sobre el código nuevo del PR | codecov.yml |
| Umbral local web | 100 % en sentencias, ramas, funciones y líneas | apps/web/angular.json |
| Secretos |
CODECOV_TOKEN en GitHub Secrets; el secreto de firma de tokens usa un valor de prueba solo dentro del job |
Settings → Secrets and variables |
| Permisos del token |
permissions: {} en la política de ramas y contents: read en imágenes Docker |
Cada workflow |
El resultado del pipeline condiciona la fusión mediante rulesets del repositorio:
| Rama | Requisitos para fusionar |
|---|---|
develop |
Pull Request, 1 aprobación, checks validate-source-branch y codecov/patch en verde; sin force push ni borrado |
main |
Pull Request, 1 aprobación, check validate-source-branch en verde; sin force push ni borrado |
release/** |
Pull Request, 1 aprobación, check validate-source-branch en verde |
La política de ramas rechaza automáticamente un PR cuya rama origen no corresponda: develop solo recibe feature/*, release/* y hotfix/*; main solo recibe release/* y hotfix/*; release/* solo recibe bugfix/*.
La infraestructura de AWS sobre la que se desplegará Solventa está definida con Terraform en infra/terraform, alineada con la vista de despliegue del documento de arquitectura. Cubre el ambiente mínimo de producto: un ambiente que se levanta, se usa para evidenciar y se destruye, de modo que siempre se parte de una infraestructura idéntica y reproducible.
Estructura
infra/terraform/
├── README.md # uso, costo y verificación
├── PLAN.md # decisiones y trazabilidad contra el diagrama de despliegue
├── environments/
│ └── minimo/ # ambiente mínimo: composición de los módulos
│ ├── main.tf # instancia y conecta los módulos
│ ├── variables.tf # 61 variables (región, tamaños, banderas de costo)
│ ├── outputs.tf # 21 salidas (endpoints, ARN, nombres)
│ ├── providers.tf # AWS (región principal y us-east-1) y Helm
│ ├── versions.tf # versiones de Terraform y de los providers
│ ├── backend.tf.example
│ └── terraform.tfvars.example
└── modules/ # un módulo por servicio de la arquitectura
Los 17 módulos se agrupan por capa:
| Capa | Módulos | Qué crean |
|---|---|---|
| Base |
network, security_groups, kms, secrets
|
VPC y subredes en dos zonas, grupos de seguridad por nivel, llaves de cifrado y Secrets Manager |
| Datos |
rds_polizas, rds_siniestros, rds_compartida, elasticache, msk
|
Tres instancias PostgreSQL (pólizas con réplica de lectura, siniestros con respaldo Multi-AZ, y una compartida para los demás esquemas), Redis y Kafka |
| Cómputo |
eks, eks_addons, ecr, irsa_aplicacion
|
Clúster EKS con dos grupos de nodos, complementos del clúster, un repositorio de imágenes por microservicio y un rol IAM por servicio |
| Borde y almacenamiento |
alb, edge, s3_evidencias
|
Balanceador interno, API Gateway, WAF, CloudFront, hosting de la SPA y bucket de evidencias |
| Observabilidad | observability |
Grupos de logs, alarmas y tablero de CloudWatch |
Configuración
| Aspecto | Valor |
|---|---|
| Versiones | Terraform ≥ 1.5.0; providers AWS ~> 5.0, Helm ~> 2.12, Random ~> 3.6 y TLS ≥ 4.0 |
| Parametrización | Cada ambiente se ajusta con terraform.tfvars, a partir de terraform.tfvars.example
|
| Estado | Local (.tfstate fuera del repositorio por .gitignore); backend.tf.example documenta la migración a S3 si el equipo necesita compartirlo |
| Nombres y etiquetas |
solventa-<ambiente>-<recurso>, con las etiquetas Project, Environment y ManagedBy = "terraform" en todos los recursos |
| Seguridad | Cifrado en reposo con llaves propias (KMS); credenciales generadas por Terraform y guardadas en Secrets Manager, sin contraseñas en el código |
| Costo | Variables para reducir el gasto en pruebas: un solo NAT, menos brokers de Kafka, instancias y nodos más pequeños |
| Destrucción | Sin protección de borrado ni snapshot final en el ambiente mínimo, para que terraform destroy deje la cuenta limpia |
Frontera con Kubernetes. Terraform crea la plataforma: red, clúster, complementos, repositorios de imágenes, bases de datos, caché, bus de eventos y borde. Los despliegues de los microservicios no están en Terraform: viven en infra/k8s como un chart de Helm genérico con un archivo de valores por componente. Así, publicar una nueva versión de un microservicio no exige reaplicar la infraestructura, y el autoescalado se ajusta en Kubernetes.
Uso
cd infra/terraform/environments/minimo
cp terraform.tfvars.example terraform.tfvars # ajustar valores
terraform init
terraform plan
terraform apply
terraform destroy # deja la cuenta limpiaVerificación. El código se valida con terraform fmt -check -recursive y terraform validate. Hoy Terraform se ejecuta de forma manual; su integración al pipeline está en el plan de 1.1.8.
Cada componente desplegable se empaqueta como una imagen Docker. La imagen es la unidad que viaja por el pipeline: se construye y se prueba en integración continua, se almacena en Amazon ECR y es lo que el clúster EKS ejecuta.
Patrón de imagen del backend
Los microservicios y los BFF comparten un mismo Dockerfile de tres etapas, definido en los arquetipos (ms-arquetipo y bff-arquetipo) y copiado por cada servicio nuevo:
| Etapa | Contenido | Uso |
|---|---|---|
base |
python:3.12.7-slim-bookworm, pyproject.toml y el código de app/
|
Capa común de las otras dos etapas |
test |
Dependencias de prueba y carpeta tests/; su comando ejecuta PyTest con cobertura |
Probar el servicio dentro del mismo contenedor que se va a ejecutar |
runtime |
Solo dependencias de ejecución; usuario sin privilegios; arranca uvicorn
|
Imagen que se publica y se despliega |
docker build --target test -t ms-cotizacion:test apps/backend/ms-cotizacion
docker run --rm ms-cotizacion:test # ejecuta las pruebas
docker build --target runtime -t ms-cotizacion:runtime apps/backend/ms-cotizacionDecisiones del patrón:
-
Versión fija de la imagen base (
3.12.7-slim-bookworm), para que la construcción sea reproducible. -
Dependencias fijadas con
requirements.locken los arquetipos. -
Usuario sin privilegios en la etapa
runtime; el chart de Helm exige ademásrunAsNonRooty sistema de archivos de solo lectura. -
.dockerignoreque excluye entornos virtuales, cachés, reportes y archivos.env. -
Los BFF se construyen desde
apps/backendcomo contexto (-f <servicio>/Dockerfile), porque suDockerfilecopia rutas relativas a esa carpeta.
Estado por componente
| Componente | Dockerfile |
Contexto de construcción | Puerto | Entorno local (docker-compose.yml) |
|---|---|---|---|---|
ms-arquetipo |
✅ | apps/backend/ms-arquetipo |
8080 | Servicio + PostgreSQL 16.4 |
bff-arquetipo |
✅ | apps/backend |
8080 | BFF + microservicio de ejemplo + PostgreSQL |
ms-cotizacion |
✅ | apps/backend/ms-cotizacion |
8000 | Servicio + PostgreSQL 16.4 |
api-socios |
✅ | apps/backend |
8080 | API + ms-cotizacion + PostgreSQL |
| Portal web | ✅ | apps/web |
80 | Portal servido por nginx en el puerto 8080 |
bff-web, bff-movil
|
⏳ | — | — | Se ejecutan con uvicorn; su imagen se crea a partir de bff-arquetipo
|
| Demás microservicios | ⏳ | — | — | Se crean a partir de ms-arquetipo cuando entra su primera historia |
La imagen del portal web tiene dos etapas: node:22.22.3-bookworm compila la aplicación Angular y nginx:1.27-alpine sirve el resultado. Es la misma imagen contra la que el pipeline ejecuta las pruebas E2E.
Entorno local. Cada servicio con Dockerfile trae un docker-compose.yml que levanta la etapa runtime junto con sus dependencias. La base de datos se inicializa con los scripts de la carpeta db/ del servicio y la aplicación espera a que PostgreSQL esté saludable antes de arrancar:
cd apps/backend/ms-cotizacion
docker compose up --buildDocker en el pipeline. El workflow docker-images.yml construye la etapa test de los arquetipos, ejecuta las pruebas dentro del contenedor, construye la etapa runtime y registra las versiones de Python y de las dependencias instaladas. El workflow web-pr.yml construye la imagen del portal y la usa como ambiente de las pruebas E2E.
Configuración de ECR
Los repositorios de imágenes se crean con el módulo ecr de Terraform (1.1.6):
| Aspecto | Configuración |
|---|---|
| Repositorios | Uno por componente desplegable, 14 en total: nueve microservicios (ms-*), bff-web, bff-movil, api-socios, analitica y notificaciones
|
| Nombre |
solventa-<ambiente>-<componente>; por ejemplo, solventa-minimo-ms-cotizacion
|
| Análisis de vulnerabilidades | Activado en cada publicación (scan_on_push) |
| Cifrado | En reposo, con una llave propia de KMS |
| Retención | Se conservan las 10 imágenes etiquetadas más recientes; las imágenes sin etiqueta expiran a los 7 días |
| Etiquetas | Mutables, para poder mover la etiqueta develop; cada despliegue referencia el SHA del commit |
| Lectura desde el clúster | Los nodos de EKS tienen la política AmazonEC2ContainerRegistryReadOnly, por lo que descargan imágenes sin credenciales en los manifiestos |
| Salida |
ecr_repository_urls entrega la URL de cada repositorio para el pipeline y para Helm |
Cada archivo de valores de Helm en infra/k8s/values/ ya apunta a su repositorio (<cuenta>.dkr.ecr.us-east-1.amazonaws.com/solventa-minimo-<componente>) y deja la etiqueta de la imagen vacía, porque la fija el pipeline en cada despliegue.
Publicación de una imagen. Con el ambiente creado, una imagen se publica con las etiquetas definidas en la estrategia de versionamiento:
REGISTRO=<cuenta>.dkr.ecr.us-east-1.amazonaws.com
REPO=$REGISTRO/solventa-minimo-ms-cotizacion
SHA=$(git rev-parse --short HEAD)
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $REGISTRO
docker build --target runtime -t $REPO:develop -t $REPO:sha-$SHA apps/backend/ms-cotizacion
docker push --all-tags $REPOAutomatizar esta publicación desde GitHub Actions es el siguiente paso del pipeline y está en el plan de 1.1.8. Requiere un rol de IAM que GitHub Actions asuma por OIDC, sin llaves de AWS guardadas en el repositorio.
En la semana 1 el pipeline cubre la integración continua y la entrega de artefactos (APK e imágenes construidas y probadas). El despliegue automático a un ambiente se esta trabajando sobre ECR. La infraestructura ya está descrita como código (infra/terraform para AWS e infra/k8s con el chart de Helm de los microservicios).
Estrategia de entrega y despliegue
El despliegue se hace desde GitHub Actions hacia el clúster de EKS, con las imágenes en ECR y el chart de Helm de infra/k8s. La estrategia se apoya en cuatro reglas:
- La imagen se construye una sola vez. La misma imagen que pasó las pruebas es la que se despliega; entre ambientes se promueve la imagen, no se reconstruye.
-
Cada despliegue referencia el SHA del commit. La etiqueta
sha-<commit>identifica una imagen única;developy el número de versión son etiquetas de lectura que se mueven. -
Sin llaves de AWS en el repositorio. GitHub Actions asume un rol de IAM por OIDC, con credenciales temporales y permisos limitados a publicar en ECR y desplegar en el namespace
solventa. -
Solo se despliega lo que cambió. El pipeline reutiliza la selección de servicios de
backend-unit-tests.ymlpara construir y desplegar únicamente los componentes modificados.
flowchart LR
MERGE["Merge a develop"] --> CI["Pruebas unitarias y cobertura"]
CI --> BUILD["Construir imagen runtime"]
BUILD --> PUSH["Publicar en ECR: develop + sha"]
PUSH --> SCAN["Análisis de vulnerabilidades de ECR"]
SCAN --> DEPLOY["helm upgrade --install con el sha"]
DEPLOY --> CHECK["Verificar rollout y salud"]
CHECK -->|falla| ROLLBACK["Rollback automático de Helm"]
TAG["Tag vX.Y.Z en main"] --> PROMO["Etiquetar la misma imagen con la versión"]
PROMO --> APROB["Aprobación manual"]
APROB --> DEPLOY
| Etapa | Qué hace | Con qué |
|---|---|---|
| Autenticación | Asume el rol de despliegue con credenciales temporales |
aws-actions/configure-aws-credentials con OIDC |
| Construcción | Construye la etapa runtime de cada servicio modificado |
docker build --target runtime |
| Publicación | Publica la imagen con las etiquetas develop y sha-<commit>
|
aws-actions/amazon-ecr-login y docker push
|
| Análisis de la imagen | ECR analiza la imagen al recibirla; el pipeline consulta el resultado y se detiene ante vulnerabilidades críticas |
scan_on_push del módulo ecr
|
| Despliegue | Actualiza el release del componente fijando la etiqueta de la imagen | helm upgrade --install --atomic --set imagen.tag=sha-<commit> |
| Verificación | Espera a que los pods nuevos estén listos | Sondas startup, readiness y liveness del chart |
| Reversión | Si el despliegue no queda saludable dentro del tiempo límite, Helm vuelve a la versión anterior | --atomic --timeout |
Despliegue de un componente. El pipeline ejecuta por cada servicio modificado el mismo comando que hoy se usa a mano, agregando la etiqueta de la imagen:
aws eks update-kubeconfig --name <cluster> --region us-east-1
helm upgrade --install ms-cotizacion infra/k8s/charts/microservicio \
--namespace solventa \
--values infra/k8s/values/ms-cotizacion.yaml \
--set imagen.tag=sha-$SHA \
--atomic --timeout 5mActualización sin interrupción. El chart despliega cada componente como un Deployment con actualización gradual (rolling update): Kubernetes crea los pods nuevos, espera a que respondan la sonda de disponibilidad y solo entonces retira los anteriores. El PodDisruptionBudget del chart mantiene un mínimo de réplicas atendiendo durante el cambio.
Disparadores por rama
| Evento | Entrega | Despliegue |
|---|---|---|
PR hacia develop
|
Ninguna; solo integración continua | Ninguno |
Merge a develop
|
Imagen en ECR con develop + sha-<commit>
|
Automático al ambiente de desarrollo |
Tag vX.Y.Z en main
|
La imagen ya publicada recibe la etiqueta de la versión | Con aprobación manual, mediante un environment de GitHub |
El despliegue desde develop es automático (despliegue continuo) y el de una versión requiere aprobación (entrega continua), de modo que lo que se muestra en la revisión del sprint siempre es una versión decidida por el equipo.
Reversión manual. Como cada despliegue queda asociado a un SHA, volver a una versión anterior es ejecutar el mismo workflow con el SHA anterior, o helm rollback <componente> sobre el clúster.
Qué falta para ponerla en marcha
| Brecha | Plan |
|---|---|
| Rol de despliegue | Crear en Terraform el proveedor OIDC de GitHub y el rol de IAM con permiso de publicación en ECR y acceso al clúster |
| Publicación de imágenes | Workflow que publique en ECR desde develop con etiqueta develop + SHA, extendido a todos los servicios con Dockerfile
|
| Despliegue a un ambiente | Workflow que ejecute helm upgrade al fusionar en develop y, con aprobación, al etiquetar una versión |
| Valores de Helm | Reemplazar los marcadores de infra/k8s/values/ (cuenta de AWS, endpoints) con las salidas de Terraform antes de desplegar |
| Validación de infraestructura |
terraform plan en los PR que cambien infra/
|
| Análisis estático | Agregar ruff (backend), ESLint (web) y lint de Android como jobs del PR |
| Pruebas como requisito de fusión | Marcar como requeridos los checks de pruebas unitarias y E2E |
| Liberación por versión | Publicar artefactos versionados al etiquetar main
|
Ninguna credencial vive en el código ni en los manifiestos. Cada secreto se guarda en el servicio propio del nivel donde se usa, y los componentes lo reciben en tiempo de ejecución:
| Nivel | Dónde se guardan | Qué contiene hoy | Quién lo lee |
|---|---|---|---|
| Pipeline | Secrets de GitHub Actions |
CODECOV_TOKEN, el único secreto del repositorio |
Los workflows de backend, web y móvil al publicar la cobertura |
| Infraestructura | AWS Secrets Manager, creado con el módulo secrets de Terraform |
10 secretos: 3 de bases de datos y 7 de proveedores externos | El clúster de EKS |
| Clúster |
Secret de Kubernetes, sincronizado por External Secrets Operator |
Copia de los secretos que cada componente declara | Los pods, como variables de entorno |
| Desarrollo local |
docker-compose.yml de cada servicio |
Credenciales de prueba de PostgreSQL, sin valor fuera del equipo local | El desarrollador |
Secretos en AWS
| Aspecto | Configuración |
|---|---|
| Nombre |
solventa-<ambiente>-<recurso>-credentials; por ejemplo, solventa-minimo-polizas-db-credentials
|
| Bases de datos |
polizas-db, siniestros-db y compartida-db, cada uno con usuario, contraseña, host, puerto y nombre de la base |
| Proveedores externos |
open_finance, open_data, kyc_aml, pasarela_pago, firma_electronica, telemetria_iot y reaseguro_acord
|
| Generación | Terraform genera la contraseña maestra de cada base de datos y el token de Redis con random_password; nadie las define a mano |
| Cifrado | En reposo, con una llave de KMS dedicada a los secretos y con rotación anual de la llave activada |
| Borrado | Ventana de recuperación configurable (secrets_recovery_window_in_days) antes de la eliminación definitiva |
| Exposición en Terraform | Las variables y salidas con credenciales están marcadas sensitive, por lo que no aparecen en la salida de plan ni de apply
|
Del secreto al contenedor
flowchart LR
TF["Terraform: genera la contraseña"] --> SM["AWS Secrets Manager, cifrado con KMS"]
SM --> ESO["External Secrets Operator"]
ESO --> KS["Secret de Kubernetes"]
KS --> POD["Pod: variables de entorno"]
IRSA["Rol de IAM de la cuenta de servicio"] -.-> ESO
-
Terraform crea el secreto en Secrets Manager al aprovisionar la base de datos.
-
El
ClusterSecretStore(infra/k8s/platform/clustersecretstore.yaml) conecta el clúster con Secrets Manager. El operador se autentica con el rol de IAM de su cuenta de servicio (IRSA), sin llaves de acceso. -
Cada componente declara en su archivo de valores qué secretos necesita, y el chart genera un
ExternalSecretpor cada uno:externalSecrets: habilitado: true secretStoreRef: solventa-secretstore remoteSecrets: - nombreRemoto: solventa-minimo-open_finance-credentials nombreLocal: ms-cotizacion-open-finance claves: - clientId - clientSecret
-
El operador copia el valor a un
Secretde Kubernetes y lo vuelve a sincronizar cada hora. -
El chart inyecta ese
Secretal contenedor como variables de entorno. Cuando cambia la lista de secretos de un componente, el chart reinicia sus pods para que tomen el cambio.
Acceso a servicios de AWS sin secretos. Los componentes que usan S3 o MSK (ms-siniestros, ms-parametrico, ms-pagos, analitica y notificaciones) no reciben llaves: cada uno tiene un rol de IAM propio, con permisos mínimos, ligado a su cuenta de servicio de Kubernetes. Los nodos descargan las imágenes de ECR con el rol del nodo. El despliegue desde GitHub Actions seguirá el mismo criterio con OIDC (1.1.8).
Protección en el repositorio. El .gitignore excluye los archivos .env*, el estado de Terraform (*.tfstate) y los almacenes de llaves de Android (*.keystore). Los archivos de valores de Helm solo contienen el nombre del secreto, nunca su valor.
Pendientes
| Brecha | Plan |
|---|---|
| Permiso del operador | Limitar el rol de External Secrets a los secretos solventa-*; hoy puede leer cualquier secreto de la cuenta |
| Estado de Terraform | Mover el estado a un backend remoto cifrado (S3); hoy es local y contiene las contraseñas generadas |
| Variables de Terraform | Agregar *.tfvars al .gitignore para que un archivo con valores reales no llegue al repositorio |
| Secretos de proveedores externos | Se crean vacíos; su valor se carga en Secrets Manager después del aprovisionamiento |
| Rotación de credenciales | Definir la rotación de las contraseñas de base de datos |
| Detección de secretos | Agregar un análisis de secretos al pipeline del PR |
Historias del Sprint 1 cargadas en el tablero https://uniandes-team-proyecto.atlassian.net/jira/software/projects/SOLV/boards/1?filter=&groupBy=none
-
Convención de mensajes de commit https://github.com/martin-hendricks/MISO-PROYECTO-FINAL-SOLVENTA/commits/develop
-
Plantilla y checklist de Pull Request https://github.com/martin-hendricks/MISO-PROYECTO-FINAL-SOLVENTA/pulls?q=is%3Apr+state%3Aclosed
El equipo trabaja con GitFlow, como fija el acuerdo de gestión de código y ramas de la página de inicio: todo desarrollo nuevo sale de develop y vuelve a develop por Pull Request. La misma estrategia aplica a todos los repositorios del equipo (web, móvil y backend).
Las reglas que gobiernan todo lo demás:
-
mainsolo contiene versiones liberadas. Cada commit enmaincorresponde a un tagvX.Y.Zy es lo que se presenta en la revisión de sprint. -
developes la rama de integración. Refleja lo último terminado del sprint en curso y siempre debe compilar y pasar las pruebas. -
Nadie hace push directo a
mainni adevelop. Todo cambio entra por Pull Request con CI en verde y al menos una aprobación (acuerdo de revisión por pares).
Por qué GitFlow y no GitHub Flow. El PF2 se entrega en tres sprints con una revisión al cierre de cada uno. GitFlow separa lo que se está integrando (develop) de lo que ya se mostró y aceptó (main), y la rama release/* da un espacio para estabilizar el incremento antes de la demo sin congelar el trabajo del siguiente sprint. Con un equipo pequeño y CI automatizado, el costo extra de mantener develop es bajo.
| Rama | Tipo | Nace de | Se fusiona en | Propósito | Vida |
|---|---|---|---|---|---|
main |
Permanente | — | — | Versiones liberadas y etiquetadas. Es lo que se demuestra al cierre de cada sprint. | Todo el proyecto |
develop |
Permanente |
main (una sola vez) |
release/* |
Integración continua del sprint en curso. | Todo el proyecto |
feature/* |
Temporal | develop |
develop |
Una historia de usuario o de arquitectura. | Días; idealmente ≤ 3 |
bugfix/* |
Temporal | develop |
develop |
Defecto encontrado en develop, antes de liberar. |
Horas o días |
release/* |
Temporal | develop |
main y develop
|
Estabilizar el incremento del sprint: solo correcciones, versión y notas de liberación. No entran funcionalidades nuevas. | Del cierre del desarrollo a la demo |
hotfix/* |
Temporal | main |
main y develop
|
Defecto en una versión ya liberada que no puede esperar al siguiente sprint. | Horas |
gitGraph
commit id: "init"
branch develop
checkout develop
commit id: "ci: pipeline base"
branch feature/HU-123-descripcion
checkout feature/HU-123-descripcion
commit id: "feat: cambio A"
commit id: "test: pruebas A"
checkout develop
merge feature/HU-123-descripcion
branch feature/HU-124-descripcion
checkout feature/HU-124-descripcion
commit id: "feat: cambio B"
checkout develop
merge feature/HU-124-descripcion
branch release/0.1.0
checkout release/0.1.0
commit id: "fix: estabilizacion"
checkout main
merge release/0.1.0 tag: "v0.1.0"
checkout develop
merge release/0.1.0
checkout main
branch hotfix/0.1.1
checkout hotfix/0.1.1
commit id: "fix: correccion urgente"
checkout main
merge hotfix/0.1.1 tag: "v0.1.1"
checkout develop
merge hotfix/0.1.1
Formato: <tipo>/<clave-HU>-<descripcion-corta>
| Regla | Detalle |
|---|---|
| Tipo |
feature, bugfix, release o hotfix
|
| Clave HU | Identificador de la historia de usuario en el backlog refinado (ej. HU-123), no el número de ticket de Jira. Enlaza la rama con la historia del sprint backlog y con su tarjeta correspondiente en el tablero. |
| Descripción | Minúsculas, en kebab-case, sin tildes ni ñ, máximo 5 palabras |
release y hotfix
|
Llevan el número de versión en lugar de la clave HU: release/0.1.0, hotfix/0.1.1
|
| Correcto | Incorrecto | Por qué |
|---|---|---|
feature/HU-123-registro-usuario |
feature/registro |
Sin clave HU no hay trazabilidad con la historia |
feature/HU-124-consulta-poliza |
Feature/HU-124_ConsultaPoliza |
Mayúsculas y _ rompen la convención |
bugfix/HU-125-validacion-formulario |
fix-formulario |
Falta tipo con / y clave |
release/0.1.0 |
release/sprint-1 |
La rama de release se nombra por versión, no por sprint |
hotfix/0.1.1 |
hotfix/HU-126 |
El hotfix se nombra por la versión que produce |
Desarrollo de una historia (feature/* / bugfix/*)
- Mover la historia a En curso en Jira (sistema pull, ver metodología).
- Actualizar
developy crear la rama:git checkout develop git pull origin develop git checkout -b feature/HU-123-descripcion-corta
- Hacer commits pequeños con la convención de mensajes de la §1.3 (Conventional Commits con la clave HU).
- Mantener la rama al día con
develop(git pull --rebase origin developo merge dedevelop) al menos una vez al día para evitar conflictos grandes. - Abrir Pull Request hacia
developcon la plantilla del repositorio. El PR dispara el pipeline de la §1.1: build, pruebas unitarias, cobertura y análisis estático. - Revisión por al menos un integrante distinto al autor (CODEOWNERS sugiere el revisor).
- Con CI en verde y aprobación: squash and merge a
developy borrar la rama. - Mover la historia a Hecho solo si cumple la DoD.
Cierre de sprint (release/*)
- Al terminar el desarrollo del sprint se crea
release/X.Y.0desdedevelop. - En la rama de release solo se permiten correcciones, ajuste del número de versión (
package.json,build.gradle,pyproject.toml) y actualización delCHANGELOG.md. - Se abre PR de
release/X.Y.0haciamain. Al aprobarse se fusiona con merge commit (--no-ff) para que la liberación quede visible en el historial. - Se crea el tag anotado
vX.Y.0sobremainy la GitHub Release con las notas. - Se fusiona
release/X.Y.0de vuelta endeveloppara no perder las correcciones, y se borra la rama.
Corrección urgente (hotfix/*)
- Se crea
hotfix/X.Y.Zdesdemain(Z = parche siguiente). - Se corrige, se sube el número de versión y se abre PR hacia
main. - Al fusionar se etiqueta
vX.Y.Zy se fusiona también endevelop(o en larelease/*abierta, si existe).
Se usa versionamiento semántico (SemVer 2.0.0) con formato MAJOR.MINOR.PATCH:
| Componente | Se incrementa cuando… | Ejemplo |
|---|---|---|
| MAJOR | Cambia de forma incompatible un contrato público (API de socios, contrato de un BFF consumido por web o móvil). |
1.4.2 → 2.0.0
|
| MINOR | Se libera funcionalidad nueva compatible hacia atrás. Es el incremento normal al cierre de cada sprint. |
0.1.0 → 0.2.0
|
| PATCH | Se libera una corrección compatible (hotfix o corrección dentro de una release). |
0.2.0 → 0.2.1
|
Hoja de ruta de versiones del PF2. Mientras el producto sea un MVP en construcción se mantiene MAJOR = 0, lo que en SemVer indica que la API todavía puede cambiar:
| Hito | Versión | Contenido |
|---|---|---|
| Cierre Sprint 1 | v0.1.0 |
Incremento aceptado en la revisión del Sprint 1 |
| Cierre Sprint 2 | v0.2.0 |
Incremento aceptado en la revisión del Sprint 2 |
| Cierre Sprint 3 | v0.3.0 |
Incremento aceptado en la revisión del Sprint 3 |
| Entrega final del PF2 | v1.0.0 |
Versión aceptada del MVP; desde aquí los contratos públicos quedan estables |
Reglas de etiquetado
- Cada repositorio (web, móvil, backend) se versiona de forma independiente, pero al cierre de sprint los tres liberan el mismo MINOR para que la demo sea trazable (
v0.1.0web +v0.1.0móvil +v0.1.0backend). - Los tags son anotados y llevan el prefijo
v:git tag -a v0.1.0 -m "Release Sprint 1". - Solo se crean tags sobre commits de
main. Un tag publicado no se mueve ni se borra. - Versiones previas para validación desde
release/*usan sufijo de pre-release:v0.2.0-rc.1. -
Imágenes Docker: se publican con el tag de la versión (
0.1.0) y con el SHA corto del commit (sha-1a2b3c4); las construidas desdedevelopse etiquetandevelop+ SHA, nunca con número de versión. -
App Android:
versionName= versión SemVer;versionCode= entero creciente calculado comoMAJOR*10000 + MINOR*100 + PATCH(ej.0.2.1→201). - Cada liberación actualiza
CHANGELOG.mdagrupando los cambios por tipo (Added, Changed, Fixed), alimentado por los mensajes de commit de la §1.3.
| Evento | Pipeline | Despliegue |
|---|---|---|
Push a feature/* / bugfix/*
|
Build + pruebas unitarias | Ninguno |
PR hacia develop
|
Build, pruebas unitarias, cobertura mínima, análisis estático, terraform plan si hay cambios de IaC |
Ninguno; el PR no se puede fusionar si algún job falla |
Merge a develop
|
Pipeline completo + construcción de imágenes develop-SHA |
Ambiente de desarrollo/integración en AWS |
PR release/* → main
|
Pipeline completo + pruebas de integración/E2E | Ambiente de validación previo a la demo |
Tag vX.Y.Z en main
|
Construcción y publicación de artefactos versionados (imágenes, APK, build web) | Ambiente de demostración del sprint |
El detalle de cada workflow de GitHub Actions se documenta en la §1.1.
Configuradas en Settings → Branches (branch protection rules / rulesets) de cada repositorio:
| Regla | main |
develop |
|---|---|---|
| Requiere Pull Request antes de fusionar | ✅ | ✅ |
| Aprobaciones mínimas | 1 | 1 |
| Descartar aprobaciones si se suben nuevos commits | ✅ | ✅ |
| Requiere revisión de CODEOWNERS | ✅ | ✅ |
| Requiere status checks en verde (build, pruebas, cobertura) | ✅ | ✅ |
| Requiere que la rama esté actualizada antes de fusionar | ✅ | ✅ |
| Requiere resolver todas las conversaciones del PR | ✅ | ✅ |
| Bloquea force push | ✅ | ✅ |
| Bloquea borrado de la rama | ✅ | ✅ |
Solo acepta PR desde release/* y hotfix/*
|
✅ (verificado por el revisor) | — |
| Método de merge permitido | Merge commit | Squash |
Protección de tags v* (solo mantenedores crean tags) |
✅ | — |
Adicionalmente, en cada repositorio se habilita el borrado automático de ramas tras el merge y se mantienen una plantilla de PR y un archivo CODEOWNERS.
-
Ramas cortas: una
feature/*no debería vivir más de tres días; si la historia es más grande, se parte en sub-tareas con su propia rama. - Un propósito por rama: no se mezclan funcionalidades con refactors ni con cambios de infraestructura.
-
developsiempre en verde: si el pipeline falla endevelop, arreglarlo es la prioridad del equipo antes de fusionar nada más. -
Sin secretos en el repositorio: credenciales en GitHub Secrets o AWS SSM Parameter Store; nunca en código ni en
.envversionados. - El PR describe el porqué: enlace a la historia (HU) y a su tarjeta de Jira, qué cambia, cómo se probó y capturas cuando hay cambios de UI.
Integración y liberación. Con GitFlow, una historia se considera integrada cuando llega a
developpor PR revisado; llega amainal cierre del sprint con larelease/*.
El acuerdo del equipo, publicado en Home, exige que todo cambio entre por Pull Request y que lo apruebe al menos un integrante distinto del autor. La definición de hecho repite la misma condición: una historia pasa a Hecho cuando el código fue revisado por otro compañero, las pruebas pasaron y la documentación quedó actualizada. Nadie hace push directo a develop ni a main.
La revisión ocurre en GitHub, sobre el Pull Request hacia develop. El autor describe el cambio, enlaza la historia de Jira, indica cómo se probó y adjunta capturas cuando hay interfaz. Solicita revisión a un compañero que no escribió el cambio. El revisor comprueba que el diff cumple la historia, que los checks del pipeline están en verde y que la rama mantiene un solo propósito. Con al menos una aprobación y los status checks en verde, el Pull Request se fusiona con squash and merge y se borra la rama. Si el revisor pide cambios, el autor corrige y sube commits nuevos; una aprobación previa se descarta y la revisión vuelve a empezar.
flowchart TD
A["Autor toma la historia en Jira<br/>y crea feature/* desde develop"] --> B["Abre Pull Request hacia develop<br/>con historia, pruebas y capturas"]
B --> C["Solicita revisión<br/>a un compañero distinto del autor"]
B --> D["GitHub Actions ejecuta<br/>pruebas, Codecov y política de ramas"]
C --> E{"¿El revisor aprueba?"}
D --> F{"¿Los checks están en verde?"}
E -->|Pide cambios| G["El autor corrige y sube commits.<br/>La aprobación anterior se descarta"]
G --> C
G --> D
F -->|No| G
E -->|Aprueba| H{"¿Hay al menos una aprobación<br/>y los checks en verde?"}
F -->|Sí| H
H -->|No| E
H -->|Sí| I["Squash and merge a develop<br/>y se borra la rama"]
I --> J["La historia pasa a Hecho<br/>cuando cumple la definición de hecho"]
El autor toma la historia en Jira y abre la rama feature/* desde develop. Al abrir el Pull Request quedan en paralelo la solicitud de revisión y GitHub Actions: pruebas, Codecov y la política de ramas de la §1.7. Si el revisor pide cambios o algún check falla, el autor corrige y los dos caminos se vuelven a ejecutar. El merge ocurre cuando hay al menos una aprobación y los checks están en verde. La historia pasa a Hecho cuando, además, cumple la definición de hecho.
La lectura del diff queda en el compañero. El pipeline informa el resultado de las pruebas y de la cobertura.
La revisión automática de cobertura corre en GitHub Actions y se publica en Codecov. La política está en codecov.yml del repositorio MISO-PROYECTO-FINAL-SOLVENTA. El umbral es 80 % para el proyecto y para el patch (el código nuevo o modificado del Pull Request), con un objetivo por plataforma mediante flags: backend, web y mobile. carryforward: true conserva la cobertura de las plataformas que el Pull Request no toca, de modo que un cambio de una sola plataforma mantiene el indicador de las demás.
flowchart TD
PR["Pull Request hacia develop, main, release/* o hotfix/*"] --> RUTAS{"Carpetas que cambian"}
RUTAS -->|apps/mobile| MUT["mobile-pr.yml<br/>JUnit: createDebugUnitTestCoverageReport"]
RUTAS -->|apps/web| WUT["web-pr.yml<br/>unitarias: pnpm test"]
RUTAS -->|apps/backend| BUT["backend-unit-tests.yml<br/>pytest unitario, sin integration ni contract"]
MUT --> MUP["JaCoCo report.xml<br/>flag mobile"]
WUT --> WUP["lcov.info<br/>flag web"]
WUT --> WE2E["E2E en el mismo PR<br/>Cucumber y Playwright contra la imagen nginx"]
BUT --> BUP["coverage.xml<br/>flag backend"]
MUP --> COV["Codecov<br/>codecov.yml"]
WUP --> COV
BUP --> COV
COV --> UMBRAL{"Patch y cobertura del flag<br/>en 80 % o más"}
COV -.-> CF["carryforward conserva<br/>la cobertura de las plataformas que el PR no toca"]
UMBRAL -->|Por debajo| ROJO["Check en rojo en el PR"]
UMBRAL -->|Cumple| VERDE["Check en verde en el PR"]
VERDE --> REV["Se espera la aprobación de un compañero"]
WE2E --> REV
REV --> MERGE["Squash and merge a develop"]
MERGE --> ME2E["mobile-e2e.yml<br/>emulador API 34, connectedDebugAndroidTest"]
Al abrirse o actualizarse un Pull Request hacia develop, main, release/* o hotfix/*, GitHub Actions mira qué carpetas cambiaron y dispara el pipeline de esa plataforma.
En móvil, las unitarias generan el informe JaCoCo y lo suben con el flag mobile. En web, las unitarias suben lcov.info con el flag web y, si quedan en verde, Cucumber corre en el mismo Pull Request contra la imagen nginx. En backend, pytest ejecuta las pruebas unitarias y sube coverage.xml con el flag backend.
Codecov aplica el 80 % al código nuevo del Pull Request y a la cobertura del flag de esa plataforma. Con carryforward, la cobertura de las plataformas que el cambio no toca se conserva. Por debajo del umbral el check queda en rojo. Si lo cumple, queda en verde y el Pull Request espera la aprobación de un compañero (§1.6). Después del merge a develop, el móvil ejecuta las pruebas instrumentadas en el emulador.
| Plataforma | Workflow | Pruebas en el Pull Request | Informe que sube Codecov | Flag | Si falla la subida |
|---|---|---|---|---|---|
| Móvil | mobile-pr.yml |
Unitarias JUnit: ./gradlew :app:createDebugUnitTestCoverageReport
|
JaCoCo report.xml
|
mobile |
El job falla (fail_ci_if_error: true) |
| Móvil E2E | mobile-e2e.yml |
connectedDebugAndroidTest en emulador API 34, después del merge a develop
|
El workflow publica el reporte de la corrida | — | — |
| Web | web-pr.yml |
Unitarias (pnpm test) y luego E2E Cucumber/Playwright contra la imagen nginx |
apps/web/coverage/solventa-web/lcov.info |
web |
El job de pruebas sigue; Codecov no tumba el workflow (fail_ci_if_error: false) |
| Backend | backend-unit-tests.yml |
pytest de los servicios tocados, con -m "not integration and not contract" y --cov-report=xml
|
coverage.xml bajo apps/backend
|
backend |
Igual que web: la subida no tumba el job |
codecov.yml excluye del cálculo móvil las pantallas Compose que cubren las pruebas en dispositivo: MainActivity.kt, CustomerShell.kt, SplashScreen.kt, IdiomaRegionScreen.kt, IdiomaRegionSheet.kt y PerfilScreen.kt.
Codecov marca en el Pull Request las líneas del diff que quedan por debajo del umbral. La lectura del cambio sigue en la revisión por pares de la §1.6.
| Versión | Fecha | Cambios | Autor |
|---|---|---|---|
| 0.1 | 2026-10-09 | Creación del borrador con la estructura de títulos de la rúbrica de la semana 1 del PF2 | Juan Acevedo |
| 0.2 | 2026-10-10 | Proceso de peer review (§1.6) y de revisión automática con Codecov (§1.7), con diagramas de flujo | John Guerrero |