Cada número neste site foi extraído de uma fonte oficial de imigração por um pipeline automático. Esta página explica exatamente como.
No dia 1 de cada mês às 06:00 UTC, o workflow monthly-update.yml inicia.
Nenhuma intervenção manual é necessária. O histórico de execuções fica visível
na aba Actions do repositório.
Para cada país, o fetcher acessa as URLs declaradas em src/sources/{cc}.ts
usando fetch nativo do Bun. Sites que exigem JavaScript recebem
fallback via Playwright headless. Mínimo de 2 segundos entre requests no mesmo domínio.
O HTML é processado pelo @mozilla/readability para isolar o conteúdo
principal. O texto limpo é enviado para a API da Anthropic. Claude Haiku 4.5 processa
a maioria das URLs. URLs marcadas como críticas usam Claude Sonnet 4.5.
O output é um JSON seguindo o schema declarado.
Cada campo do JSON é validado contra o schema Zod antes de qualquer escrita.
Falha na validação interrompe o processo — nada inválido é publicado.
O snapshot vai para data/current/ e uma cópia arquivada para
data/history/. Se houver mudança significativa, uma issue é aberta
automaticamente no GitHub.
1on: 2 schedule: 3 # Dia 1 de cada mês, 06:00 UTC 4 - cron: '0 6 1 * *' 5 workflow_dispatch: # disparo manual 6 7jobs: 8 update: 9 runs-on: ubuntu-latest 10 steps: 11 - name: Checkout 12 uses: actions/checkout@v4 13 14 - name: Setup Bun 15 uses: oven-sh/setup-bun@v2 16 17 - name: Instalar dependências 18 run: bun install 19 20 - name: Extrair todos os países 21 run: bun run extract 22 env: 23 ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} 24 25 - name: Detectar mudanças 26 run: bun run diff 27 28 - name: Publicar no GitHub Pages 29 uses: peaceiris/actions-gh-pages@v4 30 with: 31 publish_dir: ./data/current 32 publish_branch: gh-pages
Todos os 10 países seguem o mesmo schema. Os campos são validados pelo Zod antes de qualquer publicação. Se um campo obrigatório vier vazio ou com tipo errado, o snapshot inteiro é rejeitado.
1{ 2 "country": "nl", 3 "lastUpdated": "2026-04-01T06:00:00Z", 4 "visaTypes": [{ 5 "id": "highly-skilled-migrant", 6 "name": "Altamente Qualificado", 7 "processingTime": "2-4 semanas", 8 "requirements": { 9 "incomeRequirement": { 10 "amount": 5688, 11 "currency": "EUR", 12 "period": "monthly" 13 } 14 } 15 }], 16 "reliability": { 17 "extractionConfidence": "high", 18 "lastVerified": "2026-04-01" 19 } 20}
1const VisaTypeSchema = z.object({ 2 id: z.string(), 3 name: z.string(), 4 processingTime: z.string().optional(), 5 requirements: z.object({ 6 incomeRequirement: z.object({ 7 amount: z.number(), 8 currency: z.literal('EUR'), 9 period: z.enum(['monthly','annual']) 10 }).optional() 11 }) 12}) 13 14const CountrySchema = z.object({ 15 country: z.string().length(2), 16 lastUpdated: z.string().datetime(), 17 visaTypes: z.array(VisaTypeSchema), 18 reliability: ReliabilitySchema 19})
Cada decisão foi tomada para minimizar infraestrutura, maximizar confiabilidade e manter o custo mensal abaixo de USD 1.
Fetch nativo sem polyfill, runtime de testes embutido, instalação única. Compatível com Node 20+ se necessário.
Schema tipado impede campos ausentes silenciosos. O tsc --noEmit
roda no CI antes de qualquer extração.
Haiku 4.5 para a maioria das URLs (barato, rápido). Sonnet 4.5 apenas para URLs marcadas como críticas. Custo estimado: USD 4 a 10 por ano.
Schema declarativo colocado em src/extractors/schema.ts.
Falha de parse lança exceção e impede publicação de dados inválidos.
Zero infraestrutura. O histórico mensal é o próprio data/history/.
Diff visual no GitHub. Qualquer um pode consumir via CDN sem autenticação.
Free tier cobre folgadamente um cron mensal. O log de cada extração fica arquivado por 90 dias na aba Actions.
Os snapshots ficam disponíveis publicamente via GitHub Pages, com CORS aberto. Nenhuma chave de API necessária.
# País específico https://vl-builds.github.io/rota-legal-monitor/nl.json https://vl-builds.github.io/rota-legal-monitor/pt.json https://vl-builds.github.io/rota-legal-monitor/de.json # Índice de todos os países https://vl-builds.github.io/rota-legal-monitor/index.json # Países disponíveis: nl pt de es ie it fr be at au
Inspecione o pipeline, proponha melhorias ou adicione um novo país. Todo o processo está no repositório público.