Blog
Architecture
18 de dezembro de 202510 min

Esquema de gamificação PostgreSQL: 5 tabelas, 12 níveis

Pontos chave a reter: Um sistema de gamificação robusto baseia-se num esquema PostgreSQL dedicado com 5 tabelas, RPCs atómicas transacionais e uma progressão calibrada em 12 níveis. O segredo: isolar a gamificação no seu próprio esquema, limitar as sequências a 365 dias para evitar o vício e tornar tudo atómico para garantir a consistência dos dados.

A gamificação parece simples à superfície. Pontos, distintivos, um placar — parece fácil, não é? Na realidade, assim que começamos a modelar seriamente, a complexidade explode. Para o TAMSIV, eu queria um sistema completo: níveis, distintivos, sequências, desafios diários, histórico de pontos e um feed de atividade. Tudo em PostgreSQL, com garantias transacionais.

Aqui está como concebi o esquema de gamificação do TAMSIV, tabela por tabela, decisão por decisão.

Esquema de base de dados complexo desenhado num quadro branco com post-its coloridos e setas
O design do esquema de gamificação: muitos post-its antes da primeira linha de SQL.

Porquê um esquema PostgreSQL dedicado para a gamificação?

O TAMSIV já utiliza dois esquemas no Supabase: privat para os dados do utilizador (tarefas, notas, eventos) e collaborative para as funcionalidades de grupo. Eu poderia ter adicionado as tabelas de gamificação em privat. Mas não o fiz.

O esquema gamification é um esquema dedicado e isolado. Porquê?

  • Separação de responsabilidades: a gamificação tem as suas próprias políticas RLS (Row Level Security), as suas próprias funções RPC, os seus próprios índices. Não há mistura com a lógica de negócio.
  • Evolução independente: posso modificar o sistema de pontos ou adicionar distintivos sem o risco de quebrar a criação de tarefas.
  • Performance: as consultas de gamificação (placar, classificação, estatísticas) não partilham os índices com as tabelas de conteúdo.
  • Segurança: as políticas RLS de gamificação são mais simples — um utilizador vê apenas as suas próprias estatísticas. Não há permissões de grupo para gerir.

Esta abordagem segue o princípio de separação de esquemas recomendado pelo PostgreSQL. Cada esquema é um namespace que isola as tabelas, funções e políticas de segurança.

Quais são as 5 tabelas do esquema de gamificação?

O esquema completo baseia-se em 5 tabelas interligadas:

1. user_stats — o painel de controlo de cada jogador

Esta é a tabela central. Armazena o estado atual de cada utilizador:

  • total_points: a pontuação acumulada desde o início
  • current_level: o nível atual (1 a 12+)
  • current_streak: o número de dias consecutivos de atividade
  • max_streak: o recorde pessoal de sequência
  • last_activity_date: a data da última atividade (para o cálculo da sequência)
  • streak_freeze_count: o número de "congelamentos" de sequência disponíveis

Porquê armazenar o nível em vez de o calcular em tempo real? Porque a verificação do nível implica uma comparação com os limiares, e esta verificação deve ser atómica com a adição de pontos. Se o cálculo fosse feito no lado do cliente, haveria risco de inconsistências.

2. user_badges — a coleção de conquistas

Uma relação muitos-para-muitos entre utilizadores e distintivos. Cada linha regista:

  • O ID do distintivo (entre os 10 distintivos disponíveis)
  • A data de obtenção
  • O contexto de obtenção (que ação desencadeou o distintivo)

Os distintivos no TAMSIV recompensam comportamentos específicos: primeira nota de voz, 10 tarefas concluídas, 7 dias de sequência, etc. Nunca são removidos — um distintivo obtido é para sempre.

3. points_history — o registo de cada ganho

Cada ganho de pontos é registado individualmente. Esta tabela é essencial para:

  • A análise (quais ações geram mais pontos?)
  • A depuração (um utilizador contesta a sua pontuação? Temos o rasto)
  • Os desafios diários (verificação das condições)
  • O feed de atividade (exibição cronológica dos ganhos)

4. daily_challenges — um desafio por dia

Todos os dias, cada utilizador recebe um desafio personalizado. A tabela armazena:

  • O tipo de desafio (criar X tarefas, usar a voz, completar uma nota, etc.)
  • O objetivo numérico (3 tarefas, 5 notas, etc.)
  • A progressão atual
  • O estado (em curso, completo, expirado)

Os desafios são gerados por uma função RPC que leva em conta o nível do utilizador — um iniciante recebe desafios mais simples do que um jogador de nível 10.

5. feed_activity — o fluxo social

O feed de atividade exibe as ações recentes: distintivos obtidos, níveis alcançados, sequências notáveis. É a dimensão social da gamificação — ver outros utilizadores a progredir motiva.

Troféu dourado rodeado de distintivos e medalhas coloridas numa secretária de madeira escura
Distintivos, troféus, níveis: a gamificação torna cada ação visível e gratificante.

Como funcionam os 12 níveis de progressão?

O sistema de níveis é o coração da gamificação. Os limiares de pontos para cada nível:

[0, 100, 250, 500, 1000, 2000, 3500, 5500, 8000, 12000, 17500, 25000]

Esta progressão segue uma curva exponencial suavizada. Os primeiros níveis são voluntariamente fáceis:

  • Níveis 1-3 (0 a 250 pontos): alcançáveis em 2-3 dias de uso normal. Esta é a fase de onboarding — o utilizador descobre o sistema e recebe gratificações rápidas.
  • Níveis 4-7 (500 a 3500 pontos): a fase de engajamento. 1 a 4 semanas. O utilizador integrou o TAMSIV na sua rotina.
  • Níveis 8-10 (5500 a 12000 pontos): a fase de mestria. Vários meses. Estes níveis são um sinal de forte retenção.
  • Níveis 11-12 (17500 a 25000 pontos): os "realizadores". Menos de 5% dos utilizadores os alcançam.

Além do nível 12? Uma fórmula matemática assume o controlo: limiar = 25000 + (nível - 12) * 10000. Isso evita codificar centenas de níveis, permitindo uma progressão infinita.

Esta calibração inspira-se nos trabalhos de Yu-kai Chou sobre o framework Octalysis, que recomenda recompensas imediatas no início do percurso e uma dificuldade progressiva para manter o engajamento a longo prazo.

Porquê as funções RPC devem ser atómicas?

Quando um utilizador completa uma tarefa no TAMSIV, o seguinte deve acontecer no lado da gamificação:

  1. Adicionar os pontos correspondentes
  2. Verificar se o limiar do próximo nível foi atingido
  3. Atualizar a sequência (dia consecutivo de atividade)
  4. Verificar se novos distintivos foram desbloqueados
  5. Atualizar o progresso do desafio diário
  6. Registrar o histórico de pontos

Se a etapa 3 falhar depois que a etapa 1 for bem-sucedida, os dados ficam inconsistentes. É por isso que todas essas operações são encapsuladas em funções PostgreSQL transacionais. Ou tudo é bem-sucedido, ou tudo falha.

A função principal record_task_completed orquestra tudo numa única transação:

  • add_gamification_points — adiciona os pontos e registra o histórico
  • check_and_update_streak — atualiza a sequência com gestão de fusos horários
  • check_and_unlock_badges — verifica as condições de cada distintivo

No frontend, o GamificationService (singleton) chama esses RPCs e gerencia as notificações locais para os distintivos, níveis e marcos de sequência.

Como gerir as sequências sem tornar os utilizadores viciados?

As sequências são o mecanismo de gamificação mais poderoso — e o mais perigoso. Uma sequência de 100 dias cria uma pressão enorme para não a "quebrar". É por isso que estabeleci salvaguardas:

  • Limite de 365 dias: após um ano, a sequência é reiniciada. Uma sequência de 500 dias já não é gamificação — é vício por design.
  • Congelamentos de sequência: o utilizador pode "congelar" a sua sequência por um dia (férias, doença). O número de congelamentos disponíveis aumenta com o nível.
  • Sem punição: perder uma sequência não remove pontos nem distintivos. Apenas reinicia o contador.

A gestão dos fusos horários é um quebra-cabeças técnico. Um utilizador em Paris e um utilizador em Tóquio não têm o mesmo "dia". A deteção de quebra de sequência é feita comparando last_activity_date com a data atual no fuso horário do utilizador, não em UTC.

Escadaria luminosa progressiva simbolizando os níveis de progressão num jogo
A progressão por níveis: cada degrau é uma vitória visível para o utilizador.

Como o frontend consome a gamificação?

O GamificationService é um singleton que centraliza todas as interações do frontend com o esquema de gamificação:

  • Chamadas RPC: cada conclusão de tarefa ou criação de nota desencadeia uma chamada para record_task_completed ou record_memo_created.
  • Notificações locais: através de NotificationService.notifyAchievement(), o utilizador é notificado sobre distintivos, subidas de nível e marcos de sequência.
  • Cache otimizada: as estatísticas do utilizador são armazenadas em cache localmente para evitar uma chamada ao Supabase a cada exibição do perfil.
  • Feed em tempo real: o feed de atividade utiliza Supabase Realtime para exibir as conquistas de outros utilizadores em direto.

A integração no Dictaphone é transparente: quando a IA cria uma tarefa por voz, o hook useTaskDetail chama automaticamente o GamificationService na conclusão. O utilizador não precisa de fazer nada — os pontos caem naturalmente.

Que métricas monitorizar para ajustar a gamificação?

A tabela points_history permite analisar detalhadamente:

  • Distribuição dos níveis: se 80% dos utilizadores estão presos no nível 3, os limiares são demasiado elevados.
  • Taxa de conclusão dos desafios: abaixo de 30%, os desafios são demasiado difíceis. Acima de 90%, demasiado fáceis.
  • Sequência média: um indicador direto de retenção diária.
  • Distintivos mais raros: os distintivos que ninguém obtém devem ser reavaliados.

Tudo é visível no dashboard admin com gráficos Recharts. Isso permite ajustar os limiares em produção sem reimplantar.

Como evitar as armadilhas clássicas da gamificação?

A gamificação mal concebida faz mais mal do que bem. Aqui estão as armadilhas que evitei:

  • Sem placar público: os rankings públicos desmoralizam 95% dos utilizadores para motivar os 5% do topo. O TAMSIV mostra a progressão pessoal, não a competição.
  • Sem gamificação punitiva: perder pontos por inatividade é um dark pattern. No TAMSIV, a inatividade não tem consequências negativas.
  • Pontos significativos: cada ponto corresponde a uma ação real (tarefa criada, nota gravada, sequência mantida). Sem pontos gratuitos por "entrar".
  • Feedback imediato: as notificações de distintivo e de subida de nível chegam instantaneamente, não no final do dia.

Como aplicar este esquema ao teu próprio projeto?

Se tu quiseres implementar um sistema de gamificação semelhante, aqui estão os princípios:

  1. Isola o esquema: não mistures gamificação e lógica de negócio. Um esquema dedicado facilita as migrações e a depuração.
  2. Tudo atómico: cada ação do utilizador que impacta a gamificação deve ser uma transação única.
  3. Calibra a progressão: testa os limiares de níveis com dados reais. Os primeiros níveis devem ser alcançáveis em dias, não em semanas.
  4. Prevê a manutenção: a tabela points_history cresce rapidamente. Prevê uma política de retenção ou arquivamento.
  5. Mede tudo: sem análises, tu não saberás se a tua gamificação motiva ou frustra os teus utilizadores.

FAQ

Quanto tempo é necessário para implementar um sistema de gamificação completo?

Para o TAMSIV, o esquema e os RPCs levaram cerca de 4 dias. A integração frontend (GamificationService, notificações, UI) adicionou 3 dias adicionais. O mais demorado é a calibração dos limiares de níveis, que requer dados reais de utilização.

PostgreSQL é adequado para gamificação ou é necessário Redis?

PostgreSQL é mais do que suficiente para uma aplicação do tamanho do TAMSIV. As funções transacionais garantem a consistência, e os índices em user_stats tornam as consultas rápidas. Redis seria útil apenas para um placar em tempo real com milhões de utilizadores — o que não é o caso aqui.

Como evitar que a gamificação se torne um dark pattern?

Três regras: sem punição por inatividade, sem pressão social através de placar público e um limite nas sequências. A gamificação deve recompensar a ação, não punir a ausência. O congelamento de sequência é um mecanismo de segurança essencial.

Os pontos devem ser os mesmos para todas as ações?

Não. No TAMSIV, completar uma tarefa vale mais do que criar uma nota, e usar a voz dá um bónus. A escala reflete o valor de cada ação para o utilizador. Uma escala plana (tudo vale 10 pontos) não cria nenhuma hierarquia de comportamento.

É preciso exibir os pontos em tempo real ou com atraso?

Em tempo real, sempre. O feedback imediato é a base da gamificação eficaz. No TAMSIV, os pontos são exibidos instantaneamente após cada ação, com uma animação e um som opcional. O atraso mata a dopamina.