Architecture Overview
SnackBase follows Clean Architecture principles with clear separation between business logic and infrastructure concerns.Layer Structure
| Layer | Purpose | Dependencies |
|---|---|---|
| Frontend | React admin UI | API Layer (HTTP) |
| API Layer | FastAPI routes, middleware | Domain, Core, Infrastructure |
| Core Layer | Cross-cutting concerns | Zero framework deps |
| Domain Layer | Business logic, entities | Core only |
| Application Layer | Use cases (placeholder) | Domain |
| Infrastructure Layer | External concerns | Domain, Core |
Key Architectural Patterns
- Repository Pattern: 17 repositories abstract data access
- Service Layer Pattern: 17 domain services contain business logic
- Hook System: 33+ events across 8 categories for extensibility (stable API v1.0)
- Rule Engine: Custom DSL for permission expressions
- Multi-Tenancy: Row-level isolation via
account_id - JWT Authentication: Access token (1h) + refresh token (7d)
- Configuration System: Hierarchical provider configuration with encryption at rest
- 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
| Category | Technology |
|---|---|
| Backend | Python 3.12+, FastAPI, SQLAlchemy 2.0 (async) |
| Database | SQLite (dev), PostgreSQL (prod) |
| Frontend | React 19, TypeScript, Vite 7, React Router v7 |
| UI | TailwindCSS 4, Radix UI, ShadCN, Lucide Icons |
| State | Zustand, TanStack Query |
| Auth | JWT (HS256), Argon2id password hashing |
| Logging | structlog (JSON in production) |
| Validation | Pydantic, Zod |
| Templates | Jinja2 for email templates |
| Crypto | cryptography (Fernet) for config encryption |
| OAuth | Authlib for OAuth 2.0 flow |
| SAML | python3-saml for SAML SSO |
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-000000000000for 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
| Category | Providers |
|---|---|
| Auth Providers | Email/Password |
| Email Providers | SMTP, AWS SES, Resend |
| OAuth Providers | Google, GitHub, Microsoft, Apple |
| SAML Providers | Okta, Azure AD, Generic SAML |
| System | System Configuration |
2. Email Verification System
Handles email address verification with secure token-based workflow. Components:EmailVerificationTokenModel- Stores SHA-256 hashed tokensEmailVerificationRepository- Database operationsEmailVerificationService- Business logic for verification workflow- Token expiration: 24 hours
- Single-use tokens (marked as used after verification)
- User registers →
send_verification_email()generates token - Token stored as SHA-256 hash
- Email sent with verification URL
- User clicks link →
verify_email()validates token - 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 supportEmailTemplateRepository- Template CRUD operationsTemplateRenderer- Jinja2-based renderingEmailService- Orchestrates sending with provider selection
email_verification- Email verification emailspassword_reset- Password reset emailsinvitation- User invitation emails
- Account-level templates override system defaults
- Multi-language support via
localefield - 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:| Category | Events |
|---|---|
| App Lifecycle (3) | on_bootstrap, on_serve, on_terminate |
| Model Operations (6) | on_model_before/after_create/update/delete |
| Record Operations (8) | on_record_before/after_create/update/delete/query |
| Collection Operations (6) | on_collection_before/after_create/update/delete |
| Auth Operations (8) | on_auth_before/after_login/logout/register/password_reset |
| Request Processing (2) | on_before_request, on_after_request |
| Realtime (4) | on_realtime_connect/disconnect/message/subscribe/unsubscribe |
| Mailer (2) | on_mailer_before/after_send |
timestamp_hook(priority: -100) - Setscreated_at/updated_ataccount_isolation_hook(priority: -200) - Enforcesaccount_idon recordscreated_by_hook(priority: -150) - Setscreated_by/updated_byaudit_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:- Column-level granularity: Each row represents a single column change
- Immutable: Database triggers prevent UPDATE/DELETE operations
- Blockchain integrity:
checksumandprevious_hashchain - 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
- SQLAlchemy event listener detects model change OR hook detects record change
AuditLogServicecreates audit entries for each changed columnAuditChecksumcomputes SHA-256 hash linking to previous entry- Entries written atomically with the operation
- Database triggers enforce immutability
Data Flow Examples
Authentication Flow
Permission Check Flow
Record Creation Flow
Email Sending Flow
Key Files
| File | Purpose |
|---|---|
src/snackbase/infrastructure/api/app.py | FastAPI app factory |
src/snackbase/core/config.py | Pydantic Settings |
src/snackbase/core/hooks/hook_registry.py | Hook system core |
src/snackbase/core/configuration/config_registry.py | Configuration registry |
src/snackbase/core/rules/ | Rule engine (lexer→parser→AST→evaluator) |
src/snackbase/domain/services/permission_resolver.py | Permission resolution |
src/snackbase/domain/services/email_verification_service.py | Email verification logic |
src/snackbase/domain/services/audit_log_service.py | Audit logging service |
src/snackbase/infrastructure/persistence/database.py | SQLAlchemy engine |
src/snackbase/infrastructure/persistence/table_builder.py | Dynamic table creation |
src/snackbase/infrastructure/services/email_service.py | Email sending with templates |
src/snackbase/infrastructure/hooks/builtin_hooks.py | Built-in hook implementations |
ui/src/main.tsx | React app entry |
ui/src/App.tsx | Route configuration |
ui/src/lib/api.ts | Axios client with token refresh |