Social Posts API Refactoring - Complete Overview
📋 Executive Summary
This refactoring transforms the social posts publishing system from a monolithic route handler (351 lines) to a secure, workflow-based architecture with token encryption, reducing complexity by 87% while adding enterprise-grade security.
🎯 Goals
- Security First - Encrypt all tokens at rest (AES-256-GCM)
- Reduce Complexity - Move business logic from routes to workflows
- Eliminate Duplication - Unified publishing logic across platforms
- Improve Testability - Independently testable workflow steps
- Enable Observability - Track workflow execution and failures
📊 Current Problems
1. Route Handler Complexity
- 351 lines of business logic in
/social-posts/[id]/publish/route.ts - Platform detection, token resolution, validation, retry logic all mixed together
- Difficult to test, maintain, and extend
2. Security Risk
- Tokens stored in plaintext in database
- Vulnerable to database breaches
- Exposed in backups and logs
- No compliance with GDPR/PCI DSS
3. Code Duplication
- Logic duplicated between:
/social-posts/[id]/publish/socials/publish-both
- Same validation, token resolution, content detection repeated
4. Inconsistent Patterns
- Some routes use workflows
- Others use direct service calls
- Mixed error handling approaches
🏗️ Proposed Architecture
Before
┌─────────────────────────────────────────┐
│ Route Handler (351 lines) │
│ ├─ Platform detection │
│ ├─ Token resolution │
│ ├─ Content extraction │
│ ├─ Validation │
│ ├─ Smart retry logic │
│ ├─ Publishing │
│ └─ Post update │
└─────────────────────────────────────────┘
↓
Direct Service Calls
↓
Facebook/Instagram/Twitter APIs
After
┌─────────────────────────────────────────┐
│ Route Handler (45 lines) │
│ └─ Call Workflow │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Unified Publishing Workflow │
│ ├─ loadPostWithPlatformStep │
│ ├─ validatePlatformStep (decrypt) │
│ ├─ resolvePublishTargetStep │
│ ├─ extractContentStep │
│ ├─ validateCompatibilityStep │
│ ├─ publishToTargetPlatformsStep │
│ ├─ mergePublishResultsStep │
│ └─ updatePostWithResultsStep │
└──────────────────────────── ─────────────┘
↓
Platform-Specific Workflows
↓
Facebook/Instagram/Twitter APIs
🔐 Security Enhancement: Token Encryption
Implementation
- Algorithm: AES-256-GCM (Galois/Counter Mode)
- Key Management: Environment variables with rotation support
- IV: Unique per encryption (12 bytes)
- Authentication: Built-in with GCM mode
Encrypted Data Structure
{
encrypted: "base64-encrypted-data",
iv: "base64-initialization-vector",
authTag: "base64-authentication-tag",
keyVersion: 1 // For key rotation
}
Token Flow
OAuth Callback
↓
Plaintext Tokens
↓
Encrypt with AES-256-GCM
↓
Store Encrypted in Database
↓
Workflow Retrieves
↓
Decrypt for API Calls
↓
Use Token (never logged)
What Gets Encrypted
✅ Access tokens (OAuth 2.0) ✅ Refresh tokens ✅ Page access tokens (Facebook) ✅ OAuth 1.0a secrets (Twitter) ✅ API keys and consumer secrets
What Stays Plaintext
❌ User IDs, usernames ❌ Platform names ❌ Timestamps ❌ Non-sensitive metadata
📐 Schema Validation
Platform-Specific Schemas
Each platform has a validated schema with encrypted tokens:
Facebook:
{
platform: "facebook",
access_token_encrypted: EncryptedData,
page_access_token_encrypted: EncryptedData,
user_access_token_encrypted: EncryptedData,
token_type: "PAGE",
page_id: string,
user_id: string,
authenticated_at: string,
expires_at: string
}
Instagram:
{
platform: "instagram",
access_token_encrypted: EncryptedData,
token_type: "USER",
ig_user_id: string,
page_id: string,
user_id: string,
authenticated_at: string
}
Twitter:
{
platform: "twitter",
access_token_encrypted: EncryptedData,
oauth1_credentials_encrypted: {
access_token: EncryptedData,
access_token_secret: EncryptedData
},
token_type: "USER",
user_id: string,
authenticated_at: string
}
🔄 Workflow Steps
1. Load Post
- Fetch post with platform relation
- Validate post exists
2. Validate Platform
- Check platform exists
- Decrypt tokens from api_config
- Validate token expiration
- Check OAuth credentials
3. Resolve Publish Target
- Determine: facebook, instagram, both, twitter
- Smart retry logic: Only retry failed platforms
- Check previous publish attempts
4. Extract Content
- Parse media attachments
- Determine content type (photo, video, text, reel, carousel)
- Extract caption/message
5. Validate Compatibility
- Check platform constraints
- Twitter: 280 chars, 4 images max
- Instagram: requires media
- Validate content type support
6. Publish to Platforms
- Call appropriate workflow based on target
- Handle errors per platform
- Return results
7. Merge Results
- Merge new results with previous attempts
- Handle retry scenarios
- Preserve webhook insights data
8. Update Post
- Update post status (posted/failed)
- Set post_url
- Update insights
- Set error_message if failed
📈 Impact Metrics
| Metric | Before | After | Improvement |
|---|---|---|---|
| Route Handler | 351 lines | 45 lines | 87% reduction |
| Code Duplication | High | None | 100% eliminated |
| Token Security | Plaintext | AES-256-GCM | Encrypted at rest |
| Testability | Low | High | Independently testable |
| Type Safety | Partial | Full | Runtime + compile-time |
| Maintainability | Low | High | Clear separation |
| Observability | Limited | Full | Workflow tracking |
| Compliance | Basic | Full | GDPR/PCI DSS ready |
🚀 Implementation Phases
Phase 0: Security & External API Foundation ⭐ START HERE
Duration: 3-4 days
Tasks:
-
Encryption Service (Day 1)
- Create
/src/services/encryption-service.ts - Generate encryption keys (dev, staging, prod)
- Add keys to environment variables
- Write unit tests for encrypt/decrypt
- Test key rotation support
- Create
-
External API Module (Day 1-2) ⭐ NEW
- Rename
social-platforms→external-apis - Create
external-apimodel (replaces social-platform) - Create
external-api-connectionmodel (replaces social-platform-account) - Add
categoryfield (social, payment, shipping, etc.) - Update service layer with encryption support
- Create generic API client
- Rename
-
Schema Definition (Day 2-3)
- Create
/src/schemas/external-api-config.ts - Define Zod schemas with encrypted fields
- Support multiple auth types (OAuth2, OAuth1, API Key, Bearer)
- Create helper functions (encrypt/decrypt config)
- Update OAuth callback to encrypt tokens
- Test OAuth flow with encryption
- Create
-
Data Migration (Day 3-4)
- Backup production database
- Create migration script (social-platforms → external-apis)
- Migrate existing social platforms
- Encrypt all credentials
- Test migration on staging
- Run migration on production
- Verify all platforms work
Deliverables:
- ✅ Encryption service with tests
- ✅ External APIs module with multi-API support
- ✅ Generic API client for any integration
- ✅ Schemas with encrypted fields
- ✅ All tokens encrypted in database
- ✅ OAuth flow storing encrypted tokens
- ✅ Foundation for future API integrations (Stripe, Twilio, etc.)
Phase 1: Workflow Implementation
Duration: 3-4 days
Tasks:
-
Create Workflow Steps (Day 1-2)
- Create
/src/workflows/socials/steps/directory - Implement all 8 workflow steps
- Add decryption in validatePlatformStep
- Write unit tests for each step
- Create
-
Create Unified Workflow (Day 2-3)
- Create
publish-social-post-unified.ts - Wire up all workflow steps
- Handle platform branching (Twitter vs FB/IG)
- Add error handling and rollback
- Create
-
Integration Tests (Day 3-4)
- Test Facebook publishing
- Test Instagram publishing
- Test Twitter publishing
- Test FBINSTA (both platforms)
- Test smart retry logic
Deliverables:
- ✅ 8 workflow steps with tests
- ✅ Unified workflow
- ✅ Comprehensive integration tests
Phase 2: Route Refactoring
Duration: 1-2 days
Tasks:
-
Update Route Handler (Day 1)
- Refactor
/social-posts/[id]/publish/route.ts - Replace logic with workflow call
- Maintain backward compatibility
- Test all publishing scenarios
- Refactor
-
Testing (Day 1-2)
- Test all platforms
- Test smart retry
- Test error handling
- Verify no plaintext tokens in logs
Deliverables:
- ✅ Refactored route handler (45 lines)
- ✅ All tests passing
Phase 3: Documentation & Deployment
Duration: 1 day
Tasks:
- Update API documentation
- Document encryption key management
- Deploy to staging
- Monitor for errors
- Deploy to production
- Monitor production metrics
Deliverables:
- ✅ Updated documentation
- ✅ Production deployment
- ✅ Monitoring in place
Phase 4: Cleanup
Duration: 1 day (after grace period)
Tasks:
- Mark
/socials/publish-bothas deprecated - Add deprecation warnings
- Update client code
- Remove deprecated endpoints
Deliverables:
- ✅ Clean codebase
- ✅ No deprecated endpoints
📚 Documentation Files
1. SOCIAL_POSTS_API_ANALYSIS.md
Purpose: Problem analysis and current state Contents:
- Current API structure
- 5 key issues identified
- Recommended refactoring approach
- Benefits and migration strategy
2. /docs/implementation/security/encryption-service ⭐ CRITICAL
Purpose: Complete encryption implementation guide Contents:
- Encryption service implementation
- Key management and rotation
- Helper functions for encrypt/decrypt
- OAuth callback integration
- Workflow usage with decryption
- Migration strategy
- Security best practices
- Testing approach
3. EXTERNAL_API_MANAGEMENT_SYSTEM.md ⭐ NEW - ARCHITECTURE
Purpose: External API management system design Contents:
- Rename social-platforms → external-apis
- Database schema for external APIs
- Support for multiple API categories (social, payment, shipping, etc.)
- Generic API client implementation
- Multi-tenancy support
- Usage examples (Facebook, Stripe, Twilio)
- Migration strategy from social-platforms