feat(crm): support a shared product catalog #23

Open
KofTwentyTwo wants to merge 1 commits from feature/shared-product-catalog into develop
pull from: feature/shared-product-catalog
KofTwentyTwo commented 2026-10-19 13:06:37 +00:00 (Migrated from github.com)

Prepare CRM to own the shared product catalog for KofTwentyTwo/Website-Backend#269. Products can have an optional unique 64-character slug and no catalog price; required deal-line prices and existing totals remain unchanged.

Hosts may opt into withProductPermissionBase("crm.product") to grant catalog read access without exposing other CRM settings. The default remains crm.manage, preserving existing hosts. Native QQQ read/write checks are used; there is no custom checker or bypass.

Host adoption is required: include db/liquibase/qbit-crm/crm-product-catalog.changelog.sql after the existing base schema before using the new metadata. Before opting into the new permission base, add corresponding product grants to existing CRM management roles and grant Marketing readers only crm.product.read. UPGRADE.md covers fresh DDL versus additive migration and role preservation.

This is the CRM prerequisite. Marketing's one-to-one brief, legacy catalog data/reference migration, host navigation and coordinated dependency adoption follow separately; this PR does not retire marketing_product or close #269 alone.

Validation: 24 focused tests passed, 0 failures/errors/skips, including populated H2/Liquibase upgrade and rerun, slug uniqueness, null pricing, required deal-line pricing, default legacy access, narrow read denial of writes/settings, and migrated manager access. Local Lore SQL review found no concrete defect. Full ./mvnw -B verify passed: 499 tests, 0 failures, 0 errors, 0 skipped; coverage and help/schema consistency gates passed in 60 seconds.

Prepare CRM to own the shared product catalog for KofTwentyTwo/Website-Backend#269. Products can have an optional unique 64-character slug and no catalog price; required deal-line prices and existing totals remain unchanged. Hosts may opt into `withProductPermissionBase("crm.product")` to grant catalog read access without exposing other CRM settings. The default remains `crm.manage`, preserving existing hosts. Native QQQ read/write checks are used; there is no custom checker or bypass. Host adoption is required: include `db/liquibase/qbit-crm/crm-product-catalog.changelog.sql` after the existing base schema before using the new metadata. Before opting into the new permission base, add corresponding product grants to existing CRM management roles and grant Marketing readers only `crm.product.read`. UPGRADE.md covers fresh DDL versus additive migration and role preservation. This is the CRM prerequisite. Marketing's one-to-one brief, legacy catalog data/reference migration, host navigation and coordinated dependency adoption follow separately; this PR does not retire marketing_product or close #269 alone. Validation: 24 focused tests passed, 0 failures/errors/skips, including populated H2/Liquibase upgrade and rerun, slug uniqueness, null pricing, required deal-line pricing, default legacy access, narrow read denial of writes/settings, and migrated manager access. Local Lore SQL review found no concrete defect. Full `./mvnw -B verify` passed: 499 tests, 0 failures, 0 errors, 0 skipped; coverage and help/schema consistency gates passed in 60 seconds.
Checking for merge conflicts…
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feature/shared-product-catalog:feature/shared-product-catalog
git checkout feature/shared-product-catalog
Sign in to join this conversation.