mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 23:53:05 +00:00
- helpers puros movidos utilities->lib: slug, phone, wordStartFilter, voteEstimate (9 inversoes lib->utilities zeradas) - chaves de consent em src/lib/campaignConsentKeys.ts (client-safe); campaignInvite/campaignConsent re-exportam; onda0ConsentTexts referencia as constantes - 'server-only' em 21 loaders Payload/cache (CLI segue com --conditions=react-server) - ciclo de tipos supporterListFilters <-> supporterUi quebrado (SupporterListFilterInput estrutural; sqlFilters idem) - votePledgeData dividido: votePledgeViews (puro, client-safe) + votePledgeData (loaders, server-only) - padrao contract-module - predicados de role client-safe em src/lib/campaignRoles.ts; access/shared deriva deles (fonte unica); nav.ts para de importar o barrel campaignAccess (casts 'as CampaignUser' eliminados)
81 lines
2.2 KiB
TypeScript
81 lines
2.2 KiB
TypeScript
import 'server-only'
|
|
|
|
import { cache } from 'react'
|
|
|
|
import type { Payload, Where } from 'payload'
|
|
|
|
import type { CampaignUser, Municipality } from '@/payload-types'
|
|
import { aggregatePledgesByMunicipality } from '@/utilities/votePledgeData'
|
|
import { type MunicipalityPledgeAggregate } from '@/utilities/votePledgeViews'
|
|
|
|
/** Superset of the fields the dashboard, map, and list overview consume. */
|
|
export type ScopedMunicipalityDoc = Pick<
|
|
Municipality,
|
|
| 'id'
|
|
| 'name'
|
|
| 'slug'
|
|
| 'kind'
|
|
| 'region'
|
|
| 'ibgeCode'
|
|
| 'advisors'
|
|
| 'priority'
|
|
| 'expectedVotes'
|
|
>
|
|
|
|
export type MunicipalityScope = {
|
|
municipalities: ScopedMunicipalityDoc[]
|
|
pledgeAggregates: Map<number, MunicipalityPledgeAggregate>
|
|
}
|
|
|
|
const loadScope = async (
|
|
payload: Payload,
|
|
user: CampaignUser,
|
|
where: Where,
|
|
): Promise<MunicipalityScope> => {
|
|
const result = await payload.find({
|
|
collection: 'municipality',
|
|
depth: 0,
|
|
limit: 0,
|
|
pagination: false,
|
|
select: {
|
|
name: true,
|
|
slug: true,
|
|
kind: true,
|
|
region: true,
|
|
ibgeCode: true,
|
|
advisors: true,
|
|
priority: true,
|
|
expectedVotes: true,
|
|
},
|
|
where,
|
|
user,
|
|
overrideAccess: false,
|
|
})
|
|
|
|
const municipalities = result.docs as ScopedMunicipalityDoc[]
|
|
const pledgeAggregates = await aggregatePledgesByMunicipality(
|
|
payload,
|
|
municipalities.map((municipality) => municipality.id),
|
|
)
|
|
|
|
return { municipalities, pledgeAggregates }
|
|
}
|
|
|
|
/**
|
|
* Request-scoped municipality scope (accessible docs + pledge aggregates),
|
|
* deduplicated with React `cache()`: the staff dashboard and the map bundle
|
|
* both need the same scope on one request and used to load it twice.
|
|
*
|
|
* `payload` (module singleton) and `user` (from the request-cached
|
|
* `getCampaignUser`) are reference-stable within a request; the `where` clause
|
|
* participates via its canonical JSON string.
|
|
*/
|
|
const loadScopeCached = cache((payload: Payload, user: CampaignUser, whereKey: string) =>
|
|
loadScope(payload, user, JSON.parse(whereKey) as Where),
|
|
)
|
|
|
|
export const loadMunicipalityScope = (
|
|
payload: Payload,
|
|
user: CampaignUser,
|
|
where: Where,
|
|
): Promise<MunicipalityScope> => loadScopeCached(payload, user, JSON.stringify(where))
|