Documentation Index Fetch the complete documentation index at: https://mintlify.com/KingPsychopath/oooc-fete-finder/llms.txt
Use this file to discover all available pages before exploring further.
Overview
OOOC Fête Finder provides automated and manual backup capabilities for event data and featured schedule. Backups are stored in PostgreSQL with configurable retention policies.
Backup system architecture
The backup system captures:
Event store data : All event rows and columns from app_event_store_* tables
Featured schedule : Spotlight and promoted placements from featured event repository
Metadata : Row count, checksum, update timestamp, origin
Backup storage
Backups are stored in PostgreSQL tables:
CREATE TABLE app_event_store_backups (
id TEXT PRIMARY KEY ,
created_at TIMESTAMPTZ NOT NULL ,
created_by TEXT NOT NULL ,
trigger TEXT NOT NULL ,
row_count INTEGER NOT NULL ,
featured_entry_count INTEGER NOT NULL ,
store_updated_at TIMESTAMPTZ ,
store_checksum TEXT NOT NULL ,
csv_content TEXT NOT NULL ,
featured_entries_json TEXT NOT NULL
);
Backup triggers
Backups can be created via:
Manual : Admin panel “Backup Now” button
Cron : Daily automated backups at 04:20 UTC
Pre-restore : Automatic snapshot before restoring a backup
Admin save : Optional snapshot before event sheet save
Creating backups
Manual backup via admin panel
Navigate to operations
Open /admin/operations in your browser.
Create snapshot
In the “Event Store Controls” section, click “Backup Now”.
Verify backup
The backup appears in “Recent Backups” list with:
Snapshot ID
Created timestamp
Row count
Featured entry count
Automated backup via cron
Configured in vercel.json:
{
"crons" : [
{ "path" : "/api/cron/backup-event-store" , "schedule" : "20 4 * * *" }
]
}
Schedule : Daily at 04:20 UTC
Retention : Latest 30 snapshots (older backups automatically pruned)
Verify cron execution:
# Check cron logs in Vercel dashboard
# Or manually trigger:
curl https://your-domain.com/api/cron/backup-event-store \
-H "Authorization: Bearer <CRON_SECRET>"
Expected response:
{
"ok" : true ,
"message" : "Backup created (123 rows, 5 featured entries)" ,
"backup" : {
"id" : "backup_20260228_042015" ,
"createdAt" : "2026-02-28T04:20:15.000Z" ,
"rowCount" : 123 ,
"featuredEntryCount" : 5
},
"prunedCount" : 2
}
Set CRON_SECRET in environment variables to enable cron-triggered backups.
Programmatic backup via service
Create backups programmatically:
import { EventStoreBackupService } from "@/features/data-management/event-store-backup-service" ;
const result = await EventStoreBackupService . createBackup ({
createdBy: "admin" ,
trigger: "manual"
});
if ( result . success ) {
console . log ( result . message ); // "Backup created (123 rows, 5 featured entries)"
console . log ( result . backup . id ); // "backup_20260228_103045"
console . log ( result . prunedCount ); // 1
}
Backup retention
The system maintains 30 most recent backups :
const BACKUP_RETENTION_LIMIT = 30 ;
// After each backup creation:
const prunedCount = await repository . pruneOldBackups ( BACKUP_RETENTION_LIMIT );
Retention applies per environment. Production and Preview environments maintain separate backup histories.
Retention policy details
Retention count : 30 snapshots
Pruning : Automatic after each backup creation
Sort order : Oldest backups deleted first
Exception : Manual backups have same retention as automated backups
Restoring backups
Restore via admin panel
Navigate to operations
Open /admin/operations.
Select backup
In “Recent Backups” section:
Click “Restore Latest” for most recent backup
Or select specific snapshot and click “Restore”
Confirm restoration
The system will:
Create pre-restore snapshot of current data
Restore selected backup to event store
Restore featured schedule entries
Display confirmation with row counts
Revalidate homepage
Click “Save and Revalidate Homepage” to publish restored data.
Verify restoration
Check “Live Runtime Snapshot” to confirm:
Row count matches restored backup
Data source is postgres-store
Update timestamp is recent
Restore via service
Restore programmatically:
Restore latest
Restore specific backup
import { EventStoreBackupService } from "@/features/data-management/event-store-backup-service" ;
const result = await EventStoreBackupService . restoreLatestBackup ({
createdBy: "admin"
});
if ( result . success ) {
console . log ( result . message ); // "Restored latest backup from 2/28/2026, 10:30:00 AM"
console . log ( result . restoredRowCount ); // 123
console . log ( result . restoredFeaturedCount ); // 5
}
Pre-restore snapshot
Before restoring, the system automatically:
Captures current event store state
Creates pre-restore backup with trigger "pre-restore"
Prunes old backups to maintain retention limit
Proceeds with restoration
Pre-restore snapshots count toward the 30-backup retention limit. Very old pre-restore snapshots may be pruned.
Backup contents
Event store CSV
Full event data in CSV format:
Event Key, Title, Date, Location, Categories, Tags, ...
event_001, Live Jazz at Blue Note, 2026-03-15, 6 Rue de l'Arbre Sec, Music, jazz;live, ...
event_002, Art Exhibition Opening, 2026-03-20, Galerie Perrotin, Art, contemporary;gallery, ...
Featured schedule JSON
Spotlight and promoted placements:
[
{
"id" : "featured_001" ,
"eventKey" : "event_001" ,
"requestedStartAt" : "2026-03-15T00:00:00.000Z" ,
"effectiveStartAt" : "2026-03-15T00:00:00.000Z" ,
"effectiveEndAt" : "2026-03-18T00:00:00.000Z" ,
"durationHours" : 72 ,
"status" : "scheduled" ,
"createdBy" : "admin" ,
"createdAt" : "2026-02-28T10:00:00.000Z" ,
"updatedAt" : "2026-02-28T10:00:00.000Z"
}
]
{
"id" : "backup_20260228_042015" ,
"createdAt" : "2026-02-28T04:20:15.000Z" ,
"createdBy" : "cron" ,
"trigger" : "cron" ,
"rowCount" : 123 ,
"featuredEntryCount" : 5 ,
"storeUpdatedAt" : "2026-02-28T03:45:00.000Z" ,
"storeChecksum" : "a1b2c3d4e5f67890"
}
Backup status and health
Check backup system health:
Via admin panel
From /admin/operations:
Latest backup : Timestamp and row count
Backup count : Total snapshots in retention
Recent backups : List with details
Via service
import { EventStoreBackupService } from "@/features/data-management/event-store-backup-service" ;
const statusResult = await EventStoreBackupService . getBackupStatus ();
if ( statusResult . supported ) {
const { status } = statusResult ;
console . log ( status . latestBackup ?. createdAt ); // "2026-02-28T04:20:15.000Z"
console . log ( status . backupCount ); // 28
}
const listResult = await EventStoreBackupService . listRecentBackups ( 10 );
if ( listResult . supported ) {
for ( const backup of listResult . backups ) {
console . log ( ` ${ backup . id } : ${ backup . rowCount } rows` );
}
}
Disaster recovery procedures
Scenario 1: Accidental data deletion
Identify issue
Notice missing or incorrect events on homepage.
Navigate to admin operations
Open /admin/operations.
Restore latest backup
Click “Restore Latest Backup”.
Revalidate
Click “Save and Revalidate Homepage”.
Verify
Check homepage to confirm events are restored.
Scenario 2: Database corruption
Assess damage
Run health check: DATABASE_URL = "your-url" pnpm health:check
Drop corrupted tables
DROP TABLE IF EXISTS app_event_store_rows;
DROP TABLE IF EXISTS app_event_store_columns;
DROP TABLE IF EXISTS app_event_store_meta;
Re-bootstrap database
DATABASE_URL = "your-url" pnpm bootstrap:postgres-store
Restore from backup
From /admin/operations, restore latest backup.
Verify data integrity
DATABASE_URL = "your-url" pnpm db:cli status
Scenario 3: Complete database loss
Provision new database
Create new PostgreSQL database and obtain DATABASE_URL.
Update environment variables
Set new DATABASE_URL in Vercel dashboard.
Bootstrap new database
DATABASE_URL = "new-url" pnpm bootstrap:postgres-store
Manual data recovery
If backups were in lost database:
Use local CSV from data/events.csv
Or restore from Google Sheets backup
Or upload CSV via admin panel
Rebuild backups
Create new baseline backup: curl https://your-domain.com/api/cron/backup-event-store \
-H "Authorization: Bearer <CRON_SECRET>"
Complete database loss means losing all backups stored in that database. Implement off-database backup strategy for critical deployments.
Off-database backup strategy
For production environments, implement additional backup layers:
Google Sheets as backup store
Configure Google Sheets integration:
# Environment variables
GOOGLE_SHEET_ID = your-sheet-id
GOOGLE_SERVICE_ACCOUNT_KEY = '{"type":"service_account",...}'
Periodic export to Google Sheets:
From /admin/operations, click “Export to Google Sheets”
Or configure custom automation to call export endpoint
Verify sheet is updated with latest events
CSV export via admin panel
Manual CSV download:
Navigate to /admin/content
Open “Event Sheet Editor”
Click “Export CSV”
Save to secure location (encrypted storage, version control)
Database-level backups
Use your database provider’s native backup:
Vercel Postgres
Neon
Supabase
# Automatic backups included
# Configure retention in Vercel dashboard
# Storage > Database > Settings > Backups
Backup best practices
Regular backup schedule
Enable automated cron backups
Verify CRON_SECRET is set and cron job is registered in Vercel.
Monitor backup success
Check Vercel cron logs or set up alerts for backup failures.
Test restore procedure monthly
Perform test restoration to verify backup integrity:
Restore backup in preview environment
Verify data completeness
Document restore time
Pre-change snapshots
Create manual backups before:
Bulk event imports
Major content changes
Schema migrations
Featured schedule changes
Retention planning
With 30-backup retention and daily cron:
Coverage : 30 days of history
Granularity : Daily snapshots
Manual backups : Count toward 30-backup limit
For longer retention:
Export critical backups to external storage
Use database provider’s native backup (separate retention)
Archive CSV exports to cloud storage
Monitoring backup health
Set up alerts for:
Backup age
-- Alert if latest backup is older than 48 hours
SELECT created_at
FROM app_event_store_backups
ORDER BY created_at DESC
LIMIT 1 ;
Backup failures
Monitor cron logs for:
{ "ok" : false , "message" : "Failed to create event store backup" , "error" : "..." }
Backup count
-- Alert if backup count is unusually low
SELECT COUNT ( * ) FROM app_event_store_backups;
-- Expected: ~30 (or close to retention limit)
Next steps