Skip to main content

Architecture Overview

SnackBase follows Clean Architecture principles with clear separation between business logic and infrastructure concerns.

Layer Structure

Key Architectural Patterns

  1. Repository Pattern: 17 repositories abstract data access
  2. Service Layer Pattern: 17 domain services contain business logic
  3. Hook System: 33+ events across 8 categories for extensibility (stable API v1.0)
  4. Rule Engine: Custom DSL for permission expressions
  5. Multi-Tenancy: Row-level isolation via account_id
  6. JWT Authentication: Access token (1h) + refresh token (7d)
  7. Configuration System: Hierarchical provider configuration with encryption at rest
  8. Email System: Multi-provider email with template rendering

Component Statistics

  • 19 API Routers: auth, oauth, saml, accounts, collections, roles, permissions, users, groups, invitations, macros, dashboard, files, audit-logs, migrations, admin, email_templates, records, health
  • 17 ORM Models: Account, User, Role, Permission, Collection, Macro, Group, Invitation, RefreshToken, UsersGroups, AuditLog, Configuration, OAuthState, EmailVerification, EmailTemplate, EmailLog
  • 17 Repositories matching each model
  • 17 Domain Entities + 17 Domain Services
  • 10 React Pages + 40+ Components
  • 14 ShadCN UI Components

Technology Stack

Major Systems

1. Configuration/Provider System

The configuration system provides hierarchical provider configuration for external services (authentication, email, storage). Architecture:
  • System-level configs: Use account_id 00000000-0000-0000-0000-000000000000 for defaults
  • Account-level configs: Per-account overrides that take precedence
  • Encryption at rest: All sensitive values encrypted using Fernet symmetric encryption
  • 5-minute TTL cache: ConfigRegistry caches resolved configurations
Built-in Providers (12):

2. Email Verification System

Handles email address verification with secure token-based workflow. Components:
  • EmailVerificationTokenModel - Stores SHA-256 hashed tokens
  • EmailVerificationRepository - Database operations
  • EmailVerificationService - Business logic for verification workflow
  • Token expiration: 24 hours
  • Single-use tokens (marked as used after verification)
Flow:
  1. User registers → send_verification_email() generates token
  2. Token stored as SHA-256 hash
  3. Email sent with verification URL
  4. User clicks link → verify_email() validates token
  5. User record updated: email_verified=True, email_verified_at=now()

3. Email Template System

Multi-language email template system with Jinja2 variable support. Components:
  • EmailTemplateModel - ORM model with locale support
  • EmailTemplateRepository - Template CRUD operations
  • TemplateRenderer - Jinja2-based rendering
  • EmailService - Orchestrates sending with provider selection
Template Types:
  • email_verification - Email verification emails
  • password_reset - Password reset emails
  • invitation - User invitation emails
Features:
  • Account-level templates override system defaults
  • Multi-language support via locale field
  • System variables injected: app_name, app_url, support_email
  • Comprehensive logging via EmailLogModel

4. Hook System (Stable API v1.0)

33+ Hook Events across 8 Categories: Built-in Hooks:
  • timestamp_hook (priority: -100) - Sets created_at/updated_at
  • account_isolation_hook (priority: -200) - Enforces account_id on records
  • created_by_hook (priority: -150) - Sets created_by/updated_by
  • audit_capture_hook (priority: 100) - Captures audit trails for records
  • SQLAlchemy Event Listeners - Systemic audit logging for models

5. Audit Logging System

GxP-compliant audit logging with blockchain-style integrity chain. Features:
  • Configurable: Toggle via SNACKBASE_AUDIT_LOGGING_ENABLED (default: true)
  • Column-level granularity: Each row represents a single column change
  • Immutable: Database triggers prevent UPDATE/DELETE operations
  • Blockchain integrity: checksum and previous_hash chain
  • Electronic signature support: CFR Part 11 compliant (es_username, es_reason, es_timestamp)
  • Systemic capture: SQLAlchemy event listeners automatically log all model changes
  • Record capture: Hooks automatically log all dynamic collection record changes
Audit Flow:
  1. SQLAlchemy event listener detects model change OR hook detects record change
  2. AuditLogService creates audit entries for each changed column
  3. AuditChecksum computes SHA-256 hash linking to previous entry
  4. Entries written atomically with the operation
  5. Database triggers enforce immutability

Data Flow Examples

Authentication Flow

Permission Check Flow

Record Creation Flow

Email Sending Flow

Key Files