teqo/src/utilities/electionCandidateOptions.ts
Francisco Ignácio Fontoura Solla cf13c441aa Remodel /campanha around predefined Praças replacing electoral nuclei.
436 seeded Praças (municipality-based; per-TSE-zone in Salvador/Camaçari) become
the operational unit; roles renamed to coordinator/advisor/leader with advisors
scoped to administered Praças. Leadership is one record per person across many
Praças/organizations; vote pledges split leader-declared vs staff-estimated
(estimates never serialized to leaders). Adds organizations, demand workflow
with staff-only cost/receipts, action-plan results with deputy presence, manual
political trend, multi-candidate comparison and the diverging red/white/blue
map mode. Migration 20260721_020109_remodel_plazas deliberately resets the
campaign vertical in production (public site untouched); test suite ported to
the new model (unit 187 / int 306 / e2e 9 green).
2026-07-21 02:28:00 -03:00

56 lines
1.7 KiB
TypeScript

import type { Payload } from 'payload'
import {
BASELINE_TICKET_2022,
ELECTION_YEAR_2022,
FEDERAL_DEPUTY_OFFICE,
} from '@/lib/electionResults'
import type { CampaignUser, User } from '@/payload-types'
import { assertCanReadElectionData } from '@/utilities/campaignAccess'
export type FederalCandidateOption = {
candidateNumber: number
name: string
party: string | null
totalVotesState: number
}
/**
* Federal-deputy candidates available for comparison (2022 registry ordered by
* statewide votes). Solla himself is excluded — he is always the reference.
*/
export const loadFederalCandidateOptions = async (
payload: Payload,
user: CampaignUser | User,
limit = 60,
): Promise<FederalCandidateOption[]> => {
assertCanReadElectionData(user)
const result = await payload.find({
collection: 'electionCandidate',
where: {
and: [
{ year: { equals: ELECTION_YEAR_2022 } },
{ office: { equals: FEDERAL_DEPUTY_OFFICE } },
{ turn: { equals: '1' } },
{ candidateNumber: { not_equals: BASELINE_TICKET_2022.candidate.candidateNumber } },
// NULL totals sort first on DESC in Postgres — and a candidate without
// statewide votes is useless as a comparison target anyway.
{ totalVotesState: { greater_than: 0 } },
],
},
depth: 0,
limit,
pagination: false,
sort: '-totalVotesState',
select: { candidateNumber: true, urnaName: true, party: true, totalVotesState: true },
overrideAccess: true,
})
return result.docs.map((candidate) => ({
candidateNumber: candidate.candidateNumber,
name: candidate.urnaName,
party: candidate.party ?? null,
totalVotesState: candidate.totalVotesState ?? 0,
}))
}