Documento vivo. É o cérebro do projecto — orientado a fluxo, jornada do utilizador e propriedade de dados.
O Chronus é uma plataforma inovadora de gestão de tempo voltada para equipes, totalmente focada em produtividade e organização estratégica de tarefas para combater e evitar a procrastinação no ambiente de desenvolvimento e trabalho coletivo.
Este projeto está sendo desenvolvido de forma 100% colaborativa dentro do ecossistema da Comunidade Juninhos. Nosso objetivo primordial é aplicar conceitos modernos de engenharia de software para entregar uma solução robusta, escalável e com impacto real na rotina de times tech.
💡 Nota do Squad: Este README serve como um documento vivo. Ele será atualizado continuamente conforme novas funcionalidades forem integradas nas sprints de 30 dias.
Monorepo estruturado com Turborepo + Bun, seguindo conceitos de modularização, alta coesão e baixo acoplamento:
| Camada | Tecnologia |
|---|---|
| Backend | Laravel + PHP |
| Frontend | React 19 + Vite + Tailwind CSS v4 + Redux Toolkit |
| Admin Frontend | React 19 + Vite + Tailwind CSS v4 |
| Banco de Dados | PostgreSQL + Drizzle ORM |
| Autenticação | JWT + Argon2 |
| Container | Docker + Docker Compose |
📖 Guia completo de setup em
docs/how-to-run.md
Um projeto completo só ganha vida com uma equipe sintonizada. Conheça as mentes por trás do desenvolvimento do Chronus:
| Avatar | Membro | Função / Especialidade | GitHub |
|---|---|---|---|
| Kauê Henrick Wiliam de Jesus Weber | Frontend | kauehenrick | |
| Sabrina | Frontend | SabrinaZ8 | |
| Gustavo Oliveira Souza | Backend | gstvoli | |
| Vitoria Pio Camilo da Silva | Backend | VitoriaPio | |
| Felipe Gomes | Frontend | felipegs0 | |
| Edgar Manuel Janota | Backend | ndulomk |
| Actor | Quem é | O que quer |
|---|---|---|
| Member | Qualquer pessoa da equipa | Saber o que fazer agora, registar o tempo, não perder foco |
| Lead | Líder de sprint ou tech lead | Distribuir tarefas, ver o progresso, identificar bloqueios |
| Admin | Quem criou o workspace | Gerir membros, ver métricas globais, configurar o sistema |
Um utilizador pode ser Member num workspace e Lead noutro. Os papéis são por workspace, não globais.
| Módulo | Responsabilidade |
|---|---|
| Identity | Auth, perfis, workspaces, sessões |
| Tasks | Criação, atribuição, priorização e ciclo de vida de tarefas |
| Kanban | Visualização e movimentação de tarefas por estado |
| Timer | Cronómetros por tarefa, sessões Pomodoro, rastreio de tempo |
| Sprint | Planeamento de ciclos de 30 dias, backlog, capacidade |
| Metrics | Dashboard de produtividade, relatórios anti-procrastinação |
| Badges | Gamificação, insígnias, metas de foco e consistência |
| Notifications | Alertas em tempo real para todos os actores |
| Activity Log | Registo imutável de todas as acções relevantes |
As jornadas são o coração deste documento. Tudo o que o sistema faz serve uma destas jornadas.
[1] Abre o Chronus
↓
[2] Vê o seu painel pessoal:
- Tarefas atribuídas a si
- Tarefas em curso (com cronómetro activo)
- Tarefas bloqueadas
↓
[3] Escolhe uma tarefa → abre o detalhe
↓
[4] Clica "Iniciar" → cronómetro arranca
↓
[5] Trabalha na tarefa
↓
[6] Pausa ou termina o cronómetro
↓
[7] Move a tarefa no kanban (ex: "Em curso" → "Em revisão")
↓
[8] Se bloqueado → marca tarefa como bloqueada + adiciona nota
↓
[9] Fim do dia → vê tempo total registado e resumo das sessões
↓
[10] Acumula streak de foco → desbloqueia badge
Regras desta jornada:
- Um member só pode ter um cronómetro activo de cada vez. Se iniciar outro, o anterior é pausado automaticamente.
- O cronómetro continua mesmo que o member feche o browser — é server-side, não client-side.
- A tarefa não muda de estado automaticamente quando o cronómetro arranca. O member controla o estado.
- O tempo mínimo registado é de 1 minuto. Sessões abaixo disso são descartadas.
[1] Abre o painel de sprint
↓
[2] Vê o backlog: tarefas sem sprint atribuído
↓
[3] Cria novo sprint (nome, datas, capacidade da equipa em horas)
↓
[4] Arrasta tarefas do backlog para o sprint
↓
[5] Distribui tarefas pelos membros (atribuição)
↓
[6] Define prioridades (urgent / high / medium / low)
↓
[7] Inicia o sprint → tarefas ficam visíveis no kanban de todos
↓
[8] Durante o sprint: acompanha o progresso no dashboard
↓
[9] Detecta tarefas paradas há mais de X horas → alerta
↓
[10] Sprint termina → retrospectiva: tarefas entregues vs planeadas
Regras desta jornada:
- Um sprint só pode ser iniciado se tiver pelo menos uma tarefa atribuída.
- Tarefas podem ser movidas entre sprints enquanto o sprint de destino não tiver iniciado.
- Quando um sprint termina, as tarefas não concluídas voltam automaticamente ao backlog.
- O Lead pode ver o tempo real gasto vs estimado por tarefa e por membro.
[1] Abre dashboard de sprint activo
↓
[2] Vê métricas em tempo real:
- Tarefas: to-do / em curso / bloqueadas / concluídas
- Tempo: estimado vs real por membro
- Velocidade: tarefas fechadas por dia
↓
[3] Identifica tarefas bloqueadas → entra no detalhe → lê a nota do member
↓
[4] Desbloqueia: reatribui, divide em sub-tarefas ou remove do sprint
↓
[5] Adiciona comentário na tarefa → member é notificado
↓
[6] Vê quem está sem tarefas activas → redistribui carga
↓
[7] No fim do dia: exporta relatório de progresso
[1] Member abre tarefa
↓
[2] Activa modo Pomodoro (25min foco / 5min pausa)
↓
[3] Cronómetro conta 25 minutos
↓
[4] Notificação: "Pausa de 5 minutos"
↓
[5] Após 4 ciclos → pausa longa de 15 minutos
↓
[6] Sistema regista automaticamente quantos pomodoros foram feitos naquela tarefa
↓
[7] Ao fim do dia: resumo de pomodoros completos → pontos para badge "Foco Profundo"
Regras desta jornada:
- O Pomodoro pode ser interrompido manualmente. O ciclo incompleto não conta para badges mas o tempo é registado.
- O Lead vê no dashboard quantos pomodoros o team completou hoje.
[1] Admin cria workspace (nome, slug único, timezone)
↓
[2] Convida membros via email (link de convite com expiração de 72h)
↓
[3] Membros aceitam o convite → criam conta → entram no workspace
↓
[4] Admin atribui roles: Member ou Lead
↓
[5] Admin configura o kanban (estados por defeito ou customizados)
↓
[6] Admin define a duração do sprint padrão (7, 14 ou 30 dias)
↓
[7] Primeiro sprint criado pelo Lead → sistema está operacional
Esta jornada não é accionada por um humano — é o sistema a agir proactivamente.
[1] Sistema verifica continuamente:
- Tarefas "Em curso" sem actividade de cronómetro há mais de 4h
- Tarefas não movidas no kanban há mais de 2 dias
- Membros sem nenhum cronómetro activo durante horas de trabalho
↓
[2] Gera alertas internos (não spam — máximo 1 alerta por tarefa por dia)
↓
[3] Notifica o Lead: "3 tarefas parecem estar paradas"
↓
[4] Notifica o Member: "Tens uma tarefa em curso sem tempo registado há 4h"
↓
[5] Regista o evento no activity log para análise posterior
↓
[6] No relatório semanal: mostra padrões de procrastinação por membro e por tipo de tarefa
users — tabela global de todos os utilizadores.
Campos chave: email, name, avatar_url, password_hash, google_id (OAuth), timezone, status (active | suspended), created_at.
workspaces — cada equipa tem um workspace isolado.
Campos chave: name, slug (único globalmente, ex: juninhos-chronus), owner_id (FK → users), sprint_duration_days (7 / 14 / 30), timezone, kanban_config (jsonb — estados customizados), created_at.
workspace_members — relação entre user e workspace.
Campos chave: workspace_id, user_id, role (admin | lead | member), invited_by (FK → users), joined_at, status (active | suspended).
invites — convites pendentes para entrar no workspace.
Campos chave: workspace_id, email, role, token (único, hash), invited_by, expires_at, accepted_at (nullable).
sessions — sessões autenticadas.
Campos chave: user_id, token_hash, device_info, ip_address, expires_at, last_active_at.
tasks — a unidade central do sistema.
Campos chave: workspace_id, sprint_id (nullable — null significa backlog), title, description, status (backlog | todo | in_progress | in_review | blocked | done | cancelled), priority (urgent | high | medium | low), assignee_id (FK → users, nullable), created_by (FK → users), estimated_minutes (nullable), actual_minutes (calculado a partir de time_entries), due_date, tags (jsonb array), position (número de ordem no kanban — para drag & drop), is_blocked, blocked_reason, blocked_since.
Sem sub-tarefas na fase 1. Uma tarefa é atómica. Se for grande demais, o Lead divide em múltiplas tarefas.
task_comments — comentários contextuais numa tarefa.
Campos chave: task_id, author_id (FK → users), content, created_at, edited_at (nullable).
task_history — registo imutável de todas as mudanças de estado de uma tarefa.
Campos chave: task_id, changed_by (FK → users), field (ex: status, assignee_id, priority), old_value, new_value, changed_at.
O Kanban não tem tabela própria — é uma view sobre tasks, filtrada por workspace_id + sprint_id, agrupada por status e ordenada por position.
Estados por defeito:
| Estado | Descrição |
|---|---|
todo |
Tarefa planeada para este sprint, não iniciada |
in_progress |
Cronómetro activo ou recentemente activo |
in_review |
Aguarda revisão de outro membro |
blocked |
Impedimento identificado |
done |
Concluída e aceite |
O Admin pode renomear os estados ou adicionar estados intermédios (ex: in_qa, waiting_deploy). A configuração vive em workspaces.kanban_config.
Regra de posição: position é um número de vírgula flutuante (ex: 1.0, 2.0, 1.5) para permitir inserção entre items sem reordenar tudo — padrão LexoRank simplificado, como usa o Linear e o Jira.
time_entries — cada sessão de trabalho numa tarefa.
Campos chave: task_id, user_id, workspace_id, started_at, ended_at (nullable — null significa cronómetro activo), duration_seconds (calculado ao fechar), type (manual | timer | pomodoro), pomodoro_count (número de ciclos completos, para type=pomodoro), notes (opcional).
duration_seconds é sempre calculado no servidor quando ended_at é preenchido. O cliente não envia a duração — envia o ended_at e o servidor calcula. Protege contra manipulação.
Regra de concorrência: O sistema verifica, antes de criar um novo time_entry com ended_at = null, se o utilizador já tem algum entry activo naquele workspace. Se sim, fecha o anterior automaticamente com ended_at = now().
active_timers — cache em memória (Redis) dos cronómetros activos. Não é a fonte de verdade — é só para performance de leitura.
Campos chave: user_id, task_id, started_at, ttl (renovado a cada heartbeat do cliente).
Se o cliente fechar o browser sem parar o cronómetro, o TTL expira e o sistema fecha o time_entry automaticamente com ended_at = last_heartbeat_at.
sprints — ciclo de trabalho da equipa.
Campos chave: workspace_id, name (ex: "Sprint 1 — Autenticação"), status (draft | active | completed | cancelled), started_at, ends_at, created_by (FK → users), capacity_hours (estimativa de horas disponíveis da equipa), goal (texto livre — o objectivo do sprint), retrospective_notes (preenchido ao fechar o sprint).
Apenas um sprint pode estar active por workspace de cada vez.
sprint_metrics — snapshot calculado ao fechar o sprint. Não é recalculado — é imutável.
Campos chave: sprint_id, total_tasks_planned, total_tasks_completed, total_tasks_carried_over (voltaram ao backlog), total_time_logged_seconds, completion_rate (%), members_snapshot (jsonb — contribuição por membro neste sprint).
O módulo de métricas não tem tabelas próprias na maioria dos casos — é servido por queries sobre time_entries, tasks e task_history.
daily_snapshots — agregação diária por workspace. Calculada no fim de cada dia (job nocturno). Para performance — evita recalcular histórico.
Campos chave: workspace_id, date, tasks_created, tasks_completed, tasks_blocked, total_time_seconds, active_members (quantos membros registaram pelo menos 1 entrada), pomodoros_completed.
Métricas em tempo real (calculadas on-demand, sem snapshot):
- Tempo total por membro hoje
- Tarefas por estado agora
- Cronómetros activos agora
Métricas de procrastinação (calculadas no job nocturno):
- Tarefas
in_progresssemtime_entriesnas últimas 4h - Tarefas sem mudança de estado há mais de 2 dias
- Membros sem actividade no dia
badge_definitions — catálogo de todas as insígnias possíveis. Gerido pelo sistema (não pelos utilizadores).
Campos chave: code (único, ex: focus_first_pomodoro), name, description, icon_url, category (focus | consistency | speed | collaboration | milestone), condition (jsonb — critérios para desbloquear: ex: {"type": "pomodoros_completed", "threshold": 1}).
user_badges — insígnias desbloqueadas por um utilizador num workspace.
Campos chave: user_id, workspace_id, badge_code (FK → badge_definitions), unlocked_at, context (jsonb — ex: {"sprint_id": 3, "task_id": 42}).
Exemplos de badges:
| Badge | Condição |
|---|---|
| 🍅 Primeiro Foco | Completar o primeiro Pomodoro |
| 🔥 Em Chama | 7 dias consecutivos com pelo menos 1 Pomodoro |
| ⚡ Velocidade | Fechar 5 tarefas num único dia |
| 🧱 Construtor | Registar 100 horas totais no workspace |
| 🎯 Sprint Perfeito | Sprint com 100% de conclusão |
| 🤝 Desbloqueador | Remover o bloqueio de uma tarefa de outro membro |
Regra de desbloqueio: Um job corre a cada hora e verifica condições de badges por utilizador. Se a condição for cumprida e o badge não estiver ainda desbloqueado, cria o registo em user_badges e dispara uma notificação.
notifications — alertas para todos os actores.
Campos chave: recipient_id (FK → users), workspace_id, type (ex: task.assigned, task.blocked, badge.unlocked, sprint.started, timer.idle_alert), title, message, action_url, data (jsonb), is_read, read_at, created_at.
Canais de entrega (fase 1): in-app (polling ou WebSocket). Email apenas para convites e badges importantes.
activity_log — registo imutável de todas as acções relevantes. Nunca se apaga.
Campos chave: workspace_id, actor_id (FK → users), action (ex: task.status_changed, sprint.started, badge.unlocked, timer.started), entity_type, entity_id, old_value (jsonb, nullable), new_value (jsonb, nullable), ip_address, created_at.
O cronómetro parece simples. Não é. É o coração do sistema e tem de ser robusto.
[1] Member clica "Iniciar" numa tarefa
↓
[2] Cliente envia POST /timers/start { task_id }
↓
[3] Servidor verifica se há cronómetro activo para este user no workspace
├── Se sim → fecha o anterior: time_entry.ended_at = now(), calcula duration
└── Se não → continua
↓
[4] Cria time_entry { task_id, user_id, started_at: now(), ended_at: null }
[5] Actualiza active_timers no Redis (TTL: 90 segundos)
↓
[6] Cliente envia heartbeat a cada 60 segundos (renova TTL no Redis)
↓
[7] Member clica "Parar"
→ Cliente envia POST /timers/stop { time_entry_id }
→ Servidor: time_entry.ended_at = now(), duration_seconds calculado
→ Remove de active_timers no Redis
↓
[8] Se cliente fechar o browser sem parar:
→ TTL expira no Redis (após 90 segundos sem heartbeat)
→ Job de limpeza detecta time_entry com ended_at = null e started_at > 90s atrás
→ Fecha automaticamente com ended_at = last_heartbeat_at
Porquê server-side? O Toggl e o Clockify aprenderam da forma difícil: cronómetros client-side perdem-se quando o browser fecha, o telemóvel bloqueia ou a ligação cai. O tempo de trabalho real é precioso — não pode desaparecer.
[1] Member arrasta tarefa de "To Do" para "In Progress"
↓
[2] Cliente calcula nova posição (LexoRank):
nova_posição = (posição_anterior + posição_seguinte) / 2
↓
[3] Cliente envia PATCH /tasks/{id} { status: "in_progress", position: 1.5 }
↓
[4] Servidor valida a transição de estado (ex: não pode ir de "Done" para "In Progress" sem passar por "In Review")
↓
[5] Actualiza task.status e task.position
[6] Cria registo em task_history
↓
[7] Broadcast via WebSocket para todos os membros do workspace:
{ type: "task.moved", task_id, new_status, new_position, moved_by }
↓
[8] Todos os clientes actualizam a sua view em tempo real
Porquê WebSocket aqui? O Slack ensinou que updates em tempo real mudam completamente a experiência colectiva. Quando o Lead vê a tarefa a mover-se no kanban ao mesmo tempo que o member a move, o trabalho deixa de ser assíncrono — passa a ser colaborativo. O Linear usa o mesmo padrão.
ABERTURA:
[1] Lead cria sprint (nome, datas, capacidade)
↓
[2] Lead adiciona tarefas do backlog ao sprint (sprint_id preenchido nas tasks)
↓
[3] Lead clica "Iniciar Sprint"
→ sprint.status = active
→ tasks.status = todo (para todas as tarefas do sprint ainda em backlog)
→ Notificação para todos os membros: "Sprint X iniciado"
↓
[4] Sprint activo: sistema monitoriza tarefas e tempo em tempo real
FECHO:
[5] Data de fim chegou OU Lead fecha manualmente
↓
[6] Sistema calcula sprint_metrics (snapshot imutável)
↓
[7] Tarefas não concluídas → sprint_id = null (voltam ao backlog)
↓
[8] sprint.status = completed
↓
[9] Verifica badges de sprint (ex: "Sprint Perfeito" se completion_rate = 100%)
↓
[10] Lead preenche retrospective_notes
↓
[11] Relatório de sprint disponível para toda a equipa
[1] Job corre a cada hora
↓
[2] Para cada badge_definition activo:
- Lê a condição (ex: { type: "pomodoros_completed", threshold: 10 })
- Corre query para verificar quem cumpriu a condição e ainda não tem o badge
↓
[3] Para cada utilizador elegível:
- Cria registo em user_badges
- Cria notificação: { type: "badge.unlocked", ... }
- Regista em activity_log
↓
[4] Cliente recebe notificação (WebSocket ou polling)
↓
[5] Modal de celebração aparece: "Desbloqueaste: 🔥 Em Chama"
[1] Job corre a cada hora (hora de trabalho: 8h-22h, timezone do workspace)
↓
[2] Detecta tarefas problemáticas:
- SELECT tasks WHERE status = 'in_progress'
AND task_id NOT IN (
SELECT task_id FROM time_entries
WHERE ended_at IS NULL OR ended_at > now() - interval '4 hours'
)
↓
[3] Verifica se já foi enviado alerta para esta tarefa hoje
→ Se sim: skip (máximo 1 alerta por tarefa por dia)
↓
[4] Cria notificação para o assignee: "Tens uma tarefa em curso sem actividade há 4h"
[5] Cria notificação para o Lead: "X tarefas parecem estar paradas"
↓
[6] Regista em activity_log { action: "alert.idle_task_detected" }
O Chronus precisa de tempo real para três casos de uso:
- Kanban colaborativo (todos vêem o board mudar em simultâneo)
- Cronómetros activos visíveis para o Lead
- Notificações instantâneas (badges, alertas, comentários)
O Slack serve tens of millions of WebSocket connections simultâneas. Nós não precisamos de nada disso na fase 1 — mas aprendemos os padrões certos.
- Cliente faz polling a cada 5 segundos para o board activo
- Polling a cada 30 segundos para notificações
- Suficiente para equipas pequenas (até 50 membros por workspace)
- Zero complexidade de infra
- Quando houver volume e a latência do polling se tornar notável
- Cada cliente mantém uma conexão WebSocket persistente
- Servidor publica eventos via pub/sub interno (Redis)
- Eventos:
task.moved,timer.started,badge.unlocked,sprint.updated - Segue o modelo de fan-out do Slack: um evento publicado uma vez, entregue a todos os clientes conectados ao workspace
| Decisão | Escolha | Motivo |
|---|---|---|
| Cronómetro | Server-side | Sobrevive ao fecho do browser — Toggl e Clockify aprenderam da forma difícil |
| Posição no kanban | LexoRank (float) | Inserção entre items sem reordenar — padrão do Linear e Jira |
| Estados do kanban | Configuráveis por workspace | Equipas diferentes têm workflows diferentes — rigidez mata adopção |
| Sub-tarefas | Sem sub-tarefas na fase 1 | Complexidade sem ROI claro para equipas pequenas |
| Sprint | Um activo por workspace | Foco — equipas pequenas não gerem múltiplos sprints em paralelo |
| Métricas anti-procrastinação | Job horário, não real-time | Real-time seria over-engineering; 1h de lag é suficiente para alertas de inactividade |
| Badge check | Job horário | Consistente com o anterior; desbloqueio em 1h é aceitável para gamificação |
| Kanban real-time | Polling na fase 1 | Equipas pequenas toleram 5s de lag; WebSocket na fase 2 quando necessário |
| Roles | Por workspace | Um utilizador pode ser Lead num workspace e Member noutro |
| Contas para entrar | Convite obrigatório | Workspace privado — não é produto público |
| Timezone | Por workspace | Equipas distribuídas têm horários diferentes — alertas de inactividade respeitam o timezone |
| task_history | Imutável | Audit trail permanente — quem mudou o quê e quando |
| sprint_metrics | Snapshot ao fechar | Histórico de sprints não deve mudar com o tempo |
- Integração com GitHub/GitLab — ligar commits a tarefas é útil mas não é blocker para lançar
- Time tracking automático (como o TimeCamp faz, detectando janelas activas) — privacidade e complexidade técnica alta
- Facturação / billable hours — o Harvest e o Toggl fazem isso bem; o Chronus é focado em foco, não em invoicing
- Chat integrado — o Slack existe e integra melhor do que qualquer chat que construíssemos
- Mobile app nativa — Progressive Web App (PWA) na fase 1
- Sub-tarefas — futuro; complica o kanban e o rastreio de tempo sem valor claro agora
- Múltiplos sprints activos em paralelo — foco é o produto; complexidade de planeamento na fase 2
- Exportação para Jira/Linear — futuro, quando houver pedido real da comunidade
- Permissões granulares (além de admin/lead/member) — over-engineering para equipas de 6 pessoas
- Registo com email + password
- Login com Google (OAuth)
- Criação de workspace (nome, slug, timezone)
- Convite de membros por email (token com expiração de 72h)
- Aceitação de convite → criação de conta
- Gestão de roles pelo Admin (promover / remover Lead)
- Logout e invalidação de sessão
- Edição de perfil (nome, avatar, timezone)
- Iniciar cronómetro numa tarefa (um por vez)
- Pausar / retomar cronómetro
- Parar cronómetro e registar tempo
- Modo Pomodoro (25min/5min com notificações)
- Registo manual de tempo (para retroactivo)
- Heartbeat client-side (manter cronómetro vivo)
- Job de limpeza de cronómetros abandonados (TTL expirado)
- Visualização de tempo total do dia
- Criar tarefa (título, descrição, prioridade, estimativa, assignee)
- Mover tarefa entre estados (drag & drop no kanban)
- Atribuir / reatribuir tarefa
- Marcar tarefa como bloqueada + nota de bloqueio
- Adicionar comentário numa tarefa
- Ver histórico de mudanças de uma tarefa
- Filtrar tarefas (por assignee, prioridade, estado, tags)
- Adicionar tarefa ao backlog (sem sprint)
- Estados de kanban configuráveis pelo Admin
- Criar sprint (nome, datas, capacidade em horas, objectivo)
- Adicionar tarefas do backlog ao sprint
- Iniciar sprint → notificar equipa
- Fechar sprint → calcular métricas, mover não concluídas para backlog
- Ver tarefas por sprint (histórico)
- Retrospectiva: notas do Lead ao fechar o sprint
- Dashboard pessoal: tempo hoje, tarefas activas, streak
- Dashboard de sprint: progresso por estado, tempo por membro
- Alerta de tarefas sem actividade há mais de 4h (job horário)
- Relatório semanal: produtividade, padrões de procrastinação
- Histórico de sprints: completion rate, velocidade da equipa
- Catálogo de badges no sistema (definições iniciais)
- Job de verificação de condições (horário)
- Notificação e modal de celebração ao desbloquear badge
- Perfil de utilizador com badges desbloqueados
- Badges de foco (Pomodoro), consistência (streak), sprint (conclusão)
- Notificação: tarefa atribuída a mim
- Notificação: tarefa bloqueada (para o Lead)
- Notificação: sprint iniciado / fechado
- Notificação: badge desbloqueado
- Notificação: alerta de inactividade
- Marcar notificações como lidas
- Preferências de notificação (o que receber)
- Workspace criado com nome, slug e timezone
- Pelo menos 2 membros convidados e dentro do workspace
- Pelo menos 1 Lead atribuído
- Configuração do kanban revisada (estados por defeito ou customizados)
- Primeiro sprint criado
- Primeiro sprint criado com nome e datas
- Pelo menos 3 tarefas no sprint com assignees definidos
- Sprint iniciado
- Perfil preenchido (avatar, timezone)
- Primeira tarefa iniciada
- Primeiro cronómetro activo
- Primeiro Pomodoro completo
| Métrica | O que mede |
|---|---|
| DAU (Daily Active Users) | Quantos membros registam pelo menos 1 entrada de tempo por dia |
| Tempo médio por sessão | Duração média de um cronómetro — indicador de foco real |
| Taxa de conclusão de sprint | Tarefas concluídas / tarefas planeadas |
| Tarefas bloqueadas em aberto | Indicador de fricção e bloqueios da equipa |
| Pomodoros completados por dia | Proxy de foco colectivo |
| Badges desbloqueados por semana | Engajamento com o sistema de gamificação |
| Tempo médio de uma tarefa em cada estado | Detecta onde o trabalho para — no kanban, em revisão, etc. |
| Alertas de inactividade gerados | Quantas vezes o sistema detectou procrastinação |
Para manter o código limpo e organizado para todo o time, seguimos rigorosamente estas regras de contribuição:
Sempre crie uma ramificação específica para a sua tarefa a partir da branch principal:
feature/nome-da-funcionalidadefix/correcao-de-bugdocs/atualizacao-readme
git checkout -b feature/minha-tarefaOs commits devem ser claros, em português e indicar a intenção da alteração:
feat: adiciona componente de cronometro pomodorofix: corrige vazamento de memoria no painel de metricasstyle: atualiza cores do kanban
- Nunca faça o merge direto na branch principal.
- Abra um Pull Request (PR) e solicite a revisão de pelo menos um outro membro do squad antes de aplicar as alterações.
Nota do Squad: Este documento é atualizado a cada sprint. Funcionalidades marcadas como "fase 2" ou "futuro" não têm data — entram no backlog quando houver pedido real da comunidade ou quando a fase 1 estiver sólida.
Este projeto é de uso exclusivo e educacional dos membros vinculados à Juninhos Community.
Este projeto é desenvolvido e mantido pelos membros da Juninhos Community. Se precisar de suporte técnico, mentoria de deploy ou dúvidas sobre infraestrutura, use os canais oficiais no Discord.
Bora transformar ideias em código! [++]