Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt

Use this file to discover all available pages before exploring further.

Status: ✅ Complete
Spec: specs/pf/specs/PF-98-ai-staff-headshot-generator.md
Tasks: specs/pf/tasks/PF-98-TASKS.md
Context: specs/pf/specs/PF-98-CONTEXT.md
Created: 2026-04-11
Updated: 2026-04-11

Purpose

Defines integration contracts for the AI Staff Headshot Generator feature: events published, storage contracts, provider API abstraction, and Edge Function inventory. PF-98 is a PF-internal feature with no cross-core consumers; integrations are limited to PF platform services (notifications, quota tracking).

Dependencies

DependencyPurposeIntegration Type
PF-04Audit logging for consent, generation, deletion eventsPlatform Layer
PF-06Permission keys for headshot and campaign operationsPlatform Layer
PF-10Notifications (campaign invites, generation complete, reminders)Event
PF-27Profile photo update (set generated headshot as profile photo)Platform Layer
PF-30Organization settings (provider config, quotas, retention)Platform Layer
PF-43Quota tracking (generation credits per org)Event
PF-56Biometric consent management (upload consent gate)Platform Layer
PF-66File upload patterns (react-dropzone, validation)Platform Layer

Events Published

pf_headshot_job_completed

  • Publisher: PF-98 (Edge Function pf-headshot-webhook)
  • Subscribers: PF-10 (user notification), PF-43 (quota decrement)
  • Trigger: AI provider webhook confirms job completion
  • Payload: See EVENT_CONTRACTS.md § PF-98

pf_headshot_campaign_completed

  • Publisher: PF-98 (Edge Function pf-headshot-webhook or pf-headshot-status-poll)
  • Subscribers: PF-10 (admin notification)
  • Trigger: All campaign members have completed headshot generation
  • Payload: See EVENT_CONTRACTS.md § PF-98

Storage Contract

PropertyValue
Bucketheadshots (private)
Upload path{org_id}/{user_id}/uploads/{upload_id}/{filename}
Generated path{org_id}/{user_id}/{job_id}/{filename}
AccessSigned URLs only (1-hour expiry)
RetentionSource photos: configurable (upload_retention_days, default 90); Generated: indefinite unless user-deleted
CleanupDaily cron via pf-headshot-cleanup Edge Function

Edge Functions

FunctionPurpose
pf-headshot-submitReceives upload metadata + style; dispatches to configured provider
pf-headshot-webhookReceives provider callbacks; updates job status; publishes events
pf-headshot-status-pollPolls provider status for providers without webhook support
pf-headshot-signed-urlGenerates signed URLs for gallery display
pf-headshot-cleanupDaily cron: deletes expired source photos per retention config
pf-headshot-campaign-inviteSends batch PF-10 notifications for campaign invites

Permission Keys

KeyDescription
headshot.upload.createUpload source photos
headshot.job.createTrigger headshot generation
headshot.gallery.readView own generated headshots
headshot.gallery.deleteDelete own headshots
headshot.campaign.manageCreate/edit/delete campaigns (admin)
headshot.settings.manageConfigure provider, quotas, retention (admin)

Notes

  • PF-98 is PF-internal; no other core consumes or publishes to it.
  • Provider API keys are stored as Supabase Edge Function secrets, not in the database.
  • RLS helpers must use expires_at check on pf_user_role_assignments (not is_active); see PF-98-CONTEXT.md § Area 7.
  • Trigger functions use update_updated_at_column() (not pf_set_updated_at()).