update
This commit is contained in:
+138
@@ -0,0 +1,138 @@
|
||||
# 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` |
|
||||
Reference in New Issue
Block a user