Approval Workflows
Simple email-based approval system for content review before publishing.
How It Works
The approval system is straightforward:
- Brand Setting: Set
require_approval: truein brand generation settings - Email Sent: When content is generated, an email is sent via Resend
- Review: Click approve or reject links in the email
- Status Update: Content status changes based on action
Configuration
Brand-Level Setting
Approvals are configured at the brand level in the database:
// In brandGenerationSettings.publishing
{
"require_approval": true,
"auto_publish": false
}When enabled, ALL content for profiles under that brand requires approval.
Post-Level Override
Individual posts can skip approval using the autoPublish checkbox in the content form. This overrides the brand setting for that specific post.
Content States
Reviewing
- Content awaiting approval
- Email has been sent
- Cannot be published until approved
Approved
- Ready for publishing
- Will publish at scheduled time
- Approval tracked in database
Rejected
- Will not be published
- Requires regeneration or manual intervention
- Rejection notes stored with content
Approval Actions
Via Email
- Approve/Reject links in email
- Direct action without logging in
- One-click decision
Via Dashboard
In the Content Details Panel:
- Approve button - marks content as approved
- Reject button - opens dialog for rejection notes
- Both actions update status immediately
Timing Considerations
Before Scheduled Time
- Content must be approved before scheduled publish time
- If not approved, content remains in "reviewing" status
- Will not publish until approved
After Scheduled Time
- If approved after scheduled time, content status changes to "approved"
- Content does not automatically publish - it misses its scheduled slot
- Must be manually rescheduled or published
No Expiration
- Approval links don't expire (no 7-day limit)
- Content remains in reviewing status indefinitely until action taken
Database Fields
Content approval tracked in content_generations table:
approvedBy- User who approved (Clerk userId)approvedAt- Timestamp of approvalrejectedBy- User who rejected (Clerk userId)rejectedAt- Timestamp of rejectionreviewNotes- Rejection reasonapprovalMethod- How it was approved (email, dashboard, api)
Current Implementation
What Works
✅ Brand-level require_approval setting ✅ Email notifications via Resend ✅ Dashboard approve/reject buttons ✅ Status tracking in database ✅ Post-level autoPublish override
What Doesn't Exist
❌ Multiple approvers ❌ Approval delegation ❌ In-app notifications ❌ Approval reminders ❌ Bulk approval interface ❌ Slack/Teams integration ❌ Custom approval rules ❌ Approval analytics
API Endpoints
// Approve content
POST /api/content/:id/approve
// Reject content
POST /api/content/:id/reject
{
"notes": "Rejection reason"
}Best Practices
- Set at Brand Level - Configure once for all profiles
- Review Promptly - Don't let content pile up in review
- Clear Feedback - Provide specific rejection reasons
- Monitor Queue - Check reviewing items regularly
Limitations
- Single approver only (no approval chains)
- No automated reminders
- No bulk operations in UI
- Email-only notifications
- Basic email template (not customizable)
- No approval history/audit trail beyond basic fields