teqo-backup/src/utilities/revalidateRequest.ts
Francisco Solla 269b3d9e3b feat(ops): CLI ops:global para flags de globais públicos (C247)
Grava um único campo do global via Local API e busta a tag no processo Next vivo pelo POST /api/revalidate (allowlist ampliada com REVALIDATE_PHOTO_ALBUM_CACHE_TAG), com guardas de escrita, plan/apply/verify, recibo com rollback e int pin do update parcial.
2026-10-02 10:10:16 -03:00

80 lines
3 KiB
TypeScript

import { getCollectionListingTag } from '@/utilities/documents'
import { ELECTION_TSE_CACHE_TAG } from '@/utilities/electionCache'
import { getGlobalCacheTag } from '@/utilities/globals'
import { MUNICIPALITY_CATALOG_CACHE_TAG } from '@/utilities/municipality/municipalityCatalogCache'
export const REVALIDATE_POSTS_TAG = 'posts' as const
export const REVALIDATE_PRIVACY_POLICY_CACHE_TAG = getGlobalCacheTag('privacy-policy')
/**
* C247 — the `photoAlbum` global's tag (`/fotos`, `/fotos/encontre` and the
* home section cache under it). The ops CLI (`pnpm ops:global`) writes the
* global outside the deployed runtime, where the `afterChange` hook's
* `revalidateTag` cannot reach the live cache: it busts the tag through this
* endpoint. Derived from the same owner the global hook busts.
*/
export const REVALIDATE_PHOTO_ALBUM_CACHE_TAG = getGlobalCacheTag('photoAlbum')
/**
* C233 — the archive photos listing tag the public album (`/fotos`) caches
* under. Derived from the same owner the collection hook busts, so the runbook
* tag and the code can never drift.
*/
const REVALIDATE_ARCHIVE_PHOTOS_TAG = getCollectionListingTag('archivePhoto')
/**
* C230-followup — the Central de Conteúdos listing tag: the Instagram import
* CLI writes straight to the DB (outside any request, so the collection hook's
* `revalidateTag` is a no-op in that process) and busts it through this
* endpoint after publishing. Derived from the same owner as the hook.
*/
export const REVALIDATE_CONTENT_PIECES_TAG = getCollectionListingTag('contentPiece')
/**
* Cache tag of the campaign home content board's external feeds (`unstable_cache`
* entry of `getYouTubeFeed`). The `SocialFeedSettings` global's `afterChange`
* busts it; the runbook tag is also allowlisted here for direct-DB writes.
*/
export const REVALIDATE_SOCIAL_FEED_TAG = 'social-feed' as const
const ALLOWED_REVALIDATE_TAGS = [
REVALIDATE_POSTS_TAG,
REVALIDATE_PRIVACY_POLICY_CACHE_TAG,
REVALIDATE_PHOTO_ALBUM_CACHE_TAG,
ELECTION_TSE_CACHE_TAG,
MUNICIPALITY_CATALOG_CACHE_TAG,
REVALIDATE_SOCIAL_FEED_TAG,
REVALIDATE_ARCHIVE_PHOTOS_TAG,
REVALIDATE_CONTENT_PIECES_TAG,
] as const
type AllowedRevalidateTag = (typeof ALLOWED_REVALIDATE_TAGS)[number]
const allowedTagSet = new Set<string>(ALLOWED_REVALIDATE_TAGS)
export type ResolveRevalidateTagResult =
| { ok: true; tag: AllowedRevalidateTag }
| { ok: false; error: string }
const isAllowedRevalidateTag = (tag: string): tag is AllowedRevalidateTag => allowedTagSet.has(tag)
export const resolveRevalidateTag = (
queryTag: string | null | undefined,
bodyTag: string | null | undefined,
): ResolveRevalidateTagResult => {
const requested = queryTag ?? bodyTag
if (requested == null || requested === '') {
return { ok: true, tag: REVALIDATE_POSTS_TAG }
}
if (!isAllowedRevalidateTag(requested)) {
return {
ok: false,
error: `Unknown tag. Allowed: ${ALLOWED_REVALIDATE_TAGS.join(', ')}`,
}
}
return { ok: true, tag: requested }
}