Geek Social — Documentação
Módulos

Rolê (Eventos)

Sistema de encontros entre usuários — presencial ou online, com inscrição, lista de espera, lembretes 48h/2h, e cancelamento.

Visão geral

Rolê é o sistema de encontros do Geek Social. Qualquer usuário cria um Rolê (presencial ou online) e outros se inscrevem. Cobre desde mesa fechada de RPG entre 4 amigos até lançamento aberto de jogo numa cafeteria.

Três tipos de visibilidade:

  • public — qualquer usuário logado vê e pode se inscrever
  • friends — só amigos do anfitrião
  • invite — só usuários explicitamente convidados (tabela event_invites)

Tempo é definido como início + duração (dropdown fechado: 60, 120, 180, 240, 360, 600 minutos). ends_at é persistido como starts_at + duration pra simplificar índices e checagem de conflito.

Entidades principais

TabelaPapel
eventsContainer do Rolê (anfitrião, capa, datas, status, capacidade)
event_addresses1:1 condicional pra rolês presencial (CEP, logradouro, cidade…)
event_online_details1:1 condicional pra rolês online (link da reunião + detalhes)
event_participantsN:N com status (subscribed/confirmed/waitlist/left)
event_invitesMaterializa quem foi convidado em rolês visibility=invite

Endpoints

14 rotas em /events:

Eventos (7): create, list (descoberta com filtros), get detail, update (host only), cancel (host only), my hosted, my attending.

Participantes (4): subscribe, leave, confirm presence (resposta ao lembrete T-48h), list participants.

Convites (3): invite users, revoke invite, list invites — todos host only.

Fluxos

Criar Rolê presencial com capa

Inscrever-se com waitlist e auto-promoção

Quando alguém sai de um Rolê com capacidade cheia:

Confirmação T-48h

Worker event.reminder_48h dispara automaticamente 48h antes do início. Pra cada participante ainda em subscribed/confirmed, cria notificação event_reminder_48h com ação requerida: o usuário clica Confirmar (status → confirmed) ou Sair (status → left). Se ignorar, segue como subscribed — não há auto-remoção. Worker pula evento se status virou cancelled ou ended.

Worker event.reminder_2h dispara 2h antes — só ping informativo, sem ação.

Edição com notificação automática

Anfitrião faz PATCH /events/:id. Se algum campo sensível mudou — startsAt, durationMinutes, type, endereço, meetingUrl, capacity, visibility — service:

  1. Persiste a mudança em transação
  2. Reagenda jobs de lembrete (cancela antigos, cria novos)
  3. Notifica todos os inscritos com event_updated (payload inclui lista de campos alterados)
  4. Pra cada inscrito, re-checa conflito; se passou a conflitar com outro Rolê dele, manda event_conflict_after_edit adicional — usuário decide qual manter (sem auto-remoção)

Mudanças em capa/nome/descrição são silenciosas (não notificam).

Cancelamento

Anfitrião faz DELETE /events/:id opcionalmente passando { reason: "..." }. Service marca status=cancelled, cancela jobs pendentes (pgboss.cancelEventJobs(eventId)), e notifica todos os participantes com event_cancelled. Eventos cancelados ficam visíveis (read-only) — não são apagados.

Finalização automática

Cron horário roda UPDATE events SET status='ended' WHERE status='scheduled' AND ends_at < now(). Eventos passados ficam visíveis no perfil de quem participou e no detalhe do próprio Rolê, mas botões de inscrição ficam desabilitados.

Notificações

7 tipos novos no enum notification_type:

TipoDisparado quandoAção
event_reminder_48hT-48h, pra cada subscribed/confirmedConfirmar / Sair
event_reminder_2hT-2h, pra cada subscribed/confirmedsó ping
event_cancelledAnfitrião cancelasó ping
event_updatedCampo sensível editadosó ping (inclui changedFields)
event_conflict_after_editEdição criou conflito com outro rolê do usersó ping
event_promoted_from_waitlistVaga liberou e user subiu da filasó ping
event_invitedConvidado pra rolê com visibility=invitesó ping

Todas seguem o pipeline existente: row em notifications + emit via Socket.io (chatGateway.emitNotification).

Códigos de erro

EventsError.code:

  • 403: NOT_HOST, NOT_INVITED, EVENT_CANCELLED, NOT_FRIEND_OF_HOST
  • 404: EVENT_NOT_FOUND, PARTICIPATION_NOT_FOUND
  • 409: TIME_CONFLICT, ALREADY_SUBSCRIBED, EVENT_ALREADY_STARTED
  • 422: INVALID_DURATION, INVALID_CAPACITY, MISSING_ADDRESS_FOR_PRESENCIAL, MISSING_MEETING_URL_FOR_ONLINE

Limitações conhecidas (alpha)

  • Sem comentários/chat dentro do Rolê — usuários conversam via DM
  • Sem recorrência (rolê semanal precisa ser recriado)
  • Sem export pra calendário externo (.ics / Google Calendar)
  • Sem geolocalização — filtro por cidade é texto livre
  • Capa é obrigatória (sem galeria pré-definida)
  • Soft-delete de user remove os Rolês dele (cascade) — em revisão pra v2

On this page