Aplicativo desktop de registro de horas trabalhadas, construído com Tauri + React + TypeScript. Adaptável ao modo de trabalho de cada pessoa — não o contrário.
- Timer ao vivo com play, pausa e stop
- Edição de hora de início com recálculo automático do timer
- Cancelamento imediato de tarefa sem confirmação
- Apenas uma tarefa em execução por vez — é necessário parar a atual para iniciar outra
- Confirmação de conclusão ao parar (Concluída / Pendente), com hora de término editável inline para corrigir timers esquecidos
- Totalizadores diários e semanais (billable / non-billable)
- Tela dedicada para registro de tarefas passadas em sequência
- Modos: hora início + hora fim, ou hora início + duração
- Cadeia de horários: o início da próxima tarefa é preenchido automaticamente com o fim da anterior
- Detecção de tarefas que cruzam meia-noite (overnight)
- Navegação de data com DatePicker
- Visão semanal com navegação ← → e filtros rápidos por dia
- Tipos de agendamento:
specific_date(atalho "Hoje"),recurring(dias da semana),period(intervalo de datas) - Tarefas recorrentes sem data de término
- Concluir/Pendente por dia (sem excluir a tarefa)
- Ações por tarefa (abrir URL ou arquivo): aparecem como chips clicáveis no popup flyout durante a execução, disparáveis sob demanda
- Importa eventos da semana atual como tarefas planejadas
- Agrupamento por dia com accordion expansível
- Seleção por dia ou individual por evento
- Editor inline por evento: projeto, categoria, tipo de agendamento
- Detecção automática de recorrência via RRULE
- Filtra automaticamente eventos de local de trabalho, ausência e foco
- Filtros rápidos: Hoje, 7 dias, 30 dias, Este mês
- Filtros avançados: período, nome, projeto, categoria, billable
- Agrupamento por dia no fuso local do usuário
- Totalizadores: total, billable, non-billable, qtd registros
- Edição e exclusão por tarefa
- Perfis de exportação reutilizáveis (CRUD)
- Formatos: CSV, XLSX, JSON
- Separador CSV configurável (vírgula ou ponto-e-vírgula)
- Formato de duração: HH:MM:SS, decimal, minutos
- Formato de data: ISO ou DD/MM/AAAA
- Colunas reordenáveis com toggle de visibilidade
- Destino: salvar arquivo, copiar para área de transferência
- Google Sheets: envio manual pela tela de Integrações ou automático ao concluir tarefa; duração como formato de hora nativo da planilha
- Google Calendar: importação de eventos como tarefas planejadas (ver seção acima)
- Conexão OAuth única para Sheets + Calendar
- Clockify: envio de time-entries via API Key; importação de projetos/tags como entidades do DeskClock; mapeamento por workspace; tags padrão; auto-sync por tarefa ou diário; modal "Gerenciar apontamentos" com CRUD direto sobre as time entries do Clockify (criar, editar inline, excluir; filtros por período e por tags padrão)
- Importação em massa (um por linha)
- Adição individual + exclusão sem confirmação
- Prefixo
!para marcar categoria como non-billable na importação
- Painel de ações acessível via
Ctrl+Kou ao abrir o app (configurável) - Atalhos numéricos
Ctrl+1–7para navegar direto às telas - Iniciar nova tarefa em branco sem abrir a janela principal
- Busca fuzzy nas ações e tarefas planejadas do dia
- Compact Overlay: sempre visível (always-on-top), arrastável com persistência de posição; mostra ícone + badge de tarefas pendentes quando idle, timer
MM:SSpulsante quando em execução - Popup Flyout: aberto ao clicar no Compact; mostra tarefas planejadas (idle) ou controles da tarefa em execução (running/paused); edição inline por campo (nome, projeto, categoria, hora de início) sem abrir modal
- Toast: notificações de sistema no canto inferior direito
- Opacidade em repouso configurável, snap-to-grid opcional
- Servidor HTTP embutido acessível em
http://localhost:27420(porta configurável) - Documentação interativa em
/docs(Swagger UI) - Endpoints para controle de timer:
start,pause,resume,stop,toggle,cancel - CRUD completo de tarefas planejadas: lista por data com regras de recorrência, marcar/desmarcar conclusão
- Listagem de projetos e categorias
- Habilitável/desabilitável nas Configurações
- Autostart na inicialização do sistema operacional
- Timer ao vivo no ícone da bandeja (system tray)
- Atalhos globais configuráveis: toggle tarefa, parar, mostrar/ocultar overlay e janela
- Temas: Azul, Verde, Escuro, Claro
- Tamanho de fonte: P, M, G, GG
- Abrir acesso rápido (Command Palette) ao iniciar o app (configurável)
| Camada | Tecnologia |
|---|---|
| Framework desktop | Tauri v2 |
| Frontend | React 19 + TypeScript |
| Estilização | Tailwind CSS v4 |
| Ícones | Lucide React |
| Banco de dados | SQLite (tauri-plugin-sql) |
| Arquitetura | Clean Architecture |
| Testes | Vitest (unit) |
| Links externos | tauri-plugin-opener |
| Atalhos globais | tauri-plugin-global-shortcut |
| Autostart | tauri-plugin-autostart |
| API REST local | axum + utoipa (Swagger UI) |
- Node.js 18+
- pnpm 9+
- Rust (stable, mínimo 1.77.2)
- Dependências do sistema para o seu SO (ver seção abaixo)
sudo apt-get update
sudo apt-get install -y \
build-essential \
curl \
wget \
file \
pkg-config \
libssl-dev \
libgtk-3-dev \
libwebkit2gtk-4.1-dev \
librsvg2-dev \
patchelf \
libxdo-dev \
libayatana-appindicator3-dev
build-essential,pkg-configelibssl-devsão necessários para compilar crates Rust com dependências nativas. Sem eles ocargo buildfalha.
Instale todas as dependências do Linux acima e adicione as dependências de display. A forma mais simples é usar o WSLg, disponível no Windows 11 e Windows 10 (build 21364+):
# Verifique se WSLg está ativo
ls /mnt/wslg
# Dependências de display adicionais
sudo apt-get install -y libgl1-mesa-glx libgl1-mesa-driSe o WSLg não estiver disponível, instale um servidor X (ex: VcXsrv) e defina
DISPLAY=:0antes de rodarpnpm tauri dev.
O Rust no Windows utiliza o toolchain MSVC, que depende do compilador C++ da Microsoft.
1. Visual Studio Build Tools
Baixe e instale o Visual Studio Build Tools. Durante a instalação, selecione o workload:
- Desenvolvimento para desktop com C++
- MSVC v143 (ou mais recente)
- SDK do Windows 10/11
Alternativa: instalar o Visual Studio Community com o mesmo workload.
2. Rust
Instale via rustup. O instalador detecta automaticamente o toolchain MSVC. Após a instalação, confirme:
rustup default stable-x86_64-pc-windows-msvc
rustc --version3. WebView2
Já integrado no Windows 10 (atualização 1803+) e Windows 11. Nenhuma ação necessária.
A integração com o Clockify usa API Key gerada diretamente no painel do usuário — sem credenciais de servidor necessárias.
- Acesse app.clockify.me/user/preferences#advanced
- Role até a seção API e clique em Generate
- Copie a chave e cole em Configurações → Integrações → Clockify → Conectar
Após conectar, selecione o workspace ativo, importe projetos e tags do Clockify e configure os mapeamentos.
Para visualizar e editar as time entries diretamente no DeskClock (sem precisar abrir o painel do Clockify), use Gerenciar apontamentos no card Clockify — abre um modal com filtro por período, criar/editar/excluir e o filtro "Apenas com tags padrão" ligado por padrão quando há tags padrão configuradas.
As integrações com Google Sheets e Google Calendar requerem credenciais OAuth do Google Cloud Platform. Sem elas o app funciona normalmente — apenas as integrações ficam indisponíveis.
- Crie um projeto no Google Cloud Console
- Ative as APIs: Google Sheets API e Google Calendar API
- Crie credenciais OAuth 2.0 do tipo Desktop app
- Copie o Client ID e o Client Secret
- Crie um arquivo
.envna raiz do projeto:
GCP_CLIENT_ID=seu-client-id.apps.googleusercontent.com
GCP_CLIENT_SECRET=seu-client-secretO prefixo
GCP_é permitido pelo Vite (configurado emvite.config.ts). Nunca commite o arquivo.env.
git clone <repo>
cd deskclock-tauri
pnpm install# Frontend apenas (Vite dev server, sem janela nativa)
pnpm dev
# App Tauri completo com hot reload
pnpm tauri dev# Execução única
pnpm test
# Watch mode
pnpm test:watch
# Cobertura
pnpm test:coverageOs testes são unitários, focados em casos de uso de domínio e utilitários puros. Veja a seção Testes para mais detalhes.
pnpm lint
pnpm lint:fix
pnpm format
pnpm format:checkPara gerar o instalador nativo para o SO atual:
pnpm tsc --noEmit # verifica tipos
pnpm test # roda os testes unitários
pnpm tauri build # gera o instaladorImportante:
pnpm tauri buildgera instaladores apenas para a plataforma onde está rodando. Para gerar o instalador Windows, execute no Windows (não no WSL2) ou use o CI (ver seção abaixo).
Os artefatos são gerados em src-tauri/target/release/bundle/:
| SO | Pasta | Formatos |
|---|---|---|
| Windows | bundle/msi/ e bundle/nsis/ |
.msi, .exe |
| Ubuntu / Debian | bundle/deb/ |
.deb |
| Linux (universal) | bundle/appimage/ |
.AppImage |
O projeto possui dois workflows no GitHub Actions, localizados em .github/workflows/.
Roda automaticamente em todo push para main e em todo pull request aberto contra main.
O que executa:
pnpm tsc --noEmit— verifica tipos TypeScript sem gerar artefatospnpm test— roda os testes unitários com Vitestpnpm lint— valida o código com ESLint
Um PR só deve ser mergeado se todos esses passos passarem.
Gera instaladores nativos e publica uma release no GitHub. Pode ser ativado de duas formas:
git checkout main && git pull
git tag v0.1.0
git push origin v0.1.0O workflow é disparado automaticamente, builda para Linux e Windows em paralelo, e cria um rascunho de release no GitHub com os instaladores anexados.
- Acesse Actions → Release no repositório
- Clique em Run workflow
- Escolha se deseja criar como rascunho ou publicar diretamente
| Plataforma | Arquivo | Uso |
|---|---|---|
| Linux | DeskClock_x.y.z_amd64.deb |
Ubuntu, Debian, Mint e derivados |
| Linux | DeskClock_x.y.z_amd64.AppImage |
Qualquer distro (incluindo Arch) — sem instalação |
| Windows | DeskClock_x.y.z_x64.msi |
Instalador MSI (recomendado para empresas) |
| Windows | DeskClock_x.y.z_x64-setup.exe |
Instalador NSIS (recomendado para usuários finais) |
O projeto usa Vitest com foco em testes unitários das camadas de domínio e utilitários puros.
| Camada | Arquivos de teste |
|---|---|
domain/usecases/ |
Use cases de Task, PlannedTask, Category, Project, ExportProfile |
infra/database/ |
Repositórios SQLite (com getDb() mockado) |
infra/integrations/google/ |
parseRRuleDays (lógica de RRULE) |
shared/utils/ |
time, groupTasks, exportFormatter, theme, snapToGrid, actions |
| Motivo | Exemplos |
|---|---|
Dependem de fetch externo |
GoogleCalendarImporter, GoogleSheetsTaskSender |
| Acoplados ao runtime Tauri | RunningTaskContext, overlays |
Requerem @testing-library/react (não configurado) |
Componentes React |
pnpm test # execução única
pnpm test:watch # modo watch
pnpm test:coverage # coberturasrc/
├── domain/ # Entidades, repositórios (interfaces) e casos de uso
│ ├── entities/ # Task, PlannedTask, Project, Category, ExportProfile
│ ├── repositories/ # Interfaces (ports)
│ └── usecases/ # Lógica de negócio pura, sem dependências de framework
├── infra/ # Implementações concretas
│ ├── database/ # Repositórios SQLite via tauri-plugin-sql
│ └── integrations/ # Google Sheets, Google Calendar (OAuth, sender, importer)
├── presentation/ # React UI
│ ├── pages/ # Tasks, Planning, Retroactive, History, Data, Settings, Integrations
│ ├── components/ # Autocomplete, DatePickerInput, Sidebar, CommandPalette…
│ ├── overlays/ # Execution, Planning, Compact, CommandPaletteApp, Toast
│ ├── modals/ # EditTaskModal, ExportModal, ImportCalendarModal…
│ ├── hooks/ # useRunningTask, useHistory, usePlannedTasks…
│ └── contexts/ # RunningTaskContext, ConfigContext
├── shared/ # Types, utils (time, groupTasks, fontSize, theme, toast)
└── tests/ # Espelha src/ — unit tests com Vitest
src-tauri/ # Backend Rust (Tauri)
├── src/
│ ├── api/ # Servidor REST local (axum): handlers, models, routes, openapi
│ ├── commands/ # Comandos Tauri expostos ao frontend
│ └── lib.rs # Tray, atalhos globais, servidor OAuth, janelas
├── capabilities/ # Permissões por janela (default.json)
├── migrations/ # Migrações SQLite
└── Cargo.toml
.github/
├── workflows/ci.yml # Testes e lint em todo push/PR
└── workflows/release.yml # Build multiplataforma e publicação de release
-
Antes de criar um branch, verifique se há branches antigas já mergeadas para limpar:
git branch --merged main | grep -v '^\* \| main$' # apague as desnecessárias: git branch -d nome-da-branch
-
Crie um branch a partir de
main:git checkout -b feat/nome-da-feature # ou git checkout -b fix/nome-do-bug -
Implemente a mudança. Se adicionar lógica de domínio ou utilitários puros, escreva testes.
-
Verifique antes de abrir PR:
pnpm tsc --noEmit # sem erros de tipo pnpm test # todos os testes passando pnpm lint # sem warnings de lint
-
Abra um Pull Request contra
main. O CI valida automaticamente os três passos acima. -
Após o merge, apague o branch local:
git branch -d nome-da-feature
O projeto usa commits semânticos:
| Prefixo | Uso |
|---|---|
feat: |
Nova funcionalidade |
fix: |
Correção de bug |
refactor: |
Refatoração sem mudança de comportamento |
test: |
Adição ou correção de testes |
docs: |
Documentação (CLAUDE.md, README.md) |
chore: |
Configuração, dependências, CI |
maindeve sempre compilar e ter todos os testes passando- PRs pequenos e focados são preferidos a PRs grandes
- Não faça commit de
.envou arquivos com credenciais - Siga a Clean Architecture:
domain/não importainfra/oupresentation/
O projeto segue Semantic Versioning:
- MAJOR (
v1.0.0): mudanças incompatíveis - MINOR (
v0.2.0): novas funcionalidades retrocompatíveis - PATCH (
v0.1.1): correções de bugs
O projeto usa standard-version para automatizar o bump de versão. Ele atualiza package.json e src-tauri/tauri.conf.json atomicamente, gera o CHANGELOG e cria a tag Git.
1. Execute o script de release:
pnpm release:patch # v0.1.0 → v0.1.1
pnpm release:minor # v0.1.0 → v0.2.0
pnpm release:major # v0.1.0 → v1.0.0Isso cria um commit chore(release): x.y.z com todos os arquivos de versão atualizados e a tag vx.y.z localmente.
2. Faça push do commit e da tag:
git push origin main --follow-tagsO workflow release.yml dispara automaticamente, builda para Linux e Windows em paralelo, e cria um rascunho de release no GitHub com os instaladores anexados.
3. Publique o release:
Acesse Releases no repositório, revise o rascunho e clique em Publish release.