altarra/README.md
2026-01-08 18:18:26 +00:00

179 lines
No EOL
6.1 KiB
Markdown

# 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
- Edição de configuração em tempo real (Meet ID, Auth String, etc)
- Upload de CSV e logo sem recompilar a aplicação
- Visualização de estatísticas (quantos atletas estão no ficheiro, etc)
- Suporta múltiplas competições apenas trocando ficheiro CSV e configuração
### 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
```bash
npm install
```
### 2. Configurar
Edita `src/config/config.json`:
```json
{
"meetId": "seu-meet-id-do-liftingcast",
"csvFileName": "seu-ficheiro.csv",
"authString": "palavra-passe-segura",
"adminPassword": "password-admin",
"competitionName": "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
```bash
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/ # Config e upload (admin)
layout.tsx
page.tsx # Página principal
components/ # UI reutilizável
config/ # config.json (não commitar!)
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
- Upload de novo CSV (troca automática)
- Upload de logo
- Editar todas as configurações (Meet ID, Auth String, etc) sem tocar em ficheiros
As mudanças levam efeito imediatamente.
## 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
- Variáveis de ambiente: a app lê de `src/config/config.json`, portanto não precisa .env (mas podes adicionar se quiseres)
- 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`
- 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 `authString` em config.json. 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