System Settings
Tenant-specific configuration and branding management.
Overview
The System Settings module provides per-tenant configuration management including company information, branding, feature toggles, and integration settings. All settings are tenant-isolated and can be managed by tenant administrators.
Features
- Company Information: Name, address, contact details
- Branding: Colors, logo, theme customization
- Feature Toggles: Enable/disable modules per tenant
- Integration Settings: API keys, webhook URLs
- Notification Settings: Email, SMS, push notification preferences
- Multi-Tenant: Complete tenant isolation
Architecture
graph TB
A[Tenant Admin] --> B[System Settings UI]
B --> C[Settings API]
C --> D[system_settings Table]
D --> E[Tenant Isolation]
F[Application] --> C
C --> G[Default Settings]
style B fill:#3b82f6
style D fill:#10b981
style E fill:#f59e0bDatabase Schema
system_settings Table
| Column | Type | Constraints | Description |
|---|---|---|---|
id | uuid | PRIMARY KEY | Unique settings identifier |
tenant_id | uuid | UNIQUE NOT NULL, FK → tenants | Tenant (1:1 relationship) |
settings | jsonb | NOT NULL, DEFAULT '{}' | Settings JSON object |
created_at | timestamptz | NOT NULL, DEFAULT now() | Creation timestamp |
updated_at | timestamptz | NOT NULL, DEFAULT now() | Last update timestamp |
Indexes:
idx_system_settings_tenantontenant_id(UNIQUE)
Settings Structure
Company Settings
interface CompanySettings {
name: string;
address?: string;
city?: string;
postalCode?: string;
country?: string;
phone?: string;
email?: string;
website?: string;
taxId?: string;
logoUrl?: string;
}Branding Settings
interface BrandingSettings {
primaryColor: string; // Hex color, e.g., '#3b82f6'
accentColor: string; // Hex color, e.g., '#10b981'
theme: 'light' | 'dark' | 'auto';
logoUrl?: string;
faviconUrl?: string;
}Feature Toggles
interface FeatureToggles {
inventory: boolean;
pickPack: boolean;
floorPlan: boolean;
slottingAI: boolean;
maintenance: boolean;
safety: boolean;
equipmentTracking: boolean;
autoAssignment: boolean;
sso: boolean;
}Integration Settings
interface IntegrationSettings {
apiKeys?: {
[key: string]: string;
};
webhookUrls?: {
[key: string]: string;
};
externalSystems?: {
[key: string]: any;
};
}Notification Settings
interface NotificationSettings {
email: {
enabled: boolean;
fromAddress?: string;
templates?: {
[key: string]: string;
};
};
sms: {
enabled: boolean;
provider?: string;
};
push: {
enabled: boolean;
};
}Complete Settings Object
interface SystemSettings {
company: CompanySettings;
branding: BrandingSettings;
features: FeatureToggles;
integrations: IntegrationSettings;
notifications: NotificationSettings;
// ... other settings
}API Functions
Get Settings
import { getSettings } from '@/lib/systemSettings';
const { data, error } = await getSettings();
// Returns: SystemSettings with tenant defaults mergedBehavior:
- Fetches tenant-specific settings
- Merges with default settings
- Returns complete settings object
Update Settings
import { updateSettings } from '@/lib/systemSettings';
const { data, error } = await updateSettings({
company: {
name: 'Updated Company Name',
address: '123 Main St',
},
branding: {
primaryColor: '#3b82f6',
accentColor: '#10b981',
},
});Parameters:
- Partial
SystemSettingsobject - Only provided fields are updated
- Other fields remain unchanged
Returns: { data: SystemSettings | null, error: any }
Get Setting Value
import { getSettingValue } from '@/lib/systemSettings';
const primaryColor = await getSettingValue('branding.primaryColor');
// Returns: string | nullPath Syntax:
- Dot notation for nested properties
- Returns
nullif not found - Returns default if available
Default Settings
const DEFAULT_SETTINGS: SystemSettings = {
company: {
name: '',
address: '',
// ... empty defaults
},
branding: {
primaryColor: '#3b82f6',
accentColor: '#10b981',
theme: 'dark',
},
features: {
inventory: true,
pickPack: true,
floorPlan: true,
slottingAI: true,
maintenance: true,
safety: true,
equipmentTracking: true,
autoAssignment: true,
sso: false,
},
integrations: {},
notifications: {
email: { enabled: true },
sms: { enabled: false },
push: { enabled: true },
},
};Usage Examples
Apply Branding
// Get settings
const { data: settings } = await getSettings();
// Apply primary color
document.documentElement.style.setProperty(
'--primary',
settings.branding.primaryColor
);
// Apply accent color
document.documentElement.style.setProperty(
'--accent',
settings.branding.accentColor
);Check Feature Access
import { isFeatureEnabled } from '@/lib/systemSettings';
const canUseSSO = await isFeatureEnabled('sso');
if (canUseSSO) {
// Show SSO login button
}Get Company Name
const companyName = await getSettingValue('company.name');
// Use in UI: "Welcome to {companyName}"Permissions
| Role | Permissions |
|---|---|
| Tenant Admin | Full access: read, update all settings |
| Tenant User | Read-only access |
| Super Admin | Full access to all tenants' settings |
Best Practices
1. Use Defaults
Always merge with defaults:
// ✅ GOOD
const { data: settings } = await getSettings(); // Auto-merges defaults
// ❌ BAD
const { data: rawSettings } = await supabase
.from('system_settings')
.select('settings')
.single(); // No defaults2. Validate Settings
Validate before updating:
if (!settings.company.name) {
throw new Error('Company name is required');
}3. Cache Settings
Cache settings in application state:
// Settings don't change frequently
// Cache for 5-10 minutes4. Feature Toggles
Use feature toggles for gradual rollouts:
const { data: settings } = await getSettings();
if (settings.features.slottingAI) {
// Show Slotting AI features
}Integration
UI Integration
Settings are applied throughout the application:
// Theme application
const theme = settings.branding.theme;
// Apply theme to UI
// Color application
const primaryColor = settings.branding.primaryColor;
// Apply to CSS variablesSSO Integration
SSO feature toggle controls SSO availability:
const { data: settings } = await getSettings();
if (settings.features.sso) {
// Show SSO login option
// Load SSO providers
}Troubleshooting
Issue: Settings Not Applied
Symptom: Changes to settings don't reflect in UI.
Solution:
- Verify settings were saved successfully
- Clear application cache
- Refresh page
- Check tenant context is correct
Issue: Defaults Not Merging
Symptom: Missing settings return undefined instead of defaults.
Solution:
- Use
getSettings()function (not direct query) - Verify default settings are defined
- Check merge logic in function
Issue: Feature Toggle Not Working
Symptom: Feature still visible when disabled.
Solution:
- Verify feature toggle is set correctly
- Check UI code checks feature flag
- Clear cache and refresh
Related Documentation
- Multi-Tenant Architecture - Tenant isolation
- SSO Integration - SSO configuration
- Tenant Bootstrap - Initial settings setup