feat: initialize AI agent skill framework, establish project documentation, and update ignore patterns
This commit is contained in:
parent
994ed732d0
commit
14ac0170c9
42
.agents/README.md
Normal file
42
.agents/README.md
Normal 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`
|
||||||
122
.agents/skills/code-review-excellence/SKILL.md
Normal file
122
.agents/skills/code-review-excellence/SKILL.md
Normal 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 |
|
||||||
167
.agents/skills/documentation-writer/SKILL.md
Normal file
167
.agents/skills/documentation-writer/SKILL.md
Normal 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]
|
||||||
|
```
|
||||||
152
.agents/skills/security-best-practices/SKILL.md
Normal file
152
.agents/skills/security-best-practices/SKILL.md
Normal 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
|
||||||
|
```
|
||||||
131
.agents/skills/systematic-debugging/SKILL.md
Normal file
131
.agents/skills/systematic-debugging/SKILL.md
Normal 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
|
||||||
166
.agents/skills/test-driven-development/SKILL.md
Normal file
166
.agents/skills/test-driven-development/SKILL.md
Normal 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.
|
||||||
11
.gentle/context/business-rules.md
Normal file
11
.gentle/context/business-rules.md
Normal 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.
|
||||||
449
.gentle/context/context-app.md
Normal file
449
.gentle/context/context-app.md
Normal 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
6
.gitignore
vendored
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user