# 05 - Progresso e Estado Atual > [!IMPORTANT] > **Atenção IA (Agentes):** Este documento é um Registo de Progresso (Living Document). É obrigação de qualquer agente de IA atualizar este ficheiro quando terminar um conjunto de tarefas com sucesso, ou caso depare-se com impedimentos, de forma a passar contexto às próximas iterações. ## O que já foi alcançado (Abril 2026) O projeto sofreu um esforço significativo na estabilização do **Scraper** e da interface de utilizador (UI) na **App Android**. ### No Scraper (Java) - Foi configurada a extração das Tabelas Classificativas (Standings) e cálculos otimizados para garantir dados precisos baseados na AFAVCD. - Alterou-se o endpoint de single-matchday para aceder a todo o calendário de época via `/jorneys` (plural endpoint). - O Scraper está apto a recolher não apenas golos, mas todos os campos vitais de um `Game` (Jornada, Data, Campo de Jogo e URL do Relatório), enviando-os corretamente para o Firebase. - Iniciaram-se trabalhos nos perfis dos jogadores (PlayersScraper), com mapeamento e sincronização em curso. - A Estrutura da class `GameMatch.java` foi mantida inalterada de forma propositada durante o refactoring, para não quebrar a compatibilidade com a schema na base de dados antiga. ### Na App Android (VdcScore) - Interface de "Jornadas" (Matchday Display UI) revista: Desenvolvidos cartões com visual premium (Card-style). - O Data Binding no `MatchesAdapter` foi resolvido para corretamente mapear e mostrar: nomes das equipas, logótipos descarregados com `Glide`, os resultados (scores) e a informação de agendamento do jogo (Data/Campo). - A Autenticação de base (Logins e Registos) está implementada usando o Firebase Authentication. ## Tarefas A Decorrer / Próximos Passos (TODOs) - **Testes Finais de UI:** Garantir que quando campos opcionais do Scraper regressam a `null` (e.g. jogos ainda não marcados não têm Data), a interface Android se comporta silenciosamente (sem Crashes e apresentando estado vazio "A Definir"). - **PlayersScraper:** Completar e validar a ingestão do plantel de todos os clubes para exibir no Menu de "Equipas". - **Sistema Offline:** Melhorar a experiência da App permitindo o Firebase cache persistir localmente quando não há acesso à Internet. - **Push Notifications:** Quando um Scraper deteta um fim de jogo (mudança de estado para 'Terminado'), explorar a hipótese de chamar Firebase Cloud Messaging para notificar a App Android. ## Relatório de Intervenção (Desenvolvimento do Scraper de Jornadas) **Progresso Geral Atualizado** Foi implementada a funcionalidade para recolher e sincronizar detalhadamente todas as jornadas e jogos correspondentes. O scraper agora processa todas as informações de jornadas da API da AFAVCD e insere esses dados na Firebase Realtime Database na respetiva estrutura (`jornadas/{escalao}/{id_jornada}/{id_jogo}`), alimentando os ecrãs da App Android. **O que foi criado ou adicionado** - Adicionada lógica de extração e formatação ao `StandingsScraper.java` para sincronizar as jornadas com a Firebase. - Inclusão dos campos de cada jogo com compatibilidade direta com a classe `Match.java` da App Android (`home_nome`, `away_nome`, `home_logo`, `away_logo`, `home_golos`, `away_golos`, `data`, `hora`, `campo`, `matchReportUrl`). **O que foi modificado e porquê** - Modificou-se o ficheiro `StandingsScraper.java` para reaproveitar a chamada de rede que já estava a ser feita ao endpoint `/jorneys`. Optou-se por introduzir a lógica neste ficheiro, pois ele já contém o mapeamento de clubes (`clubesMap`) necessário para buscar nomes e logótipos através dos IDs das equipas (`homeId`, `awayId`). **O que foi removido** - Nenhuma funcionalidade ou ficheiro foi removido nesta intervenção. Apenas foi expandida a capacidade do código já existente. ## Relatório de Intervenção (Desenvolvimento do Scraper de Melhores Marcadores) **Progresso Geral Atualizado** Foi implementada a funcionalidade para extrair e sincronizar a lista de melhores marcadores (Top Scorers) para os escalões de Seniores e Juniores. Conseguimos identificar o endpoint de "disciplina" da AFAVCD que contém os golos marcados por cada jogador em cada jornada, permitindo calcular o total acumulado. **O que foi criado ou adicionado** - **Novo Modelo:** Criado `TopScorer.java` no projeto Scraper para espelhar a estrutura esperada pela App Android. - **Novo Scraper:** Criado `TopScorersScraper.java` que: - Identifica e acede ao endpoint: `https://api.afavcd.pt/teams/modality/{id}/season/33/discipline`. - Soma os golos de cada jogador através de todas as jornadas. - Faz o mapeamento automático para o nome e logo do clube usando o ID da equipa. - Ordena os marcadores por número de golos. - Sincroniza os dados com o Firebase em `marcadores/{escalao}`. **O que foi modificado e porquê** - A estrutura de classes do projeto Scraper foi expandida para incluir modelos de dados mais granulares (TopScorer), facilitando a manutenção e a paridade com o projeto Android. **O que foi removido** - Nenhuma funcionalidade foi removida. ## Relatório de Intervenção (UI das Jornadas - App Android) **Progresso Geral Atualizado** As jornadas agora são carregadas e exibidas corretamente e de forma ordenada na aplicação Android (Ecrã Jornadas / GalleryFragment). A visualização dos detalhes dos jogos foi também enriquecida permitindo o acesso à "Ficha de Jogo" oficial quando o link é fornecido pelo Scraper. **O que foi criado ou adicionado** - Adicionado o botão "Ficha de Jogo" no layout `item_match.xml` dos cartões de jogo. - Implementada a propriedade `matchReportUrl` (e respetivos getters/setters) no Model `Match.java` garantindo a correspondência `@PropertyName` com os dados guardados na Firebase. - Criada a intenção (Intent) no `MatchesAdapter.java` para abrir o browser nativo e consultar o relatório da partida. **O que foi modificado e porquê** - O `GalleryFragment.java` foi modificado para ordenar as jornadas `matchdaysList` de forma numérica (`Collections.sort`). Isto resolveu o problema em que o Firebase devolvia as chaves ordenadas de forma alfabética (1, 10, 11, 2, 3...) baralhando a navegação sequencial no ecrã. - O `MatchesAdapter.java` foi modificado para suportar a alternância de visibilidade do novo botão de "Ficha de Jogo" consoante a disponibilidade do URL na base de dados. **O que foi removido** - Nenhuma funcionalidade ou ficheiro foi removido nesta iteração, focando-se unicamente em enriquecer a experiência do utilizador. ## Relatório de Intervenção (Ecrã de Melhores Marcadores - App Android) **Progresso Geral Atualizado** Foi criada toda a infraestrutura base e a interface visual para acomodar os "Melhores Marcadores" da liga (Top Scorers). O ecrã foi integrado na navegação principal da App e está desenhado para alternar rapidamente entre Seniores e Juniores. Está agora perfeitamente alinhado com a árvore do Firebase `melhores_marcadores/{escalao}`, aguardando que o Scraper Java inicie a injeção de dados. **O que foi criado ou adicionado** - Novo Model `TopScorer.java` com as propriedades exatas esperadas (`playerName`, `playerPhoto`, `clubName`, `clubLogo`, `goals`, `position`). - Interface de layout (`fragment_top_scorers.xml` e `item_top_scorer.xml`) com um design em formato de cartões premium, suportando a exibição da posição do jogador, foto circular do perfil, logótipo do clube e a contagem de golos. - `TopScorersFragment.java` e `TopScorersAdapter.java` que tratam a lógica de escuta em tempo real do Firebase e fazem a ordenação pela quantidade de golos de forma descendente. - Menu de navegação foi alargado (`mobile_navigation.xml`, `activity_main_drawer.xml`, `MainActivity.java` e `strings.xml`) para incluir a opção lateral visível e interativa "Melhores Marcadores". **O que foi modificado e porquê** - Adicionado ao ficheiro `themes.xml` o estilo auxiliar `ShapeAppearanceOverlay.App.CornerSize50Percent` para garantir que as fotos dos jogadores (`ShapeableImageView`) fiquem perfeitamente circulares sem recurso a bibliotecas externas complexas. **O que foi removido** - Nenhuma funcionalidade removida. O código consiste numa extensão (feature) 100% nova. ## Relatório de Intervenção (Implementação da Secção de Notícias) **Progresso Geral Atualizado** Foi implementado um novo sistema de notícias que permite à app exibir as novidades mais recentes da AFAVCD. O sistema é composto por um scraper que recolhe os dados da API oficial e uma nova interface na app Android que apresenta as notícias num formato de resumo visualmente apelativo (cards), seguindo a estética solicitada. **O que foi criado ou adicionado** - **No Scraper (Java):** - Criado o modelo `News.java`. - Criado o `NewsScraper.java` que extrai dados de `https://api.afavcd.pt/news/1` e sincroniza-os com o nó `noticias` na Firebase. - **Na App Android:** - Adicionado o modelo `News.java` com mapeamento para os campos da Firebase. - Desenvolvido o layout `item_news.xml` com um design premium (Imagens de destaque, títulos em cyan e resumos limpos). - Criado o `fragment_news.xml` com um cabeçalho personalizado e uma `RecyclerView`. - Implementados o `NewsAdapter.java` (com limpeza de tags HTML do corpo da notícia) e o `NewsFragment.java`. - Integrada a nova secção no menu lateral (`activity_main_drawer.xml`), no grafo de navegação (`mobile_navigation.xml`) e configurada como destino de topo na `MainActivity.java`. **O que foi modificado e porquê** - `strings.xml`: Adicionada a label "Notícias" para internacionalização e uso no menu. - `MainActivity.java`: Atualizada a `AppBarConfiguration` para incluir o novo fragmento de notícias, garantindo que o menu lateral esteja disponível em vez do botão de retrocesso. - `mobile_navigation.xml` e `activity_main_drawer.xml`: Atualizados para permitir a navegação para a nova funcionalidade. **O que foi removido** - Nenhuma funcionalidade foi removida. O projeto foi expandido com uma nova feature. ## Relatório de Intervenção (Ecrã de Ínicio / Notícias) **Progresso Geral Atualizado** As notícias foram promovidas a ecrã principal (Ínicio) da aplicação. A secção de notícias é agora a primeira a ser apresentada quando o utilizador abre a app e o ecrã foi sujeito a uma profunda revisão estética para apresentar uma leitura mais imersiva, moderna e limpa (Cards formatados). **O que foi criado ou adicionado** - Nenhuma class nova foi criada. O foco foi estritamente na reorganização e melhoria de UI e UX. - Adicionada lógica de parsing e formatação da data no `NewsAdapter.java` para converter strings ISO complexas (`"2026-04-20T20:05:01.000Z"`) em datas humanamente legíveis e agradáveis (e.g. `20 abr 2026`). **O que foi modificado e porquê** - `strings.xml`: A string `@string/menu_news` foi alterada de "Notícias" para "Ínicio" para corresponder à semântica desejada pelo utilizador para o ecrã de entrada. - `mobile_navigation.xml`: O `startDestination` foi alterado de `nav_home` (Classificações) para `nav_news` (Ínicio/Notícias) para garantir que a app abre logo nas notícias recentes. - `activity_main_drawer.xml`: O item `nav_news` foi movido para o topo do menu para respeitar a hierarquia visual. - `fragment_news.xml`: Removido o cabeçalho cyan ("Notícias"), integrando perfeitamente a lista com a barra de ferramentas nativa da aplicação Android. - `item_news.xml`: Completamente redesenhado. Adicionado um layout `MaterialCardView` com cantos mais arredondados, margens e sombras otimizadas, e melhorada drasticamente a hierarquia tipográfica (cores neutras premium `#1F2937` e `#4B5563`, e a imagem a ocupar a largura total do card). **O que foi removido** - O cabeçalho estático no ficheiro `fragment_news.xml` foi removido para promover um design mais nativo e espaçoso. ## Relatório de Intervenção (Preparação de Jogos em Direto - Live Matches) **Progresso Geral Atualizado** Foi implementada a lógica para o Scraper detetar jogos que ainda não foram disputados (sem golos) e prepará-los automaticamente na base de dados para acompanhamento em direto. A estrutura base do jogo é injetada no Firebase de modo a que um árbitro ou gestor possa depois adicionar eventos em tempo real, sem o risco do Scraper apagar o seu trabalho a meio do jogo. **O que foi criado ou adicionado** - Adicionada a extração inicial (usando um `ValueEventListener` com `CountDownLatch`) para obter todas as chaves (IDs de jornada) dos jogos já registados no nó `live_matches`. - Adicionada lógica no processo de iteração dos jogos do `StandingsScraper.java` para injetar um objeto JSON preparatório nos jogos futuros. A estrutura inclui o nó `info` (com os nomes, logótipos, estado de agendado, e 0 golos) e o nó de `eventos` com o primeiro texto automático ("Partida iniciada em..."). **O que foi modificado e porquê** - O `StandingsScraper.java` foi modificado para suportar o estado de "agendado". Para além de não enviar golos para a classificação nestes jogos, ele avalia ativamente se deve instanciar o jogo no Firebase. O bloqueio anti-overwrite (ler os `existingLiveMatches`) foi criado intencionalmente porque se o Scraper corresse a meio de uma partida, faria reset dos golos para `0` e apagaria as anotações do árbitro. **O que foi removido** - Nada foi removido. Apenas foi expandida a robustez e conectividade do Scraper. ## Relatório de Intervenção (Campo 'played' nas Jornadas) **Progresso Geral Atualizado** Foi implementada a lógica para distinguir entre jogos já realizados e jogos agendados através de um novo campo booleano `played`. Esta melhoria permite à aplicação Android e a outros sistemas identificar rapidamente o estado de cada partida sem necessidade de inferência baseada na presença ou ausência de golos em tempo de execução. **O que foi criado ou adicionado** - Adicionado o campo `played` (booleano) a cada objeto de jogo dentro do nó `jornadas` na Firebase. - No projeto Android, foi adicionado o atributo `played` à classe `Match.java` (no package `ui.gallery`), juntamente com os seus getters e setters devidamente anotados com `@PropertyName("played")`. **O que foi modificado e porquê** - **StandingsScraper.java:** Modificado para calcular o valor de `played`. A lógica baseia-se na presença de dados de golos (`homeGoals` / `awayGoals`) retornados pela API da AFAVCD. Se existirem golos registados, o campo é definido como `true`; caso contrário, é `false`. - **Match.java (Android):** Atualizado para permitir que a aplicação consuma esta nova propriedade da base de dados, facilitando futuras implementações de UI (ex: esconder scores em jogos não jogados ou aplicar estilos diferenciados). **O que foi removido** - Nenhuma funcionalidade foi removida. Trata-se de um enriquecimento do modelo de dados existente.