{"id":50680363,"url":"https://github.com/vruizz22/innova-clients","last_synced_at":"2026-06-08T18:04:16.039Z","repository":{"id":355455121,"uuid":"1215509199","full_name":"vruizz22/innova-clients","owner":"vruizz22","description":"Client applications for Innova EdTech. Turborepo + pnpm + Next.js 14 + Expo + Astro. Web and mobile apps for students, teachers, and parents to practice, track mastery, and receive alerts.","archived":false,"fork":false,"pushed_at":"2026-05-03T18:43:21.000Z","size":133,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-03T19:14:23.945Z","etag":null,"topics":["astro","edtech","expo","mobile","nextjs","students","teachers","turborepo","typescript","web"],"latest_commit_sha":null,"homepage":"https://superprofes.app/","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vruizz22.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-20T01:43:23.000Z","updated_at":"2026-05-03T16:21:48.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/vruizz22/innova-clients","commit_stats":null,"previous_names":["vruizz22/innova-clients"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/vruizz22/innova-clients","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vruizz22%2Finnova-clients","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vruizz22%2Finnova-clients/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vruizz22%2Finnova-clients/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vruizz22%2Finnova-clients/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vruizz22","download_url":"https://codeload.github.com/vruizz22/innova-clients/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vruizz22%2Finnova-clients/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34073829,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["astro","edtech","expo","mobile","nextjs","students","teachers","turborepo","typescript","web"],"created_at":"2026-06-08T18:04:15.147Z","updated_at":"2026-06-08T18:04:16.029Z","avatar_url":"https://github.com/vruizz22.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# innova-clients\n\n\u003e Monorepo Turborepo de todas las aplicaciones cliente de **Innova EdTech** — detección de errores matemáticos procedurales, 3°–6° básico chileno.\n\u003e\n\u003e Turborepo · pnpm · Next.js 14 App Router · Expo SDK 51 · Astro · TypeScript strict · AWS Amplify · Cloudflare Pages · EAS\n\n---\n\n## Tabla de contenidos\n\n- [innova-clients](#innova-clients)\n  - [Tabla de contenidos](#tabla-de-contenidos)\n  - [1. Visión general](#1-visión-general)\n  - [2. Arquitectura](#2-arquitectura)\n  - [3. Apps y plataformas](#3-apps-y-plataformas)\n    - [apps/practice (Expo Router)](#appspractice-expo-router)\n    - [apps/teacher (Next.js 14 App Router)](#appsteacher-nextjs-14-app-router)\n    - [apps/parent (Expo Router)](#appsparent-expo-router)\n    - [apps/landing (Astro)](#appslanding-astro)\n  - [4. Stack tecnológico](#4-stack-tecnológico)\n  - [5. Estructura del monorepo](#5-estructura-del-monorepo)\n  - [6. Metodología y flujo de trabajo](#6-metodología-y-flujo-de-trabajo)\n    - [6.1 GSD / BMAD](#61-gsd--bmad)\n    - [6.2 AI usage logs](#62-ai-usage-logs)\n    - [6.3 Gitflow](#63-gitflow)\n    - [6.4 Quality gates](#64-quality-gates)\n    - [6.5 Reglas obligatorias](#65-reglas-obligatorias)\n  - [7. Variables de entorno](#7-variables-de-entorno)\n    - [Next.js apps (apps/teacher)](#nextjs-apps-appsteacher)\n    - [Expo apps (apps/practice, apps/parent)](#expo-apps-appspractice-appsparent)\n  - [8. Setup local](#8-setup-local)\n    - [Prerrequisitos](#prerrequisitos)\n    - [Instalación](#instalación)\n    - [Correr apps individualmente](#correr-apps-individualmente)\n    - [Comandos globales (Turborepo)](#comandos-globales-turborepo)\n  - [9. Tests y cobertura](#9-tests-y-cobertura)\n    - [Suites clave](#suites-clave)\n    - [Configuración MSW (Mock Service Worker)](#configuración-msw-mock-service-worker)\n  - [10. Despliegue](#10-despliegue)\n    - [Web apps (apps/teacher) → AWS Amplify](#web-apps-appsteacher--aws-amplify)\n    - [Astro landing → Cloudflare Pages](#astro-landing--cloudflare-pages)\n    - [Mobile apps (apps/practice, apps/parent) → Expo EAS](#mobile-apps-appspractice-appsparent--expo-eas)\n    - [Re-deploy tras cambios](#re-deploy-tras-cambios)\n    - [CI/CD (GitHub Actions)](#cicd-github-actions)\n  - [11. Decisión de deploy: AWS Amplify vs Vercel](#11-decisión-de-deploy-aws-amplify-vs-vercel)\n    - [Por qué Amplify sobre Vercel](#por-qué-amplify-sobre-vercel)\n  - [12. Diseño y UI/UX](#12-diseño-y-uiux)\n    - [Stack visual](#stack-visual)\n    - [Tokens de diseño](#tokens-de-diseño)\n    - [Accesibilidad](#accesibilidad)\n  - [13. Privacidad y cumplimiento NNA](#13-privacidad-y-cumplimiento-nna)\n  - [14. Roadmap](#14-roadmap)\n  - [15. Recursos](#15-recursos)\n  - [16. Licencia](#16-licencia)\n\n---\n\n## 1. Visión general\n\nEste monorepo contiene las **aplicaciones cliente** que exponen la plataforma Innova a sus tres tipos de usuario:\n\n| Usuario | App | Necesidad |\n|---------|-----|-----------|\n| Alumno | `apps/practice` | Hacer ejercicios paso a paso o escanear worksheet; ver feedback inmediato |\n| Profesor | `apps/teacher` | Ver heatmap de dominio por skill, alertas de alumnos en riesgo, asignar práctica |\n| Apoderado | `apps/parent` | Ver asignaciones del hijo, progreso de dominio, recibir notificaciones push |\n| Público | `apps/landing` | Página institucional de Innova |\n\n**Integración de plataformas por usuario:**\n\n| App | Web | iOS | Android | Desktop |\n|-----|-----|-----|---------|---------|\n| `apps/practice` | ✅ MVP | ✅ MVP | ✅ MVP | post-MVP |\n| `apps/teacher` | ✅ MVP | — | — | post-MVP |\n| `apps/parent` | ✅ MVP | ✅ MVP | ✅ MVP | post-MVP |\n| `apps/landing` | ✅ MVP | — | — | — |\n\n---\n\n## 2. Arquitectura\n\n```mermaid\nflowchart LR\n  subgraph APPS[\"Client Applications\"]\n    PRACTICE[\"Practice App\\nExpo Router\\nweb + iOS + Android\\nAlumno\"]\n    TEACHER[\"Teacher Dashboard\\nNext.js 14\\nweb\\nProfesor\"]\n    PARENT[\"Parent App\\nExpo Router\\nweb + iOS + Android\\nApoderado\"]\n    LANDING[\"Landing\\nAstro\\nweb\\nPublico\"]\n  end\n\n  subgraph PACKAGES[\"Shared Packages\"]\n    MATH_INPUT[\"math-input\\nstep keyboard\\nweb + native\"]\n    UPLOAD_SCAN[\"upload-scanner\\ncamera + S3 presigned\\nweb + native\"]\n    TELEMETRY[\"telemetry\\n2s buffer + flush\\nno PII\"]\n    API_CLIENT[\"api-client\\nZod schemas\\nOpenAPI generated\"]\n    ERROR_RENDER[\"error-renderer\\nstep diff visualization\"]\n    UI[\"ui\\nTailwind + shadcn\"]\n  end\n\n  subgraph INFRA[\"Deploy Targets\"]\n    AMPLIFY[\"AWS Amplify\\nNext.js SSR + ISR\"]\n    CF[\"Cloudflare Pages\\nAstro static\"]\n    EAS[\"Expo EAS\\nBuild + Update OTA\"]\n  end\n\n  subgraph BACKEND[\"innova-backend-serverless\"]\n    AGW[\"API Gateway + Lambda\"]\n    S3U[(\"S3 uploads\")]\n    COG[\"Cognito JWT\"]\n  end\n\n  PRACTICE --\u003e MATH_INPUT\n  PRACTICE --\u003e UPLOAD_SCAN\n  PRACTICE --\u003e TELEMETRY\n  PRACTICE --\u003e API_CLIENT\n  TEACHER --\u003e API_CLIENT\n  TEACHER --\u003e ERROR_RENDER\n  TEACHER --\u003e UI\n  PARENT --\u003e API_CLIENT\n  PARENT --\u003e UI\n\n  PRACTICE --\u003e EAS\n  PARENT --\u003e EAS\n  TEACHER --\u003e AMPLIFY\n  LANDING --\u003e CF\n\n  API_CLIENT --\u003e AGW\n  UPLOAD_SCAN --\u003e S3U\n  AGW --\u003e COG\n```\n\n\u003e Diagramas UML formales en `docs/drawio/`. Guía de construcción en Draw.io: `docs/drawio/01-how-to-draw-high-level-architecture.md`.\n\n---\n\n## 3. Apps y plataformas\n\n### apps/practice (Expo Router)\n\nFlujos principales:\n\n1. Alumno entra a asignación → selecciona ejercicio.\n2. **Input digital**: `packages/math-input` renderiza teclado numérico + filas de steps. Cada step se guarda en telemetry buffer.\n3. Submit final → `POST /api/attempts` con `rawSteps[]`.\n4. Feedback: `is_correct`, label del tipo de error (human-readable), animación de ánimo.\n5. **Input foto**: `packages/upload-scanner` abre cámara, strip EXIF, presigned S3 upload. Poll `/api/attempts/:id/status` hasta que OCR + clasificación terminen.\n\n### apps/teacher (Next.js 14 App Router)\n\nVistas:\n\n1. **Heatmap de classroom**: grilla (alumno × skill) con color por `p_known`. Verde ≥0.7, amarillo 0.4–0.7, rojo \u003c0.4.\n2. **Panel de alertas**: `TeacherAlert` sin resolver, ordenados por urgencia. Botón \"Marcar resuelto\".\n3. **Drill-down alumno**: historial de intentos, frecuencia de errores por tipo, evolución de `p_known`.\n4. **Asignar práctica**: seleccionar alumno/grupo → genera `PracticeAssignment` con ítems recomendados por Fisher information.\n\n### apps/parent (Expo Router)\n\nVistas:\n\n1. Lista de `PracticeAssignment` activas del hijo.\n2. Barras de progreso de dominio por skill (sin mostrar números crudos — solo colores y etiquetas amigables).\n3. Push notification cuando se crea nueva asignación (`expo-notifications`).\n4. Tap en ejercicio → abre `apps/practice` (in-app webview o redirect).\n\n### apps/landing (Astro)\n\nPágina institucional estática: propuesta de valor, cómo funciona, contacto. Deployed en aws S3 con cloudfront.\n\n---\n\n## 4. Stack tecnológico\n\n| Capa | Tecnología | Versión | Razón |\n|------|-----------|---------|-------|\n| Monorepo | Turborepo + pnpm | latest | Pipeline de tasks, caché de builds, workspace protocol |\n| Lenguaje | TypeScript strict | 5.x | `noImplicitAny`, `exactOptionalPropertyTypes` |\n| Web framework | Next.js 14 App Router | 14+ | SSR/ISR/Streaming, Server Components |\n| Mobile framework | Expo SDK + Expo Router | 51+ | Web + iOS + Android desde un codebase |\n| Static site | Astro | 4+ | Zero JS by default, ideal para landing |\n| Auth | AWS Cognito + Amplify Auth | — | Mismo ecosystem que backend |\n| Estilos | Tailwind CSS v3 | 3.x | Utility-first, tree-shakeable |\n| UI primitives | shadcn/ui + Radix UI | — | Headless, accesible, customizable |\n| Validación | Zod | 3+ | Runtime validation + inferred types |\n| HTTP client | fetch nativo + wrapper tipado | — | Sin axios, `api-client` package custom |\n| Charts | recharts | 2.x | Lightweight, para heatmap y barras |\n| Notif. push | expo-notifications | — | iOS + Android + web |\n| Tests unit | Vitest + React Testing Library | latest | Fast, ESM-native |\n| Tests E2E | Playwright | latest | Web flows, Chromium + WebKit |\n| Mocking API | MSW (Mock Service Worker) | 2+ | Mocks a nivel de red, compartido unit+e2e |\n| Coverage | v8 provider | — | Gate ≥75% en `packages/*` |\n| Deploy web | AWS Amplify Gen 2 | — | Next.js SSR nativo, mismo ecosystem AWS |\n| Deploy static | Cloudflare Pages | — | Free, global CDN, zero cold start |\n| Deploy mobile | Expo EAS | — | EAS Build + EAS Update OTA |\n| Package manager | pnpm | 9+ | Workspace, eficiencia disco |\n\n---\n\n## 5. Estructura del monorepo\n\n```\ninnova-clients/\n├── turbo.json                       # pipeline de tasks (build, test, lint)\n├── pnpm-workspace.yaml\n├── package.json                     # root scripts\n├── apps/\n│   ├── practice/                    # Expo Router (web + iOS + Android)\n│   │   ├── app/                     # Expo Router file-based routing\n│   │   │   ├── (auth)/\n│   │   │   ├── (student)/\n│   │   │   │   ├── index.tsx        # lista de asignaciones\n│   │   │   │   └── exercise/[id].tsx\n│   │   │   └── _layout.tsx\n│   │   ├── components/\n│   │   ├── hooks/\n│   │   ├── app.json\n│   │   └── package.json\n│   ├── teacher/                     # Next.js 14 App Router\n│   │   ├── app/\n│   │   │   ├── (auth)/\n│   │   │   ├── dashboard/\n│   │   │   │   ├── classroom/[id]/  # heatmap + alertas\n│   │   │   │   └── student/[id]/   # drill-down alumno\n│   │   │   └── layout.tsx\n│   │   ├── components/\n│   │   │   ├── MasteryHeatmap.tsx\n│   │   │   ├── AlertsPanel.tsx\n│   │   │   └── ErrorFrequencyChart.tsx\n│   │   ├── next.config.js\n│   │   └── package.json\n│   ├── parent/                      # Expo Router (web + iOS + Android)\n│   │   ├── app/\n│   │   └── package.json\n│   └── landing/                     # Astro\n│       ├── src/pages/\n│       └── package.json\n├── packages/\n│   ├── math-input/                  # teclado matemático step-by-step\n│   │   ├── src/\n│   │   │   ├── MathInput.tsx        # web\n│   │   │   └── MathInput.native.tsx # native\n│   │   └── package.json\n│   ├── upload-scanner/              # cámara + presigned S3\n│   │   ├── src/\n│   │   └── package.json\n│   ├── telemetry/                   # buffer 2s + flush\n│   │   ├── src/\n│   │   │   ├── buffer.ts\n│   │   │   └── flush.ts\n│   │   └── package.json\n│   ├── api-client/                  # cliente HTTP tipado\n│   │   ├── src/\n│   │   │   ├── attempts.ts\n│   │   │   ├── mastery.ts\n│   │   │   └── alerts.ts\n│   │   └── package.json\n│   ├── error-renderer/              # visualiza diff de steps\n│   │   └── package.json\n│   └── ui/                          # design system\n│       ├── src/\n│       │   └── components/\n│       └── package.json\n├── e2e/                             # Playwright specs globales\n│   ├── teacher-heatmap.spec.ts\n│   ├── practice-submit.spec.ts\n│   └── parent-assignment.spec.ts\n└── .github/\n    └── workflows/\n        ├── ci.yml\n        ├── deploy-web.yml\n        └── deploy-mobile.yml\n```\n\n---\n\n## 6. Metodología y flujo de trabajo\n\n### 6.1 GSD / BMAD\n\nArtefactos en `docs/` (repo raíz `innova/`):\n\n| Archivo | Propósito |\n|---------|-----------|\n| `docs/roadmap.md` | Milestones M0–M6 con fechas |\n| `docs/milestones.md` | Sprints, DoR, DoD |\n| `docs/requirements.md` | RF/NFR trazables |\n\n### 6.2 AI usage logs\n\nCada sesión de Claude Code → log en `docs/ai-logs/YYYY-MM-DD-\u003ctema\u003e.md`. Incluir: Prompt · Output resumido · Decisión · Tradeoffs.\n\n### 6.3 Gitflow\n\n```\nmain (protegida) \u003c── feature/\u003capp-scope\u003e\n                  \u003c── fix/\u003cscope\u003e\n```\n\n- `main` protegida: PR obligatorio, ≥2 reviewers, CI verde.\n- Conventional Commits en inglés: `feat(practice): add step-by-step math input`, `fix(telemetry): flush on unload event`\n- Squash and merge.\n\n### 6.4 Quality gates\n\n| Gate | Criterio | Bloquea merge |\n|------|---------|---------------|\n| `pnpm -r run type-check` | 0 errores TS | ✅ |\n| `pnpm -r run lint` | 0 errores ESLint | ✅ |\n| `pnpm -r run test:coverage` | ≥75% en `packages/*` | ✅ |\n| `pnpm -r run build` | exit 0 | ✅ |\n| Playwright E2E (en push) | happy paths OK | ✅ |\n| Reviewers | 2 aprobados | ✅ |\n\n### 6.5 Reglas obligatorias\n\n- **Nunca `localStorage` para session tokens** — httpOnly cookies (web) / `expo-secure-store` (native).\n- **Nunca analytics que capturen PII** (no GA4 user_id, no Amplitude, no Mixpanel).\n- Solo `student_uuid` en payloads de API — nunca nombre ni email.\n- `useEffect` para data fetching está prohibido en Next.js App Router — usar async Server Components.\n- Todos los componentes React: definir interfaz `Props` explícita.\n\n---\n\n## 7. Variables de entorno\n\nValidadas en build-time. **Nunca commitear `.env.local` ni `.env`.**\n\n### Next.js apps (apps/practice, apps/teacher)\n\n```env\nNEXT_PUBLIC_API_URL=https://api.superprofes.app\nNEXT_PUBLIC_LANDING_URL=https://superprofes.app\nNEXT_PUBLIC_PRACTICE_URL=https://practice.superprofes.app\nNEXT_PUBLIC_TEACHER_URL=https://profe.superprofes.app\nNEXT_PUBLIC_PARENT_URL=https://superprofes.app\nNEXT_PUBLIC_COGNITO_USER_POOL_ID=\nNEXT_PUBLIC_COGNITO_CLIENT_ID=\n```\n\nEl classroom se resuelve desde `/classrooms/mine` o `/classrooms/student/mine`; no configurar `NEXT_PUBLIC_CLASSROOM_ID`.\n\n### Landing Astro\n\n```env\nPUBLIC_LANDING_URL=https://superprofes.app\nPUBLIC_PRACTICE_URL=https://practice.superprofes.app\nPUBLIC_TEACHER_URL=https://profe.superprofes.app\nPUBLIC_PARENT_URL=https://superprofes.app\nPUBLIC_API_URL=https://api.superprofes.app\n```\n\n### Expo app (apps/mobile)\n\n```env\nEXPO_PUBLIC_API_URL=https://api.superprofes.app\nEXPO_PUBLIC_COGNITO_CLIENT_ID=\nEXPO_PUBLIC_COGNITO_REGION=us-east-1\n```\n\n---\n\n## 8. Setup local\n\n### Prerrequisitos\n\n- Node.js ≥20 (recomendado vía `nvm`)\n- pnpm ≥9: `corepack enable \u0026\u0026 corepack prepare pnpm@latest --activate`\n- Para Expo mobile:\n  - iOS: Xcode + iOS Simulator\n  - Android: Android Studio + Emulator (o dispositivo físico)\n  - `eas-cli`: `pnpm add -g eas-cli`\n\n### Instalación\n\n```bash\n# 1. Clonar\ngit clone git@github.com:\u003corg\u003e/innova-clients.git\ncd innova-clients\n\n# 2. Instalar todas las dependencias del workspace\npnpm install\n\n# 3. Variables de entorno\ncp apps/teacher/.env.example apps/teacher/.env.local\ncp apps/practice/.env.example apps/practice/.env.local\ncp apps/parent/.env.example apps/parent/.env.local\n# editar cada archivo con API_URL, COGNITO_* vars\n```\n\n### Correr apps individualmente\n\n```bash\n# Teacher dashboard (web)\npnpm --filter apps/teacher dev\n# → http://localhost:3000\n\n# Practice app (Expo web)\npnpm --filter apps/practice start\n# → http://localhost:8081\n\n# Practice app (iOS simulator)\npnpm --filter apps/practice ios\n\n# Practice app (Android emulator)\npnpm --filter apps/practice android\n\n# Parent app (Expo web)\npnpm --filter apps/parent start\n\n# Landing (Astro)\npnpm --filter apps/landing dev\n# → http://localhost:4321\n```\n\n### Comandos globales (Turborepo)\n\n```bash\npnpm -r run build           # build de todos los apps y packages\npnpm -r run test            # unit tests en todos\npnpm -r run test:coverage   # con cobertura\npnpm -r run lint            # lint en todos\npnpm -r run type-check      # type-check en todos\n```\n\n---\n\n## 9. Tests y cobertura\n\n```bash\n# Unit tests (Vitest)\npnpm -r run test\n\n# Con cobertura (gate ≥75% en packages/)\npnpm --filter \"./packages/**\" run test:coverage\n\n# E2E Playwright (teacher dashboard)\npnpm --filter apps/teacher run test:e2e\n\n# E2E en modo UI interactivo\npnpm --filter apps/teacher exec playwright test --ui\n\n# Watch mode para desarrollo\npnpm --filter packages/telemetry run test --watch\n```\n\n### Suites clave\n\n| Suite | App/Package | Qué verifica |\n|-------|------------|-------------|\n| `buffer.test.ts` | `packages/telemetry` | Flush en 2s, flush en 50 eventos, retry 3x |\n| `no-pii.test.ts` | `packages/telemetry` | Eventos no contienen `student_name`, `email`, `@` |\n| `MathInput.test.tsx` | `packages/math-input` | `onStepSubmit` con step_index + duration_ms correctos |\n| `AttemptForm.test.tsx` | `apps/practice` | Submit con `rawSteps[]`, feedback correcto/incorrecto |\n| `classroom-heatmap.spec.ts` | `apps/teacher` (E2E) | Heatmap colors por `p_known`, badge de alertas |\n| `alert-resolution.spec.ts` | `apps/teacher` (E2E) | Marcar alerta → desaparece + toast confirmación |\n\nSpec completo: `docs/prompt/03-innova-clients-testing.md`\n\n### Configuración MSW (Mock Service Worker)\n\nHandlers compartidos en `packages/api-client/src/mocks/handlers.ts`. Importar en `setupTests.ts` de cada app/package.\n\n---\n\n## 10. Despliegue\n\n### Web apps (apps/teacher) → AWS Amplify\n\n```bash\n# Deploy manual (override)\namplify push --yes\n\n# O via GitHub Actions (automático en merge a main)\n# .github/workflows/deploy-web.yml\n```\n\nAmplify detecta automáticamente Next.js 14 App Router, SSR, ISR. Variables de entorno configuradas en Amplify Console → Environment Variables.\n\n### Astro landing → Cloudflare Pages\n\n```bash\npnpm --filter apps/landing build\n# Cloudflare Pages detecta el push a main y deploya dist/ automáticamente\n```\n\nConfigurar en Cloudflare Dashboard: Build command = `pnpm build`, Output directory = `dist`.\n\n### Mobile apps (apps/practice, apps/parent) → Expo EAS\n\n```bash\n# Login EAS (primera vez)\neas login\n\n# Configurar proyecto (primera vez)\neas init\n\n# Build producción (iOS + Android)\neas build --platform all --profile production\n\n# Actualización OTA (solo cambios JS, sin re-build nativo)\neas update --branch main --message \"descripción del update\"\n\n# Submit a App Store / Play Console\neas submit --platform ios\neas submit --platform android\n```\n\n### Re-deploy tras cambios\n\n```bash\ngit pull origin main\n\n# Web: Amplify hace deploy automático en push a main\n\n# Mobile OTA (sin nuevo build nativo):\neas update --branch main --message \"fix: improve step input validation\"\n\n# Mobile con cambios nativos (requiere nuevo build):\neas build --platform all --profile production\neas submit --platform all\n```\n\n### CI/CD (GitHub Actions)\n\n`.github/workflows/ci.yml` — en cada PR:\n\n1. `pnpm -r run type-check` → `pnpm -r run lint` → `pnpm -r run test:coverage`\n2. `pnpm -r run build` (verifica sin errores de build)\n3. Playwright E2E (en push)\n\n`.github/workflows/deploy-web.yml` — en merge a main:\n\n1. Build teacher app\n2. Deploy a AWS Amplify via Amplify CLI\n\n`.github/workflows/deploy-mobile.yml` — en merge a main:\n\n1. `eas update --branch main` para OTA a practice + parent\n\n---\n\n## 11. Decisión de deploy: AWS Amplify vs Vercel\n\n**Decisión: AWS Amplify Gen 2** para apps Next.js. **Cloudflare Pages** para Astro. **Expo EAS** para mobile.\n\n### Por qué Amplify sobre Vercel\n\n| Criterio | AWS Amplify | Vercel |\n|---------|------------|--------|\n| Next.js 14 App Router / SSR / ISR | ✅ soporte nativo | ✅ excelente |\n| Integración Cognito | ✅ mismo ecosystem, sin cross-cloud auth | ⚠️ requiere config adicional |\n| Integración S3 presigned URLs | ✅ IAM nativo | ⚠️ cross-cloud |\n| Costo MVP | ✅ Free tier: 1000 build min + 15 GB storage + 5 GB data out | ⚠️ $20/mes mínimo por team |\n| Vendor lock-in | ✅ dentro del ecosistema AWS ya elegido | ❌ agrega segundo vendor |\n| DX (Developer Experience) | ✅ buena, CLI maduro | ✅ excelente |\n\n**Por qué Cloudflare Pages para Astro:**\n\n- Sitio 100% estático → zero cold starts, global CDN, literalmente free.\n- Amplify cobraría por requests de CDN en un sitio que no necesita SSR.\n\n**Por qué EAS para mobile:**\n\n- OTA updates sin re-submit a stores → iteración más rápida en MVP.\n- EAS Build provee builds reproducibles en cloud (sin necesitar Mac propio para iOS).\n\nDocumentado como ADR-011 en `docs/architecture.md`.\n\n---\n\n## 12. Diseño y UI/UX\n\n### Stack visual\n\n| Tecnología | Uso |\n|-----------|-----|\n| Tailwind CSS v3 | Utility-first, todas las apps web |\n| shadcn/ui + Radix UI | Componentes accesibles (Dialog, DropdownMenu, Badge) para apps Next.js |\n| NativeWind | Tailwind en Expo (mobile) |\n| Lucide React | Iconos tree-shakeable |\n| recharts | Heatmap y barras de progreso (teacher dashboard) |\n| expo-haptics | Feedback táctil en practice app |\n\n### Tokens de diseño\n\nDefinidos en `packages/ui/src/tokens.css`:\n\n- `--color-mastery-high`: verde (#16a34a) — p_known ≥ 0.7\n- `--color-mastery-mid`: amarillo (#ca8a04) — p_known 0.4–0.7\n- `--color-mastery-low`: rojo (#dc2626) — p_known \u003c 0.4\n\n### Accesibilidad\n\n- Touch targets mínimos 44×44px (WCAG 2.1 AA + COPPA friendly)\n- High contrast mode support en `packages/math-input`\n- `aria-label` en todos los botones del teclado matemático\n- `role=\"status\"` en toasts de feedback\n\n---\n\n## 13. Privacidad y cumplimiento NNA\n\nLos alumnos son menores de edad. Aplica:\n\n| Regulación | Medida implementada |\n|-----------|-------------------|\n| COPPA (USA) | Sin analytics que capturen user_id. Sin cookies de terceros en apps de alumnos. |\n| Ley 21.180 (Chile) | Solo `student_uuid` en payloads — nunca nombre ni RUT. |\n| Session security | httpOnly cookies (web) + `expo-secure-store` (native) — nunca `localStorage` |\n| Datos de menores | No se comparten con terceros analíticos (no GA4 user_id, no Amplitude) |\n| Upload de fotos | EXIF stripped en `packages/upload-scanner` antes del presigned PUT |\n| Telemetry | Solo `attempt_id`, `event_type`, `payload` matemático — cero identificadores personales |\n\n---\n\n## 14. Roadmap\n\n| Milestone | Fecha | Entregable |\n|-----------|-------|-----------|\n| M0 | 29 abr | Especificaciones, ADRs, taxonomía de errores |\n| M1 | 30 abr | Instructions + prompts + drawio |\n| M2 | 3 may | Backend skeleton (Entrega 2) |\n| M3 | 17 may | AI engine |\n| **M4 — Frontend** | **7 jun (Entrega 3)** | `apps/practice` (web + Expo) + `apps/teacher` + `apps/parent` + packages core |\n| M5 | 12 jun | Integration pilot (~20 alumnos, 1 curso piloto) |\n| **M6 — Hardening** | **19 jun (Entrega 4)** | E2E Playwright completo, monitoring, pitch incubadora |\n\n---\n\n## 15. Recursos\n\n- Especificaciones backend: `.github/instructions/07-implementacion-backend.md`\n- Deployment y DevOps: `.github/instructions/08-deployment-y-devops.md`\n- Costos y escalabilidad: `.github/instructions/09-costos-y-escalabilidad.md`\n- Testing spec completo: `docs/prompt/03-innova-clients-testing.md`\n- Prompt de implementación: `docs/prompt/03-innova-clients.md`\n- ADRs (incluye ADR-011 Amplify vs Vercel): `docs/architecture.md`\n\n---\n\n## 16. Licencia\n\nInnova - Team 23. Internal GPL-3.0 License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvruizz22%2Finnova-clients","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvruizz22%2Finnova-clients","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvruizz22%2Finnova-clients/lists"}