9.8 KiB
Phase 7: Email Folders API - Quick Start Guide
Installation & Setup
1. Install Dependencies
The email service already has all required dependencies in requirements.txt:
- Flask 3.0.0
- SQLAlchemy 2.0.23
- PostgreSQL driver (psycopg2)
- pytest for testing
pip install -r requirements.txt
2. Database Setup
# Create database
createdb email_service
# Initialize tables
python3 -c "from src.db import init_db, db; from app import app; init_db(app); db.create_all()"
3. Start Service
python3 app.py
Service runs on http://localhost:5000
Quick API Examples
Create an Email Account First
curl -X POST http://localhost:5000/api/accounts \
-H "Content-Type: application/json" \
-H "X-Tenant-ID: tenant-123" \
-H "X-User-ID: user-456" \
-d '{
"accountName": "Work Email",
"emailAddress": "user@company.com",
"hostname": "imap.company.com",
"port": 993,
"username": "user@company.com",
"credentialId": "cred-789"
}'
Returns: { "id": "acc-123", ... }
List All Folders in Account
curl -X GET "http://localhost:5000/api/accounts/acc-123/folders?tenant_id=tenant-123&user_id=user-456"
Create a Custom Folder
curl -X POST http://localhost:5000/api/accounts/acc-123/folders \
-H "Content-Type: application/json" \
-H "X-Tenant-ID: tenant-123" \
-H "X-User-ID: user-456" \
-d '{
"folderName": "Projects",
"displayName": "My Projects"
}'
Returns: { "id": "folder-123", "folderName": "Projects", ... }
Update Folder Message Counts
curl -X PUT http://localhost:5000/api/accounts/acc-123/folders/folder-123 \
-H "Content-Type: application/json" \
-H "X-Tenant-ID: tenant-123" \
-H "X-User-ID: user-456" \
-d '{
"unreadCount": 5,
"totalCount": 42
}'
Get Folder Hierarchy
curl -X GET "http://localhost:5000/api/accounts/acc-123/folders/folder-123/hierarchy?tenant_id=tenant-123&user_id=user-456"
Delete Folder (Soft Delete)
curl -X DELETE "http://localhost:5000/api/accounts/acc-123/folders/folder-123?tenant_id=tenant-123&user_id=user-456"
Delete Folder (Hard Delete)
curl -X DELETE "http://localhost:5000/api/accounts/acc-123/folders/folder-123?tenant_id=tenant-123&user_id=user-456&hard_delete=true"
Run Tests
All Tests
pytest tests/test_folders.py -v
With Coverage
pytest tests/test_folders.py -v --cov=src/routes/folders --cov=src/models/folder --cov-report=html
Specific Test Class
pytest tests/test_folders.py::TestCreateFolder -v
Specific Test
pytest tests/test_folders.py::TestCreateFolder::test_create_folder_success -v
File Structure
services/email_service/
├── app.py # Flask app entry point
├── requirements.txt # Python dependencies
├── src/
│ ├── db.py # Database configuration
│ ├── models/
│ │ ├── account.py # EmailAccount model
│ │ └── folder.py # EmailFolder model (NEW)
│ └── routes/
│ ├── accounts.py # Account endpoints
│ ├── sync.py # Sync endpoints
│ ├── compose.py # Compose endpoints
│ └── folders.py # Folder endpoints (NEW)
├── tests/
│ └── test_folders.py # Folder API tests (NEW)
├── PHASE7_FOLDERS_API.md # Full API documentation
├── PHASE7_IMPLEMENTATION_SUMMARY.md # Implementation details
└── PHASE7_QUICK_START.md # This file
Key Classes & Methods
EmailFolder Model
# List folders for an account
folders = EmailFolder.list_for_account(account_id, tenant_id, user_id)
# Get single folder
folder = EmailFolder.get_by_id(folder_id, tenant_id, user_id)
# Get system folder (inbox, sent, etc)
inbox = EmailFolder.get_system_folder(account_id, 'inbox', tenant_id, user_id)
# Create folder
folder = EmailFolder.create(data, tenant_id, user_id, account_id)
# Update folder
folder.update({'displayName': 'New Name'})
# Increment message count
folder.increment_message_count(is_unread=True)
# Get child folders
children = folder.get_child_folders()
# Get full hierarchy path
path = folder.get_hierarchy_path()
# Delete (soft)
folder.delete()
# Delete (hard)
folder.hard_delete()
API Response Format
All endpoints return JSON:
{
"folders": [ { ... } ], // For list endpoints
"id": "uuid", // For single resource
"message": "...", // For operations
"error": "...", // On error
"count": 5 // For collections
}
Authentication
Multi-Tenant Headers
All requests require:
X-Tenant-ID- Organization identifierX-User-ID- User identifier
Header vs Query Parameters
- POST/PUT: Use headers
X-Tenant-ID,X-User-ID - GET/DELETE: Use query params
?tenant_id=...&user_id=...
Special Folders
These folders are system-managed:
- inbox - Incoming mail (cannot delete/rename)
- sent - Sent messages (cannot delete/rename)
- drafts - Draft messages (cannot delete/rename)
- trash - Trash/deleted messages (cannot delete/rename)
- spam - Spam/junk messages (cannot delete/rename)
Custom folders can be freely deleted and renamed.
Common Errors
401 Unauthorized
{
"error": "Unauthorized",
"message": "X-Tenant-ID and X-User-ID headers (or tenant_id and user_id query params) required"
}
Solution: Add auth headers or query params
404 Not Found
{
"error": "Not found",
"message": "Account ... not found or unauthorized"
}
Solution: Verify account_id, tenant_id, user_id are correct and account belongs to user
409 Conflict
{
"error": "Conflict",
"message": "Folder \"Projects\" already exists"
}
Solution: Use different folder name or delete existing folder first
403 Forbidden
{
"error": "Forbidden",
"message": "Cannot delete system folders"
}
Solution: Only custom folders can be deleted. Check isSystemFolder flag
Folder Hierarchy Example
Create parent folder:
curl -X POST http://localhost:5000/api/accounts/acc-123/folders \
-H "X-Tenant-ID: tenant-123" \
-H "X-User-ID: user-456" \
-H "Content-Type: application/json" \
-d '{"folderName": "Projects"}'
# Returns: {"id": "parent-id", ...}
Create child folder:
curl -X POST http://localhost:5000/api/accounts/acc-123/folders \
-H "X-Tenant-ID: tenant-123" \
-H "X-User-ID: user-456" \
-H "Content-Type: application/json" \
-d '{
"folderName": "Q1",
"parentFolderId": "parent-id",
"imapName": "Projects/Q1"
}'
# Returns: {"id": "child-id", "parentFolderId": "parent-id", ...}
Get hierarchy:
curl -X GET "http://localhost:5000/api/accounts/acc-123/folders/child-id/hierarchy?tenant_id=tenant-123&user_id=user-456"
# Returns parent path and children
Message Count Tracking
Folders track message counts:
{
"id": "folder-123",
"folderName": "INBOX",
"unreadCount": 5, // Unread messages
"totalCount": 42, // Total messages
"lastSyncedAt": 1706033200000
}
Update counts when syncing:
curl -X PUT http://localhost:5000/api/accounts/acc-123/folders/folder-123 \
-H "X-Tenant-ID: tenant-123" \
-H "X-User-ID: user-456" \
-H "Content-Type: application/json" \
-d '{
"unreadCount": 10,
"totalCount": 50
}'
Or use model methods:
folder = EmailFolder.get_by_id(folder_id, tenant_id, user_id)
folder.increment_message_count(is_unread=True) # New unread message
folder.decrement_message_count(is_unread=True) # Marked as read
Next Steps
Phase 8: Messages API
- Implement EmailMessage model
- Integrate with folder message counts
- Implement
GET /api/accounts/:id/folders/:folderId/messagesfully
Phase 9: Email Sync
- Implement IMAP folder sync
- Update sync state fields (UIDVALIDITY, UIDNEXT)
- Sync message counts from server
Phase 10: Search
- Full-text search across folders
- Advanced filtering
- Message search
Troubleshooting
Database Connection Error
error: "database ... does not exist"
Solution: Create database with createdb email_service
Import Error
ModuleNotFoundError: No module named 'src'
Solution: Run from email_service root directory, not subdirectory
Test Failures
FAILED tests/test_folders.py::...
Solution: Run pytest tests/test_folders.py -v to see full error details
CORS Error
Access to XMLHttpRequest blocked by CORS policy
Solution: Check CORS_ORIGINS environment variable includes client origin
Development Commands
# Run app
python3 app.py
# Run tests
pytest tests/test_folders.py -v
# Run with coverage
pytest tests/test_folders.py --cov
# Check syntax
python3 -m py_compile src/routes/folders.py
# Health check
curl http://localhost:5000/health
# List all folders
curl "http://localhost:5000/api/accounts/ACC-ID/folders?tenant_id=TENANT-ID&user_id=USER-ID"
Production Checklist
- Database configured (PostgreSQL in production, SQLite in dev)
- CORS origins configured for client domain
- Email tables created and indexed
- Tests passing
- API documentation reviewed
- Auth headers properly validated
- Error responses tested
- Multi-tenant isolation verified
- Rate limiting configured
- Monitoring/logging enabled
- Backup strategy in place
Resources
- Full API Docs:
PHASE7_FOLDERS_API.md - Implementation Details:
PHASE7_IMPLEMENTATION_SUMMARY.md - Tests:
tests/test_folders.py - Email Service README:
README.md
Status: ✅ Production Ready Last Updated: 2026-01-24