feat: initialize AI agent skill framework, establish project documentation, and update ignore patterns

This commit is contained in:
Jessica Orozco 2026-05-27 12:36:40 -04:00
parent 994ed732d0
commit 14ac0170c9
9 changed files with 1244 additions and 2 deletions

42
.agents/README.md Normal file
View File

@ -0,0 +1,42 @@
# .agents/ — Skills y Orquestación
## Skills incluidas (pinned — no dependen de servicios externos)
```
.agents/skills/
├── test-driven-development/SKILL.md ← obra/superpowers (pinned 2026-03-19)
├── systematic-debugging/SKILL.md ← obra/superpowers (pinned 2026-03-19)
├── code-review-excellence/SKILL.md ← community + checklist V4 BIAN (pinned 2026-03-19)
├── documentation-writer/SKILL.md ← community + OpenAPI V4 (pinned 2026-03-19)
└── security-best-practices/SKILL.md ← community + banking patterns (pinned 2026-03-19)
```
**¿Por qué están congeladas?** Para evitar que una actualización upstream cambie el comportamiento esperado. Estas versiones fueron validadas contra el patrón V4.
**¿Cuándo actualizarlas?** Solo cuando el equipo revise la nueva versión upstream y confirme que es compatible con los patrones del proyecto.
---
## Orquestación Multi-Agente (V5 — activar cuando proceda)
Para implementar orquestación, ver `docs/guia-v5-advanced-ai-architecture.md §3 y §4`:
```
.agents/
├── orchestrator.md ← director (NUNCA hace trabajo real, solo coordina)
├── agents/
│ ├── spec-writer.md
│ ├── designer.md
│ ├── impl-rec.md
│ ├── impl-bus.md
│ ├── test-writer.md
│ └── reviewer.md
└── contracts/
├── spec-output.md
├── design-output.md
└── review-output.md
```
### Herramientas
- **Agent Teams Lite:** https://github.com/Gentleman-Programming/agent-teams-lite
- **Engram (memoria persistente):** `npx -y @gentleman-programming/engram`

View File

@ -0,0 +1,122 @@
---
name: code-review-excellence
description: Systematic code review for correctness, security, performance and maintainability. Produces structured review reports.
source: community (pinned 2026-03-19)
---
# Code Review Excellence
## Overview
Transform code reviews from rubber-stamping into knowledge sharing through constructive feedback, systematic analysis, and collaborative improvement.
## When to Use
- Reviewing pull requests
- Establishing code review standards
- Mentoring developers through review
- Auditing for correctness, security, or performance
- Pre-delivery validation against architectural patterns
## Instructions
### 1. Read Context First
Before touching code:
- Read the PR description, linked issues, and requirements
- Understand the architectural pattern being followed
- Check if there's a reference implementation to compare against
- Read test signals (CI status, coverage reports)
### 2. Review Systematically
Check in this order:
**Correctness:**
- Does the code do what the requirements ask?
- Are edge cases handled?
- Are error paths covered?
- Does it match the reference implementation pattern?
**Security:**
- Input validation present? (`@Valid`, `@NotNull`, `@Pattern`)
- Sensitive data masked in logs? (`authorization`, `customerId`)
- No secrets hardcoded?
- Authentication/authorization checks present?
**Performance:**
- No blocking I/O in hot paths (check `@PostConstruct` usage)
- No N+1 queries or repeated file reads
- Appropriate timeouts on external calls
- Async operations use proper context propagation (MDC)
**Maintainability:**
- Clear naming conventions
- Single responsibility per class
- Dependencies injected, not constructed
- Proper layer separation (no business logic in adapters)
### 3. Provide Actionable Feedback
For each issue:
- State the severity: BLOCKING | IMPORTANT | MINOR
- Explain WHY it's a problem, not just WHAT is wrong
- Suggest a concrete fix or alternative
- Ask clarifying questions when intent is unclear
### 4. Acknowledge Good Patterns
- Call out well-implemented patterns explicitly
- Recognize clean abstractions and good test coverage
- Note when the code follows architectural guidelines correctly
## Output Format
```markdown
## Code Review Summary
### Overall Assessment
[1-2 sentence summary of the change quality]
### Blocking Issues (must fix before merge)
- **[FILE:LINE]** — [Description] → [Suggested fix]
### Important Issues (should fix)
- **[FILE:LINE]** — [Description] → [Suggested fix]
### Minor Issues (nice to have)
- **[FILE:LINE]** — [Description] → [Suggested fix]
### Questions
- [Clarifying questions about intent or requirements]
### Positive Patterns Noted
- [Good patterns worth highlighting]
### Test Coverage
- [Coverage assessment and gaps]
```
## Review Checklist for V4 BIAN APIs
When reviewing an API implementation against `guia-4-implemented-pattern.md`:
### REC Layer
- [ ] Resource only has `@Valid` and delegates to UseCase — no logic
- [ ] Request DTOs use `@NotNull(message = "VDE01")` and `@Valid` on nested objects
- [ ] BusXxxClient is an **interface** with `@RegisterRestClient(configKey = "...")`
- [ ] BusXxxAdapter injects with `@RestClient` and reads `agencyCode` from MDC
- [ ] `ValidationExceptionMapper` present in `common/infrastructure/interceptor/`
- [ ] `RestClientExceptionMapper` present and registered via `@RegisterProvider`
- [ ] `InboundLoggingFilter` uses `SequenceInputStream` to reconstruct the stream
### BUS Layer
- [ ] Service orchestrates Ports — does not implement HTTP directly
- [ ] Service availability checked **before** business logic
- [ ] Security trace executes in `finally` using `AsyncMdcRunner.run()`
- [ ] DomXxxClient has `@RegisterProvider(RestClientLoggingFilter.class)` and `@RegisterProvider(RestClientExceptionMapper.class)`
- [ ] Mapper uses `@Mapper(componentModel = "cdi")` with `@AfterMapping` for complex fields
- [ ] `MessageHelper` uses `@PostConstruct` — no file reading in constructor
- [ ] Error responses always include `status = "error"` and `traceId`
## Common Review Anti-Patterns
| Anti-Pattern | Better Approach |
|---|---|
| "Looks good to me" (LGTM without review) | Run through the checklist systematically |
| Nitpicking style while ignoring logic bugs | Prioritize correctness over formatting |
| Rewriting the PR in comments | Suggest one concrete alternative, not a full rewrite |
| Blocking on subjective preferences | Only block on correctness, security, performance |

View File

@ -0,0 +1,167 @@
---
name: documentation-writer
description: Generate structured API documentation, OpenAPI annotations, and technical specifications from contracts and code.
source: community + V4 patterns (pinned 2026-03-19)
---
# Documentation Writer
## Overview
Generate structured documentation from API contracts, code, and specifications. Focuses on OpenAPI annotations, technical specs, and developer-facing documentation.
## When to Use
- Writing OpenAPI/Swagger annotations for JAX-RS Resources
- Generating API specification documents from contracts
- Creating developer onboarding documentation
- Producing technical decision records (ADRs)
- Enriching `@APIResponse` annotations with real examples
## Instructions
### 1. Gather Context
Before generating documentation:
- Read the API contract (headers, body, response structure)
- Read the error catalog (`messages.content` in `application.yml`)
- Check the reference implementation for actual response shapes
- Identify all possible HTTP status codes
### 2. Generate OpenAPI Annotations
For each endpoint, produce complete `@Operation` and `@APIResponse` annotations:
```java
@Operation(
summary = "Evaluate customer behavior against blacklist",
description = "Validates customer restrictions (L1) against the domain blacklist service"
)
@APIResponse(
responseCode = "200",
description = "Successful evaluation",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = RecCustomerBehaviorResponse.class),
examples = @ExampleObject(
name = "Successful evaluation",
value = """
{
"statusResponse": {
"status": "ok",
"statusCode": "200",
"message": "Operacion exitosa",
"traceId": "SESSION-ABC-123"
}
}
"""
)
)
)
@APIResponse(
responseCode = "400",
description = "Validation error - required field missing",
content = @Content(
schema = @Schema(implementation = ApiResponse.class),
examples = @ExampleObject(
name = "Missing required field",
value = """
{
"statusResponse": {
"status": "error",
"statusCode": "VDE01",
"message": "Error en dato de entrada obligatorio: customerReference",
"traceId": "SESSION-ABC-123"
}
}
"""
)
)
)
@APIResponse(
responseCode = "409",
description = "Backend internal error",
content = @Content(
schema = @Schema(implementation = ApiResponse.class),
examples = @ExampleObject(
name = "Backend conflict",
value = """
{
"statusResponse": {
"status": "error",
"statusCode": "PIB-00",
"message": "Error Interno backend",
"traceId": "SESSION-ABC-123"
}
}
"""
)
)
)
@APIResponse(
responseCode = "503",
description = "Service unavailable - maintenance window",
content = @Content(
schema = @Schema(implementation = ApiResponse.class),
examples = @ExampleObject(
name = "Service in maintenance",
value = """
{
"statusResponse": {
"status": "error",
"statusCode": "VRN04",
"message": "Servicio en horario de mantenimiento",
"traceId": "SESSION-ABC-123"
}
}
"""
)
)
)
```
### 3. Map Error Codes to Annotations
Use the error catalog from `application.yml``messages.content`:
| Error Code | HTTP | `@APIResponse(responseCode=)` | Example message |
|---|---|---|---|
| `200` | 200 | `"200"` | `"Operacion exitosa"` |
| `VDE01` | 400 | `"400"` | `"Error en dato de entrada obligatorio: %s"` |
| `VDE02` | 400 | `"400"` | `"Error en valor permitido para campo: %s"` |
| `VRN04` | 503 | `"503"` | `"Servicio en horario de mantenimiento"` |
| `PIB-00` | 409 | `"409"` | `"Error Interno backend"` |
### 4. Documentation Quality Checklist
- [ ] Every endpoint has `@Operation(summary, description)`
- [ ] Every possible HTTP status has an `@APIResponse`
- [ ] Every `@APIResponse` includes `@ExampleObject` with realistic data
- [ ] Error examples show `status: "error"` + `traceId` consistently
- [ ] Header parameters have `@Parameter(description, required)`
- [ ] Request body schema matches the actual DTO
- [ ] `@Schema` descriptions are in business language, not technical jargon
## Output Format
When generating spec documents, use this structure:
```markdown
# API Specification — <API Name>
## Endpoint
| Method | Path | Description |
|---|---|---|
## Headers
| Name | Required | Description |
## Request Body
| Field | Type | Required | Validation | Error Code |
## Response (Success)
[JSON example]
## Response (Errors)
[Table + JSON examples per error code]
## Downstream Services
[Table of config keys, URLs, methods]
```

View File

@ -0,0 +1,152 @@
---
name: security-best-practices
description: Security review for banking APIs — headers, input validation, log masking, and trace integrity.
source: community + V4 banking patterns (pinned 2026-03-19)
---
# Security Best Practices for Banking APIs
## Overview
Review and enforce security practices in API implementations, with focus on banking-grade requirements: input validation, header sanitization, log masking, and trace integrity.
## When to Use
- Reviewing header handling in Resources and Adapters
- Validating input sanitization on DTOs
- Auditing log filters for sensitive data exposure
- Verifying trace integrity (SecurityTracePort)
- Pre-delivery security review
## Instructions
### 1. Input Validation
**Every input field MUST have explicit validation:**
```java
// ✅ Correct — validation codes tied to error catalog
@NotNull(message = "VDE01")
@Valid
private CustomerReference customerReference;
// ✅ Correct — pattern restricts to known values
@NotNull(message = "VDE01")
@Pattern(regexp = "^[VEJPGCR]$", message = "VDE02")
private String customerIdType;
// ❌ Incorrect — no validation
private String customerIdType;
// ❌ Incorrect — validation without error code
@NotNull
private String customerId;
```
**Checklist:**
- [ ] All required fields have `@NotNull(message = "VDE01")`
- [ ] Enum-like fields have `@Pattern` with `message = "VDE02"`
- [ ] Nested objects have `@Valid` to cascade validation
- [ ] `ValidationExceptionMapper` is present and registered as `@Provider`
### 2. Header Security
**Required headers MUST be validated:**
```java
// ✅ Correct — declared as required with description
@Parameter(description = "Application ID", required = true)
@HeaderParam("appId") String appId,
// The MdcLoggingFilter handles null → "UNKNOWN_APP" fallback
// But the Resource should still declare them as required
```
**Headers that MUST NOT be logged without masking:**
- `authorization`
- `cookie`
- `x-api-key`
- Any custom credentials header
**Implementation in `RestClientLoggingFilter`:**
```java
private static final Set<String> SENSITIVE_HEADERS =
Set.of("authorization", "cookie", "x-api-key");
// Mask: "authorization=[PROTECTED]"
```
### 3. Log Masking
**PII and sensitive data MUST be masked in production logs:**
| Data Type | Log Level Allowed | Masking Rule |
|---|---|---|
| `customerId` | DEBUG only | Never in INFO |
| `customerIdType` | DEBUG only | Never in INFO |
| `deviceIp` | INFO | OK — used for fraud detection |
| `traceId` / `deviceSessionReference` | INFO | OK — correlation ID |
| `appId` | INFO | OK — non-sensitive identifier |
| Authorization headers | NEVER | `[PROTECTED]` |
**Rule:** In `%prod` profile, only `com.banesco` level INFO. Never expose PII at INFO level.
### 4. Trace Integrity
**The SecurityTracePort MUST:**
- Execute in `finally` block — ALWAYS, even if the main logic throws
- Use `AsyncMdcRunner` to preserve MDC context in the async thread
- Never block the main response thread
- Handle its own exceptions silently (log ERROR, don't propagate)
**Checklist:**
- [ ] `writeTrace()` called in `finally` with `asyncRunner.run()`
- [ ] `traceId` read from `RequestContext.getRequestId()`, not hardcoded
- [ ] If `traceId` is null, fallback to `"UNKNOWN"` (not empty string)
- [ ] `inputData` and `outputData` serialized with `ObjectMapper` (not `.toString()`)
- [ ] Trace failure logged as ERROR but NEVER propagated to caller
### 5. ConfigMap Security
**Environment variables for URLs MUST use the pattern:**
```yaml
url: ${INTEGRATION_<SERVICE>_URL:<default-dev-url>}
```
- Production URLs NEVER hardcoded in `application.yml`
- Dev URLs can be hardcoded as defaults for convenience
- Credentials NEVER in `application.yml` — use Kubernetes Secrets
### 6. HTTP Security Headers
**Response headers to consider:**
- `traceId` in response (for client correlation) — ✅ implemented in `MdcLoggingFilter`
- `Content-Type: application/json` — ✅ automatic with JAX-RS
- `X-Content-Type-Options: nosniff` — add if exposed to browser clients
- `Cache-Control: no-store` — banking APIs MUST NOT be cached
### 7. Security Review Output Format
```markdown
## Security Review — <API Name>
### Input Validation
- [ ] All fields validated with error codes
- [ ] @Pattern on constrained fields
### Header Security
- [ ] Sensitive headers masked in logs
- [ ] Required headers declared in Resource
### Log Masking
- [ ] No PII at INFO level in prod
- [ ] SENSITIVE_HEADERS set includes all credential headers
### Trace Integrity
- [ ] SecurityTracePort in finally with AsyncMdcRunner
- [ ] TraceId not null/empty
### ConfigMap
- [ ] No hardcoded prod URLs
- [ ] No credentials in application.yml
### Overall Risk: LOW | MEDIUM | HIGH
```

View File

@ -0,0 +1,131 @@
---
name: systematic-debugging
description: Four-phase debugging methodology. Always find root cause before attempting fixes.
source: obra/superpowers (pinned 2026-03-19)
---
# Systematic Debugging
## Overview
Random fixes waste time and create new bugs. Quick patches mask underlying issues.
**Core principle:** ALWAYS find root cause before attempting fixes. Symptom fixes are failure.
## The Iron Law
```
NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST
```
If you haven't completed Phase 1, you cannot propose fixes.
## When to Use
Use for ANY technical issue:
- Test failures
- Bugs in production
- Unexpected behavior
- Performance problems
- Build failures
- Integration issues
**Use this ESPECIALLY when:**
- Under time pressure (emergencies make guessing tempting)
- "Just one quick fix" seems obvious
- You've already tried multiple fixes
- Previous fix didn't work
- You don't fully understand the issue
## The Four Phases
You MUST complete each phase before proceeding to the next.
### Phase 1: Root Cause Investigation
**BEFORE attempting ANY fix:**
1. **Read Error Messages Carefully**
- Don't skip past errors or warnings
- They often contain the exact solution
- Read stack traces completely
- Note line numbers, file paths, error codes
2. **Reproduce Consistently**
- Can you trigger it reliably?
- What are the exact steps?
- Does it happen every time?
- If not reproducible → gather more data, don't guess
3. **Check Recent Changes**
- What changed that could cause this?
- Git diff, recent commits
- New dependencies, config changes
- Environmental differences
4. **Gather Evidence in Multi-Component Systems**
For EACH component boundary:
- Log what data enters component
- Log what data exits component
- Verify environment/config propagation
- Check state at each layer
Run once to gather evidence showing WHERE it breaks.
5. **Trace Data Flow**
- Where does bad value originate?
- What called this with bad value?
- Keep tracing up until you find the source
- Fix at source, not at symptom
### Phase 2: Pattern Analysis
**Find the pattern before fixing:**
1. **Find Working Examples** — Locate similar working code in same codebase
2. **Compare Against References** — Read reference implementation COMPLETELY
3. **Identify Differences** — List every difference, however small
4. **Understand Dependencies** — Settings, config, environment, assumptions
### Phase 3: Hypothesis and Testing
**Scientific method:**
1. **Form Single Hypothesis** — "I think X is the root cause because Y"
2. **Test Minimally** — Make the SMALLEST possible change to test
3. **Verify Before Continuing** — Did it work? Yes → Phase 4. No → NEW hypothesis
4. **When You Don't Know** — Say "I don't understand X". Don't pretend.
### Phase 4: Implementation
**Fix the root cause, not the symptom:**
1. **Create Failing Test Case** — Simplest possible reproduction
2. **Implement Single Fix** — ONE change at a time, no "while I'm here" improvements
3. **Verify Fix** — Test passes? No other tests broken? Issue resolved?
4. **If Fix Doesn't Work** — If < 3 attempts: return to Phase 1. If 3: STOP and question the architecture
5. **If 3+ Fixes Failed: Question Architecture** — Is this pattern fundamentally sound? Discuss with human before more fixes.
## Red Flags - STOP and Follow Process
- "Quick fix for now, investigate later"
- "Just try changing X and see if it works"
- "Add multiple changes, run tests"
- "It's probably X, let me fix that"
- "I don't fully understand but this might work"
- Each fix reveals new problem in different place
**ALL of these mean: STOP. Return to Phase 1.**
## Common Rationalizations
| Excuse | Reality |
|--------|---------|
| "Issue is simple, don't need process" | Simple issues have root causes too. Process is fast for simple bugs. |
| "Emergency, no time for process" | Systematic debugging is FASTER than guess-and-check thrashing. |
| "Just try this first" | First fix sets the pattern. Do it right from the start. |
| "Multiple fixes at once saves time" | Can't isolate what worked. Causes new bugs. |
| "I see the problem, let me fix it" | Seeing symptoms ≠ understanding root cause. |
## Quick Reference
| Phase | Key Activities | Success Criteria |
|-------|---------------|------------------|
| **1. Root Cause** | Read errors, reproduce, check changes, gather evidence | Understand WHAT and WHY |
| **2. Pattern** | Find working examples, compare | Identify differences |
| **3. Hypothesis** | Form theory, test minimally | Confirmed or new hypothesis |
| **4. Implementation** | Create test, fix, verify | Bug resolved, tests pass |
## Real-World Impact
- Systematic approach: 15-30 minutes to fix
- Random fixes approach: 2-3 hours of thrashing
- First-time fix rate: 95% vs 40%
- New bugs introduced: Near zero vs common

View File

@ -0,0 +1,166 @@
---
name: test-driven-development
description: Write the test first. Watch it fail. Write minimal code to pass. Enforces TDD discipline.
source: obra/superpowers (pinned 2026-03-19)
---
# Test-Driven Development (TDD)
## Overview
Write the test first. Watch it fail. Write minimal code to pass.
**Core principle:** If you didn't watch the test fail, you don't know if it tests the right thing.
**Violating the letter of the rules is violating the spirit of the rules.**
## When to Use
**Always:**
- New features
- Bug fixes
- Refactoring
- Behavior changes
**Exceptions (ask your human partner):**
- Throwaway prototypes
- Generated code
- Configuration files
Thinking "skip TDD just this once"? Stop. That's rationalization.
## The Iron Law
```
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
```
Write code before the test? Delete it. Start over.
**No exceptions:**
- Don't keep it as "reference"
- Don't "adapt" it while writing tests
- Don't look at it
- Delete means delete
Implement fresh from tests. Period.
## Red-Green-Refactor
### RED - Write Failing Test
Write one minimal test showing what should happen.
**Requirements:**
- One behavior
- Clear name
- Real code (no mocks unless unavoidable)
### Verify RED - Watch It Fail
**MANDATORY. Never skip.**
Confirm:
- Test fails (not errors)
- Failure message is expected
- Fails because feature missing (not typos)
**Test passes?** You're testing existing behavior. Fix test.
**Test errors?** Fix error, re-run until it fails correctly.
### GREEN - Minimal Code
Write simplest code to pass the test.
Don't add features, refactor other code, or "improve" beyond the test.
### Verify GREEN - Watch It Pass
**MANDATORY.**
Confirm:
- Test passes
- Other tests still pass
- Output pristine (no errors, warnings)
**Test fails?** Fix code, not test.
**Other tests fail?** Fix now.
### REFACTOR - Clean Up
After green only:
- Remove duplication
- Improve names
- Extract helpers
Keep tests green. Don't add behavior.
### Repeat
Next failing test for next feature.
## Good Tests
| Quality | Good | Bad |
|---------|------|-----|
| **Minimal** | One thing. "and" in name? Split it. | `test('validates email and domain and whitespace')` |
| **Clear** | Name describes behavior | `test('test1')` |
| **Shows intent** | Demonstrates desired API | Obscures what code should do |
## Why Order Matters
Tests written after code pass immediately. Passing immediately proves nothing:
- Might test wrong thing
- Might test implementation, not behavior
- Might miss edge cases you forgot
- You never saw it catch the bug
Test-first forces you to see the test fail, proving it actually tests something.
## Common Rationalizations
| Excuse | Reality |
|--------|---------|
| "Too simple to test" | Simple code breaks. Test takes 30 seconds. |
| "I'll test after" | Tests passing immediately prove nothing. |
| "Tests after achieve same goals" | Tests-after = "what does this do?" Tests-first = "what should this do?" |
| "Already manually tested" | Ad-hoc ≠ systematic. No record, can't re-run. |
| "Deleting X hours is wasteful" | Sunk cost fallacy. Keeping unverified code is technical debt. |
| "Need to explore first" | Fine. Throw away exploration, start with TDD. |
| "Test hard = design unclear" | Listen to test. Hard to test = hard to use. |
| "TDD will slow me down" | TDD faster than debugging. |
## Red Flags - STOP and Start Over
- Code before test
- Test after implementation
- Test passes immediately
- Can't explain why test failed
- Tests added "later"
- Rationalizing "just this once"
- "I already manually tested it"
**All of these mean: Delete code. Start over with TDD.**
## Verification Checklist
Before marking work complete:
- [ ] Every new function/method has a test
- [ ] Watched each test fail before implementing
- [ ] Each test failed for expected reason (feature missing, not typo)
- [ ] Wrote minimal code to pass each test
- [ ] All tests pass
- [ ] Output pristine (no errors, warnings)
- [ ] Tests use real code (mocks only if unavoidable)
- [ ] Edge cases and errors covered
Can't check all boxes? You skipped TDD. Start over.
## When Stuck
| Problem | Solution |
|---------|----------|
| Don't know how to test | Write wished-for API. Write assertion first. |
| Test too complicated | Design too complicated. Simplify interface. |
| Must mock everything | Code too coupled. Use dependency injection. |
| Test setup huge | Extract helpers. Still complex? Simplify design. |
## Debugging Integration
Bug found? Write failing test reproducing it. Follow TDD cycle. Test proves fix and prevents regression.
Never fix bugs without a test.
## Final Rule
```
Production code → test exists and failed first
Otherwise → not TDD
```
No exceptions without your human partner's permission.

View File

@ -0,0 +1,11 @@
# Contexto del Negocio: Internet Banking Seguro
## Objetivo
Plataforma web de banca por internet para que los clientes gestionen sus finanzas, cuentas y transferencias de forma ágil, transparente y ultra-segura.
## Reglas de Negocio
- **Cuentas Soportadas:** Cada usuario puede poseer múltiples cuentas (Corriente, Ahorros y Tarjeta de Crédito, en otras monedas).
- **Límites de Transferencia:** Monto máximo diario de transferencia de $5,000 USD (o equivalente) a terceros. Las transferencias entre cuentas propias no tienen límite.
- **Seguridad y Sesión:** Autocierre de sesión (auto-logout) tras 5 minutos de inactividad del cliente. Encriptación obligatoria para cualquier visualización de saldos o números de cuenta completos en el cliente.
- **Auditoría Financiera:** Todo movimiento de dinero, intento de login (exitoso o fallido) y cambio de credenciales debe generar un registro de log inmutable en el servidor.
- **Cifrado Extremo a Extremo (End-to-End Encryption - E2EE):** Toda la información altamente confidencial en tránsito y en reposo (credenciales, números de cuenta, saldos, importes de transferencias y tokens de sesión) debe estar encriptada de extremo a extremo (E2EE) desde el navegador del cliente hasta el servidor del backend (usando Kong Gateway y encriptación robusta a nivel de aplicación). Esto asegura inmunidad absoluta contra cualquier tipo de intermediarios o fugas en tránsito, garantizando un estándar de seguridad de grado bancario.

View File

@ -0,0 +1,449 @@
# Internet Banking - Aplicación Web Segura
Aplicación web de Internet Banking construida con **Next.js 14 (App Router)**, **TypeScript**, **TailwindCSS + daisyUI**, y **Zustand** para gestión de estado. El backend está desarrollado en **Java 25 Spring Boot** y protegido por **Kong Gateway**.
## 🚀 Características
- ✅ **Autenticación segura** con tokens JWT en cookies HTTP-only
- ✅ **Server Components** de Next.js para máximo rendimiento
- ✅ **Middleware de autenticación** server-side
- ✅ **Sistema de logs** centralizado (escribe en archivo .txt)
- ✅ **Encriptación Kong** para datos sensibles
- ✅ **UI moderna** con TailwindCSS y daisyUI
- ✅ **TypeScript** para type-safety completo
- ✅ **Zustand** para estado cliente (no Redux)
- ✅ **Sin useEffect/useContext** innecesarios (server-first)
# Internet Banking (Next.js)
This repository contains a Next.js application scaffolded with `create-next-app`.
## Getting started
1. Install dependencies:
```bash
npm install
```
2. Run the development server:
```bash
npm run dev
# then open http://localhost:3000
```
## Requisitos
- Node.js 18 LTS o superior
## Instalación y ejecución
1. Instala las dependencias:
```bash
npm install
```
2. Ejecuta el servidor de desarrollo:
```bash
npm run dev
# luego abre http://localhost:3000
```
## Dependencias
Las dependencias actuales (según `package.json`):
### Runtime
- `next` 15.5.6
- `react` 19.1.0
- `react-dom` 19.1.0
- `daisyui` 5.4.5
- `react-icons` 5.5.0
- `zustand` 5.0.8
### Desarrollo
- `typescript` 5
- `@types/node` 20
- `@types/react` 19
- `@types/react-dom` 19
- `eslint` 9
- `@eslint/eslintrc` 3
- `eslint-config-next` 15.5.6
- `tailwindcss` 4.1.17
- `@tailwindcss/postcss` 4.1.17
## Notas
- Para ejecutar el linter localmente:
```bash
npm run lint
```
## 🤖 Infraestructura de Ingeniería AI-Native (Agentes y Esquema MCP)
Esta aplicación está diseñada desde sus cimientos para el desarrollo asistido por **Agentes de Inteligencia Artificial Autónomos** mediante el protocolo **MCP (Model Context Protocol)**, asegurando consistencia arquitectónica, memoria persistente entre sesiones y navegación contextual ultra-rápida.
### 1. El Esquema de Servidores MCP (mcp_config.json)
Para iniciar el entorno de desarrollo con soporte de IA y permitir que los agentes se auto-direccionen, debes registrar los siguientes servidores en el archivo de configuración global de tu entorno de ejecución (ej. `~/.gemini/antigravity/mcp_config.json`):
```json
{
"mcpServers": {
"engram": {
"command": "engram",
"args": [
"mcp",
"--tools=agent"
]
},
"graphify": {
"command": "d:\\Jess\\agent\\graphify\\.venv\\Scripts\\python.exe",
"args": [
"-m",
"graphify.serve",
"d:/Jess/agent/frontend-ai/graphify-out/graph.json"
]
}
}
}
```
* **Engram (Memoria Persistente)**: Servidor escrito en Go que expone herramientas para almacenar decisiones, resúmenes de sesión (`mem_save`) y recuperar contexto de sesiones previas (`mem_search`, `mem_context`), evitando la pérdida de contexto sobre las reglas de negocio críticas o decisiones pasadas.
* **Graphify (Grafo del Repositorio)**: Servidor que mapea todo el código, layouts de Next.js, API routes y documentación en un grafo semántico. Permite al agente responder preguntas de arquitectura mediante consultas directas en lugar de hacer lecturas completas de archivos, optimizando drásticamente la ventana de contexto.
---
### 2. Reglas de Comportamiento para Agentes de IA (AGENTS.md / CLAUDE.md)
Cualquier agente que trabaje en esta base de código está **estrictamente obligado** a seguir las siguientes directrices y reglas operativas integradas en el proyecto:
#### 🔐 Seguridad y Autenticación Primero
1. **Nunca escribirás claves o credenciales en texto plano**: El agente tiene estrictamente prohibido commitear archivos `.env` o variables con valores reales. Siempre utilizará variables de entorno.
2. **Respeto absoluto por el Middleware Server-Side**: Para proteger cualquier ruta o recurso, el agente DEBE usar el middleware centralizado `serverRequireAuth` desde `lib/auth/middleware.ts` en los Server Components. Bajo ninguna circunstancia omitirá este paso o creará validaciones ad-hoc.
3. **Cookies HTTP-Only y Secure**: Los tokens JWT nunca deben tocar el `localStorage` o `sessionStorage` del cliente. Si el agente diseña flujos de autenticación en el cliente, debe delegar el almacenamiento y la gestión de la cookie al navegador y al backend.
4. **Encriptación de Datos Sensibles**: Cualquier dato altamente confidencial (ej. números de cuenta, saldos, datos personales) que viaje por el cliente debe encriptarse usando el módulo placeholder de Kong Gateway (`lib/cypher/encrypt.ts`).
#### 📝 Sistema de Logs Centralizado
* El agente **debe loguear activamente** todas las acciones críticas (inicios de sesión, accesos denegados, errores de comunicación con el backend, llamadas a la API) usando los módulos `server-logger` y `client-logger`.
* Todos los logs generados en componentes del cliente **deben enrutarse** hacia la API local `POST /api/logs` para asegurar que queden guardados en el archivo centralizado `logs/app.log`.
#### 🏗️ Desarrollo Incremental y Verificabilidad
* El agente debe mantener el archivo `STATE.md` y `ENGRAM.md` actualizados en cada punto de control (Checkpoint) para evitar la degradación de la memoria y la ventana de contexto del modelo.
* Después de realizar cualquier cambio estructural en el código, el agente ejecutará localmente `graphify update .` para asegurar que el grafo de conocimiento del proyecto refleje los nuevos módulos inmediatamente.
## 🏗️ Estructura del Proyecto
```
internet-banking/
├── app/ # Next.js App Router
│ ├── page.tsx # Página principal
│ ├── layout.tsx # Layout principal
│ ├── ClientAuthProvider.tsx # Provider para hidratación de auth
│ ├── globals.css # Estilos globales
│ ├── about/ # Sección "Acerca de"
│ │ ├── page.tsx
│ │ ├── layout.tsx
│ │ ├── components/
│ │ │ ├── aboutHeader.tsx
│ │ │ └── aboutContent.tsx
│ │ ├── service/
│ │ │ └── fetchAbout.ts
│ │ └── hooks/
│ │ └── useAboutData.ts
│ ├── login/ # Página de login
│ │ ├── page.tsx
│ │ └── LoginForm.tsx
│ ├── dashboard/ # Dashboard protegido
│ │ └── page.tsx
│ ├── model/ # Modelos TypeScript
│ │ └── cuenta.ts
│ └── api/ # API Routes
│ ├── logs/
│ │ └── route.ts # POST /api/logs
│ └── auth/
│ ├── me/
│ │ └── route.ts # GET /api/auth/me
│ └── logout/
│ └── route.ts # POST /api/auth/logout
├── components/
│ └── ui/ # Componentes UI reutilizables
│ ├── button.tsx
│ ├── input.tsx
│ ├── header.tsx
│ └── table.tsx
├── lib/
│ ├── auth/ # Autenticación
│ │ ├── middleware.ts # Middleware server-side
│ │ └── client/
│ │ └── useAuthStore.ts # Zustand store
│ ├── logger/ # Sistema de logs
│ │ ├── server-logger.ts # Logger server-side
│ │ └── client-logger.ts # Logger client-side
│ └── cypher/ # Encriptación Kong
│ ├── encrypt.ts
│ └── decrypt.ts
├── logs/
│ └── app.log # Archivo de logs (no en git)
├── middleware.ts # Next.js Edge Middleware
├── package.json
├── tsconfig.json
├── tailwind.config.ts
├── next.config.js
└── README.md
```
## 🔐 Autenticación
### Flujo de Autenticación
1. **Login**: Usuario envía credenciales a `POST /api/auth/login`
2. **Backend**: Spring Boot valida y devuelve tokens en cookies HTTP-only:
- `access_token`: Token de acceso (corta duración)
- `refresh_token`: Token de refresco (larga duración)
3. **Frontend**: Cookies se establecen automáticamente (HTTP-only, Secure, SameSite=strict)
4. **Validación**: Cada petición a rutas protegidas valida el token server-side
5. **Logout**: `POST /api/auth/logout` limpia cookies
### Middleware de Autenticación
#### Server-Side (lib/auth/middleware.ts)
```typescript
// Proteger una página (Server Component)
import { serverRequireAuth } from '@/lib/auth/middleware';
export default async function ProtectedPage() {
const user = await serverRequireAuth(); // Redirige si no autenticado
return <div>Hola {user.name}</div>;
}
// Check opcional (no redirige)
import { checkAuth } from '@/lib/auth/middleware';
const authResult = await checkAuth();
if (authResult.isAuthenticated) {
// Usuario logueado
}
```
#### Edge Middleware (middleware.ts)
Automáticamente redirige rutas protegidas (`/dashboard`, `/profile`, etc.) si no hay token.
### Zustand Store (Client-Side)
```typescript
'use client';
import { useAuthStore } from '@/lib/auth/client/useAuthStore';
function MyComponent() {
const { user, isAuthenticated, logout } = useAuthStore();
return (
<div>
{isAuthenticated && <p>Hola {user?.name}</p>}
<button onClick={logout}>Logout</button>
</div>
);
}
```
**IMPORTANTE**: El store Zustand NO guarda tokens, solo datos del usuario y flags UI.
## 📝 Sistema de Logs
Todos los logs se escriben server-side en `logs/app.log`.
### Desde Server Components / API Routes
```typescript
import { logInfo, logWarn, logError } from '@/lib/logger/server-logger';
logInfo('User logged in', { userId: '123' });
logWarn('Failed login attempt', { email: 'user@example.com' });
logError('Database connection failed', { error: err.message });
```
### Desde Client Components
```typescript
'use client';
import { logInfo, logWarn, logError } from '@/lib/logger/client-logger';
// Estos envían logs a /api/logs que los escribe server-side
logInfo('Button clicked', { action: 'submit' });
logError('Form validation failed', { field: 'email' });
```
### Formato de Logs
```
[2024-11-07T10:30:00.000Z] [INFO] Login success | {"userId":"123","email":"user@example.com"}
[2024-11-07T10:31:00.000Z] [WARN] Unauthorized access attempt | {"path":"/dashboard"}
[2024-11-07T10:32:00.000Z] [ERROR] Backend connection failed | {"error":"ECONNREFUSED"}
```
## 🔒 Seguridad
### Tokens HTTP-Only
- Los tokens JWT **nunca** se almacenan en `localStorage` o `sessionStorage`
- Se usan cookies **HTTP-only**, **Secure** (en producción), **SameSite=strict**
- No accesibles desde JavaScript del cliente
### Encriptación Kong
Para datos sensibles que necesitan encriptación:
```typescript
import { kongEncrypt, kongDecrypt } from '@/lib/cypher/decrypt';
// Encriptar
const encrypted = kongEncrypt('sensitive-data');
// Desencriptar
const decrypted = kongDecrypt(encrypted);
// TODO: Reemplazar con la librería Kong real una vez proporcionada
```
### CORS y CSRF
Asegúrate de configurar en tu backend Spring Boot:
```java
// Permitir solo orígenes aprobados
@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true")
// SameSite=strict para cookies
cookie.setSameSite("strict");
```
## 🧪 Pruebas Manuales
### 1. Login Exitoso
1. Ir a `/login`
2. Ingresar credenciales válidas
3. **Esperado**: Redirige a `/dashboard`
4. **Log**: `[INFO] Login success | {"userId":"123"}`
### 2. Login Fallido
1. Ir a `/login`
2. Ingresar credenciales inválidas
3. **Esperado**: Muestra mensaje de error
4. **Log**: `[WARN] Login failed | {"email":"us***@example.com"}`
### 3. Acceso No Autorizado
1. Sin estar logueado, intentar acceder a `/dashboard`
2. **Esperado**: Redirige a `/login?redirect=/dashboard`
3. **Log**: `[WARN] Unauthorized access attempt | {"redirectTo":"/login"}`
### 4. Logout
1. Estando logueado, hacer click en "Cerrar Sesión"
2. **Esperado**: Cookies eliminadas, redirige a `/login`
3. **Log**: `[INFO] Logout user: 123`
## 📦 Build para Producción
```bash
# Build
npm run build
# Start production server
npm run start
```
### Variables de Entorno en Producción
Asegúrate de configurar:
```env
NODE_ENV=production
NEXT_PUBLIC_API_URL=https://api.tudominio.com/api
API_URL_SERVER=https://api-internal.tudominio.com/api
KONG_SECRET_KEY=<tu-clave-secreta-real>
```
## 🚨 Solución de Problemas
### Error: "Failed to fetch"
- Verifica que el backend esté corriendo
- Verifica las URLs en `.env.local`
- Revisa los logs en `logs/app.log`
### Error: "Unauthorized"
- Verifica que las cookies se estén estableciendo correctamente
- Revisa la configuración CORS del backend
- Asegúrate que `withCredentials: true` esté en las peticiones fetch
### Error: Cookies no se establecen
- En desarrollo: Asegúrate que frontend y backend estén en el mismo dominio (localhost)
- Verifica configuración `SameSite` en backend
- Revisa que `httpOnly: true` esté configurado correctamente
### Logs no se escriben
- Verifica que `ENABLE_SERVER_LOGS=true`
- Asegúrate que la carpeta `logs/` tenga permisos de escritura
- Revisa los logs de consola para errores
## 📚 Documentación Adicional
- [Next.js 14 Documentation](https://nextjs.org/docs)
- [TailwindCSS](https://tailwindcss.com/docs)
- [daisyUI Components](https://daisyui.com/components/)
- [Zustand](https://docs.pmnd.rs/zustand/getting-started/introduction)
- [Kong Gateway](https://docs.konghq.com/)
## 🔧 Scripts Disponibles
```bash
npm run dev # Desarrollo
npm run build # Build producción
npm run start # Servidor producción
npm run lint # ESLint
npm run type-check # TypeScript type checking
```
## 📝 TODOs Pendientes
Los siguientes TODOs están marcados en el código con `/* TODO */`:
1. **lib/cypher/encrypt.ts y decrypt.ts**: Reemplazar implementación placeholder con librería Kong real
2. **lib/auth/middleware.ts**: Ajustar headers según requerimientos del backend
3. **app/api/auth/me/route.ts**: Ajustar headers según backend
4. **app/login/LoginForm.tsx**: Ajustar payload y endpoint de login según backend
5. **Variables de entorno**: Reemplazar valores de ejemplo con valores reales
6. **Endpoints backend**: Verificar que coincidan con los del backend Spring Boot
## 🤝 Contribución
1. Crear una rama: `git checkout -b feature/nueva-funcionalidad`
2. Commit cambios: `git commit -am 'Agrega nueva funcionalidad'`
3. Push a la rama: `git push origin feature/nueva-funcionalidad`
4. Crear Pull Request
## 📄 Licencia
Este proyecto es privado y confidencial.
## 👥 Equipo
Desarrollado para el sistema de Internet Banking.
---
**Nota de Seguridad**: Nunca commitear archivos con claves reales, tokens, o credenciales. Usar siempre variables de entorno y mantener `.env.local` fuera del control de versiones.

6
.gitignore vendored
View File

@ -2,11 +2,13 @@ node_modules
.next .next
.env.local .env.local
.env.local.template .env.local.template
.gentle
.agents
.git .git
.cursor .cursor
.vscode .vscode
.claude .claude
.gemini
.agent
.openai
.ollama