Skip to main content

DeelRx CRM - Data Integrity Invariants

Domain rules that must ALWAYS hold true across all operations

📦 Inventory Management

  • Stock Quantity: product.stockQuantity >= 0 (never negative)
  • Adjustment Math: newQuantity = previousQuantity + adjustmentQuantity (signed)
  • Adjustment Validation: previousQuantity + adjustmentQuantity >= 0 (before commit)
  • Concurrent Safety: Stock updates use database transactions with row-level locking

💰 Financial Integrity

  • No Overpayment: totalPaid <= order.totalAmount across all payments
  • Money Precision: All monetary values use Decimal(12,2) - no floating point
  • Payment Status: COMPLETED payments only count toward order balance
  • Refund Limits: refundAmount <= originalPaymentAmount

🏢 Multi-Tenancy

  • Data Isolation: ALL queries MUST filter by teamId (no cross-tenant leaks)
  • Team Membership: Users can only access data for teams where TeamMembership.isActive = true
  • Resource Scoping: SKUs and orderNumbers unique within team, not globally
  • Cascade Deletes: Team deletion removes all related business data safely

🛒 Order Processing

  • Order Totals: totalAmount = sum(orderItems.quantity * unitPrice) + taxAmount - discountAmount
  • Line Item Integrity: quantity > 0 and unitPrice >= 0 for all order items
  • Status Progression: Orders follow business workflow (PENDING → CONFIRMED → PROCESSING → SHIPPED/DELIVERED)
  • Number Uniqueness: orderNumber unique per team (handle concurrency with retry logic)

👥 Customer Data

  • Contact Requirements: At least one of email or phone must be provided
  • Address Validation: JSON addresses validated via Zod schema before persistence
  • Referral Logic: CustomerReferral requires referrer contact method (email/phone/customerId)
  • PII Handling: Customer data follows GDPR deletion requirements

🎯 Credit & Receivables

  • Balance Accuracy: outstandingBalance = totalAmount - sum(completedPayments)
  • Aging Calculation: daysOutstanding = floor((now - order.createdAt) / 86400000)
  • Status Consistency: Credit status (NEW/PARTIAL/PAID/PASTDUE) matches payment state
  • Risk Assessment: Credit scores based on payment history, not speculation

🔄 System Operations

  • Audit Trails: All state changes log createdAt, updatedAt, createdById
  • Soft Deletes: Use isActive = false for business entities, hard deletes for system cleanup
  • Concurrent Updates: Use optimistic locking (updatedAt checks) for critical operations
  • Transaction Boundaries: Multi-table updates use database transactions

🚨 Error Handling

  • Server Actions: Always return { data: T | null, error: string | null }
  • Validation: Zod schemas validate input before database operations
  • Sentry Integration: All unhandled exceptions captured for observability
  • User Feedback: Business rule violations return helpful error messages

🔐 Security Constraints

  • Authentication: All operations require valid Clerk session
  • Authorization: Team-based permissions enforced at application layer
  • Input Sanitization: All user inputs validated/sanitized before persistence
  • Rate Limiting: API endpoints protected with @repo/security (Arcjet)