mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-05-04 10:44:52 +00:00
df5398a7ee
Complete implementation of enterprise-grade authentication middleware for email service: Features: - JWT token creation/validation with configurable expiration - Bearer token extraction and validation - Multi-tenant isolation enforced at middleware level - Role-based access control (RBAC) with user/admin roles - Row-level security (RLS) for resource access - Automatic request logging with user context and audit trail - CORS configuration for email client frontend - Rate limiting (50 req/min per user with Redis backend) - Comprehensive error handling with proper HTTP status codes Implementation: - Enhanced src/middleware/auth.py (415 lines) - JWTConfig class for token management - create_jwt_token() for token generation - decode_jwt_token() for token validation - @verify_tenant_context decorator for auth middleware - @verify_role decorator for RBAC - verify_resource_access() for row-level security - log_request_context() for audit logging Testing: - 52 comprehensive test cases covering all features - 100% pass rate with fast execution (0.15s) - Test categories: JWT, multi-tenant, RBAC, RLS, logging, integration - Full coverage of error scenarios and edge cases Documentation: - AUTH_MIDDLEWARE.md: Complete API reference and configuration guide - AUTH_INTEGRATION_EXAMPLE.py: Real-world usage examples for 5+ scenarios - PHASE_7_SUMMARY.md: Implementation summary with checklist - Inline code documentation with type hints Security: - Multi-tenant data isolation at all levels - Constant-time password comparison - JWT signature validation - CORS protection - Rate limiting against abuse - Comprehensive audit logging Dependencies Added: - PyJWT==2.8.1 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
499 lines
13 KiB
Markdown
499 lines
13 KiB
Markdown
# Email Service PostgreSQL Container
|
|
|
|
PostgreSQL 16 Docker container configured for MetaBuilder email client with IMAP/SMTP support. Provides multi-tenant database with row-level security, comprehensive indexing, and production-ready configuration.
|
|
|
|
## Features
|
|
|
|
### Database Design
|
|
- **4 Core Tables**: email_accounts, email_folders, email_messages, email_attachments
|
|
- **Multi-Tenant**: Tenant isolation via Row Level Security (RLS) policies
|
|
- **RFC 5322 Compliant**: Full email header support with threading
|
|
- **Soft Deletes**: Audit trail via is_deleted flags and deleted_at timestamps
|
|
- **IMAP Sync**: Message-ID and IMAP UID tracking for incremental sync
|
|
|
|
### Security
|
|
- **Row Level Security**: All tables use RLS for tenant isolation
|
|
- **pgcrypto Extension**: UUID generation and password hashing
|
|
- **Application User**: Separate email_service user with limited privileges
|
|
- **Encryption Support**: TLS/STARTTLS configuration for remote connections
|
|
|
|
### Performance
|
|
- **30+ Indexes**: Optimized for common queries (sync, search, threading)
|
|
- **Connection Pooling**: Supports 200 concurrent connections
|
|
- **Full-Text Search**: GIN index for subject and body search
|
|
- **Query Optimization**: Partial indexes for active/unread messages
|
|
|
|
### High Availability
|
|
- **Health Checks**: Automatic liveness probe on port 5432
|
|
- **Data Persistence**: Docker volumes for recovery across container restarts
|
|
- **Incremental Backups**: WAL configuration for point-in-time recovery
|
|
- **Replication Ready**: Configuration for primary/standby setup
|
|
|
|
## Quick Start
|
|
|
|
### Development
|
|
|
|
```bash
|
|
# Start PostgreSQL container
|
|
docker-compose -f deployment/docker/docker-compose.email-service.yml up email-postgres
|
|
|
|
# Connect with psql
|
|
psql postgresql://email_service:postgres@localhost:5434/email_service
|
|
|
|
# View database structure
|
|
\dt email_*
|
|
\di idx_email_*
|
|
|
|
# Check connection pool status
|
|
SELECT * FROM pg_stat_activity;
|
|
```
|
|
|
|
### Docker Compose
|
|
|
|
```yaml
|
|
version: '3.8'
|
|
|
|
services:
|
|
email-postgres:
|
|
build:
|
|
context: deployment/docker/postgres
|
|
dockerfile: Dockerfile
|
|
container_name: email-postgres
|
|
environment:
|
|
POSTGRES_DB: email_service
|
|
POSTGRES_USER: email_service
|
|
POSTGRES_PASSWORD: secure_password
|
|
volumes:
|
|
- email_postgres_data:/var/lib/postgresql/data
|
|
ports:
|
|
- "5434:5432"
|
|
networks:
|
|
- email-service-network
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U email_service -d email_service"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
volumes:
|
|
email_postgres_data:
|
|
driver: local
|
|
|
|
networks:
|
|
email-service-network:
|
|
driver: bridge
|
|
```
|
|
|
|
## Database Schema
|
|
|
|
### email_accounts
|
|
Email account configuration (IMAP/POP3/SMTP).
|
|
|
|
```sql
|
|
CREATE TABLE email_accounts (
|
|
id UUID PRIMARY KEY,
|
|
tenant_id UUID NOT NULL,
|
|
user_id UUID NOT NULL,
|
|
account_name VARCHAR(255),
|
|
email_address VARCHAR(255) UNIQUE,
|
|
protocol VARCHAR(20) -- 'imap', 'pop3'
|
|
hostname VARCHAR(255),
|
|
port INTEGER,
|
|
encryption VARCHAR(20) -- 'none', 'tls', 'starttls'
|
|
username VARCHAR(255),
|
|
credential_id UUID,
|
|
is_sync_enabled BOOLEAN DEFAULT TRUE,
|
|
sync_interval INTEGER DEFAULT 300,
|
|
last_sync_at BIGINT,
|
|
is_syncing BOOLEAN DEFAULT FALSE,
|
|
is_enabled BOOLEAN DEFAULT TRUE,
|
|
created_at BIGINT,
|
|
updated_at BIGINT
|
|
);
|
|
|
|
Indexes:
|
|
- idx_email_accounts_tenant_user (tenant_id, user_id)
|
|
- idx_email_accounts_email_address (email_address)
|
|
- idx_email_accounts_sync_enabled (tenant_id, is_sync_enabled, last_sync_at)
|
|
```
|
|
|
|
### email_folders
|
|
Email folder hierarchy (Inbox, Sent, Drafts, custom).
|
|
|
|
```sql
|
|
CREATE TABLE email_folders (
|
|
id UUID PRIMARY KEY,
|
|
tenant_id UUID NOT NULL,
|
|
account_id UUID NOT NULL REFERENCES email_accounts,
|
|
name VARCHAR(255),
|
|
type VARCHAR(20) -- 'inbox', 'sent', 'drafts', 'trash', 'spam', 'archive', 'custom'
|
|
unread_count INTEGER DEFAULT 0,
|
|
total_count INTEGER DEFAULT 0,
|
|
sync_token TEXT,
|
|
is_selectable BOOLEAN DEFAULT TRUE,
|
|
created_at BIGINT,
|
|
updated_at BIGINT
|
|
);
|
|
|
|
Indexes:
|
|
- idx_email_folders_account_type (account_id, type)
|
|
- idx_email_folders_tenant_account (tenant_id, account_id)
|
|
- idx_email_folders_type (type) WHERE type IN ('inbox', 'sent', ...)
|
|
```
|
|
|
|
### email_messages
|
|
Email messages with RFC 5322 headers and threading support.
|
|
|
|
```sql
|
|
CREATE TABLE email_messages (
|
|
id UUID PRIMARY KEY,
|
|
tenant_id UUID NOT NULL,
|
|
account_id UUID NOT NULL REFERENCES email_accounts,
|
|
folder_id UUID NOT NULL REFERENCES email_folders,
|
|
message_id VARCHAR(500) NOT NULL,
|
|
imap_uid VARCHAR(100),
|
|
in_reply_to VARCHAR(500),
|
|
from VARCHAR(500),
|
|
to JSONB, -- ['user@example.com', ...]
|
|
cc JSONB,
|
|
bcc JSONB,
|
|
reply_to VARCHAR(255),
|
|
subject VARCHAR(500),
|
|
text_body TEXT,
|
|
html_body TEXT,
|
|
is_read BOOLEAN DEFAULT FALSE,
|
|
is_flagged BOOLEAN DEFAULT FALSE,
|
|
is_draft BOOLEAN DEFAULT FALSE,
|
|
thread_id UUID,
|
|
sent_at BIGINT,
|
|
received_at BIGINT,
|
|
created_at BIGINT,
|
|
updated_at BIGINT
|
|
);
|
|
|
|
Indexes:
|
|
- idx_email_messages_folder_received (folder_id, received_at DESC)
|
|
- idx_email_messages_thread_id (thread_id)
|
|
- idx_email_messages_account_read (account_id, is_read)
|
|
- idx_email_messages_message_id (message_id, account_id) UNIQUE
|
|
- idx_email_messages_imap_uid (imap_uid, folder_id) UNIQUE
|
|
- idx_email_messages_text_search (full-text search on subject + body)
|
|
```
|
|
|
|
### email_attachments
|
|
File attachments with S3/blob storage references.
|
|
|
|
```sql
|
|
CREATE TABLE email_attachments (
|
|
id UUID PRIMARY KEY,
|
|
tenant_id UUID NOT NULL,
|
|
message_id UUID NOT NULL REFERENCES email_messages,
|
|
filename VARCHAR(500),
|
|
mime_type VARCHAR(100),
|
|
size_bytes INTEGER,
|
|
storage_path VARCHAR(1000),
|
|
storage_type VARCHAR(20) -- 'blob', 's3', 'local'
|
|
blob_id UUID,
|
|
content_hash VARCHAR(64),
|
|
created_at BIGINT
|
|
);
|
|
|
|
Indexes:
|
|
- idx_email_attachments_message_id (message_id)
|
|
- idx_email_attachments_tenant (tenant_id)
|
|
- idx_email_attachments_storage_path (storage_path)
|
|
- idx_email_attachments_content_hash (content_hash)
|
|
```
|
|
|
|
## Configuration
|
|
|
|
### Connection Pooling (Port 5432)
|
|
|
|
```
|
|
max_connections = 200
|
|
|
|
For external pooling with PgBouncer:
|
|
max_client_conn = 1000 (clients)
|
|
max_db_connections = 25 (per database)
|
|
default_pool_size = 25 (per user)
|
|
reserve_pool_size = 5 (reserve)
|
|
```
|
|
|
|
### Memory Settings
|
|
|
|
```
|
|
shared_buffers = 256MB # PostgreSQL page cache
|
|
effective_cache_size = 1GB # Query planner hint
|
|
work_mem = 1310kB # Per-operation sorting/hashing
|
|
maintenance_work_mem = 64MB # CREATE INDEX, VACUUM, ALTER
|
|
```
|
|
|
|
### WAL (Write-Ahead Logging)
|
|
|
|
```
|
|
wal_buffers = 16MB # WAL page cache
|
|
min_wal_size = 1GB # Minimum WAL files
|
|
max_wal_size = 4GB # Maximum WAL files before checkpoint
|
|
checkpoint_completion_target = 0.9 # Spread I/O over time
|
|
```
|
|
|
|
### Query Planning
|
|
|
|
```
|
|
random_page_cost = 1.1 # SSD-optimized
|
|
effective_io_concurrency = 200 # NVMe-optimized
|
|
default_statistics_target = 100 # Column statistics
|
|
```
|
|
|
|
## Initialization Scripts
|
|
|
|
Executed automatically on container startup in order:
|
|
|
|
### 1. init-email-service.sql
|
|
- Creates email_service database
|
|
- Creates 4 core tables with constraints
|
|
- Enables extensions (uuid-ossp, pgcrypto, pg_trgm)
|
|
- Sets up RLS policies for multi-tenancy
|
|
- Creates audit table (email_audit_log)
|
|
|
|
### 2. init-indexes.sql
|
|
- Creates 30+ indexes for query optimization
|
|
- Partial indexes for active/unread messages
|
|
- BRIN indexes for timestamp columns
|
|
- Analyzes statistics for query planner
|
|
|
|
### 3. init-connection-pooling.sql
|
|
- Configures connection pooling parameters
|
|
- Creates monitoring views (pg_connection_stats, pg_long_queries)
|
|
- Provides helper functions (pg_table_bloat_status)
|
|
- Documents configuration guidelines
|
|
|
|
## Multi-Tenant Isolation
|
|
|
|
Row Level Security (RLS) policies ensure data isolation:
|
|
|
|
```sql
|
|
-- RLS Policy: email_messages - tenant isolation
|
|
CREATE POLICY email_messages_tenant_policy ON email_messages
|
|
USING (tenant_id = current_setting('app.current_tenant_id')::UUID)
|
|
WITH CHECK (tenant_id = current_setting('app.current_tenant_id')::UUID);
|
|
```
|
|
|
|
Application must set tenant context before queries:
|
|
|
|
```typescript
|
|
// Set tenant for this connection
|
|
await db.raw(`SET LOCAL app.current_tenant_id = '${tenantId}'`)
|
|
|
|
// All subsequent queries automatically filtered by tenant_id
|
|
const messages = await db.email_messages.select() // Only this tenant's messages
|
|
```
|
|
|
|
## Monitoring
|
|
|
|
### Connection Usage
|
|
|
|
```sql
|
|
-- Current connections by user/database
|
|
SELECT * FROM pg_connection_stats;
|
|
|
|
-- Long-running queries
|
|
SELECT * FROM pg_long_queries;
|
|
```
|
|
|
|
### Table Statistics
|
|
|
|
```sql
|
|
-- Table bloat
|
|
SELECT * FROM pg_table_bloat_status();
|
|
|
|
-- Index usage
|
|
SELECT * FROM pg_stat_user_indexes ORDER BY idx_scan DESC;
|
|
|
|
-- Unused indexes
|
|
SELECT * FROM pg_stat_user_indexes WHERE idx_scan = 0;
|
|
```
|
|
|
|
### Query Performance
|
|
|
|
```sql
|
|
-- Cache hit ratio (should be > 95%)
|
|
SELECT
|
|
sum(heap_blks_read) as heap_read,
|
|
sum(heap_blks_hit) as heap_hit,
|
|
sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) as ratio
|
|
FROM pg_statio_user_tables;
|
|
|
|
-- Slow queries (> 1 second)
|
|
SELECT query, calls, mean_exec_time FROM pg_stat_statements
|
|
WHERE mean_exec_time > 1000
|
|
ORDER BY mean_exec_time DESC;
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### PostgreSQL won't start
|
|
|
|
```bash
|
|
# Check logs
|
|
docker logs metabuilder-email-postgres
|
|
|
|
# Verify data directory permissions
|
|
docker exec metabuilder-email-postgres ls -la /var/lib/postgresql
|
|
|
|
# Reset volume
|
|
docker volume rm email_postgres_data
|
|
docker-compose up email-postgres
|
|
```
|
|
|
|
### Health check failing
|
|
|
|
```bash
|
|
# Check if PostgreSQL is responsive
|
|
docker exec metabuilder-email-postgres pg_isready -U email_service
|
|
|
|
# View last 50 lines of logs
|
|
docker logs --tail 50 metabuilder-email-postgres
|
|
|
|
# Connect directly
|
|
docker exec -it metabuilder-email-postgres psql -U email_service -d email_service
|
|
```
|
|
|
|
### Connection pool exhausted
|
|
|
|
```sql
|
|
-- Check active connections
|
|
SELECT datname, usename, COUNT(*) FROM pg_stat_activity GROUP BY datname, usename;
|
|
|
|
-- Kill idle connections (over 30 minutes)
|
|
SELECT pg_terminate_backend(pid) FROM pg_stat_activity
|
|
WHERE state = 'idle' AND query_start < NOW() - INTERVAL '30 minutes';
|
|
|
|
-- Increase max_connections (requires restart)
|
|
ALTER SYSTEM SET max_connections = 300;
|
|
SELECT pg_reload_conf();
|
|
```
|
|
|
|
### Slow queries
|
|
|
|
```sql
|
|
-- Enable slow query logging
|
|
ALTER SYSTEM SET log_min_duration_statement = 1000; -- 1 second
|
|
SELECT pg_reload_conf();
|
|
|
|
-- View slow query log
|
|
SELECT query_start, query, query_time FROM pg_stat_statements
|
|
ORDER BY mean_exec_time DESC
|
|
LIMIT 10;
|
|
```
|
|
|
|
## Performance Tuning
|
|
|
|
### For production (8GB+ RAM)
|
|
|
|
```sql
|
|
ALTER SYSTEM SET shared_buffers = '2GB';
|
|
ALTER SYSTEM SET effective_cache_size = '6GB';
|
|
ALTER SYSTEM SET work_mem = '10MB';
|
|
ALTER SYSTEM SET maintenance_work_mem = '512MB';
|
|
SELECT pg_reload_conf();
|
|
```
|
|
|
|
### For high-throughput email (1000+ messages/sec)
|
|
|
|
```sql
|
|
ALTER SYSTEM SET wal_level = 'minimal'; # Disable replication logging
|
|
ALTER SYSTEM SET synchronous_commit = 'off'; # Async WAL writes
|
|
ALTER SYSTEM SET max_wal_size = '16GB';
|
|
SELECT pg_reload_conf();
|
|
```
|
|
|
|
### For read-heavy workloads
|
|
|
|
```sql
|
|
ALTER SYSTEM SET random_page_cost = 1.01; # Favor index scans
|
|
ALTER SYSTEM SET effective_io_concurrency = 500;
|
|
ALTER SYSTEM SET effective_cache_size = '8GB';
|
|
SELECT pg_reload_conf();
|
|
```
|
|
|
|
## Backup & Recovery
|
|
|
|
### Manual backup
|
|
|
|
```bash
|
|
# Backup entire database
|
|
docker exec metabuilder-email-postgres pg_dump -U email_service email_service > backup.sql
|
|
|
|
# Backup with compression
|
|
docker exec metabuilder-email-postgres pg_dump -U email_service -Fc email_service > backup.dump
|
|
|
|
# Restore from backup
|
|
docker exec -i metabuilder-email-postgres psql -U email_service email_service < backup.sql
|
|
```
|
|
|
|
### Point-in-time recovery
|
|
|
|
```sql
|
|
-- Enable WAL archiving
|
|
ALTER SYSTEM SET archive_mode = 'on';
|
|
ALTER SYSTEM SET archive_command = 'cp %p /mnt/archive/%f';
|
|
SELECT pg_reload_conf();
|
|
|
|
-- Recover to specific timestamp
|
|
SELECT pg_create_restore_point('pre_migration');
|
|
|
|
-- Restore using backup + WAL files
|
|
```
|
|
|
|
## Docker Compose Integration
|
|
|
|
### Development Environment
|
|
|
|
```bash
|
|
# Start all services (PostgreSQL + email service + Redis)
|
|
docker-compose -f deployment/docker/docker-compose.email-service.yml up
|
|
|
|
# View logs
|
|
docker-compose -f deployment/docker/docker-compose.email-service.yml logs -f email-postgres
|
|
|
|
# Stop services
|
|
docker-compose -f deployment/docker/docker-compose.email-service.yml down
|
|
```
|
|
|
|
### Production Environment
|
|
|
|
```bash
|
|
# Start with production overrides
|
|
docker-compose \
|
|
-f deployment/docker/docker-compose.email-service.yml \
|
|
-f deployment/docker/docker-compose.email-service.prod.yml \
|
|
up -d
|
|
|
|
# View status
|
|
docker-compose -f deployment/docker/docker-compose.email-service.yml ps
|
|
```
|
|
|
|
## Environment Variables
|
|
|
|
Create `.env` file in `deployment/docker/`:
|
|
|
|
```bash
|
|
# Database
|
|
POSTGRES_PASSWORD=secure_password_here
|
|
POSTGRES_PORT=5434
|
|
|
|
# Email service (future)
|
|
FLASK_ENV=production
|
|
LOG_LEVEL=INFO
|
|
IMAP_POLL_INTERVAL=300
|
|
SMTP_TIMEOUT=30
|
|
```
|
|
|
|
## References
|
|
|
|
- [PostgreSQL Documentation](https://www.postgresql.org/docs/16/)
|
|
- [PostgreSQL Performance Tuning](https://www.postgresql.org/docs/current/runtime-config.html)
|
|
- [Row Level Security](https://www.postgresql.org/docs/current/ddl-rowsecurity.html)
|
|
- [Email Schemas](../../docs/plans/2026-01-23-email-client-implementation.md)
|