fix(12): WR-02 rotate matchPax8Companies eligibility ordering and raise the limit to prevent starvation
This commit is contained in:
parent
cb8ae85737
commit
76a652ddfd
1 changed files with 26 additions and 9 deletions
|
|
@ -186,7 +186,12 @@ export async function matchPax8Companies(opts?: {
|
|||
dryRun?: boolean;
|
||||
}): Promise<Pax8CompanyMatchResult> {
|
||||
const startedAt = Date.now();
|
||||
const limit = opts?.limit ?? 1000;
|
||||
// WR-02 default raised well above any near-term PAX8/Autotask company
|
||||
// count (validated at 118 companies; generous headroom for growth) and
|
||||
// the eligibility ORDER BY below rotates fairness so accumulating
|
||||
// review-flagged rows can no longer permanently starve alphabetically
|
||||
// later companies even if this limit is ever hit.
|
||||
const limit = opts?.limit ?? 10000;
|
||||
const dryRun = opts?.dryRun ?? false;
|
||||
|
||||
const result: Pax8CompanyMatchResult = {
|
||||
|
|
@ -198,17 +203,29 @@ export async function matchPax8Companies(opts?: {
|
|||
};
|
||||
|
||||
try {
|
||||
// WR-02: ORDER BY name is a static cursor — once flagged-for-review
|
||||
// companies accumulate (their matched_at stays NULL indefinitely; see
|
||||
// recordConflict), they keep re-occupying the same slots in every run's
|
||||
// top-N by name, and once eligible rows exceed `limit`, everything
|
||||
// sorting alphabetically after that point is starved. Ordering instead
|
||||
// by "last time this row was actually considered" (the open review's
|
||||
// detected_at, falling back to matched_at, falling back to the epoch
|
||||
// for never-yet-scanned rows) rotates fairness: least-recently-attempted
|
||||
// rows always sort first, so a permanently-open review row sinks behind
|
||||
// any row that hasn't been reconsidered as recently.
|
||||
const eligible = await postgresClient.query<EligibleCompany>(
|
||||
`SELECT id::text, name
|
||||
FROM pax8_companies
|
||||
WHERE is_deleted = false
|
||||
AND match_method IS DISTINCT FROM 'manual'
|
||||
`SELECT c.id::text, c.name
|
||||
FROM pax8_companies c
|
||||
LEFT JOIN pax8_company_match_review r
|
||||
ON r.pax8_company_id = c.id AND r.resolved_at IS NULL
|
||||
WHERE c.is_deleted = false
|
||||
AND c.match_method IS DISTINCT FROM 'manual'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM pax8_company_match_review r
|
||||
WHERE r.pax8_company_id = pax8_companies.id
|
||||
AND r.resolved_at IS NOT NULL
|
||||
SELECT 1 FROM pax8_company_match_review r2
|
||||
WHERE r2.pax8_company_id = c.id
|
||||
AND r2.resolved_at IS NOT NULL
|
||||
)
|
||||
ORDER BY name
|
||||
ORDER BY COALESCE(r.detected_at, c.matched_at, 'epoch'::timestamptz) ASC
|
||||
LIMIT $1`,
|
||||
[limit]
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue