Files
2026-03-14 19:45:08 -03:00

139 lines
6.6 KiB
Markdown

# 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` |