teqo-backup/src/collections/CalendarFeed.ts
Francisco Solla 29ed733190 fix(C92): calendar feed creation stripped by admin-only system fields
createCalendarFeedLinkRecord failed with `overrideAccess:false` +
`user: campaignUser` because Payload stripped the required
`secretSlug`/`createdBy` fields (create access was admin-only) -> 400
behind the generic message; revokeCalendarFeedRecord silently no-opped
(revokedAt update access also admin-only).

- canCreateCalendarFeed now enforces advisor filterMunicipality scope
  on data (canCreateSupporter precedent) + canSetCalendarFeedSecret /
  canSetCalendarFeedRevocation permit staff to mint the secret on create
  and mark a feed revoked; secret read stays `() => false` and update
  admin-only.
- CalendarFeed stamps createdBy via stampCampaignCreatedBy; secret
  create + revokedAt update use the new staff field accesses.
- Action refactored to `*Record` (payload, actor) cores + thin wrappers;
  assertFilterMunicipalityInScope (tour precedent); console.error keeps
  the real error on the server while the friendly message stays.
- 10 int tests for create/scope/revoke/leader/secret; fixture tracks
  calendarFeed cleanup.

Closes #436
2026-08-08 23:13:30 -03:00

103 lines
2.4 KiB
TypeScript

import type { CollectionConfig } from 'payload'
import {
canCreateCalendarFeed,
canDeleteCalendarFeed,
canReadCalendarFeed,
canSetCalendarFeedRevocation,
canSetCalendarFeedSecret,
canSetCalendarFeedSystemField,
canUpdateCalendarFeed,
} from '@/utilities/campaignAccess'
import { stampCampaignCreatedBy, systemStampedActorField } from '@/utilities/campaignAuditFields'
export const CalendarFeed: CollectionConfig = {
slug: 'calendarFeed',
labels: {
singular: 'Feed de calendário',
plural: 'Feeds de calendário',
},
admin: {
group: 'Campanha',
useAsTitle: 'label',
defaultColumns: [
'label',
'filterMunicipality',
'filterTag',
'filterDeputyPresent',
'createdAt',
],
},
access: {
create: canCreateCalendarFeed,
read: canReadCalendarFeed,
update: canUpdateCalendarFeed,
delete: canDeleteCalendarFeed,
},
hooks: {
beforeChange: [stampCampaignCreatedBy],
},
fields: [
{
name: 'secretSlug',
type: 'text',
required: true,
unique: true,
index: true,
admin: {
hidden: true,
},
access: {
create: canSetCalendarFeedSecret,
read: () => false,
update: canSetCalendarFeedSystemField,
},
},
{
name: 'label',
type: 'text',
label: 'Nome',
required: true,
admin: {
description: 'Nome descritivo para identificar o feed (ex: "Só deputado presente")',
},
},
{
name: 'filterMunicipality',
type: 'relationship',
relationTo: 'municipality',
label: 'Filtro: Município',
admin: {
description: 'Se vazio, inclui todos os municípios do escopo do criador',
},
},
{
name: 'filterDeputyPresent',
type: 'checkbox',
label: 'Filtro: Deputado presente',
defaultValue: false,
},
{
name: 'filterTag',
type: 'text',
label: 'Filtro: Tag',
admin: {
description: 'Se vazio, inclui todas as tags',
},
},
{
name: 'revokedAt',
type: 'date',
label: 'Revogado em',
index: true,
admin: {
readOnly: true,
},
access: {
create: canSetCalendarFeedSystemField,
update: canSetCalendarFeedRevocation,
},
},
systemStampedActorField({ required: true, setAccess: canSetCalendarFeedSystemField }),
],
}