Decisiones Técnicas
Sección titulada «Decisiones Técnicas»Este documento explica las decisiones técnicas clave del proyecto y sus justificaciones.
1. Video Hosting: AWS S3 + CloudFront o Azure Blob Storage
Sección titulada «1. Video Hosting: AWS S3 + CloudFront o Azure Blob Storage»Decisión
Sección titulada «Decisión»Soportar dos proveedores de almacenamiento seleccionables mediante STORAGE_PROVIDER:
aws— AWS S3 + CloudFront (predeterminado)azure— Azure Blob Storage
Alternativas Consideradas
Sección titulada «Alternativas Consideradas»| opción | Pros | Contras |
|---|---|---|
| AWS S3 + CloudFront | Pago por uso, escalable, CDN global | Más complejo de configurar (2 servicios) |
| Azure Blob Storage | Configuración más simple, SAS URLs integradas | Sin CDN dedicado (latencia variable) |
| YouTube (unlisted) | Gratis, fácil | Sin control, ads posibles, no profesional |
| Vimeo Pro | Player profesional | $20/mes mínimo, límites de almacenamiento |
| Bunny.net | Más barato | Menos integración con el ecosistema |
Justificación
Sección titulada «Justificación»- Flexibilidad operativa: Cada deployment puede elegir el proveedor que mejor encaja (precio, región, acuerdos existentes)
- Pago por uso: ambos son ~$0.02/GB almacenamiento
- URLs privadas: CloudFront Signed URLs (AWS) y SAS URLs temporales (Azure) — mismo nivel de seguridad
- Escalable: ambos crecen automáticamente con el uso
- Un solo env var: cambiar de proveedor solo requiere actualizar
STORAGE_PROVIDER
Costo Estimado
Sección titulada «Costo Estimado»AWS S3 + CloudFront:
100GB videos almacenados = $2.30/mes50GB transferencia CloudFront/mes = $4.25/mesTotal: ~$6.55/mesAzure Blob Storage:
100GB videos almacenados = $1.80/mes (LRS)50GB transferencia de salida/mes = ~$4.50/mesTotal: ~$6.30/mes2. Pricing Model: Individual + Suscripción
Sección titulada «2. Pricing Model: Individual + Suscripción»Decision
Sección titulada «Decision»Ofrecer tanto compra individual de cursos como suscripciones mensuales/anuales.
Alternativas Consideradas
Sección titulada «Alternativas Consideradas»| opción | Pros | Contras |
|---|---|---|
| Solo suscripción | Ingresos recurrentes | Barrera alta para nuevos usuarios |
| Solo individual | Baja barrera de entrada | Sin ingresos recurrentes |
| Ambos | Maxima flexibilidad | Más complejo de implementar |
Justificacion
Sección titulada «Justificacion»- Conversion: Cursos individuales para usuarios casuales
- Retencion: Suscripciones para usuarios comprometidos
- Descuento anual: Incentiva compromiso a largo plazo
- Stripe: Ya soporta ambos modelos sin costo adicional
Precios Sugeridos
Sección titulada «Precios Sugeridos»| Plan | Precio | descripción |
|---|---|---|
| Curso Individual | $29-99 | Acceso de por vida al curso |
| Mensual | $19/mes | Acceso a todos los cursos |
| Anual | $149/ano | ~35% descuento vs mensual |
3. Localizacion: Hardcode Spanish
Sección titulada «3. Localizacion: Hardcode Spanish»Decisión
Sección titulada «Decisión»Hardcodear todo el contenido en español en lugar de usar i18n.
Alternativas Consideradas
Sección titulada «Alternativas Consideradas»| opción | Pros | Contras |
|---|---|---|
| i18n (react-intl, etc) | Multi-idioma futuro | Complejidad adicional |
| Hardcode Spanish | Simple, rápido | Solo español |
| Parametrizable | Flexible | Over-engineering |
Justificación
Sección titulada «Justificación»- Mercado objetivo: Hispanohablantes en Latinoamérica
- Simplicidad: Menos código, menos bugs
- Performance: Sin overhead de i18n
- Evolucion: Se puede agregar i18n después si es necesario
implementación
Sección titulada «implementación»export const content = { auth: { login: "Iniciar sesión", signup: "Crear Cuenta", // ... }, courses: { catalog: "Catalogo de Cursos", enroll: "Inscribirme", // ... },};4. Comunidad: Post-Launch (Fase 2)
Sección titulada «4. Comunidad: Post-Launch (Fase 2)»Decision
Sección titulada «Decision»No incluir features de comunidad (foros, Q&A) en el MVP.
Alternativas Consideradas
Sección titulada «Alternativas Consideradas»| opción | Pros | Contras |
|---|---|---|
| Incluir en MVP | Feature completa | Retrasa lanzamiento |
| Post-launch | Lanzamiento rápido | Sin comunidad inicial |
| Terceros (Discord) | fácil, gratis | Fuera de la plataforma |
Justificacion
Sección titulada «Justificacion»- Enfoque: Primero el core (cursos + pagos)
- validación: Verificar que hay usuarios antes de construir comunidad
- Complejidad: Foros requieren moderacion, notificaciones, etc.
- Alternativa temporal: Discord/Slack para early adopters
Plan Post-Launch
Sección titulada «Plan Post-Launch»- Lanzar MVP (Fases 1-7)
- Conseguir primeros 100 usuarios
- Validar necesidad de comunidad
- Implementar Fase 8 si hay demanda
5. Certificados: PDF Server-Side
Sección titulada «5. Certificados: PDF Server-Side»Decisión
Sección titulada «Decisión»Generar certificados como PDFs en el servidor.
Alternativas Consideradas
Sección titulada «Alternativas Consideradas»| opción | Pros | Contras |
|---|---|---|
| PDF server-side | Control total, profesional | Más código |
| Imagen estática | Simple | No descargable |
| Servicio tercero | Menos código | Costo adicional, dependencia |
| LinkedIn certificates | integración social | Requiere partnership |
Justificación
Sección titulada «Justificación»- Control: Diseño personalizado con branding
- Sin dependencias: No requiere servicios externos
- Descargable: Los usuarios valoran PDFs
- Verificable: Se puede agregar URL de verificación
implementación
Sección titulada «implementación»import PDFDocument from "pdfkit";
export async function generateCertificatePDF({ userName, courseName, completionDate,}: CertificateData): Promise<string> { const doc = new PDFDocument(); // ... generar PDF // Subir a S3 // Retornar URL}6. Framework: Wasp
Sección titulada «6. Framework: Wasp»Decision
Sección titulada «Decision»Mantener Wasp como framework (heredado del template Open SaaS).
Ventajas de Wasp
Sección titulada «Ventajas de Wasp»- Full-stack: Frontend + Backend + DB en un solo lugar
- Type-safe: Tipos generados automaticamente
- Auth built-in: Email/password, OAuth, etc.
- Operations: Queries/Actions con cache automatico
- Jobs: Cron jobs integrados (PgBoss)
Consideraciones
Sección titulada «Consideraciones»- Curva de aprendizaje para nuevo framework
- documentación menos extensa que Next.js/Express
- Comunidad más pequeña
Recursos
Sección titulada «Recursos»7. UI Components: ShadCN
Sección titulada «7. UI Components: ShadCN»Decisión
Sección titulada «Decisión»Usar ShadCN UI (ya incluido en el, template).
Ventajas
Sección titulada «Ventajas»- Copy-paste: código tuyo, no dependencia
- Customizable: fácil de modificar
- Tailwind-based: Consistente con el resto del proyecto
- Accessible: Basado en Radix UI primitives
- 22+ componentes: Button, Card, Dialog, Table, etc.
Componentes Clave para Cursos
Sección titulada «Componentes Clave para Cursos»- Card (CourseCard)
- Progress (ProgressRing)
- Dialog (modals)
- Table (admin tables)
- Form (formularios)
8. Base de Datos: PostgreSQL
Sección titulada «8. Base de Datos: PostgreSQL»Decision
Sección titulada «Decision»Mantener PostgreSQL (heredado del template).
Ventajas
Sección titulada «Ventajas»- Robusta: Soporte para relaciones complejas
- Prisma: ORM excelente con tipos
- PgBoss: Jobs usando la misma DB
- Fly.io: fácil de desplegar
- Escalable: Maneja el crecimiento
Indices Recomendados
Sección titulada «Indices Recomendados»model Course { @@index([isPublished]) @@index([category])}
model Lesson { @@index([courseId, order])}
model Enrollment { @@index([userId]) @@index([courseId])}Resumen de Decisiones
Sección titulada «Resumen de Decisiones»| Área | Decisión | Razón Principal |
|---|---|---|
| Video | AWS S3 + CloudFront | Ya configurado, pago por uso |
| Pricing | Individual + Suscripción | Maxima flexibilidad |
| Idioma | Hardcode Spanish | Simplicidad |
| Comunidad | Post-launch | Enfoque en core primero |
| Certificados | PDF server-side | Control total |
| Framework | Wasp | Heredado, full-stack |
| UI | ShadCN | Copy-paste, customizable |
| Database | PostgreSQL | Robusta, Prisma |