ADR-003: Sync Architecture
Status: Accepted Date: December 17, 2025 Decision Makers: CODITECT Engineering Team
Context
CODITECT needs to stay synchronized with Google Drive changes:
- Detect file uploads, modifications, deletions
- Update local caches and indexes
- Trigger downstream workflows (e.g., transcription)
- Maintain consistency across sessions
Decision
Implement hybrid sync with push notifications and polling fallback.
Architecture
Push (Primary) Poll (Fallback)
│ │
Google Drive ────────────┼────────────────────────┤
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Webhook Handler │ │ Poll Service │
│ (Real-time) │ │ (Every 60s) │
└────────┬────────┘ └────────┬────────┘
│ │
▼ ▼
┌─────────────────────────────────────────┐
│ Change Processor │
│ - Deduplicate events │
│ - Update local cache │
│ - Trigger workflows │
└─────────────────────────────────────────┘
Push Notification Flow
- Register watch channel with Google Drive API
- Receive POST to webhook URL on changes
- Fetch actual changes via Changes API
- Process and route to handlers
- Renew channel before expiration (7 days max)
Polling Flow (Fallback)
- Store last
pageToken - Poll every 60 seconds
- Fetch changes since token
- Process same as push
Implementation
async def ensure_sync_active():
state = await get_sync_state()
if not state.channel_id or state.channel_expired():
# Start push notifications
await start_watching()
# Always poll as backup
await process_changes()
Consequences
Positive
- Near real-time updates via push
- Reliable with polling fallback
- No missed changes
Negative
- Push channels require renewal
- Webhook endpoint must be publicly accessible
- Some latency on fallback to polling
Document Control:
- Created: December 17, 2025