@qubiit/lmagent 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +18 -0
- package/AGENTS.md +169 -0
- package/CLAUDE.md +122 -0
- package/CONTRIBUTING.md +90 -0
- package/LICENSE +21 -0
- package/README.md +195 -0
- package/config/commands.yaml +194 -0
- package/config/levels.yaml +135 -0
- package/config/models.yaml +192 -0
- package/config/settings.yaml +405 -0
- package/config/tools-extended.yaml +534 -0
- package/config/tools.yaml +437 -0
- package/docs/assets/logo.png +0 -0
- package/docs/commands.md +132 -0
- package/docs/customization-guide.md +445 -0
- package/docs/getting-started.md +154 -0
- package/docs/how-to-start.md +242 -0
- package/docs/navigation-index.md +227 -0
- package/docs/usage-guide.md +113 -0
- package/install.js +1044 -0
- package/package.json +35 -0
- package/pyproject.toml +182 -0
- package/rules/_bootstrap.md +138 -0
- package/rules/agents-ia.md +607 -0
- package/rules/api-design.md +337 -0
- package/rules/automations-n8n.md +646 -0
- package/rules/code-style.md +570 -0
- package/rules/documentation.md +98 -0
- package/rules/security.md +316 -0
- package/rules/stack.md +395 -0
- package/rules/testing.md +326 -0
- package/rules/workflow.md +353 -0
- package/scripts/create_skill.js +300 -0
- package/scripts/validate_skills.js +283 -0
- package/skills/ai-agent-engineer/SKILL.md +394 -0
- package/skills/ai-agent-engineer/references/agent-patterns.md +149 -0
- package/skills/api-designer/SKILL.md +429 -0
- package/skills/api-designer/references/api-standards.md +13 -0
- package/skills/architect/SKILL.md +285 -0
- package/skills/architect/references/c4-model.md +133 -0
- package/skills/automation-engineer/SKILL.md +352 -0
- package/skills/automation-engineer/references/n8n-patterns.md +127 -0
- package/skills/backend-engineer/SKILL.md +261 -0
- package/skills/backend-engineer/assets/fastapi-project-structure.yaml +74 -0
- package/skills/backend-engineer/references/debugging-guide.md +174 -0
- package/skills/backend-engineer/references/design-patterns.md +208 -0
- package/skills/backend-engineer/scripts/scaffold_backend.py +313 -0
- package/skills/bmad-methodology/SKILL.md +202 -0
- package/skills/bmad-methodology/references/scale-adaptive-levels.md +141 -0
- package/skills/browser-agent/SKILL.md +502 -0
- package/skills/browser-agent/scripts/playwright_setup.ts +16 -0
- package/skills/code-reviewer/SKILL.md +306 -0
- package/skills/code-reviewer/references/code-review-checklist.md +16 -0
- package/skills/data-engineer/SKILL.md +474 -0
- package/skills/data-engineer/assets/pg-monitoring-queries.sql +154 -0
- package/skills/data-engineer/references/index-strategy.md +128 -0
- package/skills/data-engineer/scripts/backup_postgres.py +221 -0
- package/skills/devops-engineer/SKILL.md +547 -0
- package/skills/devops-engineer/references/ci-cd-patterns.md +265 -0
- package/skills/devops-engineer/scripts/docker_healthcheck.py +125 -0
- package/skills/document-generator/SKILL.md +746 -0
- package/skills/document-generator/references/pdf-generation.md +22 -0
- package/skills/frontend-engineer/SKILL.md +532 -0
- package/skills/frontend-engineer/references/accessibility-guide.md +146 -0
- package/skills/frontend-engineer/scripts/audit_bundle.py +144 -0
- package/skills/git-workflow/SKILL.md +374 -0
- package/skills/git-workflow/references/git-flow.md +25 -0
- package/skills/mcp-builder/SKILL.md +471 -0
- package/skills/mcp-builder/references/mcp-server-guide.md +23 -0
- package/skills/mobile-engineer/SKILL.md +502 -0
- package/skills/mobile-engineer/references/platform-guidelines.md +160 -0
- package/skills/orchestrator/SKILL.md +246 -0
- package/skills/orchestrator/references/methodology-routing.md +117 -0
- package/skills/orchestrator/references/persona-mapping.md +85 -0
- package/skills/orchestrator/references/routing-logic.md +110 -0
- package/skills/performance-engineer/SKILL.md +549 -0
- package/skills/performance-engineer/references/caching-patterns.md +181 -0
- package/skills/performance-engineer/scripts/profile_endpoint.py +170 -0
- package/skills/product-manager/SKILL.md +488 -0
- package/skills/product-manager/references/prioritization-frameworks.md +126 -0
- package/skills/prompt-engineer/SKILL.md +433 -0
- package/skills/prompt-engineer/references/prompt-patterns.md +158 -0
- package/skills/qa-engineer/SKILL.md +441 -0
- package/skills/qa-engineer/references/testing-strategy.md +166 -0
- package/skills/qa-engineer/scripts/run_coverage.py +147 -0
- package/skills/scrum-master/SKILL.md +225 -0
- package/skills/scrum-master/references/sprint-ceremonies.md +159 -0
- package/skills/security-analyst/SKILL.md +390 -0
- package/skills/security-analyst/references/owasp-top10.md +188 -0
- package/skills/security-analyst/scripts/audit_security.py +242 -0
- package/skills/seo-auditor/SKILL.md +523 -0
- package/skills/seo-auditor/references/seo-checklist.md +17 -0
- package/skills/spec-driven-dev/SKILL.md +342 -0
- package/skills/spec-driven-dev/references/phase-gates.md +107 -0
- package/skills/supabase-expert/SKILL.md +602 -0
- package/skills/supabase-expert/references/supabase-patterns.md +19 -0
- package/skills/swe-agent/SKILL.md +311 -0
- package/skills/swe-agent/references/trajectory-format.md +134 -0
- package/skills/systematic-debugger/SKILL.md +512 -0
- package/skills/systematic-debugger/references/debugging-guide.md +12 -0
- package/skills/tech-lead/SKILL.md +409 -0
- package/skills/tech-lead/references/code-review-checklist.md +111 -0
- package/skills/technical-writer/SKILL.md +631 -0
- package/skills/technical-writer/references/doc-templates.md +218 -0
- package/skills/testing-strategist/SKILL.md +476 -0
- package/skills/testing-strategist/references/testing-pyramid.md +16 -0
- package/skills/ux-ui-designer/SKILL.md +419 -0
- package/skills/ux-ui-designer/references/design-system-foundation.md +168 -0
- package/skills_overview.txt +94 -0
- package/templates/PROJECT_KICKOFF.md +284 -0
- package/templates/SKILL_TEMPLATE.md +131 -0
- package/templates/USAGE.md +95 -0
- package/templates/agent-python/README.md +71 -0
- package/templates/agent-python/agent.py +272 -0
- package/templates/agent-python/config.yaml +76 -0
- package/templates/agent-python/prompts/system.md +109 -0
- package/templates/agent-python/requirements.txt +7 -0
- package/templates/automation-n8n/README.md +14 -0
- package/templates/automation-n8n/webhook-handler.json +57 -0
- package/templates/backend-node/Dockerfile +12 -0
- package/templates/backend-node/README.md +15 -0
- package/templates/backend-node/package.json +30 -0
- package/templates/backend-node/src/index.ts +19 -0
- package/templates/backend-node/src/routes.ts +7 -0
- package/templates/backend-node/tsconfig.json +22 -0
- package/templates/backend-python/Dockerfile +11 -0
- package/templates/backend-python/README.md +78 -0
- package/templates/backend-python/app/core/config.py +12 -0
- package/templates/backend-python/app/core/database.py +12 -0
- package/templates/backend-python/app/main.py +17 -0
- package/templates/backend-python/app/routers/__init__.py +1 -0
- package/templates/backend-python/app/routers/health.py +7 -0
- package/templates/backend-python/requirements-dev.txt +6 -0
- package/templates/backend-python/requirements.txt +4 -0
- package/templates/backend-python/tests/test_health.py +9 -0
- package/templates/checkpoint.yaml +117 -0
- package/templates/database/README.md +474 -0
- package/templates/frontend-react/README.md +446 -0
- package/templates/plan.yaml +320 -0
- package/templates/session.yaml +125 -0
- package/templates/spec.yaml +229 -0
- package/templates/tasks.yaml +330 -0
- package/workflows/bugfix-backend.md +380 -0
- package/workflows/documentation.md +232 -0
- package/workflows/generate-prd.md +320 -0
- package/workflows/ideation.md +396 -0
- package/workflows/new-agent-ia.md +497 -0
- package/workflows/new-automation.md +374 -0
- package/workflows/new-feature.md +290 -0
- package/workflows/optimize-performance.md +373 -0
- package/workflows/resolve-github-issue.md +524 -0
- package/workflows/security-review.md +291 -0
- package/workflows/spec-driven.md +476 -0
- package/workflows/testing-strategy.md +296 -0
- package/workflows/third-party-integration.md +277 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
# LMAgent Security Rules
|
|
2
|
+
|
|
3
|
+
> **Tipo**: `rule` | **Versión**: 2.1 | **Actualización**: 2026-01
|
|
4
|
+
|
|
5
|
+
## 📌 Quick Reference
|
|
6
|
+
|
|
7
|
+
| Principio | Regla |
|
|
8
|
+
|-----------|-------|
|
|
9
|
+
| **Secrets** | NUNCA en código. Siempre `os.getenv()` o Vault. |
|
|
10
|
+
| **Passwords** | bcrypt/argon2. NUNCA MD5/SHA1. |
|
|
11
|
+
| **JWT** | RS256 preferido. Access token = 15 min máx. |
|
|
12
|
+
| **SQL** | Queries parametrizadas SIEMPRE. Nunca f-strings. |
|
|
13
|
+
| **Inputs** | Validar con Pydantic. Never trust user input. |
|
|
14
|
+
| **Headers** | HTTPS + HSTS + CSP obligatorios en prod. |
|
|
15
|
+
|
|
16
|
+
### 👥 Roles que usan esta regla
|
|
17
|
+
`security-analyst`, `backend-engineer`, `devops-engineer`, `architect`
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
Este documento define las reglas y mejores prácticas de seguridad del framework.
|
|
22
|
+
|
|
23
|
+
## 🔐 Principios Generales
|
|
24
|
+
|
|
25
|
+
1. **Defense in Depth**: Múltiples capas de seguridad
|
|
26
|
+
2. **Least Privilege**: Mínimos permisos necesarios
|
|
27
|
+
3. **Secure by Default**: Configuración segura por defecto
|
|
28
|
+
4. **Zero Trust**: No confiar en ningún input
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Autenticación
|
|
33
|
+
|
|
34
|
+
### JWT Best Practices
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
# ✅ BUENO
|
|
38
|
+
JWT_SETTINGS = {
|
|
39
|
+
"algorithm": "RS256", # Asimétrico
|
|
40
|
+
"access_token_expire": 15, # minutos
|
|
41
|
+
"refresh_token_expire": 7 * 24 * 60, # 7 días
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# ❌ MALO
|
|
45
|
+
JWT_SETTINGS = {
|
|
46
|
+
"algorithm": "HS256", # Simétrico con secret débil
|
|
47
|
+
"access_token_expire": 60 * 24 * 365, # 1 año
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Password Storage
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
# Usar bcrypt o argon2
|
|
55
|
+
from passlib.context import CryptContext
|
|
56
|
+
|
|
57
|
+
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
|
58
|
+
|
|
59
|
+
def hash_password(password: str) -> str:
|
|
60
|
+
return pwd_context.hash(password)
|
|
61
|
+
|
|
62
|
+
def verify_password(plain: str, hashed: str) -> bool:
|
|
63
|
+
return pwd_context.verify(plain, hashed)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### MFA
|
|
67
|
+
|
|
68
|
+
- Implementar TOTP para cuentas sensibles
|
|
69
|
+
- Usar librerías probadas (pyotp)
|
|
70
|
+
- Backup codes obligatorios
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Autorización
|
|
75
|
+
|
|
76
|
+
### RBAC Pattern
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
class Permission(Enum):
|
|
80
|
+
READ_USERS = "users:read"
|
|
81
|
+
WRITE_USERS = "users:write"
|
|
82
|
+
DELETE_USERS = "users:delete"
|
|
83
|
+
ADMIN = "*"
|
|
84
|
+
|
|
85
|
+
class Role:
|
|
86
|
+
ADMIN = [Permission.ADMIN]
|
|
87
|
+
EDITOR = [Permission.READ_USERS, Permission.WRITE_USERS]
|
|
88
|
+
VIEWER = [Permission.READ_USERS]
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Middleware de Autorización
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
def require_permission(permission: Permission):
|
|
95
|
+
async def dependency(user: User = Depends(get_current_user)):
|
|
96
|
+
if not user.has_permission(permission):
|
|
97
|
+
raise HTTPException(status_code=403, detail="Forbidden")
|
|
98
|
+
return user
|
|
99
|
+
return Depends(dependency)
|
|
100
|
+
|
|
101
|
+
@router.delete("/users/{id}")
|
|
102
|
+
async def delete_user(
|
|
103
|
+
id: str,
|
|
104
|
+
user: User = require_permission(Permission.DELETE_USERS)
|
|
105
|
+
):
|
|
106
|
+
...
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Input Validation
|
|
112
|
+
|
|
113
|
+
### Pydantic Validators
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
from pydantic import BaseModel, EmailStr, Field, validator
|
|
117
|
+
|
|
118
|
+
class UserCreate(BaseModel):
|
|
119
|
+
email: EmailStr
|
|
120
|
+
password: str = Field(min_length=8, max_length=128)
|
|
121
|
+
name: str = Field(min_length=1, max_length=100)
|
|
122
|
+
|
|
123
|
+
@validator("password")
|
|
124
|
+
def password_strength(cls, v):
|
|
125
|
+
if not any(c.isupper() for c in v):
|
|
126
|
+
raise ValueError("Password must contain uppercase")
|
|
127
|
+
if not any(c.isdigit() for c in v):
|
|
128
|
+
raise ValueError("Password must contain digit")
|
|
129
|
+
return v
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### SQL Injection Prevention
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
# ✅ BUENO: Parameterized queries
|
|
136
|
+
await conn.execute(
|
|
137
|
+
"SELECT * FROM users WHERE email = $1",
|
|
138
|
+
email
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
# ❌ MALO: String interpolation
|
|
142
|
+
await conn.execute(
|
|
143
|
+
f"SELECT * FROM users WHERE email = '{email}'"
|
|
144
|
+
)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### XSS Prevention
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
// ✅ BUENO: React escapa automáticamente
|
|
151
|
+
<div>{userInput}</div>
|
|
152
|
+
|
|
153
|
+
// ❌ MALO: dangerouslySetInnerHTML
|
|
154
|
+
<div dangerouslySetInnerHTML={{ __html: userInput }} />
|
|
155
|
+
|
|
156
|
+
// Si necesitas HTML, sanitizar primero
|
|
157
|
+
import DOMPurify from 'dompurify';
|
|
158
|
+
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(html) }} />
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Secrets Management
|
|
164
|
+
|
|
165
|
+
### Variables de Entorno
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# .env (NUNCA en git)
|
|
169
|
+
DATABASE_URL=postgresql://user:pass@localhost/db
|
|
170
|
+
JWT_SECRET_KEY=super-secret-key
|
|
171
|
+
API_KEY=sk_live_xxxx
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Nunca en Código
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
# ❌ MALO
|
|
178
|
+
API_KEY = "sk_live_1234567890"
|
|
179
|
+
|
|
180
|
+
# ✅ BUENO
|
|
181
|
+
API_KEY = os.getenv("API_KEY")
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Rotación de Secrets
|
|
185
|
+
|
|
186
|
+
- Rotar cada 90 días (mínimo)
|
|
187
|
+
- Tener proceso de rotación automatizado
|
|
188
|
+
- Invalidar secrets comprometidos inmediatamente
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Headers de Seguridad
|
|
193
|
+
|
|
194
|
+
### FastAPI/Starlette
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
from starlette.middleware.cors import CORSMiddleware
|
|
198
|
+
from secure import Secure
|
|
199
|
+
|
|
200
|
+
secure_headers = Secure()
|
|
201
|
+
|
|
202
|
+
@app.middleware("http")
|
|
203
|
+
async def add_security_headers(request: Request, call_next):
|
|
204
|
+
response = await call_next(request)
|
|
205
|
+
secure_headers.framework.headers(response.headers)
|
|
206
|
+
return response
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Headers Recomendados
|
|
210
|
+
|
|
211
|
+
```http
|
|
212
|
+
X-Content-Type-Options: nosniff
|
|
213
|
+
X-Frame-Options: DENY
|
|
214
|
+
X-XSS-Protection: 1; mode=block
|
|
215
|
+
Strict-Transport-Security: max-age=31536000; includeSubDomains
|
|
216
|
+
Content-Security-Policy: default-src 'self'
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Rate Limiting
|
|
222
|
+
|
|
223
|
+
```python
|
|
224
|
+
from slowapi import Limiter
|
|
225
|
+
from slowapi.util import get_remote_address
|
|
226
|
+
|
|
227
|
+
limiter = Limiter(key_func=get_remote_address)
|
|
228
|
+
|
|
229
|
+
@app.get("/api/search")
|
|
230
|
+
@limiter.limit("10/minute")
|
|
231
|
+
async def search(request: Request):
|
|
232
|
+
...
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Logging de Seguridad
|
|
238
|
+
|
|
239
|
+
### Qué Logear
|
|
240
|
+
|
|
241
|
+
```python
|
|
242
|
+
# ✅ Logear
|
|
243
|
+
logger.info("Login successful", extra={
|
|
244
|
+
"user_id": user.id,
|
|
245
|
+
"ip": request.client.host
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
logger.warning("Login failed", extra={
|
|
249
|
+
"email": email, # No password
|
|
250
|
+
"ip": request.client.host,
|
|
251
|
+
"reason": "invalid_password"
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
# ❌ NUNCA logear
|
|
255
|
+
logger.info(f"Login with password: {password}") # Contraseñas
|
|
256
|
+
logger.info(f"Card number: {card_number}") # PII
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Security Checklist
|
|
262
|
+
|
|
263
|
+
```markdown
|
|
264
|
+
## Para cada endpoint
|
|
265
|
+
- [ ] Autenticación requerida
|
|
266
|
+
- [ ] Autorización verificada
|
|
267
|
+
- [ ] Input validado
|
|
268
|
+
- [ ] Output sanitizado
|
|
269
|
+
- [ ] Rate limiting
|
|
270
|
+
|
|
271
|
+
## Para deployment
|
|
272
|
+
- [ ] HTTPS obligatorio
|
|
273
|
+
- [ ] Headers de seguridad
|
|
274
|
+
- [ ] Secrets en env vars
|
|
275
|
+
- [ ] Logs sin PII
|
|
276
|
+
- [ ] Dependency audit
|
|
277
|
+
|
|
278
|
+
## Periódico
|
|
279
|
+
- [ ] Rotar secrets (90 días)
|
|
280
|
+
- [ ] Actualizar dependencias
|
|
281
|
+
- [ ] Revisar logs de auth
|
|
282
|
+
- [ ] Penetration testing (anual)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Tools de Seguridad
|
|
288
|
+
|
|
289
|
+
| Tool | Uso |
|
|
290
|
+
|------|-----|
|
|
291
|
+
| Bandit | Static analysis Python |
|
|
292
|
+
| Safety | Dependency vulnerabilities |
|
|
293
|
+
| Snyk | Multi-language security |
|
|
294
|
+
| Trivy | Container scanning |
|
|
295
|
+
| OWASP ZAP | Dynamic testing |
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## ✅ Checklist de Validación (Security Review)
|
|
300
|
+
|
|
301
|
+
### Código
|
|
302
|
+
- [ ] Sin credenciales/secrets hardcodeados
|
|
303
|
+
- [ ] Inputs validados con Pydantic/Zod
|
|
304
|
+
- [ ] Queries SQL parametrizadas (no f-strings)
|
|
305
|
+
- [ ] Outputs sanitizados (no XSS)
|
|
306
|
+
|
|
307
|
+
### Auth
|
|
308
|
+
- [ ] JWT con expiración corta (<= 15 min)
|
|
309
|
+
- [ ] Passwords con bcrypt/argon2
|
|
310
|
+
- [ ] RBAC implementado correctamente
|
|
311
|
+
|
|
312
|
+
### Infra
|
|
313
|
+
- [ ] HTTPS obligatorio
|
|
314
|
+
- [ ] Headers de seguridad configurados
|
|
315
|
+
- [ ] Rate limiting en endpoints públicos
|
|
316
|
+
- [ ] Logs sin PII ni passwords
|
package/rules/stack.md
ADDED
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
# Stack Tecnológico - LMAgent
|
|
2
|
+
|
|
3
|
+
> **Tipo**: `rule` | **Versión**: 2.1 | **Actualización**: 2026-01
|
|
4
|
+
|
|
5
|
+
## 📌 Quick Reference
|
|
6
|
+
|
|
7
|
+
| Capa | Tecnología Principal |
|
|
8
|
+
|------|----------------------|
|
|
9
|
+
| **Backend** | Python 3.11+ (FastAPI) o TypeScript (NestJS) |
|
|
10
|
+
| **Database** | PostgreSQL 15+ (principal) + Redis 7+ (cache/colas) |
|
|
11
|
+
| **ORM** | SQLModel (Python) o Prisma (TypeScript) |
|
|
12
|
+
| **Validation** | Pydantic v2 |
|
|
13
|
+
| **LLM** | GPT-4o (complejo) / Gemini Flash (rápido) / Claude Haiku (volumen) |
|
|
14
|
+
| **AI Frameworks** | LangGraph (agentes) / LangChain (chains) |
|
|
15
|
+
| **Automation** | n8n |
|
|
16
|
+
| **Frontend** | React / Next.js |
|
|
17
|
+
| **Mobile** | React Native / Expo |
|
|
18
|
+
| **Deploy** | Docker + Dokploy |
|
|
19
|
+
|
|
20
|
+
### 👥 Roles que usan esta regla
|
|
21
|
+
`backend-engineer`, `frontend-engineer`, `devops-engineer`, `architect`
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
Este documento define el stack tecnológico base y las buenas prácticas para proyectos que usan LMAgent.
|
|
26
|
+
|
|
27
|
+
## Stack Principal
|
|
28
|
+
|
|
29
|
+
### Lenguajes
|
|
30
|
+
| Lenguaje | Versión | Uso |
|
|
31
|
+
|----------|---------|-----|
|
|
32
|
+
| Python | 3.14+ | Backends, agentes IA, scripts |
|
|
33
|
+
| TypeScript | 6.0+ | Backends Node, frontends |
|
|
34
|
+
| JavaScript | ES2026+ | Scripts, n8n custom nodes |
|
|
35
|
+
|
|
36
|
+
### Frameworks Backend
|
|
37
|
+
|
|
38
|
+
#### Python (Preferido para APIs y Agentes)
|
|
39
|
+
```
|
|
40
|
+
FastAPI - Framework web async
|
|
41
|
+
SQLModel - ORM + validación (combina SQLAlchemy + Pydantic)
|
|
42
|
+
Pydantic - Validación de datos
|
|
43
|
+
Pydantic-Settings - Configuración via env vars
|
|
44
|
+
Uvicorn - Servidor ASGI
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
#### NodeJS/TypeScript (Cuando sea necesario)
|
|
48
|
+
```
|
|
49
|
+
NestJS - Framework estructurado (preferido)
|
|
50
|
+
Express - Framework minimalista
|
|
51
|
+
Prisma - ORM para TypeScript
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Base de Datos
|
|
55
|
+
| Componente | Tecnología | Uso |
|
|
56
|
+
|------------|------------|-----|
|
|
57
|
+
| Principal | PostgreSQL 18+ | Datos relacionales |
|
|
58
|
+
| Cache | Redis 8+ | Cache, sesiones, colas |
|
|
59
|
+
| Colas | Redis Streams | Mensajería async |
|
|
60
|
+
| Búsqueda | PostgreSQL FTS | Búsqueda de texto |
|
|
61
|
+
|
|
62
|
+
### Infraestructura
|
|
63
|
+
| Componente | Tecnología | Uso |
|
|
64
|
+
|------------|------------|-----|
|
|
65
|
+
| Containers | Docker | Empaquetado |
|
|
66
|
+
| Orquestación | Docker Compose | Desarrollo local |
|
|
67
|
+
| Deployment | Dokploy | Deploy a producción |
|
|
68
|
+
| CI/CD | GitHub Actions | Automatización |
|
|
69
|
+
|
|
70
|
+
### Automatización e IA
|
|
71
|
+
| Componente | Tecnología | Uso |
|
|
72
|
+
|------------|------------|-----|
|
|
73
|
+
| Orquestación | n8n | Workflows visuales |
|
|
74
|
+
| LLM Primary | OpenAI GPT-4o | Tareas complejas |
|
|
75
|
+
| LLM Fast | Gemini Flash | Tareas rápidas |
|
|
76
|
+
| LLM Cost-effective | Claude Haiku | Alto volumen |
|
|
77
|
+
| Agent Framework | LangGraph | Agentes stateful, grafos |
|
|
78
|
+
| Chain Framework | LangChain | Chains, RAG, embeddings |
|
|
79
|
+
| MCP | Model Context Protocol | Tool-use, integración de herramientas |
|
|
80
|
+
|
|
81
|
+
### Frontend & Mobile
|
|
82
|
+
| Componente | Tecnología | Uso |
|
|
83
|
+
|------------|------------|-----|
|
|
84
|
+
| Web Framework | React / Next.js | Interfaces web |
|
|
85
|
+
| Mobile | React Native / Expo | Apps iOS y Android |
|
|
86
|
+
| State | Zustand / Redux Toolkit | Estado global |
|
|
87
|
+
| Styling | TailwindCSS / CSS Modules | Estilos |
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Estructura de Proyecto
|
|
92
|
+
|
|
93
|
+
### Monorepo Multi-servicio
|
|
94
|
+
```
|
|
95
|
+
proyecto/
|
|
96
|
+
├── .lmagent/ # Framework LMAgent
|
|
97
|
+
├── backend-python/ # API principal (FastAPI)
|
|
98
|
+
├── backend-node/ # Servicios Node (opcional)
|
|
99
|
+
├── agents/ # Agentes de IA
|
|
100
|
+
├── automations/ # Workflows n8n
|
|
101
|
+
├── infra/ # Docker, configs
|
|
102
|
+
├── docs/ # Documentación
|
|
103
|
+
└── .github/ # CI/CD
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Estructura Backend Python
|
|
107
|
+
```
|
|
108
|
+
backend-python/
|
|
109
|
+
├── app/
|
|
110
|
+
│ ├── __init__.py
|
|
111
|
+
│ ├── main.py # Entry point FastAPI
|
|
112
|
+
│ ├── config.py # Configuración
|
|
113
|
+
│ ├── routers/ # Endpoints (capa presentación)
|
|
114
|
+
│ ├── services/ # Lógica de negocio
|
|
115
|
+
│ ├── repositories/ # Acceso a datos
|
|
116
|
+
│ ├── models/ # Modelos SQLModel
|
|
117
|
+
│ ├── schemas/ # Schemas Pydantic
|
|
118
|
+
│ └── core/ # Utilidades compartidas
|
|
119
|
+
├── tests/
|
|
120
|
+
├── Dockerfile
|
|
121
|
+
└── requirements.txt
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Patrones de Arquitectura
|
|
127
|
+
|
|
128
|
+
### Capas de la Aplicación
|
|
129
|
+
```
|
|
130
|
+
┌─────────────────────────────────────┐
|
|
131
|
+
│ Routers (API) │ ← HTTP Request/Response
|
|
132
|
+
├─────────────────────────────────────┤
|
|
133
|
+
│ Services │ ← Lógica de negocio
|
|
134
|
+
├─────────────────────────────────────┤
|
|
135
|
+
│ Repositories │ ← Acceso a datos
|
|
136
|
+
├─────────────────────────────────────┤
|
|
137
|
+
│ Models/Schemas │ ← Estructuras de datos
|
|
138
|
+
└─────────────────────────────────────┘
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Principios
|
|
142
|
+
1. **Routers**: Solo manejan HTTP, sin lógica de negocio
|
|
143
|
+
2. **Services**: Toda la lógica de negocio, sin acceso directo a DB
|
|
144
|
+
3. **Repositories**: Acceso a datos, queries, transacciones
|
|
145
|
+
4. **Models**: Representan entidades de la base de datos
|
|
146
|
+
5. **Schemas**: Validación de input/output de API
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Configuración
|
|
151
|
+
|
|
152
|
+
### Variables de Entorno (obligatorio)
|
|
153
|
+
```python
|
|
154
|
+
# config.py
|
|
155
|
+
from pydantic_settings import BaseSettings
|
|
156
|
+
|
|
157
|
+
class Settings(BaseSettings):
|
|
158
|
+
# Database
|
|
159
|
+
DATABASE_URL: str
|
|
160
|
+
|
|
161
|
+
# Redis
|
|
162
|
+
REDIS_URL: str = "redis://localhost:6379"
|
|
163
|
+
|
|
164
|
+
# Security
|
|
165
|
+
JWT_SECRET: str
|
|
166
|
+
JWT_ALGORITHM: str = "HS256"
|
|
167
|
+
JWT_EXPIRE_MINUTES: int = 30
|
|
168
|
+
|
|
169
|
+
# API Keys (opcional)
|
|
170
|
+
OPENAI_API_KEY: str = ""
|
|
171
|
+
ANTHROPIC_API_KEY: str = ""
|
|
172
|
+
GOOGLE_API_KEY: str = ""
|
|
173
|
+
|
|
174
|
+
# n8n
|
|
175
|
+
N8N_WEBHOOK_URL: str = ""
|
|
176
|
+
|
|
177
|
+
# Environment
|
|
178
|
+
ENVIRONMENT: str = "development"
|
|
179
|
+
DEBUG: bool = False
|
|
180
|
+
|
|
181
|
+
class Config:
|
|
182
|
+
env_file = ".env"
|
|
183
|
+
case_sensitive = True
|
|
184
|
+
|
|
185
|
+
settings = Settings()
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### .env.example
|
|
189
|
+
```bash
|
|
190
|
+
# Database
|
|
191
|
+
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
|
|
192
|
+
|
|
193
|
+
# Redis
|
|
194
|
+
REDIS_URL=redis://localhost:6379
|
|
195
|
+
|
|
196
|
+
# Security
|
|
197
|
+
JWT_SECRET=your-super-secret-key-minimum-32-characters
|
|
198
|
+
|
|
199
|
+
# LLM API Keys
|
|
200
|
+
OPENAI_API_KEY=sk-...
|
|
201
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
202
|
+
GOOGLE_API_KEY=...
|
|
203
|
+
|
|
204
|
+
# n8n
|
|
205
|
+
N8N_WEBHOOK_URL=https://n8n.yourserver.com/webhook
|
|
206
|
+
|
|
207
|
+
# Environment
|
|
208
|
+
ENVIRONMENT=development
|
|
209
|
+
DEBUG=true
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Buenas Prácticas
|
|
215
|
+
|
|
216
|
+
### Obligatorias ✅
|
|
217
|
+
- [ ] Configuración via variables de entorno (nunca hardcode)
|
|
218
|
+
- [ ] Type hints en todas las funciones
|
|
219
|
+
- [ ] Docstrings en funciones públicas
|
|
220
|
+
- [ ] Tests para lógica de negocio (>80% coverage)
|
|
221
|
+
- [ ] Logging estructurado (JSON en producción)
|
|
222
|
+
- [ ] Manejo de errores con excepciones tipadas
|
|
223
|
+
- [ ] Validación de input con Pydantic
|
|
224
|
+
- [ ] Commits pequeños y descriptivos
|
|
225
|
+
|
|
226
|
+
### Prohibidas ❌
|
|
227
|
+
- [ ] Credenciales en código
|
|
228
|
+
- [ ] `print()` en lugar de logging
|
|
229
|
+
- [ ] `import *`
|
|
230
|
+
- [ ] Lógica de negocio en routers
|
|
231
|
+
- [ ] SQL sin parametrizar
|
|
232
|
+
- [ ] Commits sin tests
|
|
233
|
+
- [ ] PRs gigantes sin dividir
|
|
234
|
+
|
|
235
|
+
### Recomendadas 💡
|
|
236
|
+
- [ ] Usar async/await para I/O
|
|
237
|
+
- [ ] Implementar health checks
|
|
238
|
+
- [ ] Documentar APIs con OpenAPI
|
|
239
|
+
- [ ] Usar dependency injection
|
|
240
|
+
- [ ] Implementar rate limiting
|
|
241
|
+
- [ ] Agregar métricas de observabilidad
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Dependencias
|
|
246
|
+
|
|
247
|
+
### Python - requirements.txt base
|
|
248
|
+
```
|
|
249
|
+
# Framework
|
|
250
|
+
fastapi>=0.109.0
|
|
251
|
+
uvicorn[standard]>=0.27.0
|
|
252
|
+
|
|
253
|
+
# Database
|
|
254
|
+
sqlmodel>=0.0.14
|
|
255
|
+
asyncpg>=0.29.0
|
|
256
|
+
sqlalchemy[asyncio]>=2.0.0
|
|
257
|
+
|
|
258
|
+
# Validation
|
|
259
|
+
pydantic>=2.5.0
|
|
260
|
+
pydantic-settings>=2.1.0
|
|
261
|
+
|
|
262
|
+
# Redis
|
|
263
|
+
redis>=5.0.0
|
|
264
|
+
|
|
265
|
+
# HTTP Client
|
|
266
|
+
httpx>=0.26.0
|
|
267
|
+
|
|
268
|
+
# Security
|
|
269
|
+
python-jose[cryptography]>=3.3.0
|
|
270
|
+
passlib[bcrypt]>=1.7.4
|
|
271
|
+
|
|
272
|
+
# Logging
|
|
273
|
+
structlog>=24.1.0
|
|
274
|
+
|
|
275
|
+
# Dev
|
|
276
|
+
pytest>=8.0.0
|
|
277
|
+
pytest-asyncio>=0.23.0
|
|
278
|
+
pytest-cov>=4.1.0
|
|
279
|
+
ruff>=0.2.0
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Node - package.json base
|
|
283
|
+
```json
|
|
284
|
+
{
|
|
285
|
+
"dependencies": {
|
|
286
|
+
"@nestjs/common": "^10.0.0",
|
|
287
|
+
"@nestjs/core": "^10.0.0",
|
|
288
|
+
"@nestjs/platform-express": "^10.0.0",
|
|
289
|
+
"@prisma/client": "^5.0.0",
|
|
290
|
+
"ioredis": "^5.3.0",
|
|
291
|
+
"class-validator": "^0.14.0",
|
|
292
|
+
"class-transformer": "^0.5.1"
|
|
293
|
+
},
|
|
294
|
+
"devDependencies": {
|
|
295
|
+
"@types/node": "^20.0.0",
|
|
296
|
+
"typescript": "^5.0.0",
|
|
297
|
+
"jest": "^29.0.0",
|
|
298
|
+
"eslint": "^8.0.0",
|
|
299
|
+
"prettier": "^3.0.0"
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Docker
|
|
307
|
+
|
|
308
|
+
### Dockerfile Python (multi-stage)
|
|
309
|
+
```dockerfile
|
|
310
|
+
# Build stage
|
|
311
|
+
FROM python:3.11-slim as builder
|
|
312
|
+
|
|
313
|
+
WORKDIR /app
|
|
314
|
+
COPY requirements.txt .
|
|
315
|
+
RUN pip install --no-cache-dir --user -r requirements.txt
|
|
316
|
+
|
|
317
|
+
# Production stage
|
|
318
|
+
FROM python:3.11-slim
|
|
319
|
+
|
|
320
|
+
WORKDIR /app
|
|
321
|
+
COPY --from=builder /root/.local /root/.local
|
|
322
|
+
COPY ./app ./app
|
|
323
|
+
|
|
324
|
+
ENV PATH=/root/.local/bin:$PATH
|
|
325
|
+
ENV PYTHONUNBUFFERED=1
|
|
326
|
+
|
|
327
|
+
EXPOSE 8000
|
|
328
|
+
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### docker-compose.yml
|
|
332
|
+
```yaml
|
|
333
|
+
version: "3.8"
|
|
334
|
+
|
|
335
|
+
services:
|
|
336
|
+
backend:
|
|
337
|
+
build: ./backend-python
|
|
338
|
+
ports:
|
|
339
|
+
- "8000:8000"
|
|
340
|
+
environment:
|
|
341
|
+
- DATABASE_URL=postgresql://user:pass@db:5432/app
|
|
342
|
+
- REDIS_URL=redis://redis:6379
|
|
343
|
+
depends_on:
|
|
344
|
+
- db
|
|
345
|
+
- redis
|
|
346
|
+
|
|
347
|
+
db:
|
|
348
|
+
image: postgres:15-alpine
|
|
349
|
+
environment:
|
|
350
|
+
POSTGRES_USER: user
|
|
351
|
+
POSTGRES_PASSWORD: pass
|
|
352
|
+
POSTGRES_DB: app
|
|
353
|
+
volumes:
|
|
354
|
+
- postgres_data:/var/lib/postgresql/data
|
|
355
|
+
|
|
356
|
+
redis:
|
|
357
|
+
image: redis:7-alpine
|
|
358
|
+
volumes:
|
|
359
|
+
- redis_data:/data
|
|
360
|
+
|
|
361
|
+
volumes:
|
|
362
|
+
postgres_data:
|
|
363
|
+
redis_data:
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## Referencias
|
|
369
|
+
|
|
370
|
+
- [FastAPI Documentation](https://fastapi.tiangolo.com/)
|
|
371
|
+
- [SQLModel Documentation](https://sqlmodel.tiangolo.com/)
|
|
372
|
+
- [Pydantic Documentation](https://docs.pydantic.dev/)
|
|
373
|
+
- [n8n Documentation](https://docs.n8n.io/)
|
|
374
|
+
- [Docker Best Practices](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## ✅ Checklist de Validación (Nuevo Proyecto)
|
|
379
|
+
|
|
380
|
+
### Setup Inicial
|
|
381
|
+
- [ ] Estructura de directorios según patrón definido
|
|
382
|
+
- [ ] `.env.example` con todas las variables documentadas
|
|
383
|
+
- [ ] `docker-compose.yml` con PostgreSQL + Redis
|
|
384
|
+
- [ ] Config via pydantic-settings (no hardcode)
|
|
385
|
+
|
|
386
|
+
### Código
|
|
387
|
+
- [ ] Type hints en todas las funciones
|
|
388
|
+
- [ ] Capas separadas: Routers → Services → Repositories
|
|
389
|
+
- [ ] Sin credenciales en código
|
|
390
|
+
- [ ] Logging con structlog (no print)
|
|
391
|
+
|
|
392
|
+
### Calidad
|
|
393
|
+
- [ ] Tests con pytest, coverage > 80%
|
|
394
|
+
- [ ] Linting con ruff pasando
|
|
395
|
+
- [ ] CI/CD con GitHub Actions configurado
|