Files
NewStrcuture_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

5.7 KiB

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

# 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