Quick Answer: The best way to build a lead management CRM with custom reporting and no duplicate logic is to centralize all business rules in a single canonical data model and expose reporting through a read-optimized layer, not separate code paths. Use event-driven writes, normalized source-of-truth records, and a separate analytics schema or materialized views so the operational CRM and reporting queries both consume the same definitions for lifecycle stage, attribution, and conversion status.
To avoid duplicate logic, the CRM must separate transactional behavior from analytical presentation while keeping one authoritative set of rules. In practice, that means lead intake, assignment, status changes, scoring, and attribution should be handled once in the application domain layer or workflow engine, then persisted as immutable events or well-structured relational records. Custom reporting should query a dedicated reporting layer built from the same canonical entities, using materialized views, dbt-style transformations, or a warehouse sync so metrics like MQL, SQL, source, owner performance, and conversion rate are calculated from shared definitions rather than reimplemented in dashboards, filters, or frontend code. This architecture reduces drift, prevents inconsistent KPI calculations, and makes it easier to add new reports without rewriting core CRM logic.