mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-15 02:23:07 +00:00
O escopo A/C do gate (PR #1370) é superado por decisão do dono (2026-10-01, aval jurídico declarado): o índice vira anônimo (archivePhotoFace, foto + descritor 128-d, sem nome/vínculo), o enrollment por pessoa morre (faceSubject/faces:enroll removidos) e qualquer visitante encontra as próprias fotos aprovadas. - faces:index persiste os descritores por foto (transação substitui as linhas + marker = modelo); desaprovar/remover/deletar foto apaga os descritores (hooks + FK cascade) - POST /api/fotos/selfie casa o vetor da consulta contra o índice em memória (TTL 60 s) e devolve só a interseção com o read aprovado do C233, sem score/nome de terceiro; leave-index apaga os descritores que casarem - Consentimentos seguem fail-closed: busca-selfie-fotos (consulta) e busca-selfie-indice (aviso público do índice), textos versionados em scripts/lib/faceConsentTexts.mjs e provisionados por pnpm seed:face-consents - pnpm archive:publish aprova o acervo em lote (draft -> approved; removed nunca) com guardas e recibo - C243: seção condicional SelfieSearchHomeSection (port do design hi-fi, cenas 390/1280) entre a Central e a newsletter; sem engine/captura na home e sem CTA morto quando fechada - docs: planos C242/C243, AGENTS-public, runbook §C242, changelog Provas: gate:fast 457 arquivos/5.055 testes; int full 109/1.075; e2e frontendFotosSelfie 9/9; knip verde.
79 lines
2.2 KiB
TypeScript
79 lines
2.2 KiB
TypeScript
import type { CollectionConfig } from 'payload'
|
|
|
|
import { payloadAdminOnly } from '@/utilities/campaignAccess'
|
|
|
|
/**
|
|
* C242 — one detected face of an APPROVED archive photo: the anonymous index
|
|
* that lets any visitor find themselves (scope B of the gate, decision of
|
|
* 2026-10-01; supersedes the A/C `faceSubject` enrollment). The row carries no
|
|
* identity, no link to `Contact`/leadership and no name — only the photo it was
|
|
* found in, the 128-float descriptor and the model that produced it.
|
|
*
|
|
* Machine-only data: no admin surface (`admin.hidden`), admin-only access, and
|
|
* the descriptor never leaves the server. Written exclusively by the
|
|
* `pnpm faces:index` batch (trusted operator, `overrideAccess`), deleted by the
|
|
* opt-out (`leave-index` matches the person's own descriptor) and by the photo
|
|
* lifecycle hooks on unapproval/deletion. A photo that is not `approved` must
|
|
* never have rows here.
|
|
*/
|
|
export const ArchivePhotoFace: CollectionConfig = {
|
|
slug: 'archivePhotoFace',
|
|
labels: {
|
|
singular: 'Rosto no índice',
|
|
plural: 'Rostos no índice',
|
|
},
|
|
admin: {
|
|
group: 'Comunicação',
|
|
hidden: true,
|
|
description:
|
|
'Índice facial anônimo do acervo público aprovado (C242). Operado pela CLI faces:index; o descriptor nunca é exposto.',
|
|
},
|
|
access: {
|
|
create: payloadAdminOnly,
|
|
read: payloadAdminOnly,
|
|
update: payloadAdminOnly,
|
|
delete: payloadAdminOnly,
|
|
},
|
|
fields: [
|
|
{
|
|
name: 'photo',
|
|
type: 'relationship',
|
|
relationTo: 'archivePhoto',
|
|
label: 'Foto',
|
|
required: true,
|
|
index: true,
|
|
admin: {
|
|
description: 'Foto aprovada em que o rosto foi detectado.',
|
|
},
|
|
},
|
|
{
|
|
name: 'model',
|
|
type: 'text',
|
|
label: 'Modelo',
|
|
required: true,
|
|
index: true,
|
|
admin: {
|
|
readOnly: true,
|
|
description:
|
|
'Modelo do descriptor (troca de modelo invalida a revisão e o lote reprocessa).',
|
|
},
|
|
},
|
|
{
|
|
name: 'detectedAt',
|
|
type: 'date',
|
|
label: 'Detectado em',
|
|
admin: {
|
|
readOnly: true,
|
|
},
|
|
},
|
|
{
|
|
name: 'vector',
|
|
type: 'json',
|
|
label: 'Descriptor',
|
|
admin: {
|
|
hidden: true,
|
|
readOnly: true,
|
|
},
|
|
},
|
|
],
|
|
}
|