| public/branding | ||
| scripts | ||
| src | ||
| .gitignore | ||
| LICENSE | ||
| next-env.d.ts | ||
| next.config.mjs | ||
| package-lock.json | ||
| package.json | ||
| postcss.config.js | ||
| README.md | ||
| tailwind.config.ts | ||
| tsconfig.json | ||
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
- Login: O utilizador acede com ?auth=... ou vê a página de boas-vindas se não tem autorização
- Identificação: Insere nome completo e data de nascimento
- Busca: A app procura no CSV, verifica data, e confirma identidade
- Alturas: Se encontrado, preenche as alturas (agachamento, supino, blocos)
- Submissão: Envia ao LiftingCast, mostra confirmação com checkmark
- 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/epublic/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/esrc/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