Submissão automática de alturas da barra diretamente ao LiftingCast.
Find a file
2026-01-08 19:52:22 +00:00
public/branding First code commit 2026-01-08 18:18:26 +00:00
scripts issues 2026-01-08 19:52:22 +00:00
src we ball 2026-01-08 19:48:13 +00:00
.gitignore git ignore 2026-01-08 19:06:38 +00:00
LICENSE Initial commit 2026-01-08 09:24:50 +00:00
next-env.d.ts First code commit 2026-01-08 18:18:26 +00:00
next.config.mjs First code commit 2026-01-08 18:18:26 +00:00
package-lock.json updates and clean of commit history due to issues... 2026-01-08 19:06:37 +00:00
package.json issues 2026-01-08 19:52:22 +00:00
postcss.config.js First code commit 2026-01-08 18:18:26 +00:00
README.md we ball 2026-01-08 19:48:13 +00:00
tailwind.config.ts updates and clean of commit history due to issues... 2026-01-08 19:06:37 +00:00
tsconfig.json updates and clean of commit history due to issues... 2026-01-08 19:06:37 +00:00

Altarra

Submissão automática de alturas da barra diretamente ao LiftingCast. Sem papéis, sem complica, tudo online durante a competição.

O que é isto?

O Altarra é uma aplicação web rápida e segura que permite aos atletas submeterem as alturas do rack enquanto estão na zona de aquecimento. Em vez de andar com papéis, cada um acede à plataforma pelo telemóvel, identifica-se com o nome e data de nascimento, e submete as alturas. Pronto.

A plataforma sincroniza automaticamente com o LiftingCast, portanto os árbitros e técnicos têm tudo actualizado em tempo real.

Funcionalidades

Para os Atletas

  • Identificação por nome e data de nascimento (com busca inteligente)
  • Submissão de alturas em dois passos: primeiro identificação, depois as alturas
  • Interface mobile-friendly (pensada para telemóvel, funciona bem em desktop também)
  • Mensagens de erro claras em português
  • Confirmação visual com animação de checkmark quando submete
  • Spinner a carregar enquanto a app trabalha (para não parecer que está preso)

Para os Organizadores

  • Painel de administração em http://seu-dominio.pt/admin
  • Upload de CSV e logo sem recompilar a aplicação
  • Visualização de estatísticas (quantos atletas estão no ficheiro, etc)
  • Configuração lida do .env (Meet ID, Auth String, etc)
  • Suporta múltiplas competições apenas trocando ficheiro CSV e valores no .env

Técnico

  • Autenticação por URL param (?auth=...) - é seguro, não expõe credenciais
  • Busca de atletas com matching inteligente (case-insensitive, sem acentos, parcial)
  • Verificação de data de nascimento para confirmar identidade
  • API interna que faz proxy para LiftingCast (a chave de integração fica segura no servidor)
  • Nenhum ficheiro sensível (CSV, config, credenciais) está acessível publicamente
  • Design responsivo com Tailwind, estilos inspirados na bandeira portuguesa (verde + vermelho)

Instalação e Setup

1. Clonar e instalar

npm install

2. Configurar

Copia .env.example para .env e preenche:

MEET_ID=seu-meet-id-do-liftingcast
CSV_FILE_NAME=seu-ficheiro.csv
AUTH_STRING=palavra-passe-segura
ADMIN_PASSWORD=password-admin
COMPETITION_NAME=Nome da sua Competição

Copia o teu CSV para src/data/seu-ficheiro.csv (o formato esperado está documentado em baixo).

Coloca a logo em public/branding/logo.png.

3. Rodar localmente

npm run dev

Depois acede a http://localhost:3000?auth=palavra-passe-segura

Estrutura do Projeto

src/
  app/
    admin/          # Painel de admin
      page.tsx
    api/
      auth/         # Valida o auth param
      find-lifter/  # Busca atleta no CSV
      submit/       # Submete ao LiftingCast
      admin/        # Upload e stats
    layout.tsx
    page.tsx        # Página principal
  components/       # UI reutilizável
  data/             # Ficheiros CSV (não commitar!)
  services/         # Lógica de server (stats, etc)
  types/            # TypeScript types
  utils/            # Helpers (validation, normalization)
public/
  branding/         # Logo da competição

Fluxo da Aplicação

  1. Login: O utilizador acede com ?auth=... ou vê a página de boas-vindas se não tem autorização
  2. Identificação: Insere nome completo e data de nascimento
  3. Busca: A app procura no CSV, verifica data, e confirma identidade
  4. Alturas: Se encontrado, preenche as alturas (agachamento, supino, blocos)
  5. Submissão: Envia ao LiftingCast, mostra confirmação com checkmark
  6. Reutilização: Pode submeter outro atleta ou as mesmas alturas de novo

Painel de Admin

Acede a /admin com a tua password.

Daqui podes:

  • Ver quantos atletas estão carregados (e valores atuais de configuração)
  • Upload de novo CSV (troca automática)
  • Upload de logo

Nota: a configuração (Meet ID, Auth String, etc.) é lida do .env e não pode ser editada via UI.

Ficheiro CSV

Esperamos um CSV com estas colunas (extraído do LiftingCast):

name, birthDate, memberNumber, ... (outras colunas ignoradas)

Formato de data: DD/MM/YYYY

O matching de nomes é flexible:

  • Não liga a maiúsculas/minúsculas
  • Remove acentos (então "João" encontra "JOAO")
  • Busca parcial (então "João Silva" encontra "JOÃO MANUEL SILVA")

Segurança

  • A chave do LiftingCast fica no servidor (nunca vai para o cliente)
  • O CSV não está disponível via URL
  • Auth é por query param seguro (ideal para QR codes)
  • Validação de campos obrigatórios no servidor
  • Sem SQL injection, XSS, ou outras brincadeiras - tudo sanitizado

Deploy (Coolify, Vercel, ou outro)

Se usas Docker/Coolify:

  • Mount src/data/ e public/branding/ como volumes, assim podes trocar ficheiros sem rebuild
  • Define as variáveis de ambiente (MEET_ID, CSV_FILE_NAME, AUTH_STRING, ADMIN_PASSWORD, COMPETITION_NAME)
  • Build: npm run build, run: npm start

Se usas Vercel:

  • Coloca o CSV em src/data/ antes de fazer push
  • A logo em public/branding/logo.png
  • Define as variáveis de ambiente no painel da Vercel
  • Deploy automático no push

Desenvolvimento

Estrutura de pastas pensada para crescer:

  • Components reutilizáveis em src/components/
  • Lógica de server em src/services/ e src/app/api/
  • Tipos TS centralizados em src/types/
  • Validação e helpers em src/utils/

Adiciona "use client" no topo de ficheiros que usem useState, useEffect, event handlers, etc.

Troubleshooting

"Não conseguo fazer upload do CSV": Verifica se o ficheiro está bem formatado (CSV simples, não Excel). A password de admin está correcta?

"Ninguém consegue aceder à form": Verifica se o auth param na URL é igual ao AUTH_STRING no .env. Gera um QR code e testa.

"A logo não aparece": Coloca o ficheiro em public/branding/logo.png (ou outro nome) e actualiza o código se o nome for diferente.

"A app está lenta": Se há centenas de atletas, adiciona caching do CSV em memória no servidor. Contacta o suporte.

Licença e Créditos

Feito por comfy.solutions para a APP (Associação Portuguesa de Powerlifting).

Podes reportar bugs e sugestões em https://comfy.fillout.com/altarra-errors