Hoja de trabajo semana 1 PF2 - martin-hendricks/MISO-PROYECTO-FINAL-SOLVENTA GitHub Wiki

Hoja de trabajo semana 1 — Proyecto Final 2

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.

Índice


1. Configuración del ambiente de trabajo DevOps

Descripción general del ambiente DevOps montado para el Sprint 1 del PF2: repositorios, pipelines, ramas y responsables.

1.1 Parametrización de integración continua / despliegue continuo

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

1.1.1 Herramienta y alcance

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.

1.1.2 Pipelines por componente

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

1.1.3 Etapas del pipeline

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]
Loading
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)

1.1.4 Parámetros de configuración

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

1.1.5 Puertas de calidad

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/*.

1.1.6 Infraestructura como código (Terraform)

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 limpia

Verificació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.

1.1.7 Contenedores (Docker) y registro de imágenes (ECR)

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-cotizacion

Decisiones 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.lock en los arquetipos.
  • Usuario sin privilegios en la etapa runtime; el chart de Helm exige además runAsNonRoot y sistema de archivos de solo lectura.
  • .dockerignore que excluye entornos virtuales, cachés, reportes y archivos .env.
  • Los BFF se construyen desde apps/backend como contexto (-f <servicio>/Dockerfile), porque su Dockerfile copia 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 --build

Docker 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 $REPO

Automatizar 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.

1.1.8 Despliegue continuo: estado y plan

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; develop y 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.yml para 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
Loading
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 5m

Actualizació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

1.1.9 Manejo de secretos

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
Loading
  1. Terraform crea el secreto en Secrets Manager al aprovisionar la base de datos.

  2. 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.

  3. Cada componente declara en su archivo de valores qué secretos necesita, y el chart genera un ExternalSecret por cada uno:

    externalSecrets:
      habilitado: true
      secretStoreRef: solventa-secretstore
      remoteSecrets:
        - nombreRemoto: solventa-minimo-open_finance-credentials
          nombreLocal: ms-cotizacion-open-finance
          claves:
            - clientId
            - clientSecret
  4. El operador copia el valor a un Secret de Kubernetes y lo vuelve a sincronizar cada hora.

  5. El chart inyecta ese Secret al 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

1.2 Sprint Backlog y asignación por integrante (10 puntos)

Historias del Sprint 1 cargadas en el tablero https://uniandes-team-proyecto.atlassian.net/jira/software/projects/SOLV/boards/1?filter=&groupBy=none

1.3 Commits / pull requests (15 puntos)

1.4 Flujo de trabajo y estrategia de versionamiento (10 puntos)

1.4.1 Estrategia: GitFlow

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:

  1. main solo contiene versiones liberadas. Cada commit en main corresponde a un tag vX.Y.Z y es lo que se presenta en la revisión de sprint.
  2. develop es la rama de integración. Refleja lo último terminado del sprint en curso y siempre debe compilar y pasar las pruebas.
  3. Nadie hace push directo a main ni a develop. 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.

1.4.2 Ramas y su propósito

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
Loading

1.4.3 Política de nombres de rama

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

1.4.4 Flujo de trabajo paso a paso

Desarrollo de una historia (feature/* / bugfix/*)

  1. Mover la historia a En curso en Jira (sistema pull, ver metodología).
  2. Actualizar develop y crear la rama:
    git checkout develop
    git pull origin develop
    git checkout -b feature/HU-123-descripcion-corta
  3. Hacer commits pequeños con la convención de mensajes de la §1.3 (Conventional Commits con la clave HU).
  4. Mantener la rama al día con develop (git pull --rebase origin develop o merge de develop) al menos una vez al día para evitar conflictos grandes.
  5. Abrir Pull Request hacia develop con la plantilla del repositorio. El PR dispara el pipeline de la §1.1: build, pruebas unitarias, cobertura y análisis estático.
  6. Revisión por al menos un integrante distinto al autor (CODEOWNERS sugiere el revisor).
  7. Con CI en verde y aprobación: squash and merge a develop y borrar la rama.
  8. Mover la historia a Hecho solo si cumple la DoD.

Cierre de sprint (release/*)

  1. Al terminar el desarrollo del sprint se crea release/X.Y.0 desde develop.
  2. 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 del CHANGELOG.md.
  3. Se abre PR de release/X.Y.0 hacia main. Al aprobarse se fusiona con merge commit (--no-ff) para que la liberación quede visible en el historial.
  4. Se crea el tag anotado vX.Y.0 sobre main y la GitHub Release con las notas.
  5. Se fusiona release/X.Y.0 de vuelta en develop para no perder las correcciones, y se borra la rama.

Corrección urgente (hotfix/*)

  1. Se crea hotfix/X.Y.Z desde main (Z = parche siguiente).
  2. Se corrige, se sube el número de versión y se abre PR hacia main.
  3. Al fusionar se etiqueta vX.Y.Z y se fusiona también en develop (o en la release/* abierta, si existe).

1.4.5 Estrategia de versionamiento

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.0 web + v0.1.0 móvil + v0.1.0 backend).
  • 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 desde develop se etiquetan develop + SHA, nunca con número de versión.
  • App Android: versionName = versión SemVer; versionCode = entero creciente calculado como MAJOR*10000 + MINOR*100 + PATCH (ej. 0.2.1 → 201).
  • Cada liberación actualiza CHANGELOG.md agrupando los cambios por tipo (Added, Changed, Fixed), alimentado por los mensajes de commit de la §1.3.

1.4.6 Relación entre ramas, pipeline y ambientes

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.

1.4.7 Reglas de protección de ramas

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.

1.4.8 Buenas prácticas acordadas

  • 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.
  • develop siempre en verde: si el pipeline falla en develop, 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 .env versionados.
  • 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 develop por PR revisado; llega a main al cierre del sprint con la release/*.

1.6 Peer review (opcional)

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"]
Loading

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.

1.7 Revisión automática de código (opcional)

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"]
Loading

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.


2. Evidencias de avance semanal (15 puntos)

2.1 Burndown chart (5 puntos)

Burndown-chart

2.2 Velocity chart (5 puntos)

Velocity-Chart-Solventa

2.3 Value chart (5 puntos)

Business-Value-Chart-Solventa

Control de versiones

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
⚠️ **GitHub.com Fallback** ⚠️