🗣️ Developer Cookbook - FASE 8: Habilidades Blandas y Liderazgo
Recetas prácticas para comunicar, liderar y gestionar equipos técnicos efectivamente
Comunicación Técnica
Receta 8.1: ADRs (Architecture Decision Records)
¿Qué es? Documentos cortos que explican por qué tomamos decisiones de arquitectura importantes. No solo el “qué”, sino el “por qué” y las alternativas consideradas.
Cuándo escribir un ADR:
- Cambio de base de datos
- Adopción de nuevo framework
- Cambio de arquitectura (monolito → microservicios)
- Decisión que afecta a múltiples equipos
- Algo que no se puede cambiar fácil después
Template de ADR:
# ADR-001: [Título corto de la decisión]
## Status
[Proposed | Accepted | Deprecated | Superseded]
## Context
¿Qué problema estamos resolviendo? ¿Por qué necesitamos tomar esta decisión?
## Decision
¿Qué vamos a hacer?
## Consequences
¿Qué ganamos? ¿Qué perdemos? ¿Qué trade-offs?
### Positive
- Beneficio 1
- Beneficio 2
### Negative
- Costo/limitación 1
- Costo/limitación 2
### Risks
- Riesgo 1
- Riesgo 2
## Alternatives Considered
¿Qué otras opciones evaluamos y por qué NO las elegimos?
### Alternative 1: [Nombre]
- Pros: ...
- Cons: ...
- Rejected because: ...
### Alternative 2: [Nombre]
- Pros: ...
- Cons: ...
- Rejected because: ...
## References
- Links a documentación
- RFCs relacionados
- Investigación previa
Ejemplo real:
# ADR-003: Migrar de PostgreSQL a DynamoDB para tabla de sessions
**Date**: 2024-02-20
**Status**: Accepted
**Author**: Engineering Team
**Reviewers**: CTO, Backend Lead
## Context
Nuestra aplicación web almacena sessions de usuarios en PostgreSQL.
Hemos observado:
- 500K usuarios activos mensuales
- 10M+ queries/day a la tabla sessions
- Latencia p95 de 150ms (target: <50ms)
- DB CPU al 80% durante peak hours
- Sessions table = 60% del total de queries
- Costo actual: $800/mes en RDS PostgreSQL db.m5.xlarge
El problema: Las sessions son 90% reads, no necesitan relaciones,
y están saturando nuestra DB relacional.
## Decision
Migraremos la tabla de sessions de PostgreSQL a DynamoDB.
**Scope:**
- Solo sessions (usuarios, productos permanecen en PostgreSQL)
- Mantener TTL de 30 días
- Migración gradual con feature flag (canary deployment)
**Implementation plan:**
1. Crear tabla DynamoDB con partition key = session_id
2. Dual-write: escribir en ambas DBs por 1 semana
3. Gradual read migration: 10% -> 50% -> 100%
4. Deprecar PostgreSQL sessions después de 2 semanas
## Consequences
### Positive
- Performance: DynamoDB latencia menor a 10ms (vs 150ms)
- Scalability: Auto-scaling, sin límite práctico
- Cost: $120/mes DynamoDB vs $800/mes RDS = $680/mes savings
- DB load: Libera 60% de queries en PostgreSQL
- TTL native: DynamoDB TTL automático (no necesitamos cron job)
### Negative
- No SQL queries: No podemos hacer SELECT * FROM sessions WHERE user_id = X
- Learning curve: Team necesita aprender DynamoDB
- Migration complexity: Dual-write durante transición
- Vendor lock-in: Más difícil migrar de AWS
### Risks
- Data inconsistency durante migration: Mitigado con dual-write
- DynamoDB costs spike: Mitigado con auto-scaling limits
- Rollback complexity: Mantenemos PostgreSQL sessions 2 semanas
## Alternatives Considered
### Alternative 1: Redis (ElastiCache)
**Pros:**
- Más rápido que DynamoDB (~1ms)
- Team tiene experiencia con Redis
- Fácil de implementar
**Cons:**
- Volátil (se pierde en restart a menos que uses persistence)
- Costo similar a DynamoDB pero con menos durabilidad
- Requiere clustering para HA
**Rejected because:**
Necesitamos durabilidad. Perder todas las sessions en un restart
no es aceptable. DynamoDB ofrece similar performance con mejor durabilidad.
### Alternative 2: Optimize PostgreSQL queries
**Pros:**
- No migration needed
- Zero learning curve
- Keep everything in one DB
**Cons:**
- Solo reduces latencia a ~80ms (no suficiente)
- No soluciona problema de scaling
- PostgreSQL no diseñado para este access pattern
**Rejected because:**
Optimización incremental no resuelve problema fundamental.
Sessions son key-value lookups, no necesitan SQL.
### Alternative 3: Keep as-is and scale up RDS
**Pros:**
- Zero migration effort
- Familiar technology
**Cons:**
- Costo: db.m5.2xlarge = $1,600/mes (2x actual)
- Solo patea el problema 6 meses
- No mejora latencia significativamente
**Rejected because:**
Costo prohibitivo y no sustentable. No es escalable long-term.
## References
- [DynamoDB Best Practices](https://docs.aws.amazon.com/dynamodb/)
- [Session Management at Scale - Auth0](https://auth0.com/blog/)
- Internal: `experiments/dynamodb-sessions-poc` (results summary)
- Slack discussion: #architecture-decisions (2024-02-15)
## Success Metrics
- Latencia p95 < 50ms
- $500+ monthly cost savings
- Zero data loss during migration
- <1% error rate during transition
Python tool para generar ADR:
from datetime import datetime
from dataclasses import dataclass
from typing import List
@dataclass
class Alternative:
name: str
pros: List[str]
cons: List[str]
rejected_reason: str
@dataclass
class ADR:
"""Architecture Decision Record"""
number: int
title: str
status: str # Proposed, Accepted, Deprecated, Superseded
context: str
decision: str
positive_consequences: List[str]
negative_consequences: List[str]
risks: List[str]
alternatives: List[Alternative]
references: List[str]
author: str = "Engineering Team"
def generate_markdown(self) -> str:
"""Generar ADR en formato markdown"""
date = datetime.now().strftime("%Y-%m-%d")
md = f"""# ADR-{self.number:03d}: {self.title}
**Date**: {date}
**Status**: {self.status}
**Author**: {self.author}
## Context
{self.context}
## Decision
{self.decision}
## Consequences
### Positive
"""
for pro in self.positive_consequences:
md += f"- {pro}\n"
md += "\n### Negative\n"
for con in self.negative_consequences:
md += f"- {con}\n"
md += "\n### Risks\n"
for risk in self.risks:
md += f"- {risk}\n"
md += "\n## Alternatives Considered\n"
for alt in self.alternatives:
md += f"\n### Alternative: {alt.name}\n"
md += "**Pros:**\n"
for pro in alt.pros:
md += f"- {pro}\n"
md += "\n**Cons:**\n"
for con in alt.cons:
md += f"- {con}\n"
md += f"\n**Rejected because:** {alt.rejected_reason}\n"
md += "\n## References\n"
for ref in self.references:
md += f"- {ref}\n"
return md
# Ejemplo de uso
adr = ADR(
number=5,
title="Adopt TypeScript for new frontend code",
status="Proposed",
context="""
Our React codebase is 100% JavaScript. We've had recurring issues:
- 40% of production bugs are type-related (undefined is not a function)
- Refactoring is risky (no compile-time checks)
- New developers struggle to understand data shapes
- We spend ~2 hours/week debugging type issues
""",
decision="""
All new frontend code will be written in TypeScript starting March 1, 2024.
Scope:
- New components/modules: TypeScript required
- Existing code: Migrate gradually (no big-bang rewrite)
- Target: 80% TypeScript coverage by end of Q2
""",
positive_consequences=[
"Catch bugs at compile-time instead of runtime",
"Better IDE autocomplete and documentation",
"Easier onboarding (types document the code)",
"Safer refactoring with confidence"
],
negative_consequences=[
"Learning curve for team (2-3 weeks)",
"Slower initial development (~20% slower for first month)",
"Build times increase by ~30%",
"Mixed JS/TS codebase during transition (6+ months)"
],
risks=[
"Team resistance to change",
"Over-using 'any' defeats the purpose",
"Strict types might slow down prototyping"
],
alternatives=[
Alternative(
name="Flow (Facebook's type checker)",
pros=[
"Similar to TypeScript",
"We already use React (also Facebook)"
],
cons=[
"Smaller community than TypeScript",
"Facebook deprecated it internally",
"Worse IDE support"
],
rejected_reason="TypeScript has won the market. Flow is declining."
),
Alternative(
name="JSDoc comments for type hints",
pros=[
"Zero build step",
"No migration needed",
"Works with existing JS"
],
cons=[
"Not enforced (just hints)",
"Verbose syntax",
"No compile-time checks"
],
rejected_reason="Doesn't solve the core problem: we need enforcement."
),
Alternative(
name="Keep JavaScript, add more tests",
pros=[
"No learning curve",
"No migration",
"Familiar tools"
],
cons=[
"Tests catch bugs later than types",
"Test coverage never reaches 100%",
"Doesn't help with refactoring"
],
rejected_reason="Tests and types complement each other. Types prevent whole classes of bugs."
)
],
references=[
"TypeScript Handbook: https://www.typescriptlang.org/docs/",
"Internal: POC results in `experiments/typescript-migration`",
"Survey: 8/10 engineers support TypeScript adoption"
]
)
print(adr.generate_markdown())
Receta 8.2: RFCs (Request for Comments)
¿Qué es? Documento de propuesta que invita feedback ANTES de implementar. Similar a ADR pero más temprano en el proceso (propuesta vs decisión).
ADR vs RFC:
- RFC: “Estoy proponiendo X, ¿qué opinan?” (pre-decisión)
- ADR: “Decidimos X, aquí está el por qué” (post-decisión)
Template de RFC:
# RFC-042: [Título de la propuesta]
**Author**: [Tu nombre]
**Created**: 2024-02-20
**Status**: Draft | In Review | Approved | Rejected
**Reviewers**: @tech-lead, @architect
**Target Decision Date**: 2024-03-01
## Summary
[1-2 párrafos explicando la propuesta en lenguaje simple]
## Motivation
¿Por qué estamos haciendo esto? ¿Qué problema resuelve?
### Problem Statement
[Descripción clara del problema actual]
### Goals
- Goal 1
- Goal 2
### Non-Goals
- Explícitamente NO vamos a hacer esto
- Explícitamente fuera de scope
## Proposed Solution
### Architecture Diagram
[Diagrama de la solución propuesta]
### Implementation Details
[Detalles técnicos de la implementación]
### API/Interface Changes
[Si aplica, mostrar cambios en APIs]
### Database Schema Changes
[Si aplica, mostrar cambios en schema]
### Migration Strategy
¿Cómo migramos del estado actual al nuevo estado?
## Alternatives Considered
[Similar a ADR, explicar alternativas]
## Trade-offs and Risks
- Trade-off 1
- Risk 1: [Descripción] | Mitigation: [Cómo mitigamos]
## Testing Strategy
¿Cómo validamos que funciona?
## Rollout Plan
1. Phase 1: ...
2. Phase 2: ...
3. Phase 3: ...
## Success Metrics
¿Cómo medimos éxito?
- Metric 1: Target value
- Metric 2: Target value
## Timeline
| Phase | Duration | Owner |
|-------|----------|-------|
| Design | 1 week | @alice |
| Implementation | 3 weeks | @bob |
| Testing | 1 week | @charlie |
| Rollout | 2 weeks | @alice |
## Open Questions
- [ ] Question 1 that needs answer?
- [ ] Question 2 we're not sure about?
## References
- Link 1
- Link 2
---
## Review Comments
[Area para que reviewers agreguen comments]
Ejemplo real de RFC:
# RFC-018: Implement Rate Limiting on API Gateway
**Author**: @sarah-backend
**Created**: 2024-02-20
**Status**: In Review
**Reviewers**: @tech-lead, @devops-lead, @security-lead
**Target Decision Date**: 2024-02-27
## Summary
Add rate limiting to our public API to prevent abuse and ensure fair usage.
Currently, we have no rate limits, which has led to:
- 3 incidents in Q4 2023 where single users overwhelmed the API
- $2,400 in unexpected cloud costs from abuse
- Degraded performance for legitimate users
Proposal: Implement tiered rate limiting based on user plan.
## Motivation
### Problem Statement
Our API currently has no rate limiting. Last month:
- User A made 10M requests in 1 day (normal is 50K)
- Caused p99 latency to spike to 5 seconds
- Cost us $800 in extra cloud compute
- Legitimate users complained about slow API
We need rate limiting to:
1. Prevent abuse
2. Control costs
3. Guarantee SLAs for paying customers
4. Create incentive for paid plans
### Goals
- Implement fair rate limiting per user/API key
- Different limits per pricing tier
- Graceful degradation (don't hard-fail)
- Observable (metrics + alerts)
- Zero downtime deployment
### Non-Goals
- NOT implementing GraphQL-specific rate limiting (only REST)
- NOT rate limiting internal services (only public API)
- NOT building custom rate limiter (use existing solution)
## Proposed Solution
### Architecture
Client --> API Gateway (Rate Limit) --> Backend Services
|
v
Redis (Counters)
### Implementation Details
**Technology**: Use AWS API Gateway with Token Bucket algorithm
**Rate Limit Tiers**:
| Plan | Requests/min | Burst |
|------|--------------|-------|
| Free | 60 | 100 |
| Pro | 600 | 1000 |
| Enterprise | 6000 | 10000 |
**Response Headers**:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1614556800
### Migration Strategy
**Phase 1: Soft Launch (Week 1)**
- Deploy rate limiting in "log-only" mode
- Collect data on who would be rate limited
- NO enforcement yet
**Phase 2: Warning Mode (Week 2)**
- Add X-RateLimit-* headers
- Send email warnings to users approaching limits
- Still no enforcement
**Phase 3: Enforcement (Week 3)**
- Enable enforcement for new users
- Grandfather existing free users at 2x limit for 1 month
- Send announcement email
**Phase 4: Full Rollout (Week 4)**
- Enforce limits for all users
- Monitor metrics
### Rollback Plan
Feature flag: RATE_LIMITING_ENABLED
- If issues, set flag to false
- Gradual rollout per user: 1% -> 10% -> 50% -> 100%
## Alternatives Considered
### Alternative 1: Build Custom Rate Limiter
**Pros:**
- Full control over algorithm
- No vendor lock-in
**Cons:**
- 3-4 weeks development time
- Need to maintain
- Reinventing the wheel
**Rejected**: AWS API Gateway rate limiting is proven and costs $0
### Alternative 2: Use Cloudflare Rate Limiting
**Pros:**
- More flexible than API Gateway
- Better DDoS protection
**Cons:**
- Adds another vendor ($200/month)
- Requires DNS change
- More complexity
**Rejected**: API Gateway sufficient for our needs
### Alternative 3: No Rate Limiting, Just Better Monitoring
**Pros:**
- Zero implementation effort
**Cons:**
- Doesn't solve abuse problem
- Doesn't prevent cost spikes
- Reactive instead of proactive
**Rejected**: Monitoring alone doesn't prevent abuse
## Trade-offs and Risks
**Trade-offs:**
- Simplicity vs Flexibility: Using API Gateway is simple but less flexible than custom solution
- UX vs Protection: Rate limiting hurts UX but protects system
**Risks:**
| Risk | Impact | Probability | Mitigation |
|------|--------|-------------|------------|
| Legitimate users get rate limited | High | Medium | Generous limits + burst allowance |
| Implementation bugs | Medium | Low | Gradual rollout + monitoring |
| Users churn due to limits | Medium | Low | Grandfather existing users |
## Testing Strategy
Load Testing:
```python
# Simulate 100 requests/second per user
import asyncio
import aiohttp
async def test_rate_limit():
async with aiohttp.ClientSession() as session:
tasks = []
for i in range(200): # Should hit 60/min limit
tasks.append(session.get('https://api.example.com/v1/users'))
responses = await asyncio.gather(*tasks)
# Verify
status_codes = [r.status for r in responses]
assert status_codes.count(200) == 60
assert status_codes.count(429) == 140
# Check headers
for r in responses[:60]:
assert 'X-RateLimit-Limit' in r.headers
Rollout Plan
| Week | Activity | Owner |
|---|---|---|
| 1 | Configure API Gateway usage plans | @sarah-backend |
| 1 | Deploy in log-only mode | @devops-lead |
| 2 | Add monitoring dashboards | @devops-lead |
| 2 | Email campaign: upcoming changes | @product |
| 3 | Enable for new users | @sarah-backend |
| 4 | Full rollout | @sarah-backend |
Success Metrics
Must-have:
- Zero API downtime during rollout
- Less than 1% false positive rate (legitimate users rate limited)
- API abuse incidents: 3/month -> 0/month
Nice-to-have:
- 20% increase in Pro plan conversions
- $500/month cost savings from reduced abuse
Open Questions
- Should we offer temporary limit increases for special events?
- Decision: Yes, manual override via support ticket
- Should we rate limit by IP or by API key?
- Leaning towards: API key (more accurate)
- What happens to websocket connections?
- TODO: Research websocket rate limiting
References
- AWS API Gateway Rate Limiting: https://docs.aws.amazon.com/
- Token Bucket Algorithm: https://en.wikipedia.org/wiki/Token_bucket
- Industry standards: Stripe (100/sec), GitHub (5000/hour)
- Internal: Post-mortem from Q4 API abuse incident
Review Comments
@tech-lead (2024-02-21):
Looks good overall. Question: What about burst traffic from legitimate users? E.g., user has cron job that makes 100 requests at midnight?
@sarah-backend (2024-02-21):
Good catch! That’s why we use Token Bucket with burst allowance. Free tier: 60/min but allows burst of 100. So cron job would work.
@security-lead (2024-02-22):
Approved. Suggest adding IP-based rate limiting too for DDoS protection.
@sarah-backend (2024-02-22):
Added to future work. Will do in Phase 2 (out of scope for this RFC).
---
## Receta 8.3: Technical Writing - Documentación Clara
**¿Qué es?**
Escribir documentación que otros desarrolladores puedan entender sin necesitar explicación adicional.
**Principios de good technical writing:**
```python
class TechnicalWritingPrinciples:
"""Principios para documentación clara"""
@staticmethod
def principle_1_know_your_audience():
"""Escribe para tu audiencia específica"""
# PRINCIPLE 1: KNOW YOUR AUDIENCE
# Different audiences need different detail levels:
# - Para beginners: Start with WHY, not HOW. Use analogies y ejemplos.
# - Para intermediate: Balance WHY and HOW. Link a conceptos.
# - Para experts: Focus on edge cases, performance, trade-offs.
pass
@staticmethod
def principle_2_structure():
"""Estructura predecible: What, Why, How, Troubleshooting"""
# Every doc should follow:
# 1. What is it? (1 sentence)
# 2. Why do I care? (1 paragraph)
# 3. How do I use it? (examples)
# 4. How does it work? (details)
# 5. What can go wrong? (troubleshooting)
pass
@staticmethod
def principle_3_examples_first():
"""Ejemplos antes que teoría"""
# Developers learn by doing. Show, don't tell.
# - 1 example > 1000 words
# - Show the HAPPY PATH first
# - Then show edge cases
# - Then explain HOW it works
pass
@staticmethod
def principle_4_active_voice():
"""Voz activa, no pasiva"""
# BAD (passive): "The configuration file should be updated."
# GOOD (active): "Update the configuration file."
#
# BAD: "An error will be thrown if the input is invalid."
# GOOD: "The function throws an error if the input is invalid."
pass
@staticmethod
def principle_5_scannable():
"""Formato scannable: headers, bullets, code blocks"""
# Developers scan, they don't read every word.
# - Use headers (h2, h3) to create hierarchy
# - Use bullet points for lists
# - Use numbered lists for sequences
# - Use code blocks for code
# - Use **bold** for important terms
# - Use tables for comparisons
pass
Template de documentación de API:
# API Documentation Template
## Endpoint Name
### Quick Reference
POST /api/v1/users
**Authentication Required**: Yes (Bearer token)
### What it does
Creates a new user account in the system.
### Request
**Headers:**
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
**Body:**
```json
{
"email": "alice@example.com",
"name": "Alice Smith",
"role": "admin"
}
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Must be valid email format | |
| name | string | Yes | 2-50 characters |
| role | string | No | Either “user” or “admin” (default: “user”) |
Response
Success (201 Created):
{
"id": "usr_abc123",
"email": "alice@example.com",
"name": "Alice Smith",
"role": "user",
"created_at": "2024-02-20T10:30:00Z"
}
Error (400 Bad Request):
{
"error": {
"code": "INVALID_EMAIL",
"message": "Email must be a valid format",
"field": "email"
}
}
Example
cURL:
curl -X POST https://api.example.com/v1/users \
-H "Authorization: Bearer sk_live_abc123" \
-H "Content-Type: application/json" \
-d '{
"email": "alice@example.com",
"name": "Alice Smith"
}'
Python:
import requests
response = requests.post(
'https://api.example.com/v1/users',
headers={'Authorization': 'Bearer sk_live_abc123'},
json={
'email': 'alice@example.com',
'name': 'Alice Smith'
}
)
user = response.json()
print(user['id']) # usr_abc123
JavaScript:
const response = await fetch('https://api.example.com/v1/users', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk_live_abc123',
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: 'alice@example.com',
name: 'Alice Smith'
})
});
const user = await response.json();
console.log(user.id); // usr_abc123
Common Errors
| Status | Code | Reason | Solution |
|---|---|---|---|
| 400 | INVALID_EMAIL | Email format invalid | Use valid email (name@domain.com) |
| 400 | EMAIL_TAKEN | Email already exists | Use different email or update existing user |
| 401 | UNAUTHORIZED | Missing/invalid API key | Check Authorization header |
| 429 | RATE_LIMIT | Too many requests | Wait 60 seconds and retry |
Rate Limits
- 100 requests/minute per API key
Notes
- Emails are case-insensitive (Alice@example.com = alice@example.com)
- Duplicate emails return 400 error
- User IDs are prefixed with
usr_ - Maximum 10,000 users per account
Related Endpoints
- GET /api/v1/users/:id - Get user details
- PATCH /api/v1/users/:id - Update user
- DELETE /api/v1/users/:id - Delete user
---
## Receta 8.4: Presentaciones Técnicas
**¿Qué es?**
Presentar conceptos técnicos de forma clara a audiencias técnicas y no-técnicas.
**Framework: The Pyramid Principle**
```python
class PresentationStructure:
"""Estructura de presentaciones técnicas efectivas"""
@staticmethod
def pyramid_principle():
"""Start with conclusion, then support"""
# Traditional (bottom-up): Pyramid (top-down):
# "Here's the data..." "We should migrate to microservices"
# "Here's the analysis..." "Why? 3 reasons:"
# "Therefore, we should..." "1. Scalability..."
# "2. Team autonomy..."
# "3. Deployment speed..."
#
# Slide 1: CONCLUSION
# Slide 2: WHY (3 key reasons)
# Slides 3-5: EVIDENCE for each reason
# Slides 6-7: HOW (implementation plan)
# Slide 8: NEXT STEPS
pass
@staticmethod
def technical_to_business():
"""Traducir tecnicismos a lenguaje de negocio"""
translations = {
"We need to refactor":
"We need to reduce technical debt to ship features 40% faster",
"Our CI/CD pipeline is broken":
"Deployments take 3 hours instead of 30 minutes, slowing releases",
"We should use Kubernetes":
"This will reduce server costs by $3,000/month and eliminate downtime",
"Database queries are slow":
"Users wait 5 seconds for pages (target: <1 second)",
"We have 40% test coverage":
"60% of bugs reach production, costing 10 engineering hours/week",
"Technical debt":
"Code shortcuts that save time now but slow us down later (like credit card debt)"
}
# Formula: [Technical term] -> [Business impact]
# Always include: Time saved/lost, Money saved/lost,
# Customer impact, Competitive advantage, Risk reduction
return translations
@staticmethod
def slide_design_rules():
"""Reglas de diseño de slides"""
rules = [
"Rule 1: ONE IDEA PER SLIDE",
"Rule 2: 6x6 RULE - Max 6 bullets, max 6 words per bullet",
"Rule 3: VISUALS > TEXT - Chart > bullet points describing trend",
"Rule 4: HIGH CONTRAST - Black on white, or white on dark",
"Rule 5: CONSISTENT FONT SIZE - Title 36-44pt, Body 24-32pt",
"Rule 6: NO ANIMATIONS unless building complex diagram step-by-step"
]
return rules
@staticmethod
def storytelling_framework():
"""Contar historias técnicas: SITUATION -> COMPLICATION -> RESOLUTION"""
# SITUATION (Slide 1-2): Context y estado actual
# COMPLICATION (Slide 3-4): El problema y su impacto real
# RESOLUTION (Slide 5-8): Solución propuesta con ROI
# CLOSE (Slide 9): Next steps claros
#
# Why stories work:
# - Humans remember stories, not facts
# - Emotional connection
# - Clear problem -> solution arc
# - Concrete examples > abstract concepts
pass
Template de presentación técnica:
SLIDE DECK TEMPLATE
===================
Slide 1: TITLE
[Project Name] | [Your name] | [Date]
Slide 2: TL;DR (Executive Summary)
What: [One sentence]
Why: [Business impact in numbers]
Ask: [What you need from audience]
Timeline: [When it happens]
Slide 3: THE PROBLEM
[Describe current pain point]
Impact:
- Metric 1
- Metric 2
[Visual: chart/screenshot showing problem]
Slide 4-6: WHY NOW? (Evidence)
- Charts, User feedback, Incident reports, Competitive analysis
Slide 7: PROPOSED SOLUTION
[High-level description + Architecture diagram]
Key benefits: Benefit 1 | Benefit 2 | Benefit 3
Slide 8: ALTERNATIVES CONSIDERED
| Option | Pros | Cons | Cost |
| A | | | |
| B (✓) | | | |
Slide 9: IMPLEMENTATION PLAN
Timeline: Week 1-2: Phase 1 | Week 3-4: Phase 2 | Week 5-6: Phase 3
Resources: 2 engineers (6 weeks) | Budget: $X
Slide 10: RISKS & MITIGATION
| Risk | Impact | Mitigation |
Slide 11: SUCCESS METRICS
- Metric 1: Current -> Target
- Metric 2: Current -> Target
Slide 12: NEXT STEPS
1. [Action] - [Owner] - [Date]
2. [Action] - [Owner] - [Date]
Decision needed: [What you need from audience]
Slide 13: Q&A
[Your email] | [Slack channel]
APPENDIX: Technical deep-dives, Additional data, Reference materials