# 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 ```bash 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 ```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/ # 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