# 🇮🇹 Italiano Vivo App de italiano **situacional-first** com voz livre e scoring de inteligibilidade. Aprenda como uma criança: errando mas se comunicando. ## Visão - **Scoring em 3 eixos**: Sentido transmitido / Naturalidade / Precisão gramatical - **Tolerância estilo criança**: erro gramatical que não impede entendimento = sucesso comunicativo - **Voz livre**: grave, receba feedback estruturado, nunca "Errado" - **Salvavidas (Salvavita)**: treine estratégias de comunicação quando a palavra some - **SRS de chunks**: revisão espaçada de frases, não palavras isoladas - **PWA offline**: catálogo, áudio e SRS funcionam sem conexão - **CEFR can-do**: badges baseados em competências reais ("você consegue reclamar de um item com defeito") ## Como Rodar ### Pré-requisitos - Node.js ≥ 20 - LiteLLM proxy rodando (ou configure `LITELLM_BASE_URL` para outro endpoint OpenAI-compatible) ### Instalação ```bash # Instalar dependências do monorepo npm install # Configurar variáveis de ambiente cp .env.example server/.env # Edite server/.env com sua chave da API ``` ### Desenvolvimento ```bash # Roda app + server simultaneamente npm run dev ``` - App: http://localhost:5173 - Server: http://localhost:8787 - Health check: http://localhost:8787/health ### Build ```bash npm run build # Build server + app npm run typecheck # Verificação de tipos ``` ## Endpoints do Server | Método | Rota | Descrição | |--------|------|-----------| | GET | `/health` | Status do servidor | | POST | `/api/judge` | Avalia fala do aluno em 3 eixos (sentido, naturalidade, gramática) | | POST | `/api/transcribe` | Transcreve áudio via modelo omni (ASR tolerante a sotaque) | | GET | `/api/tts-proxy?text=...&voice=elsa\|diego` | Serve áudio TTS pré-gerado do cache local | ### POST /api/judge **Entrada:** ```json { "missionId": "bambino-m01", "scenario": "Al bar", "learnerGoalPt": "Pedir um café", "expectedIt": "Vorrei un caffè, per favore", "utteranceText": "io volere caffe", "transcriptRaw": "io volere caffe", "audioBase64": "..." } ``` **Saída:** ```json { "meaning_conveyed": "full", "naturalness": 45, "natural_version": "Vorrei un caffè, per favore", "grammar": [ { "it_said": "io volere", "problem_pt": "Infinitivo em vez de conjugação", "fix_it": "vorrei / voglio", "severity": "minor" } ], "next_move": { "italian": "Certo! Un caffè. Lo vuole al banco o al tavolo?", "portuguese": "Claro! Um café. Quer no balcão ou na mesa?" }, "praise_or_push": "Quase lá! Um italiano diria: Vorrei un caffè, per favore" } ``` ## Estrutura de Pastas ``` cursoitaliano/ ├── app/ # PWA React + Vite + TypeScript │ ├── public/ # manifest.webmanifest, ícones │ └── src/ │ ├── db/db.ts # IndexedDB via Dexie │ ├── engine/srs.ts # SM-2 simplificado │ ├── types/content.ts # Tipos do conteúdo JSON │ ├── App.tsx # Componente principal │ ├── main.tsx # Entry point │ └── styles.css # Design system ├── server/ # Node + Express + TypeScript │ ├── cache/audio/ # Áudios TTS pré-gerados (offline) │ └── src/ │ ├── lib/llm.ts # Cliente LiteLLM singleton │ ├── routes/ │ │ ├── judge.ts # Motor de feedback 3 eixos │ │ ├── transcribe.ts # ASR via omni model │ │ └── tts.ts # Proxy de áudio TTS │ └── index.ts # Express app ├── content/ # JSONs versionados (gerados por pipeline) ├── audio/ # Assets de áudio por missão ├── SPEC.md # Especificação completa do produto ├── .env.example # Template de variáveis de ambiente └── package.json # Monorepo root (npm workspaces) ``` ## Modelos Utilizados | Modelo | Uso | Variável | |--------|-----|----------| | qwen3.8-max | Juiz de feedback, geração de missões | `CHAT_MODEL` | | qwen3.8-flash | Drills rápidos, fallback de quota | `FAST_MODEL` | | qwen3-omni-flash | Transcrição de áudio (ASR) | `OMNI_MODEL` | Todos acessados via LiteLLM proxy (`LITELLM_BASE_URL`). ## Roadmap - [x] Esqueleto do monorepo (app PWA + server LiteLLM) - [ ] Geração de conteúdo: Trilha Bambino (12 unidades) + Viaggio M1–M6 - [ ] Pipeline de geração de áudio TTS (edge-tts) - [ ] Service Worker para modo offline completo - [ ] Minijogo "descreva sem nomear" (circunlóquio) - [ ] Modo carro/shadowing com medição de lag - [ ] Trilhas restantes (Viaggio M7–M15, Vivere completa) - [ ] Preparatório CILS/CELI B1 cidadania - [ ] Wrapper Android (Capacitor) - [ ] Calibração do judge com votos "isso estava certo" ## Licença Privado — uso pessoal.