# Curso Power BI — Nivel Intermedio / Avanzado

## Información general

| Campo | Detalle |
|-------|---------|
| **Público objetivo** | Usuarios que ya trabajan con Power BI a diario (no es introductorio) |
| **Nivel** | Intermedio → Avanzado |
| **Duración total** | 16 horas pedagógicas (12 h reloj) |
| **Estructura** | 2 módulos de 8 horas c/u |
| **Bloque** | 45 min por hora pedagógica |
| **Ritmo** | 2 bloques al día (1 h 30 min de clase + pausa) → 4 días por módulo, 8 días en total |
| **Fuente Módulo 1** | Libro de Excel (multi-hoja, datos sucios reales) |
| **Fuente Módulo 2** | Base de datos relacional (SQL Server / PostgreSQL) |
| **Modalidad** | Práctica guiada + taller por bloque |

### Requisitos previos (asumidos)
- Crear reportes básicos y manejar el lienzo de Power BI Desktop.
- Cargar datos y crear visualizaciones simples.
- Conocer qué es una medida y una columna calculada (a nivel usuario).

### Horario tipo diario (ajustable)
| Tramo | Horario ejemplo | Duración |
|-------|-----------------|----------|
| Bloque A | 19:00 – 19:45 | 45 min |
| Pausa | 19:45 – 19:55 | 10 min |
| Bloque B | 19:55 – 20:40 | 45 min |

---

## Módulo 1 — Modelado y transformación con fuente Excel
**Objetivo:** dominar Power Query (limpieza, M) y construir un modelo en estrella sólido con DAX fundamental-intermedio, partiendo de un Excel "sucio".

| Día | Bloque | Horario | Tema | Contenido detallado |
|-----|--------|---------|------|---------------------|
| 1 | A | 19:00–19:45 | Arquitectura orientada a modelo + importación robusta de Excel | Capas Power Query → Modelo → Reporte. Conexión a libro multi-hoja, detección de tablas vs rangos, problemas típicos de Excel como fuente (formatos, celdas combinadas, encabezados). |
| 1 | B | 19:55–20:40 | Power Query — limpieza avanzada | Tipos de datos y locale, manejo de errores, columnas condicionales, dividir/extraer texto, *Group By*, relleno hacia abajo, eliminar duplicados con criterio. |
| 2 | A | 19:00–19:45 | Power Query — combinar y reestructurar | *Merge* (tipos de join), *Append*, *Unpivot/Pivot*, *Reference* vs *Duplicate*, consultas como funciones reutilizables. |
| 2 | B | 19:55–20:40 | Lenguaje M, parámetros y funciones | Anatomía del paso `let...in`, parámetros, función personalizada para procesar N hojas/archivos, buenas prácticas y orden de pasos para *query folding*. |
| 3 | A | 19:00–19:45 | Modelado — esquema estrella | Hechos vs dimensiones, granularidad, por qué NO usar una sola tabla plana, desnormalización controlada para BI. |
| 3 | B | 19:55–20:40 | Relaciones y tabla calendario | Cardinalidad, dirección de filtro, relaciones activas/inactivas, `USERELATIONSHIP`, tabla calendario en DAX (`CALENDAR`/`CALENDARAUTO`) marcada como tabla de fechas. |
| 4 | A | 19:00–19:45 | DAX fundamental sólido | Columna calculada vs medida, contexto de fila vs contexto de filtro, medidas implícitas vs explícitas, `SUM`/`AVERAGE`/`COUNTROWS`, `DIVIDE`. |
| 4 | B | 19:55–20:40 | `CALCULATE` + taller integrador | `CALCULATE` y modificadores de filtro, `FILTER`, `ALL`/`REMOVEFILTERS`. **Taller:** dashboard completo de ventas a partir del Excel. |

**Entregable Módulo 1:** modelo en estrella + dashboard funcional construido desde el Excel.

---

## Módulo 2 — DAX avanzado, rendimiento y despliegue con fuente Base de Datos
**Objetivo:** conectar a una BD relacional, escribir DAX avanzado, optimizar rendimiento, aplicar seguridad y publicar con refresco automatizado.

| Día | Bloque | Horario | Tema | Contenido detallado |
|-----|--------|---------|------|---------------------|
| 5 | A | 19:00–19:45 | Conexión a BD: Import vs DirectQuery | Conectar a SQL Server/PostgreSQL, *Import* vs *DirectQuery* vs **modelos compuestos**, cuándo usar cada uno, limitaciones. |
| 5 | B | 19:55–20:40 | Query folding y optimización en origen | Verificar *folding* en Power Query, empujar transformaciones a la BD, vistas vs tablas, parámetros de conexión y seguridad básica. |
| 6 | A | 19:00–19:45 | DAX avanzado — variables e iteradores | `VAR`/`RETURN`, iteradores `SUMX`/`AVERAGEX`/`RANKX`, **context transition**, `CALCULATE` con expresiones tabla. |
| 6 | B | 19:55–20:40 | DAX — Time Intelligence | `DATESYTD`, `SAMEPERIODLASTYEAR`, `DATEADD`, `TOTALYTD`, comparativas YoY/MoM, medidas de crecimiento %. |
| 7 | A | 19:00–19:45 | Rendimiento y diagnóstico | Motor VertiPaq, cardinalidad y compresión, *Performance Analyzer*, introducción a DAX Studio, reducir columnas y evitar bidireccional innecesario. |
| 7 | B | 19:55–20:40 | Visualización avanzada e interactividad | *Drill-through*, *bookmarks*, *tooltips* de página, **field parameters**, *what-if parameters*, navegación tipo app. |
| 8 | A | 19:00–19:45 | Seguridad — Row Level Security | RLS estática y **dinámica** con `USERPRINCIPALNAME()`, tabla de seguridad desde la BD, validación de roles, RLS en DirectQuery. |
| 8 | B | 19:55–20:40 | Publicación, Service y refresco + taller final | Power BI Service, *workspaces*, **gateway** on-premise, **refresco incremental**, programación de actualización. **Taller final:** reporte end-to-end desde la BD con RLS y publicado. |

**Entregable Módulo 2:** reporte publicado en Power BI Service con RLS dinámica y refresco programado contra la base de datos.

---

## Resumen de carga horaria

| Módulo | Fuente | Bloques | Horas pedagógicas | Días |
|--------|--------|---------|-------------------|------|
| 1 | Excel | 8 × 45 min | 8 | 4 |
| 2 | Base de datos | 8 × 45 min | 8 | 4 |
| **Total** | — | **16** | **16 (≈12 h reloj)** | **8** |


---

# 📦 Material producido (estado: completo)

Todo el material del programa está listo y verificado. Resumen de lo trabajado.

## Estado por sesión

| Sesión | Tema | Presentación (HTML) | Guía base (PDF) | Guía reto (PDF) |
|--------|------|:---:|:---:|:---:|
| 1 | Arquitectura y Power Query | ✅ 28 slides | ✅ | ✅ |
| 2 | Combinar consultas y funciones M | ✅ 27 slides | ✅ | ✅ |
| 3 | Modelado: esquema estrella | ✅ 26 slides | ✅ | ✅ |
| 4 | DAX: fundamentos y CALCULATE | ✅ 26 slides | ✅ | ✅ |
| 5 | DirectQuery y optimización en origen | ✅ 24 slides | ✅ | ✅ |
| 6 | DAX avanzado e inteligencia de tiempo | ✅ 24 slides | ✅ | ✅ |
| 7 | Rendimiento y visualizaciones avanzadas | ✅ 22 slides | ✅ | ✅ |
| 8 | RLS y publicación | ✅ 22 slides | ✅ | ✅ |

**Totales:** 8 presentaciones · 16 guías de práctica (8 base + 8 reto) · 1 dataset Excel · 1 base de datos SQL.

## Entregables

- **Presentaciones HTML** (1 por sesión): tema oscuro con branding SunFruits, logo en cabecera, navegación por teclado/flechas/swipe, barra de progreso, capturas oficiales de Microsoft Learn y código (M / DAX / SQL) sobre los datos de SunFruits.
  - Sesión 1 incluye slide de presentación del instructor; **de la Sesión 2 en adelante no** (por convención del cliente).
  - Cada sesión cierra con **"Preguntas de repaso"** (5 preguntas del tema) + **"¡Gracias!"**.
  - **Lightbox**: clic en cualquier captura la amplía en un popup.
  - **Toggle de tema claro/oscuro** (preferencia recordada con `localStorage`).
- **Guías de práctica (Word + PDF)**: dos por sesión.
  - **Base**: paso a paso (acciones numeradas, código esperado, callouts TIP/NOTA/OJO, checklist y reto).
  - **Reto**: mayor complejidad — escenarios de negocio, menos paso a paso, criterios de aceptación y reto bonus.
  - Branding completo: logo en cabecera, numeración de páginas y pie con el instructor.
- **Dataset Excel** (`SunFruits_Ventas_Practica.xlsx`): ~4.000 ventas multi-hoja con "suciedad" intencional (cabecera desplazada, fechas/precios como texto, locale, países inconsistentes, totales/duplicados, costos cruzados para Unpivot) + 64 clientes, productos, fundos, tipo de cambio y metas.
- **Base de datos SQL** (`sunfruits_db_postgres.sql`, PostgreSQL): esquema estrella **limpio y normalizado** (contraste con el Excel), validado cargándolo en un PostgreSQL real. Tablas: `dim_cliente`, `dim_producto`, `dim_fundo`, `dim_tipocambio`, `metas`, `seguridad` (para RLS), `fact_ventas` (4.000) + vistas `vw_ventas` y `vw_ventas_agg_mes` (agregada para DirectQuery).
- **Sitio web central** (`index.html`): índice navegable con 2 módulos y enlaces a cada presentación y a cada guía (vía visor de PDF).

## Sitio web — estructura de archivos

```
PBI/                         ← raíz del sitio (subir a S3)
├── index.html               ← índice central (2 módulos · 8 sesiones)
├── viewer.html              ← visor de PDF embebido (con tema y descarga)
├── assets/
│   └── sunfruits-logo.png
├── sesion-01..08/           ← 8 presentaciones HTML (cada una con su img/)
├── practicas-pdf/           ← 16 PDFs (guia-sN.pdf y guia-sN-reto.pdf)
└── recursos/                ← descargas: dataset Excel, BD SQL, guía del dataset
```

> Carpetas de trabajo (no se publican): `practica/` (generadores `.py`, `.docx` fuente) y `practicas-html/` (HTML intermedio de las guías).

## Características del sitio

- **Índice**: hero con métricas, Módulo 1 (Fuente Excel) y Módulo 2 (Fuente Base de Datos); cada sesión con 3 botones — 🖥 Presentación · 📘 Guía de práctica · 🔥 Práctica reto — y sección de Recursos.
- **Visor de PDF** (`viewer.html?f=...`): abre las guías dentro del sitio (render nativo del navegador) con barra SunFruits, título de sesión, badge GUÍA/RETO y botones Índice / Nueva pestaña / Descargar PDF.
- **Tema claro/oscuro** consistente en índice, visor y presentaciones (preferencia compartida).

## Despliegue en AWS (S3 + CloudFront)

1. Subir el sitio (excluyendo carpetas de trabajo):
   ```bash
   aws s3 sync /home/edwin/MyDocuments/PBI s3://TU-BUCKET \
     --exclude "practica/*" --exclude "practicas-html/*" --exclude "*.py"
   ```
2. Servir vía **CloudFront** (recomendado con OAC y bucket privado). **Default root object** = `index.html`.
3. Subir los `.pdf` como `inline` (sin `Content-Disposition: attachment`) para que el visor los embeba; el botón "Descargar" fuerza la descarga vía atributo `download`.
4. Tras cada actualización, invalidar la caché: `aws cloudfront create-invalidation --distribution-id XXXX --paths "/*"`.

## Generadores (reproducibles)

| Script | Genera |
|--------|--------|
| `practica/gen_dataset.py` | Dataset Excel (semilla fija) |
| `practica/gen_sql_db.py` | Script SQL PostgreSQL |
| `practica/gen_guia_sesion1..4.py` | Guías base S1–S4 (Word) |
| `practica/gen_guias_5a8.py` | Guías base S5–S8 (Word) |
| `practica/gen_guias_reto.py` | 8 guías reto (Word) |
| `practica/gen_practicas_html.py` | Convierte las 16 guías a HTML (pandoc + estilo) |
| `practica/inject_lightbox_theme.py` | Inyecta lightbox + tema en las presentaciones |
