mirror of
https://git.coastit.co.za/caitlin/CRM_ENVR.git
synced 2026-07-10 11:15:43 +02:00
Current state
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
# CRM Database Schema — Enterprise RBAC + CRM
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
Enterprise-grade PostgreSQL schema implementing **hierarchical Role-Based Access Control (RBAC)**
|
||||
with a complete CRM system. Designed for production deployments with strict security requirements,
|
||||
audit compliance, and scalability to millions of records.
|
||||
|
||||
---
|
||||
|
||||
## 1. Hierarchical RBAC Model
|
||||
|
||||
Four roles arranged in a strict hierarchy by `hierarchy_level` (lower = higher privilege):
|
||||
|
||||
| Role | Level | Authority |
|
||||
|------|-------|-----------|
|
||||
| **SUPER_ADMIN** | 1 | Unrestricted — create/delete users, assign roles, override all permissions |
|
||||
| **ADMIN** | 2 | Operational — ban/suspend users, review reports, moderate activity. **Cannot create accounts.** |
|
||||
| **SALES_USER** | 3 | CRM operations — leads, customers, opportunities, communications |
|
||||
| **DEVELOPER** | 4 | Technical + CRM read access for post-sale project visibility |
|
||||
|
||||
### Enforcement via PostgreSQL Triggers
|
||||
|
||||
- **`enforce_create_user()`** (BEFORE INSERT ON users): Only SUPER_ADMIN (`hierarchy_level = 1`)
|
||||
can create new user accounts. Bootstrap case (`created_by IS NULL`) is allowed for initial setup.
|
||||
- **`enforce_role_assignment()`** (BEFORE INSERT ON user_roles): Only SUPER_ADMIN can assign roles.
|
||||
Prevents privilege escalation by checking hierarchy levels.
|
||||
|
||||
### Permission Model
|
||||
|
||||
Granular permissions stored in `permissions` table with `(resource, action)` pairs.
|
||||
`role_permissions` maps roles to permissions. The `has_permission(user_id, resource, action)`
|
||||
function provides application-layer authorization checks.
|
||||
|
||||
---
|
||||
|
||||
## 2. Ban & Suspension System
|
||||
|
||||
Two separate tables for enforcement flexibility:
|
||||
|
||||
- **`banned_users`**: Permanent or time-limited bans. Supports reversal (by SUPER_ADMIN).
|
||||
Admins can create bans; SUPER_ADMIN can reverse or permanently delete banned users.
|
||||
- **`suspended_users`**: Time-limited suspensions (always has expiry). Admins can create
|
||||
and lift suspensions.
|
||||
|
||||
Both tables are fully audited via dedicated trigger functions.
|
||||
|
||||
---
|
||||
|
||||
## 3. Session & Login Security
|
||||
|
||||
- **`sessions`**: Stores hashed session tokens with expiry. Only one active session per
|
||||
token hash.
|
||||
- **`login_attempts`**: Captures every login attempt (successful or failed) with IP address
|
||||
and user agent. Used for brute-force detection and audit.
|
||||
- Users have `failed_login_attempts` and `locked_until` for account lockout policies.
|
||||
|
||||
---
|
||||
|
||||
## 4. Password Security
|
||||
|
||||
- All passwords hashed with **bcrypt (cost factor 12)**
|
||||
- `password_change_required` forces password change on first login (TRUE for all non-root
|
||||
test accounts)
|
||||
- Password hashes are opaque to the database — validation is application-layer only
|
||||
|
||||
---
|
||||
|
||||
## 5. UUID Primary Keys
|
||||
|
||||
- All tables use `UUID PRIMARY KEY DEFAULT uuid_generate_v4()`
|
||||
- Fixed UUIDs used for seed data and system entities for referential transparency
|
||||
- Prevents enumeration attacks and supports distributed ID generation
|
||||
|
||||
---
|
||||
|
||||
## 6. Audit Trail
|
||||
|
||||
Every mutation is logged to `audit_logs` via `audit_trigger_function()`:
|
||||
|
||||
- Captures `(table_name, record_id, action, old_data, new_data, changed_by, ip_address)`
|
||||
- Ban actions, suspension actions, and successful logins have dedicated audit triggers
|
||||
- Indexed on `(table_name, record_id)` for per-record lookup
|
||||
|
||||
Dedicated audit views:
|
||||
- `v_active_bans` — Currently active bans with user details
|
||||
- `v_active_suspensions` — Currently active suspensions
|
||||
- `v_user_permissions` — Flattened permission report per user
|
||||
|
||||
---
|
||||
|
||||
## 7. Third Normal Form (3NF)
|
||||
|
||||
Customer model uses the **discriminator pattern**:
|
||||
|
||||
```
|
||||
customers (parent — shared columns: status, owner, tags, score)
|
||||
├── customer_type = 'individual' → individual_customers
|
||||
└── customer_type = 'company' → company_customers
|
||||
```
|
||||
|
||||
All lookup tables are normalized. Contact information, addresses, and notes are
|
||||
separate 1:N child tables.
|
||||
|
||||
---
|
||||
|
||||
## 8. Indexing Strategy
|
||||
|
||||
- **Core indexes**: FK columns, status/sort/date columns, unique constraints
|
||||
- **Partial indexes**: `WHERE deleted_at IS NULL` on soft-delete tables,
|
||||
`WHERE is_active = TRUE` on bans/suspensions, `WHERE due_date < NOW()` on overdue invoices
|
||||
- **Full-text search**: GIN indexes on customers, leads, products, communications, tasks
|
||||
- **Composite indexes**: Common query patterns (e.g., `opportunities(owner_id, stage_id)`)
|
||||
|
||||
---
|
||||
|
||||
## 9. Soft Delete
|
||||
|
||||
- `deleted_at TIMESTAMPTZ` on all business tables
|
||||
- Partial unique indexes ignore soft-deleted rows (e.g., `WHERE deleted_at IS NULL`)
|
||||
- Audit logs capture the full row snapshot before soft-delete
|
||||
|
||||
---
|
||||
|
||||
## 10. Test Accounts
|
||||
|
||||
| Username | Password | Role |
|
||||
|----------|----------|------|
|
||||
| `superadmin_demo` | `[REDACTED]` | SUPER_ADMIN |
|
||||
| `admin_demo` | `[REDACTED]` | ADMIN |
|
||||
| `sales_demo` | `[REDACTED]` | SALES_USER |
|
||||
| `dev_demo` | `[REDACTED]` | DEVELOPER |
|
||||
|
||||
---
|
||||
|
||||
## 11. Migration Instructions
|
||||
|
||||
```bash
|
||||
# Create database
|
||||
psql -U postgres -c "CREATE DATABASE crm;"
|
||||
|
||||
# Run full migration
|
||||
psql -U postgres -d crm -f database/migrations/run_all.sql
|
||||
|
||||
# Or step by step:
|
||||
psql -U postgres -d crm -f database/migrations/001_schema.sql
|
||||
psql -U postgres -d crm -f database/migrations/002_seed.sql
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. Security Rules Summary
|
||||
|
||||
| Rule | Enforcement |
|
||||
|------|-------------|
|
||||
| Only SUPER_ADMIN creates accounts | Trigger `trg_enforce_create_user` |
|
||||
| Only SUPER_ADMIN assigns roles | Trigger `trg_enforce_role_assignment` |
|
||||
| No privilege escalation | Level check in `enforce_role_assignment()` |
|
||||
| bcrypt password hashing | Application-layer (cost=12) |
|
||||
| Unique usernames/emails | Partial unique indexes |
|
||||
| Force password change on first login | `password_change_required` column |
|
||||
| Audit every login/logout | Trigger `trg_audit_login` on `login_attempts` |
|
||||
| Audit every ban action | Trigger `trg_audit_ban` on `banned_users` |
|
||||
| Audit every suspension action | Trigger `trg_audit_suspension` on `suspended_users` |
|
||||
Reference in New Issue
Block a user