Tenant Model Documentation
Overview​
The Tenant model is the cornerstone of CODITECT's multi-tenant architecture, providing complete data isolation and resource management for each customer organization.
Model Structure​
Core Fields​
| Field | Type | Description | Constraints |
|---|---|---|---|
tenant_id | UUID | Unique identifier for the tenant | Primary key, auto-generated |
name | String | Display name of the tenant organization | Required, max 255 chars |
domain | String (Optional) | Custom domain for the tenant | Unique when present |
plan | TenantPlan (Enum) | Subscription tier | Required |
is_active | Boolean | Whether tenant can access the system | Default: true |
created_at | DateTime | When the tenant was created | Auto-set |
updated_at | DateTime | Last modification timestamp | Auto-updated |
settings | TenantSettings | Configuration and limits | Required |
metadata | JSON (Optional) | Custom key-value pairs | Flexible storage |
TenantPlan Enum​
enum TenantPlan {
Free, // Basic features, limited resources
Starter, // Small teams, essential features
Professional, // Growing organizations
Enterprise // Unlimited resources, all features
}
TenantSettings Structure​
| Field | Type | Description | Default |
|---|---|---|---|
max_users | i32 | Maximum allowed users (-1 = unlimited) | 5 |
max_projects | i32 | Maximum allowed projects (-1 = unlimited) | 10 |
max_agents | i32 | Maximum allowed AI agents (-1 = unlimited) | 50 |
features | Vec | Enabled feature flags | ["basic"] |
Database Schema​
Primary Storage Pattern​
Key: /tenants/{tenant_id}
Value: JSON serialized Tenant object
Secondary Indexes​
Domain lookup: /tenant_by_domain/{domain} -> tenant_id
Example Data​
{
"tenant_id": "8eba182c-2ad7-44c5-b0ab-5a1915b6b98a",
"name": "Audit Complete Test 1754630330",
"domain": null,
"plan": "starter",
"is_active": true,
"created_at": "2025-08-08T05:18:51.216297769Z",
"updated_at": "2025-08-08T05:18:51.216297769Z",
"settings": {
"max_users": 10,
"max_projects": 25,
"max_agents": 100,
"features": ["basic", "api"]
},
"metadata": null
}
Plan-Based Settings​
Free Plan​
- max_users: 5
- max_projects: 10
- max_agents: 3
- features: ["basic"]
Starter Plan​
- max_users: 10
- max_projects: 25
- max_agents: 100
- features: ["basic", "api"]
Professional Plan​
- max_users: 50
- max_projects: 100
- max_agents: 500
- features: ["basic", "api", "advanced"]
Enterprise Plan​
- max_users: -1 (unlimited)
- max_projects: -1 (unlimited)
- max_agents: -1 (unlimited)
- features: ["all"]
Related Code​
Source Files​
- Model Definition:
/src/models/tenant.rs - Repository:
/src/db/repositories/tenant_repository.rs - API Handler:
/src/api/handlers/tenant_handlers.rs - DTO:
/src/api/dto/tenant.rs - Tests:
/src/db/repositories/tests/tenant_repository_tests.rs
Key Methods​
impl Tenant {
fn new(name: String, plan: TenantPlan) -> Self
fn can_add_user(&self, current_users: i32) -> bool
fn upgrade_plan(&mut self, new_plan: TenantPlan)
}
Repository Operations​
trait TenantRepository {
async fn create(&self, tenant: &Tenant) -> Result<()>
async fn get_by_id(&self, tenant_id: &Uuid) -> Result<Option<Tenant>>
async fn get_by_domain(&self, domain: &str) -> Result<Option<Tenant>>
async fn update(&self, tenant: &Tenant) -> Result<()>
async fn list_active(&self) -> Result<Vec<Tenant>>
}
API Endpoints​
Create Tenant​
- POST
/api/v1/tenants - Body:
CreateTenantRequest - Response:
Tenant - Auth: System admin only
Get Tenant​
- GET
/api/v1/tenants/{tenant_id} - Response:
Tenant - Auth: Tenant member or admin
Update Tenant​
- PUT
/api/v1/tenants/{tenant_id} - Body:
UpdateTenantRequest - Response:
Tenant - Auth: Tenant admin only
List Tenants​
- GET
/api/v1/tenants - Response:
Vec<Tenant> - Auth: System admin only
Relationships​
One-to-Many​
- Users: A tenant has many users
- Projects: A tenant has many projects
- Entities: A tenant has many entities
- Audit Logs: A tenant has many audit entries
Referenced By​
- All models include
tenant_idfor multi-tenant isolation - Audit logs track tenant-level operations
Business Rules​
-
Tenant Creation
- Name must be unique (soft requirement)
- Domain must be globally unique if specified
- Initial plan determines resource limits
- Personal workspaces auto-created for new users
-
Resource Limits
- Enforced at service layer before operations
- -1 indicates unlimited (Enterprise only)
- Upgrades take effect immediately
- Downgrades require resource compliance
-
Deactivation
- Soft delete only (is_active = false)
- Blocks all access but preserves data
- Can be reactivated by system admin
- Associated users cannot log in
Security Considerations​
-
Data Isolation
- Tenant ID prefix on all keys
- Repository layer enforces tenant boundaries
- Cross-tenant queries explicitly blocked
- Audit logs for all tenant operations
-
Access Control
- Tenant admins manage tenant settings
- System admins manage all tenants
- Users inherit tenant features/limits
- JWT includes tenant context
Performance Optimizations​
-
Caching
- Tenant settings cached in memory
- Domain-to-ID mapping cached
- Plan limits checked without DB hit
-
Indexes
- Primary key index on tenant_id
- Secondary index on domain
- Composite index for active tenant list
Migration Notes​
- Initial tenants created via seed scripts
- Plan changes preserve existing data
- Feature flags enable gradual rollout
- Metadata field for custom extensions
Last Updated: 2025-08-29 Version: 1.0