fix(audit): criticals C1 (currency-scoped deposit gate), C2 (outcome-aware berth rule), C4 (/q/ allowlist)
C1: getDepositTotalForInterest now filters to the interest's depositExpectedCurrency for the auto-advance gate, so a wrong-currency payment can no longer satisfy the deposit expectation (and mark the berth Sold). C2: setInterestOutcome fires interest_completed only for 'won'; lost/cancelled fire a new 'deal_lost' rule that frees the berth instead of flipping it to 'sold'. C4: add '/q/' to proxy PUBLIC_PATHS so tracked links in outbound mail reach external recipients. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1400,11 +1400,11 @@ export async function setInterestOutcome(
|
||||
stageAtOutcome,
|
||||
});
|
||||
|
||||
// G-C4: fire interest_completed berth-rule for any non-null outcome
|
||||
// (won / lost / cancelled all qualify). Default rule mode is 'auto' →
|
||||
// berth status flips to 'sold' for won, but admins can scope per outcome
|
||||
// via system_settings.berth_rules.
|
||||
void evaluateRule('interest_completed', id, portId, meta);
|
||||
// Berth-rule on deal close (audit C2). Only a WON deal should drive the
|
||||
// berth to 'sold' (via interest_completed). Lost/cancelled deals fire
|
||||
// `deal_lost`, which frees the berth — previously every outcome reused
|
||||
// interest_completed and silently flipped the berth to 'sold'.
|
||||
void evaluateRule(data.outcome === 'won' ? 'interest_completed' : 'deal_lost', id, portId, meta);
|
||||
|
||||
// Phase 2 nested-subfolders - rename the interest's document folder
|
||||
// to surface the outcome inline (e.g. "Deal A1-A3 (Won)"). Dynamic
|
||||
|
||||
Reference in New Issue
Block a user