components.layouts.app: @stack('head'); página pública do Play Card faz @push com <meta name="robots" content="noindex, nofollow">.RegeneratePlayerPublicCardShareUrlAction + MyCard::regenerateShareLink (com wire:confirm); painel de partilha com wire:key para atualizar o URL no Alpine.ExportVenueAcademyAttendanceCsvAction + ExportVenueAcademyAttendanceCsvController: download CSV (UTF-8 BOM) com colunas turma, data da sessão, nome e email do aluno, estado (label PT). Filtro opcional por intervalo de datas da sessão (from/to); validação (ambas ou nenhuma; from ≤ to; máx. 731 dias). Autorização: manageAcademy na action.GET /venues/{venue}/training-classes/attendance.csv (venues.training-classes.attendance-csv); na lista de turmas: formulário GET com from/to (intervalo) e ligação «Histórico completo» (sem query).Fechar itens de risco/operacional: SEO mínimo no link público, revogação de link antigo, exportação para dono da arena.
vendor/bin/sail artisan test tests/Feature/Player/PublicPlayCardRouteTest.php tests/Feature/Venue/ExportVenueAcademyAttendanceCsvTest.php/p/{token} → ver fonte com noindex.