adf3889863
- Cargo init with dependencies (ratatui, crossterm, tokio, reqwest, rusqlite, serde, chrono, dirs) - Module structure: domain/, ui/, infrastructure/ - Domain models (TaskList, Task, TaskStatus, SyncAction, SyncQueueItem) - .gitignore for target/ and *.db - Rustls-based TLS (no OpenSSL dependency)
4.6 KiB
4.6 KiB
Contexto do Projeto
Atua como um programador Rust sénior e especialista em interfaces de terminal (TUI). O teu objetivo é implementar uma aplicação de gestão de tarefas de linha de comandos (CLI/TUI) que se integra com o Google Tasks.
A aplicação deve adotar a filosofia "Offline-First", guardando as tarefas localmente e sincronizando com a cloud em pano de fundo quando houver ligação à internet.
Stack Tecnológica
- Linguagem: Rust
- UI:
ratatui+crossterm - Assincronismo:
tokio - HTTP:
reqwest - Autenticação:
yup-oauth2(usando o Device Authorization Flow) - Base de Dados Local:
rusqlite(SQLite local para guardar tarefas e fila de sincronização) - Serialização:
serde+serde_json
Arquitetura de Ficheiros (Clean Architecture + MVU)
Organiza o código estritamente com a seguinte estrutura:
src/
├── main.rs # Ponto de entrada, inicialização do terminal e DB
├── app.rs # Estado da aplicação (App struct) e processamento de eventos
├── domain/ # Lógica pura e modelos de dados
│ ├── mod.rs
│ └── models.rs # Structs de Tarefa, Lista e Eventos de Sincronização
├── ui/ # Renderização Ratatui
│ ├── mod.rs # Layout principal
│ └── components.rs # Widgets (Tabs, Listas, Pop-ups)
└── infrastructure/ # Efeitos colaterais e I/O
├── mod.rs
├── db.rs # Inicialização do SQLite, queries CRUD e fila offline
└── api.rs # Integração com Google Tasks API e OAuth2
Requisitos Principais
1. Interface de Utilizador (UI) e Layout
- O ecrã deve estar dividido numa grelha rigorosa:
- Topo (Tabs): Uma linha horizontal a representar as Listas de Tarefas. Deve ser possível navegar entre elas e adicionar novas listas.
- Corpo Principal (Split View): Abaixo das listas, o ecrã divide-se em dois painéis verticais:
- Painel da Esquerda (Lista de Tasks): Apresenta as tarefas da lista atualmente selecionada. A data e hora dos lembretes (
due dates) devem ser visíveis diretamente nesta lista, ao lado ou por baixo do título da tarefa. - Painel da Direita (Detalhes): Mostra as notas, descrição longa e/ou sub-tarefas da tarefa atualmente selecionada no painel esquerdo.
- Painel da Esquerda (Lista de Tasks): Apresenta as tarefas da lista atualmente selecionada. A data e hora dos lembretes (
2. Interação e Atalhos (UX)
- Navegação de Painéis: A mudança de foco entre os três grandes blocos (Tabs no Topo, Painel Esquerdo e Painel Direito) deve ser feita usando a combinação de teclas
Tab + Setas. - Navegação Interna: Uma vez dentro de um painel, a navegação entre os itens faz-se apenas com as setas do teclado (não usar atalhos tipo Vim com
j/k). - Reordenação Persistente: O utilizador deve conseguir organizar as tarefas na lista usando o atalho
Alt + Setas(Cima/Baixo). Esta ordenação customizada tem de ficar gravada na base de dados para se manter exatamente igual entre sessões. - Operações CRUD: Deve ser possível Adicionar, Editar e Apagar qualquer Lista ou Tarefa.
- Edição de Datas (Pop-up): Quando o utilizador for editar a data/hora de uma tarefa, a aplicação deve abrir um modal/Pop-up interativo sobreposto ao centro do ecrã para facilitar a introdução desses dados.
- O estado da rede ("Online" / "Offline" / "A Sincronizar...") deve ser apresentado num rodapé discreto.
3. Base de Dados Local (Offline-First)
- Usa o SQLite para criar um ficheiro local (ex:
tasks.db). - Tabela
tasks: Deve espelhar a estrutura de uma Google Task (ID, Title, Notes, Status, Due, Position/Order). A coluna de posição é crítica para garantir que a ordenação do utilizador não se perde ao reiniciar a aplicação. - Tabela
sync_queue: Fundamental para o funcionamento offline. Deve registar a ação pendente (CREATE, UPDATE, DELETE, REORDER), o ID local/remoto e o payload em JSON. - A interface (
app.rseui/) lê exclusivamente do SQLite, garantindo que o carregamento da interface é imediato e não bloqueia à espera de respostas de rede.
4. Motor de Sincronização (Sync Engine)
- Quando o utilizador cria, edita, apaga ou reordena uma tarefa, a ação e a nova ordem (position) são registadas no SQLite.
- Uma task assíncrona do Tokio processa a fila de sincronização em pano de fundo quando deteta ligação à internet, chamando a API oficial do Google Tasks via
reqwest. A reordenação deve refletir-se também na cloud. - Se não houver token de acesso guardado, a TUI deve apresentar um Pop-up a pedir para o utilizador visitar o URL de autorização e introduzir o código gerado pelo
yup-oauth2.