refactor: make ARNES external-repo based with ticket publish flow
This commit is contained in:
259
HOWTO-FEATURE.md
259
HOWTO-FEATURE.md
@@ -1,228 +1,41 @@
|
||||
# Cómo crear una Feature con SDD y BDD
|
||||
# HOWTO-FEATURE — Crear una feature con SDD y BDD
|
||||
|
||||
Guía paso a paso para crear una feature usando System Design Document y Behavior Driven Development.
|
||||
## Flujo corto
|
||||
1. Crear ticket en backlog (`python3 scripts/new_ticket.py`)
|
||||
2. `design` (architect)
|
||||
3. `build` (implementer)
|
||||
4. `review/security/qa`
|
||||
5. `documentation_gate`
|
||||
6. `close`
|
||||
7. `publish` (`python3 scripts/publish_ticket.py --feature-id F-001`)
|
||||
|
||||
---
|
||||
## Artefactos esperados
|
||||
- `work/artifacts/<feature_id>/triage.md` (opcional)
|
||||
- `work/artifacts/<feature_id>/architect.md` (opcional)
|
||||
- `work/artifacts/<feature_id>/implementer.md`
|
||||
- `work/artifacts/<feature_id>/reviewer.json`
|
||||
- `work/artifacts/<feature_id>/security.json`
|
||||
- `work/artifacts/<feature_id>/qa.json`
|
||||
- `work/artifacts/<feature_id>/documenter.md`
|
||||
- `work/artifacts/<feature_id>/leader-close.json`
|
||||
- `work/artifacts/<feature_id>/publish.json`
|
||||
|
||||
## 📋 Flujo general
|
||||
## Ticket style
|
||||
- English caveman
|
||||
- short title
|
||||
- short acceptance bullets
|
||||
- clear scope in/out
|
||||
|
||||
```
|
||||
1. Analizar la feature del backlog
|
||||
↓
|
||||
2. Crear SPEC/BBD (architect)
|
||||
↓
|
||||
3. Crear/actualizar SDD (architect)
|
||||
↓
|
||||
4. Generar código + tests (implementer)
|
||||
↓
|
||||
5. Review, Security, QA gates
|
||||
↓
|
||||
6. Cerrar feature
|
||||
```
|
||||
## BDD notes
|
||||
- Put `.feature` files in `spec/bdd/features/`
|
||||
- Put steps in `features/steps/`
|
||||
- Use tags like `@F-001`, `@smoke`, `@regression`
|
||||
|
||||
---
|
||||
|
||||
## Paso 1: Analizar del Backlog
|
||||
|
||||
Ejemplo: F-002 "Gestión de Perfil de Usuario"
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "F-002",
|
||||
"title": "Gestión de Perfil de Usuario",
|
||||
"description": "El usuario puede ver y editar su perfil (nombre, avatar, preferencias).",
|
||||
"acceptance": [
|
||||
"Usuario puede ver su perfil",
|
||||
"Usuario puede editar nombre y avatar",
|
||||
"Usuario puede cambiar preferencias de idioma",
|
||||
"Validación de datos en todos los campos"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Paso 2: Crear SDD (System Design Document)
|
||||
|
||||
### 2.1 Crear componente
|
||||
|
||||
Archivo: `spec/sdd/components/user-profile-service.md`
|
||||
|
||||
```markdown
|
||||
# Component: UserProfileService
|
||||
|
||||
## Responsabilidad
|
||||
Gestionar el perfil de usuario: consulta, actualización de datos básicos y preferencias.
|
||||
|
||||
## Tipo
|
||||
- [x] Microservicio
|
||||
|
||||
## Interfaces
|
||||
|
||||
### API REST
|
||||
|
||||
```
|
||||
GET /api/v1/users/{user_id}/profile
|
||||
Output: { "id", "name", "avatar_url", "language", "created_at" }
|
||||
|
||||
PUT /api/v1/users/{user_id}/profile
|
||||
Input: { "name": string, "avatar_url": string, "language": string }
|
||||
Output: { "id", "name", "avatar_url", "language", "updated_at" }
|
||||
```
|
||||
|
||||
## Validaciones
|
||||
- name: 2-50 caracteres, sin caracteres especiales
|
||||
- avatar_url: URL válida (http/https)
|
||||
- language: enum ['en', 'es', 'fr', 'de']
|
||||
```
|
||||
|
||||
### 2.2 Crear ADR (si hay decisión técnica)
|
||||
|
||||
Archivo: `spec/sdd/decisions/002-almacenamiento-avatar.md`
|
||||
|
||||
---
|
||||
|
||||
## Paso 3: Crear BDD (Behavior Driven Development)
|
||||
|
||||
### 3.1 Crear archivo .feature
|
||||
|
||||
Archivo: `spec/bdd/features/profile/user-profile.feature`
|
||||
|
||||
```gherkin
|
||||
@F-002 @profile
|
||||
Feature: Gestión de Perfil de Usuario
|
||||
|
||||
Como usuario autenticado
|
||||
Quiero gestionar mi perfil
|
||||
Para mantener mis datos actualizados
|
||||
|
||||
@smoke
|
||||
Scenario: Ver perfil de usuario
|
||||
Given un usuario autenticado con ID "user-123"
|
||||
When el usuario solicita ver su perfil
|
||||
Then el sistema retorna datos del perfil
|
||||
And incluye nombre, avatar y preferencias
|
||||
|
||||
Scenario: Editar nombre del perfil
|
||||
Given un usuario autenticado con ID "user-123"
|
||||
And el perfil tiene nombre "Juan"
|
||||
When el usuario actualiza su nombre a "Pedro"
|
||||
Then el perfil muestra nombre "Pedro"
|
||||
And la fecha de actualización se registra
|
||||
|
||||
@negative
|
||||
Scenario: Editar nombre con caracteres inválidos
|
||||
Given un usuario autenticado
|
||||
When intenta cambiar nombre a "Juan@123!"
|
||||
Then el sistema muestra error "Nombre inválido"
|
||||
And el nombre permanece sin cambios
|
||||
|
||||
Scenario: Cambiar idioma a español
|
||||
Given un usuario con idioma "en"
|
||||
When cambia idioma a "es"
|
||||
Then toda la interfaz se muestra en español
|
||||
And el preference se guarda correctamente
|
||||
```
|
||||
|
||||
### 3.2 Escribir Step Definitions
|
||||
|
||||
Archivo: `features/steps/profile_steps.py`
|
||||
|
||||
```python
|
||||
from behave import given, when, then
|
||||
|
||||
@given('un usuario autenticado con ID "{user_id}"')
|
||||
def step_user_authenticated(context, user_id):
|
||||
context.user_id = user_id
|
||||
context.auth_token = f"token_{user_id}"
|
||||
|
||||
@when('el usuario solicita ver su perfil')
|
||||
def step_get_profile(context):
|
||||
profile_service = ProfileService()
|
||||
context.profile = profile_service.get_profile(context.user_id)
|
||||
|
||||
@then('el sistema retorna datos del perfil')
|
||||
def step_return_profile(context):
|
||||
assert context.profile is not None
|
||||
assert "name" in context.profile
|
||||
|
||||
# ... más steps
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Paso 4: Ejecutar el pipeline ARNES
|
||||
|
||||
### Stage: design (architect)
|
||||
- ✅ Crea SDD component
|
||||
- ✅ Crea BDD feature
|
||||
- ✅ Produces `work/artifacts/F-002/architect.md`
|
||||
|
||||
### Stage: build (implementer)
|
||||
- Implementa `UserProfileService`
|
||||
- Escribe step definitions
|
||||
- Ejecuta `behave` para verificar
|
||||
|
||||
### Stage: review_gate (reviewer)
|
||||
- Verifica código coincide con SDD
|
||||
- Verifica BDD coverage
|
||||
|
||||
### Stage: security_gate (security)
|
||||
- Check secrets, dependencies
|
||||
- SAST scan
|
||||
|
||||
### Stage: qa_gate (qa)
|
||||
- Ejecuta BDD scenarios
|
||||
- Verifica trazabilidad
|
||||
|
||||
### Stage: close (leader)
|
||||
- Verifica todos los gates en verde
|
||||
- Produce `leader-close.json`
|
||||
|
||||
---
|
||||
|
||||
## 📁 Archivos generados
|
||||
|
||||
```
|
||||
spec/
|
||||
├── sdd/
|
||||
│ └── components/
|
||||
│ └── user-profile-service.md # Componente SDD
|
||||
│ └── decisions/
|
||||
│ └── 002-almacenamiento-avatar.md # ADR (si aplica)
|
||||
│
|
||||
├── bdd/
|
||||
│ └── features/
|
||||
│ └── profile/
|
||||
│ └── user-profile.feature # Feature BDD
|
||||
|
||||
features/
|
||||
└── steps/
|
||||
└── profile_steps.py # Step definitions
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Comandos para ejecutar
|
||||
|
||||
```bash
|
||||
# Verificar estructura
|
||||
./scripts/verify.sh
|
||||
|
||||
# Ejecutar tests BDD para la feature
|
||||
behave spec/bdd/features/profile/user-profile.feature
|
||||
|
||||
# Ejecutar solo scenarios con tag
|
||||
behave spec/bdd/features/profile/user-profile.feature --tags @smoke
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] SDD component creado en `spec/sdd/components/`
|
||||
- [ ] BDD feature creado en `spec/bdd/features/<domain>/`
|
||||
- [ ] Steps implementados en `features/steps/`
|
||||
- [ ] Todos los scenarios tienen Given/When/Then
|
||||
- [ ] Tags `@F-XXX` presentes en feature
|
||||
- [ ] SDD/BDD linkeados en artefacto architect
|
||||
## Close rule
|
||||
Feature can be `done` only if:
|
||||
- review approved
|
||||
- security approved
|
||||
- qa approved
|
||||
- documenter evidence exists
|
||||
- publish evidence exists (`publish.json`)
|
||||
- `./scripts/verify.sh` is green
|
||||
|
||||
Reference in New Issue
Block a user