feat: vérifier que la page Wikipedia existe et est une biographie

Appel à l'API MediaWiki pour valider que la page existe et possède la
catégorie « Wikipédia:Article biographique ». Interface WikipediaValidator
dans domain/services (port hexagonal), implémentation dans infra/.
This commit is contained in:
Jalil Arfaoui 2026-02-17 00:16:21 +01:00
parent 5840afa824
commit e2d0a20b45
3 changed files with 56 additions and 0 deletions

View file

@ -11,6 +11,7 @@ import {
createPublicFigureWithStatementUseCase,
FieldErrors,
} from '../../domain/use-cases/create-public-figure-with-statement'
import { createWikipediaValidator } from '../../infra/wikipedia/wikipedia-validator'
import { getAuthenticatedContributor } from './get-authenticated-contributor'
export type ActionResult =
@ -41,6 +42,7 @@ export async function createPublicFigureWithStatementAction(
subjectRepo: createSubjectRepository(supabase),
publicFigureRepo: createPublicFigureRepository(supabase),
reputationRepo: createReputationRepository(supabase),
wikipediaValidator: createWikipediaValidator(),
})
if (Either.isLeft(result)) {

View file

@ -0,0 +1,8 @@
export interface WikipediaValidationResult {
exists: boolean
isBiography: boolean
}
export interface WikipediaValidator {
validatePage(url: string): Promise<WikipediaValidationResult>
}

View file

@ -0,0 +1,46 @@
import {
WikipediaValidator,
WikipediaValidationResult,
} from '../../domain/services/wikipedia-validator'
const BIOGRAPHY_CATEGORY = 'Catégorie:Wikipédia:Article biographique'
function extractLangAndTitle(url: string): { lang: string; title: string } | null {
const match = url.match(/^https:\/\/(fr|en)\.wikipedia\.org\/wiki\/(.+)$/)
if (!match) return null
return { lang: match[1], title: match[2] }
}
export function createWikipediaValidator(): WikipediaValidator {
return {
async validatePage(url: string): Promise<WikipediaValidationResult> {
const parsed = extractLangAndTitle(url)
if (!parsed) return { exists: false, isBiography: false }
const apiUrl =
`https://${parsed.lang}.wikipedia.org/w/api.php` +
`?action=query&format=json&prop=categories&titles=${encodeURIComponent(parsed.title)}&cllimit=50`
const response = await fetch(apiUrl, {
headers: { 'User-Agent': 'Debats.co/1.0 (https://debats.co)' },
})
if (!response.ok) return { exists: false, isBiography: false }
const data = await response.json()
const pages = data.query?.pages
if (!pages) return { exists: false, isBiography: false }
const page = Object.values(pages)[0] as { missing?: string; categories?: { title: string }[] }
if ('missing' in page) {
return { exists: false, isBiography: false }
}
const categories = page.categories ?? []
const isBiography = categories.some((c) => c.title === BIOGRAPHY_CATEGORY)
return { exists: true, isBiography }
},
}
}