# MeowSpool Mobile — TODO > Última atualização: 14/03/2026 --- ## Crítico — Funcionalidades Quebradas ### Auth - [ ] **Reset de senha não executado** (`app/(auth)/reset-password.tsx`) - `onSubmit` apenas faz `console.log` e navega para `password-reset-done` - `resetPasswordUseCase` já existe em `src/infrastructure/container.ts` - Chamar `resetPasswordUseCase.execute({ token, newPassword })` no submit - O `token` deve ser lido dos params de navegação (vindo do deep link do email) - Exibir `Alert.alert` em caso de erro da API - [ ] **Verificar email — sem resend** (`app/(auth)/verify-email.tsx`) - Tela é puramente estática - Adicionar botão "Reenviar código" - Criar `ResendVerificationUseCase` ou reutilizar `forgotPasswordUseCase` conforme API - Exibir feedback de sucesso/erro no reenvio ### Filtros de Inventário — Desconexão Store/Lista - [ ] **`inventory.tsx` não consome o `activeFilter` do store** (`app/(app)/(tabs)/inventory.tsx`) - `filters.tsx` salva corretamente em `filamentStore.setFilter()` - `inventory.tsx` filtra o array local com estado interno, ignorando `activeFilter` por completo - Refatorar: ler `activeFilter` do store e aplicar junto com a busca local - Ou: ao fechar `filters.tsx`, disparar `listFilamentsUseCase.execute()` com os filtros ativos --- ## Médio — Funcionalidades Incompletas ### Google OAuth - [ ] **Login com Google é stub** (`app/(auth)/login.tsx`) - Botão navega direto para `/(app)/(tabs)/home` sem nenhuma autenticação real - Instalar e configurar `expo-auth-session` + `expo-web-browser` - Obter `id_token` do Google via `AuthSession.startAsync` - Chamar `googleLoginUseCase.execute({ idToken })` (use case já existe em `container.ts`) - Configurar `GOOGLE_CLIENT_ID` em `.env` e `app.json` ### Exportar Etiqueta SVG - [ ] **Botão de exportar é stub** (`app/(app)/filaments/[id]/label.tsx`) - Botão "Exportar SVG" exibe apenas um `Alert.alert` informativo - Chamar `GET /filaments/:id/label.svg?width_mm=W&height_mm=H` via `httpClient` - Usar `expo-file-system` para salvar o SVG localmente - Usar `expo-sharing` para abrir o sheet de compartilhamento nativo - Passar `width_mm` e `height_mm` conforme o tamanho selecionado na UI ### QR Code — Copiar Link - [ ] **"Copiar link" exibe Alert em vez de copiar** (`app/(app)/filaments/[id]/qrcode.tsx`) - Instalar `expo-clipboard` (ou usar `@react-native-clipboard/clipboard`) - Substituir o `Alert.alert` por `Clipboard.setStringAsync(deepLink)` - Exibir feedback visual breve (toast ou mudança de ícone por 2s) ### Perfil — Trocar Email / Senha - [ ] **Botões de edição sem navegação** (`app/(app)/(tabs)/profile.tsx`) - Botões "Trocar email" e "Trocar senha" existem na UI mas não navegam para nenhuma tela - Criar telas `app/(app)/profile/change-email.tsx` e `app/(app)/profile/change-password.tsx` - Chamar `PUT /users/me` (quando backend implementar `update_me_handler`) --- ## Baixo — UX / Qualidade - [ ] **Sort de filamentos sem ação** (`app/(app)/(tabs)/inventory.tsx`) - Botão de sort está renderizado mas não tem `onPress` com lógica - Implementar seleção de ordem: `net_weight_asc`, `net_weight_desc`, `created_at_desc` - Passar `sort` como parâmetro no `listFilamentsUseCase.execute()` - Ou ordenar o array local sem nova chamada à API - [ ] **Tipos `Dashboard.ts` usados em `HomeScreen`** (`app/(app)/(tabs)/home.tsx`) - `src/domain/Dashboard.ts` define `DashboardData`, `MaterialSummary`, etc. - `HomeScreen` calcula tudo inline sem usar esses tipos - Refatorar para tipar explicitamente os dados computados com as interfaces do domínio - Opcional: criar `DashboardUseCase` que chama `GET /dashboard` e retorna `DashboardData` --- ## Arquitetura — Offline-First (Fase Futura) A infraestrutura está parcialmente preparada. Os itens abaixo compõem a implementação completa: - [ ] **`SyncService`** — classe que drena a `sync_queue` e envia para a API - Criar `src/application/sync/SyncService.ts` - Ler linhas de `sync_queue` onde `synced = 0` - Para cada item: chamar o use case correspondente (create/update/delete) - Em sucesso: marcar `synced = 1` na tabela de origem e deletar da `sync_queue` - Em conflito 409: aplicar last-write-wins (aceitar versão do servidor, atualizar local) - [ ] **Registrar background task** (`src/infrastructure/backgroundSync.ts` — novo arquivo) - Instalar `expo-background-fetch` + `expo-task-manager` - Registrar task `BACKGROUND_SYNC` com `TaskManager.defineTask` - Chamar `SyncService.sync()` dentro da task - Registrar com `BackgroundFetch.registerTaskAsync` (intervalo mínimo: 15min) - [ ] **Injetar adapters locais no container** (`src/infrastructure/container.ts`) - Substituir `ApiFilamentRepository` por wrapper que escreve no SQLite e enfileira na `sync_queue` - Substituir `ApiSpoolPresetRepository` por `LocalSpoolPresetRepository` - `LocalSpoolPresetRepository.upsertSystemPresets()` já existe para sincronizar presets do sistema - [ ] **Modo offline — fallback na leitura** - Ao detectar ausência de rede (`NetInfo`), usar `LocalFilamentRepository` como fonte de leitura - Exibir badge "Offline" no header quando sem conexão --- ## Testes - [ ] Configurar Jest + Testing Library (`@testing-library/react-native`) - [ ] Testes unitários para use cases (`CreateFilamentUseCase`, cálculo de net weight) - [ ] Testes de integração para stores Zustand - [ ] Testes de snapshot para componentes `FilamentCard`, `StockBar`, `Badge` - [ ] Mock de `httpClient` para testes de repositórios remotos --- ## Referência Rápida — Arquivos por Área | Área | Arquivo | | ------------------------------------ | ------------------------------------- | | Login / Google OAuth | `app/(auth)/login.tsx` | | Reset de senha | `app/(auth)/reset-password.tsx` | | Verificar email | `app/(auth)/verify-email.tsx` | | Lista de inventário + filtros + sort | `app/(app)/(tabs)/inventory.tsx` | | Filtros (bottom sheet) | `app/(app)/inventory/filters.tsx` | | Etiqueta SVG | `app/(app)/filaments/[id]/label.tsx` | | QR Code | `app/(app)/filaments/[id]/qrcode.tsx` | | Perfil | `app/(app)/(tabs)/profile.tsx` | | DI Container | `src/infrastructure/container.ts` | | DB local / schema | `src/adapters/local/database.ts` | | Domínio Dashboard | `src/domain/Dashboard.ts` |