Guía de desarrollo
PrivaSteward
01 Estructura de ramas
siempre estable
base de trabajo
desde develop
desde main
| Rama | Propósito | Merge destino | Quién puede hacer push |
|---|---|---|---|
main | Código en producción. Siempre deployable. | — | Solo vía PR aprobado |
develop | Base de integración. Aquí convergen las features. | main | Solo vía PR aprobado |
feature/* | Una feature o tarea específica. | develop | Autor de la rama |
hotfix/* | Fix urgente que no puede esperar el ciclo normal. | main + develop | Tech Lead o Senior |
main ni a develop. Todo cambio entra por Pull Request. Sin excepción, ni en urgencias.
02 Nombres de rama
Formato: tipo/descripcion-corta-en-kebab-case
feature/rat-riesgos-obligatorios→ nueva funcionalidadfeature/multi-tenant→ nueva funcionalidadfeature/audit-cobertura-completa→ nueva funcionalidadfix/login-token-expiry→ corrección de bughotfix/brecha-sql-injection→ fix urgente de seguridadrefactor/rat-service-cleanup→ limpieza de código sin cambio funcionaldocs/actualizar-api-rat→ solo documentacióntest/cobertura-modulo-consent→ solo tests
03 Commits
Seguimos Conventional Commits. Formato:
tipo(módulo): descripción breve en imperativo # Cuerpo opcional: qué y por qué (no el cómo) # Máximo 72 caracteres por línea
| Tipo | Cuándo usarlo | Ejemplo |
|---|---|---|
feat | Nueva funcionalidad | feat(rat): agregar historial de cambios por campo |
fix | Corrección de bug | fix(auth): corregir expiración de token en Azure AD |
refactor | Reestructuración sin cambio funcional | refactor(consent): extraer lógica de validación a servicio |
test | Agregar o modificar tests | test(arcop): cubrir caso de solicitud duplicada |
docs | Solo documentación | docs: actualizar guía de deploy en README |
chore | Mantenimiento (deps, config) | chore: actualizar ruff a v0.4.0 |
security | Fix de seguridad | security(auth): sanitizar input en endpoint login |
04 Pull Requests
Cuándo abrir un PR
- La feature o fix está completo y los tests pasan localmente (
make test-unit). - Los pre-commit hooks pasan (
make pre-commit). - El PR tiene una descripción que explica qué cambia y por qué.
Plantilla de PR (ya configurada en el repo)
El repo incluye .github/PULL_REQUEST_TEMPLATE.md. Al abrir un PR en GitHub, se carga automáticamente. Los campos obligatorios:
| Campo | Qué escribir |
|---|---|
| Qué cambia este PR | Descripción en lenguaje humano. Qué funciona ahora que antes no funcionaba. |
| Tipo de cambio | Marcar uno: feat / fix / refactor / docs / test / chore / security. |
| Módulos afectados | Marcar los módulos que tocaste (auth, rat, arcop, consent…). |
| Checklist | Todos los ítems deben estar marcados antes de pedir review. |
| Notas para el reviewer | Contexto adicional, screenshots, decisiones de diseño no obvias. |
Tamaño de un PR
05 CI / CD
Pre-commit hooks (local, automático)
Se ejecutan antes de cada commit. Si fallan, el commit no se crea. Incluyen:
| Hook | Qué hace |
|---|---|
| Ruff linter | Detecta errores de estilo, imports desordenados, código muerto. Aplica fixes automáticos. |
| Ruff formatter | Formatea el código (equivalente a black). Sin discusión de estilo. |
| MyPy | Verifica tipado estático de Python. |
| Bandit | Escanea vulnerabilidades de seguridad en el código. |
| detect-secrets | Bloquea commits si detecta contraseñas, tokens o claves hardcodeadas. |
| Tests unitarios rápidos | Corre pytest tests/unit antes de cada commit. Si fallan, el commit no pasa. |
Comandos de calidad (Makefile)
make lint # Analiza código con ruff make format # Formatea código con ruff make type-check # Verifica tipos con mypy make security-scan # Escaneo de seguridad con bandit make test-unit # Tests unitarios make test-all # Todos los tests (unit + integration + e2e + security) make coverage # Genera reporte de cobertura HTML (mínimo: 80%)
fail_under = 80 en pytest. Si la cobertura cae por debajo del 80%, make coverage falla. Un PR que baja la cobertura no se aprueba.
06 Deploy
| Ambiente | Base de datos | Cómo se deploya | Quién puede |
|---|---|---|---|
| Local (dev) | SQLite | make install + python src/run.py | Cualquier miembro del equipo |
| Staging | PostgreSQL | Docker Compose + variables en .env | Senior + Tech Lead |
| Producción | PostgreSQL (Azure) | Pipeline CI/CD desde main | Solo Tech Lead |
Setup local para nuevos integrantes
# 1. Clonar el repo git clone https://github.com/gveraTrnsfty/LeydeProtecciondeDatos.git cd LeydeProtecciondeDatos # 2. Configurar entorno virtual python -m venv venv venv\Scripts\activate # Windows # source venv/bin/activate # Mac/Linux # 3. Instalar dependencias y hooks make install # 4. Copiar variables de entorno cp .env.example .env # Editar .env con los valores que te dará el Tech Lead # 5. Inicializar base de datos local flask db upgrade # 6. Correr el servidor python src/run.py # 7. Verificar que los tests pasan make test-unit
.env está en .gitignore. Nunca lo commiteés. Las credenciales de producción las maneja solo el Tech Lead y están en Azure Key Vault, no en archivos.
07 Roles y responsabilidades
- Decisiones de arquitectura
- Aprueba merge a
main - Gestiona deploys a producción
- Desbloquea al equipo
- Define prioridades técnicas
- Lidera code reviews
- Aprueba PRs a
develop - Mentoreo a practicantes
- Diseña módulos nuevos
- Desarrolla features asignadas
- Escribe tests para su código
- Abre PRs con descripción completa
- Participa en code review
- Señala bloqueos en el daily
feature/*. No tienen acceso de push directo a develop ni a main. Todo su trabajo entra por PR y requiere al menos una aprobación de un desarrollador senior o el Tech Lead.
08 Estándares de código
Python
| Regla | Herramienta | Configuración |
|---|---|---|
| Largo de línea | Ruff | Máximo 120 caracteres (pyproject.toml) |
| Orden de imports | Ruff (isort) | stdlib → third-party → local. Automático. |
| Formato | Ruff formatter | Equivalente a Black. Sin discusión, se aplica automáticamente. |
| Tipado | MyPy | Tipado en funciones nuevas. Módulos legados: best effort. |
| Seguridad | Bandit | Severity medium+. Cero excepciones sin comentario justificado. |
| No prints en producción | Ruff (T20) | Usar logging. Los print() fallan en CI. |
Estructura de un módulo
src/app/ models/ → Modelos SQLAlchemy (solo definición de datos) routes/ → Blueprints Flask (solo HTTP: recibir request, devolver response) services/ → Lógica de negocio (aquí va la carne) templates/ → HTML Jinja2 static/ → CSS, JS, imágenes
services/.
Tests
| Tipo | Dónde | Qué cubren | Cuándo corren |
|---|---|---|---|
| Unit | tests/unit/ | Funciones y servicios en aislamiento | En cada commit (pre-commit hook) |
| Integration | tests/integration/ | Módulos completos + base de datos | Antes de PR a develop |
| E2E | tests/e2e/ | Flujos completos de usuario | Antes de merge a main |
| Security | tests/ + Bandit | Vulnerabilidades y escapes | En CI y pre-commit |
09 Code review
Proceso
| Paso | Quién | Qué hace |
|---|---|---|
| 1. Abrir PR | Autor | Completa la plantilla, asigna reviewer, agrega el tag de módulo. |
| 2. Review | Reviewer asignado | Lee el diff, prueba localmente si hay duda, deja comentarios en línea. Plazo: máximo 24 h hábiles. |
| 3. Respuesta | Autor | Responde cada comentario — ya sea aplicando el cambio o argumentando por qué no. No se ignoran comentarios. |
| 4. Aprobación | Reviewer | Cuando todos los comentarios están resueltos, aprueba el PR. |
| 5. Merge | Autor o Tech Lead | Squash merge a develop. La rama feature se elimina. |
Cómo dar feedback en un code review
| Prefijo | Significado | Ejemplo |
|---|---|---|
| [blocker] | El PR no puede mergearse sin resolverlo. | [blocker] Este query es vulnerable a SQL injection, usar parámetros. |
| [suggestion] | Mejora recomendada, no obligatoria. | [suggestion] Podrías extraer esta lógica a un servicio para testearla más fácil. |
| [question] | Duda genuina, no crítica. | [question] ¿Por qué se usa PATCH acá en vez de PUT? |
| [nit] | Detalle menor de estilo o naming. | [nit] Prefiero `get_active_records` sobre `getActiveData`. |
10 Ceremonias de equipo
- Revisar backlog priorizado
- Cada miembro toma sus tareas
- Estimar esfuerzo (S/M/L o puntos)
- Definir Definition of Done por tarea
- Output: sprint board actualizado
- ¿Qué hice ayer?
- ¿Qué hago hoy?
- ¿Tengo algún bloqueo?
- No es espacio de debate técnico
- Bloqueos se resuelven después, 1:1
- Cada dev muestra lo que completó
- Se demuestra en el ambiente de staging
- Feedback inmediato del equipo
- No se muestra código — se muestra funcionalidad
- ¿Qué salió bien?
- ¿Qué podría mejorar?
- ¿Qué vamos a cambiar?
- Máximo 3 acciones concretas para el próximo sprint
- Importante para el piloto con practicantes
11 Piloto con practicantes — Setup inicial
Qué debe hacer cada practicante en la primera semana
| Día | Tarea | Verificación |
|---|---|---|
| Día 1 | Clonar el repo y completar el setup local (make install) | Servidor levanta en localhost:5000 |
| Día 1 | Correr make test-unit y confirmar que pasan | Verde en terminal |
| Día 2 | Crear su primera rama feature/practicante-[nombre]-hello | Rama visible en GitHub |
| Día 2 | Hacer un commit pequeño siguiendo Conventional Commits | Commit acepta pre-commit hooks |
| Día 3 | Abrir un PR de prueba con la plantilla completa | PR creado con todos los campos |
| Día 3-4 | Recibir y responder un code review de práctica | Al menos un ciclo de feedback |
| Día 5 | Participar en el daily y la retro de fin de semana piloto | Presencia y feedback verbal |
12 Checklist de validación del piloto
Al finalizar la primera semana, cada practicante debería poder marcar estos ítems. El Tech Lead los revisa en la retro.
- Entiendo para qué sirven las ramas
main,developyfeature/* - Sé cómo nombrar una rama correctamente
- Escribí al menos un commit usando Conventional Commits
- El pre-commit hook no me bloqueó por errores de linting o seguridad
- Abrí un PR con la plantilla completa (todos los campos)
- Recibí y respondí al menos un comentario de code review
- Corrí
make test-unity entiendo qué significa la salida - Sé qué datos NO puedo commitear (
.env, credenciales, datos personales reales) - Participé en el daily y sé cuándo señalar un bloqueo
- Este playbook me fue claro — o documenté qué sección no estaba clara para mejorarla
Code review automático en PRs
con Z.AI y GLM 5.2
13 Qué hace y cómo funciona
Cada vez que alguien abre o actualiza un Pull Request en GitHub, una GitHub Action llama automáticamente a GLM 5.2 (a través de tu plan Z.AI) y deja comentarios de revisión directamente en el PR — igual que si un desarrollador senior hubiera leído el diff y escrito sus observaciones.
Qué revisa automáticamente
| Categoría | Qué detecta |
|---|---|
| Bugs potenciales | Errores lógicos, condiciones siempre verdaderas/falsas, variables sin usar |
| Seguridad | SQL injection, secretos hardcodeados, inputs sin sanitizar |
| Calidad de código | Funciones demasiado largas, duplicación evidente, nombres confusos |
| Tests | Código sin cobertura de tests, casos borde no contemplados |
| Cumplimiento Ley 21.719 | Configurable — ver sección de system prompt personalizado |
Flujo completo
14 Setup paso a paso
Paso 1 — Obtener tu API key de Z.AI
- Ir a docs.z.ai → iniciar sesión con tu cuenta del Coding Plan
- Menú → API Keys → Create new key
- Guardar la key — solo se muestra una vez
https://api.z.ai/api/coding/paas/v4No uses el endpoint genérico
api.z.ai/api/openai/v1 — puede consumir créditos fuera del plan.
Paso 2 — Agregar el secret en GitHub
- En el repo LeydeProtecciondeDatos → Settings → Secrets and variables → Actions
- Click en New repository secret
- Nombre:
ZAI_API_KEY· Valor: tu API key del paso 1 - Click Add secret
Paso 3 — Crear el archivo de workflow
Crear el archivo en el repo: .github/workflows/zai-code-review.yml
name: Code Review — Z.AI GLM 5.2
on:
pull_request:
types: [opened, synchronize]
branches:
- develop
- main
jobs:
code-review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write # necesario para dejar comentarios
steps:
- name: Z.AI Code Review
uses: tarmojussila/zai-code-review@v0.4.0
with:
ZAI_API_KEY: ${{ secrets.ZAI_API_KEY }}
env:
ZAI_MODEL: glm-5.2
ZAI_REVIEWER_NAME: "PrivaSteward AI Reviewer"
Paso 4 — Verificar que funciona
- Hacer un commit cualquiera en una rama
feature/* - Abrir un PR hacia
develop - Ir a la pestaña Actions del PR y ver que el workflow corre
- Después de ~30–60 segundos aparecen los comentarios del reviewer en el PR
pull-requests: write habilitados en Settings → Actions → General → Workflow permissions → "Read and write permissions".
15 Configuración avanzada — System prompt personalizado
El comportamiento del reviewer se puede personalizar completamente con un system prompt propio. Esto es especialmente útil para PrivaSteward porque el código maneja datos personales bajo la Ley 21.719.
name: Code Review — Z.AI GLM 5.2
on:
pull_request:
types: [opened, synchronize]
branches:
- develop
- main
jobs:
code-review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Z.AI Code Review
uses: tarmojussila/zai-code-review@v0.4.0
with:
ZAI_API_KEY: ${{ secrets.ZAI_API_KEY }}
env:
ZAI_MODEL: glm-5.2
ZAI_REVIEWER_NAME: "PrivaSteward AI Reviewer"
ZAI_SYSTEM_PROMPT: |
Eres un revisor de código experto para PrivaSteward, sistema de
cumplimiento de la Ley 21.719 de Protección de Datos de Chile.
Stack: Python 3.11, Flask 3.0, SQLAlchemy.
En cada revisión evalúa:
1. SEGURIDAD: SQL injection, inputs sin sanitizar, secretos hardcodeados,
datos personales expuestos en logs o respuestas HTTP.
2. PRIVACIDAD (Ley 21.719): cualquier tratamiento de datos personales
(RUT, nombre, email, salud) debe estar justificado por una base legal
del RAT. Señalar si el código accede a datos sensibles sin control.
3. CALIDAD: funciones con más de 20 líneas de lógica de negocio en rutas
Flask (deben estar en services/), falta de tipado en funciones nuevas,
print() en vez de logging.
4. TESTS: código sin cobertura, casos borde no contemplados.
Formato de respuesta:
- Usa [BLOCKER], [SUGERENCIA] o [PREGUNTA] como prefijo.
- Sé concreto y actionable. No repitas lo que ya hace bien el código.
- Máximo 8 comentarios por PR. Prioriza los más importantes.
ZAI_API_KEY siempre va como secret (Settings → Secrets). Las otras variables (ZAI_MODEL, ZAI_SYSTEM_PROMPT, ZAI_REVIEWER_NAME) pueden ir directamente en el env: del workflow — no son secretas.
Actualizar el modelo sin tocar el workflow
Para cambiar el modelo sin editar el archivo YAML, se puede usar una variable de Actions (Settings → Variables → Actions → New variable):
| Variable | Valor actual | Cómo cambiarla |
|---|---|---|
ZAI_MODEL | glm-5.2 | Settings → Variables → Actions → editar |
ZAI_REVIEWER_NAME | PrivaSteward AI Reviewer | Ídem |
Si usás variables de Actions en vez de valores hardcodeados en el YAML, referéncialas con ${{ vars.ZAI_MODEL }} en el workflow.
16 Integración con Trello — Descripción de PR automática desde el ticket
Combinando la GitHub Action de Z.AI con la action de Trello, el flujo completo queda así: el desarrollador nombra su rama con el ID del ticket de Trello, y el sistema se encarga del resto.
Convención de nombres de rama (ya definida en este playbook)
feature/TSF-42-historial-rat feature/TSF-57-multi-tenant fix/TSF-61-login-azure-ad
El ID de Trello es la parte TSF-42. La action lo lee del nombre de la rama y busca el ticket automáticamente.
Workflow combinado: Trello + Z.AI review
name: PR Automation — Trello + Z.AI Review
on:
pull_request:
types: [opened, synchronize, closed]
branches:
- develop
- main
jobs:
# ── Job 1: Llenar descripción del PR desde Trello ──────────────────
trello-sync:
runs-on: ubuntu-latest
if: github.event.action == 'opened'
permissions:
pull-requests: write
steps:
- name: Trello Card → PR Description
uses: rematocorp/trello-integration-action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
trello-api-key: ${{ secrets.TRELLO_API_KEY }}
trello-auth-token: ${{ secrets.TRELLO_TOKEN }}
trello-board-id: ${{ secrets.TRELLO_BOARD_ID }}
# La action lee el ID de Trello del nombre de la rama (ej: TSF-42)
trello-card-position: top
github-include-pr-branch-name: true
# ── Job 2: Code review automático con GLM 5.2 ─────────────────────
zai-review:
runs-on: ubuntu-latest
if: github.event.action == 'opened' || github.event.action == 'synchronize'
permissions:
contents: read
pull-requests: write
steps:
- name: Z.AI Code Review — GLM 5.2
uses: tarmojussila/zai-code-review@v0.4.0
with:
ZAI_API_KEY: ${{ secrets.ZAI_API_KEY }}
env:
ZAI_MODEL: glm-5.2
ZAI_REVIEWER_NAME: "PrivaSteward AI Reviewer"
# ── Job 3: Mover tarjeta Trello al cerrar PR ──────────────────────
trello-close:
runs-on: ubuntu-latest
if: github.event.action == 'closed' && github.event.pull_request.merged == true
steps:
- name: Mover tarjeta a Done
uses: rematocorp/trello-integration-action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
trello-api-key: ${{ secrets.TRELLO_API_KEY }}
trello-auth-token: ${{ secrets.TRELLO_TOKEN }}
trello-board-id: ${{ secrets.TRELLO_BOARD_ID }}
trello-list-name-done: "Done"
github-include-pr-branch-name: true
Secrets necesarios en GitHub
| Secret | Cómo obtenerlo |
|---|---|
ZAI_API_KEY | docs.z.ai → API Keys → Create new key |
TRELLO_API_KEY | trello.com/app-key (con tu cuenta Trello) |
TRELLO_TOKEN | En la misma página de app-key, click "Token" |
TRELLO_BOARD_ID | URL del tablero: trello.com/b/BOARD_ID/nombre |
feature/TSF-42-historial-rat → abre PR → la descripción se llena con el título y contexto del ticket de Trello → GLM 5.2 revisa el código y deja comentarios → el equipo hace review humano → merge → tarjeta se mueve a Done en Trello. Cero pasos manuales repetitivos.
action == 'opened'). Si la descripción ya tiene texto (porque el dev la escribió manualmente), la action puede sobreescribirla dependiendo de la configuración. Recomendación: dejar la descripción vacía al abrir el PR y dejar que la action la complete.