adiciona documento de requisitos do produto (PRD) para MeowSpool
This commit is contained in:
@@ -0,0 +1,204 @@
|
|||||||
|
# Product Requirements Document (PRD): MeowSpool
|
||||||
|
|
||||||
|
# Paper Canva
|
||||||
|
https://app.paper.design/file/01KKM0HA6NBV44VCQDFQHC2MRY
|
||||||
|
|
||||||
|
## 1. Visão Geral
|
||||||
|
|
||||||
|
MeowSpool é uma solução para entusiastas e profissionais de impressão 3D gerenciarem seu estoque de filamentos. O diferencial está na precisão do cálculo de peso líquido (descontando o peso do carretel via presets), na identidade visual inspirada em gatos siameses, e na integração com etiquetas físicas exportáveis (SVG/QR Code/NFC).
|
||||||
|
|
||||||
|
**Foco do desenvolvimento atual:** App Mobile (React Native) + Backend em Rust. A interface Web é planejada para uma fase posterior, após a estabilização do mobile e da API.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Objetivos
|
||||||
|
|
||||||
|
* **Precisão:** Eliminar o "chute" de quanto filamento resta no rolo.
|
||||||
|
* **Agilidade:** Facilitar o cadastro e a consulta via dispositivos móveis, mesmo offline.
|
||||||
|
* **Organização:** Centralizar parâmetros técnicos (temperatura/fluxo) para consulta rápida.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Público-Alvo
|
||||||
|
|
||||||
|
* Hobbistas de impressão 3D.
|
||||||
|
* Donos de "Print Farms" (fazendas de impressão).
|
||||||
|
* Projetistas que trabalham com diversos materiais (PLA, ABS, PETG, etc).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Identidade Visual
|
||||||
|
|
||||||
|
### 4.1 Nome e Conceito
|
||||||
|
**MeowSpool** — fusão de "Meow" (gato) e "Spool" (carretel). A identidade visual é inspirada no gato siamês: tons quentes e escuros com detalhes em azul-aço que remetem aos olhos característicos da raça.
|
||||||
|
|
||||||
|
### 4.2 Paleta de Cores
|
||||||
|
|
||||||
|
| Token | Hex | Função na Interface |
|
||||||
|
|---------------|-----------|----------------------------------------------|
|
||||||
|
| `bg-base` | `#1E1B18` | Fundo geral |
|
||||||
|
| `bg-surface` | `#2A2622` | Cards, contêineres, widgets |
|
||||||
|
| `bg-hover` | `#332F2B` | Estados de hover em cards e itens de lista |
|
||||||
|
| `text-primary`| `#F5EEDC` | Títulos, peso líquido (texto importante) |
|
||||||
|
| `text-secondary`| `#C9C1B0`| Descrições, labels (material, marca) |
|
||||||
|
| `accent` | `#38BCC2` | Botões de ação, elementos ativos |
|
||||||
|
| `accent-muted`| `#38BCC226`| Backgrounds de badges e status (10% opacidade)|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Requisitos Funcionais (MVP)
|
||||||
|
|
||||||
|
### 5.1 Autenticação
|
||||||
|
|
||||||
|
* **Métodos suportados:** Email/senha e OAuth via Google.
|
||||||
|
* **Plataformas:** Mobile consome a API de auth do backend Rust. Web utilizará o mesmo sistema em fase futura.
|
||||||
|
* **Sessão:** Token JWT com refresh token. O app mobile persiste a sessão localmente para acesso offline.
|
||||||
|
|
||||||
|
### 5.2 Gestão de Inventário
|
||||||
|
|
||||||
|
* **Cadastro de Filamento:** Campos obrigatórios e opcionais:
|
||||||
|
* Material (tipo): PLA, ABS, PETG, TPU, ASA, PA, PC, etc.
|
||||||
|
* Marca (texto livre)
|
||||||
|
* Modelo (texto livre)
|
||||||
|
* Cor (seletor hex — armazena valor hexadecimal, ex: `#FF5733`)
|
||||||
|
* Temperatura Hotend (°C)
|
||||||
|
* Temperatura Mesa (°C)
|
||||||
|
* Fator de Fluxo/Extrusão (%)
|
||||||
|
|
||||||
|
* **Calculadora de Peso Líquido:**
|
||||||
|
* Seleção de **Preset de Carretel** (ver 5.3).
|
||||||
|
* Input de **Peso Total** (leitura da balança, em gramas).
|
||||||
|
* Cálculo automático: `Peso_Líquido = Peso_Total - Peso_Carretel`.
|
||||||
|
|
||||||
|
### 5.3 Presets de Carretéis
|
||||||
|
|
||||||
|
* **Presets do Sistema (built-in):** Um conjunto de presets pré-cadastrados com as principais marcas do mercado. Exemplos:
|
||||||
|
|
||||||
|
| Nome do Preset | Peso do Carretel |
|
||||||
|
|------------------------|-----------------|
|
||||||
|
| Bambu Lab (Plástico) | 250g |
|
||||||
|
| Elegoo (Papelão) | 200g |
|
||||||
|
| Creality (Plástico) | 230g |
|
||||||
|
| Prusament (Plástico) | 201g |
|
||||||
|
| Sunlu (Papelão) | 200g |
|
||||||
|
| Polymaker (Plástico) | 220g |
|
||||||
|
| Genérico Papelão 1kg | 200g |
|
||||||
|
| Genérico Plástico 1kg | 250g |
|
||||||
|
|
||||||
|
* **Presets Customizados:** O usuário pode criar, editar e excluir seus próprios presets (nome + peso em gramas). Presets customizados são vinculados à conta do usuário e sincronizados.
|
||||||
|
* **Presets do sistema são somente leitura** — não podem ser editados ou excluídos pelo usuário.
|
||||||
|
|
||||||
|
### 5.4 Identificação e Etiquetas
|
||||||
|
|
||||||
|
* **Geração de QR Code:** Cada filamento cadastrado gera um QR Code único apontando para sua página de detalhes no app/web.
|
||||||
|
* **Exportação de Etiqueta em SVG:** O sistema gera um arquivo SVG com os dados do filamento (nome, material, cor, peso líquido, QR Code) para que o usuário importe e imprima na plataforma de sua preferência (Inkscape, Canva, impressoras de etiqueta com suporte a SVG, etc).
|
||||||
|
* Layout padrão: 50mm x 30mm (ajustável via parâmetro).
|
||||||
|
* Conteúdo: cor visual do filamento, nome, material, marca, peso líquido, QR Code.
|
||||||
|
|
||||||
|
### 5.5 Interface (UI/UX)
|
||||||
|
|
||||||
|
* **Design:** Dark mode exclusivo, paleta siamês (ver 4.2).
|
||||||
|
* **Plataforma atual:** Mobile (React Native).
|
||||||
|
* **Filtros e Busca:** Filtragem por material, marca, cor e nível de estoque.
|
||||||
|
* **Dashboard:** Visão geral do inventário com totais por material e alertas visuais de estoque baixo.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Requisitos Técnicos (Stack)
|
||||||
|
|
||||||
|
### 6.1 Fase 1 — Mobile + Backend (foco atual)
|
||||||
|
|
||||||
|
| Camada | Tecnologia | Justificativa |
|
||||||
|
|-------------------|----------------------|------------------------------------------------------------------------------|
|
||||||
|
| **Mobile** | React Native | Performance nativa, suporte offline e acesso a APIs do dispositivo (câmera, NFC). |
|
||||||
|
| **Back-end** | Rust (Axum ou Actix) | Alta performance, segurança de memória e baixo consumo de recursos. |
|
||||||
|
| **Banco de Dados**| PostgreSQL | Robustez para relações entre usuários, marcas, materiais e presets. |
|
||||||
|
| **Auth** | JWT + OAuth (Google) | Padrão seguro, compatível com mobile e preparado para web futura. |
|
||||||
|
| **Banco Local** | SQLite (SQLCipher) | Armazenamento offline seguro no dispositivo móvel. |
|
||||||
|
|
||||||
|
### 6.2 Fase 2 — Web (planejado, pós-estabilização)
|
||||||
|
|
||||||
|
| Camada | Tecnologia | Justificativa |
|
||||||
|
|-------------------|----------------|------------------------------------------------------------|
|
||||||
|
| **Front-end Web** | Next.js | SEO, performance, rotas e suporte a cache via ISR/SSR. |
|
||||||
|
| **Cache (Web)** | Redis / HTTP Cache | Redução de latência nas listagens e dados de inventário.|
|
||||||
|
|
||||||
|
### 6.3 Estratégia de Sincronização (Offline-First Mobile)
|
||||||
|
|
||||||
|
1. O app mobile utiliza um banco de dados local (SQLite via SQLCipher para segurança).
|
||||||
|
2. Todas as operações são escritas localmente primeiro (write-ahead).
|
||||||
|
3. Quando há conexão, o app sincroniza via API REST com o backend Rust (estratégia: last-write-wins com timestamp, com resolução de conflitos simples).
|
||||||
|
4. A Web (fase 2) consumirá a mesma API REST, sem necessidade de alterações no backend.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Estrutura de Dados (Entidades Principais)
|
||||||
|
|
||||||
|
### `users`
|
||||||
|
| Campo | Tipo | Descrição |
|
||||||
|
|--------------|-----------|----------------------------------|
|
||||||
|
| id | UUID | Identificador único |
|
||||||
|
| email | string | Email do usuário |
|
||||||
|
| password_hash| string | Hash bcrypt (nulo se OAuth) |
|
||||||
|
| google_id | string? | ID OAuth Google (opcional) |
|
||||||
|
| created_at | timestamp | |
|
||||||
|
|
||||||
|
### `spool_presets`
|
||||||
|
| Campo | Tipo | Descrição |
|
||||||
|
|--------------|-----------|------------------------------------------------|
|
||||||
|
| id | UUID | Identificador único |
|
||||||
|
| name | string | Nome do preset (ex: "Bambu Lab Plástico") |
|
||||||
|
| spool_weight_g| integer | Peso do carretel vazio em gramas |
|
||||||
|
| is_system | boolean | `true` = preset built-in, `false` = customizado|
|
||||||
|
| user_id | UUID? | Nulo para presets do sistema |
|
||||||
|
| created_at | timestamp | |
|
||||||
|
|
||||||
|
### `filaments`
|
||||||
|
| Campo | Tipo | Descrição |
|
||||||
|
|------------------|-----------|----------------------------------------|
|
||||||
|
| id | UUID | Identificador único |
|
||||||
|
| user_id | UUID | Dono do filamento |
|
||||||
|
| material | string | PLA, ABS, PETG, etc. |
|
||||||
|
| brand | string | Marca |
|
||||||
|
| model | string? | Modelo/linha |
|
||||||
|
| color_hex | string | Cor em hex (ex: `#FF5733`) |
|
||||||
|
| spool_preset_id | UUID | Preset de carretel usado |
|
||||||
|
| total_weight_g | integer | Peso total medido na balança (gramas) |
|
||||||
|
| net_weight_g | integer | Calculado: total - preset |
|
||||||
|
| temp_hotend_c | integer? | Temperatura do hotend (°C) |
|
||||||
|
| temp_bed_c | integer? | Temperatura da mesa (°C) |
|
||||||
|
| flow_factor_pct | float? | Fator de fluxo (%) |
|
||||||
|
| notes | text? | Observações livres |
|
||||||
|
| updated_at | timestamp | Usado para sync offline |
|
||||||
|
| created_at | timestamp | |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Fluxo do Usuário (User Flow)
|
||||||
|
|
||||||
|
### Cadastro de Filamento (Mobile)
|
||||||
|
1. Usuário abre o App Mobile (autenticado).
|
||||||
|
2. Clica em "Novo Filamento".
|
||||||
|
3. Insere Marca, Material, Modelo e seleciona a Cor via seletor hex.
|
||||||
|
4. Seleciona o Preset do Carretel (ex: "Bambu Lab Plástico — 250g") ou cria um customizado.
|
||||||
|
5. Coloca o carretel na balança e digita o peso total (ex: "850g").
|
||||||
|
6. O sistema calcula e exibe: **600g de filamento disponível**.
|
||||||
|
7. Salva localmente (offline-first) e sincroniza com o backend quando online.
|
||||||
|
8. O sistema gera o QR Code e disponibiliza o SVG da etiqueta para exportação.
|
||||||
|
|
||||||
|
### Consulta via Web *(Fase 2 — planejado)*
|
||||||
|
1. Usuário acessa a web autenticado.
|
||||||
|
2. Dashboard exibe inventário completo com totais e alertas.
|
||||||
|
3. Dados são servidos via API com cache, garantindo baixa latência.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Roadmap de Funcionalidades Futuras
|
||||||
|
|
||||||
|
* **Front-end Web (Next.js):** Dashboard e inventário acessível via browser, consumindo a mesma API do backend.
|
||||||
|
* **Escrita de Tags NFC:** Gravação de dados diretamente em tags NFC coladas nos carretéis (via app mobile).
|
||||||
|
* **Histórico de Uso:** Log de gramas consumidas por projeto/impressão.
|
||||||
|
* **Alerta de Estoque Baixo:** Notificações push quando um filamento estiver abaixo de X gramas.
|
||||||
|
* **Custo por Grama:** Registro do custo de cada rolo para cálculo de custo por impressão.
|
||||||
|
* **Importação em Lote:** Upload CSV/JSON para cadastro massivo (útil para print farms).
|
||||||
|
* **Compartilhamento de Presets:** Pool público de presets de carretéis contribuídos pela comunidade.
|
||||||
Reference in New Issue
Block a user