Files
CRM_backup/database/DESIGN_DECISIONS.md
T
Ace ff56cea4b8 feat: add Facebook account tracking and management
- Introduced new migration for `facebook_accounts` and `facebook_scrape_logs` tables.
- Updated the scraping logic to handle Facebook accounts, including success and failure tracking.
- Implemented API endpoints for managing Facebook accounts and their scrape logs.
- Enhanced user permissions to restrict access to Facebook account management to admins and super admins.
- Added a dialog component for displaying and managing Facebook accounts in the UI.
- Updated lead fetching logic to include user role checks for assignment and access.
2026-06-23 14:18:18 +02:00

165 lines
5.7 KiB
Markdown

# 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` |