• Mahmoud Aglan's avatar
    fix(branch): the catalogue belongs to a branch too, and events belong to none · d3cbd5f1
    Mahmoud Aglan authored
    The first pass put programmes, products, prices, promotions, warehouses and
    receipt templates in the *shared* bucket, where `branch_id IS NULL` means "every
    branch uses this row". The reasoning was that a missing base price is a hard
    failure that stops a sale, so hard-filtering the catalogue risked leaving a
    branch unable to sell anything.
    
    That bought safety with the wrong currency. A branch is meant to read as its own
    installation — its own programmes at its own prices, its own products, its own
    stores — and a programme offered at one branch turning up in another branch's
    dropdown is the same bug as a group doing it. The shared bucket just hid it
    behind a plausible-sounding rule.
    
    The data said the caution was unnecessary. Across the live tenant no group
    points at a programme in another branch, no base price prices a programme in
    another branch, and exactly three catalogue rows had no branch at all. The
    catalogue was already per-branch in practice and merely unlabelled.
    
      - Programmes, base prices, pricing rules, promotions, products, product
        categories, kits, warehouses, receipt templates and wallets move to the
        strict bucket. `kits` and `product_categories` gain the column; the rest
        only needed their nulls resolved, from actual usage where a link existed
        and from the main branch otherwise.
    
      - Events go the other way and lose the trait entirely, with their
        registrations. An event is an academy-wide occasion and is genuinely not
        per branch. The column stays — dropping it would be destructive — but
        nothing reads it.
    
      - Only people and the academy calendar stay shared: employees, trainers,
        guardians, holidays. A coach who works two pitches needs one record visible
        from both, not two that drift. Even there the nulls are narrowed — anyone
        who demonstrably belongs to one branch is pinned to it, which in this tenant
        leaves none shared at all.
    
      - Pricing rules are the one model whose branch is genuinely many-valued: the
        wizard targets a list through `pricing_rule_branches` and deliberately
        leaves the legacy column null. A column scope would have hidden every rule
        it has ever created, so PricingRule supplies its own scope reading the pivot
        — and BelongsToBranch now lets a model do that.
    
      - Forms that let a user save a catalogue row with no branch now require one,
        and the "كل الفروع" option is gone from those pickers: on a strictly scoped
        table that choice does not mean every branch, it means none. The setup
        wizard's seeded prices are filed against their programme's branch rather
        than null, so a new academy does not finish setup unable to sell.
    
      - Comments throughout said "SHARED — branch_id NULL means every branch uses
        this row". They now say what is true.
    
    tests/Feature/PricingSurvivesBranchScopeTest.php is the guard on the original
    worry: it prices every live enrolment inside its own branch on each run. It
    passes, and reports the one programme that has no active base price at all — a
    pre-existing gap, unrelated to scoping. Branch suites: 14 tests / 23,060
    assertions against a restored tenant. Standard suite: 224 tests, no failures.
    Co-Authored-By: 's avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
    d3cbd5f1
Name
Last commit
Last update
..
Attendance Loading commit data...
Audit/Models Loading commit data...
Compliance Loading commit data...
Document Loading commit data...
Event Loading commit data...
Facility Loading commit data...
Financial Loading commit data...
HR Loading commit data...
Identity Loading commit data...
Inventory Loading commit data...
Notification Loading commit data...
POS Loading commit data...
Participant Loading commit data...
Portal/Services Loading commit data...
Pricing Loading commit data...
Scheduling Loading commit data...
Shared Loading commit data...
Training Loading commit data...
Website Loading commit data...
WhatsApp Loading commit data...