Drop reset-enriched flag and add description filter

The --reset-enriched flag was effectively a no-op: the enrichment
worker claims rows solely on enrichment_requested_at, and SetEnriched
rewrites enriched_at regardless, so clearing it never changed whether a
row was re-processed. Remove the flag and the resetEnriched parameter on
RequestEnrichmentByIDs, which now only stamps enrichment_requested_at.

Add a --without-description filter to the list and reenrich commands,
backed by a new described predicate on CommonTrackerPatternFilter, so an
operator can target catalog rows that still lack a description.

Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
Émile Ré
2026-06-08 17:13:16 +02:00
parent 4eb352a61d
commit b0e8e9b812
4 changed files with 64 additions and 29 deletions

View File

@@ -836,29 +836,27 @@ ORDER BY pattern ASC
}
// RequestEnrichmentByIDs arms enrichment on the given common tracker
// patterns. When resetEnriched is true it also clears enriched_at so rows
// that previously reached a terminal state are re-processed. Returns the
// number of rows re-queued. This is the async fallback path; the
// synchronous enricher service is preferred.
// patterns by stamping enrichment_requested_at, which is the only column
// the enrichment worker claims on. Already-enriched rows are re-processed
// too: the worker overwrites enriched_at and the description when it runs.
// Returns the number of rows re-queued. This is the async fallback path;
// the synchronous enricher service is preferred.
func (ps *CommonTrackerPatterns) RequestEnrichmentByIDs(
ctx context.Context,
tx pg.Tx,
ids []gid.GID,
resetEnriched bool,
) (int64, error) {
q := `
UPDATE common_tracker_patterns
SET
enrichment_requested_at = NOW(),
enriched_at = CASE WHEN @reset_enriched THEN NULL ELSE enriched_at END,
updated_at = NOW()
WHERE
id = ANY(@ids)
`
args := pgx.StrictNamedArgs{
"ids": ids,
"reset_enriched": resetEnriched,
"ids": ids,
}
result, err := tx.Exec(ctx, q, args)

View File

@@ -77,6 +77,7 @@ type CommonTrackerPatternFilter struct {
commonThirdPartyID *gid.GID
keyword *string
linked *bool
described *bool
state *CommonTrackerPatternEnrichmentState
}
@@ -116,6 +117,14 @@ func (f *CommonTrackerPatternFilter) WithLinked(linked *bool) *CommonTrackerPatt
return f
}
// WithDescribed filters on whether the pattern has a non-empty
// description: true keeps only described rows, false keeps only rows with
// a blank description.
func (f *CommonTrackerPatternFilter) WithDescribed(described *bool) *CommonTrackerPatternFilter {
f.described = described
return f
}
func (f *CommonTrackerPatternFilter) WithState(state *CommonTrackerPatternEnrichmentState) *CommonTrackerPatternFilter {
f.state = state
return f
@@ -165,6 +174,12 @@ func (f *CommonTrackerPatternFilter) SQLFragment() string {
ELSE common_third_party_id IS NULL
END
AND
CASE
WHEN @filter_described::boolean IS NULL THEN TRUE
WHEN @filter_described::boolean THEN description != ''
ELSE description = ''
END
AND
CASE
WHEN @filter_state_queued::boolean THEN enrichment_requested_at IS NOT NULL
WHEN @filter_state_enriched::boolean THEN
@@ -184,6 +199,7 @@ func (f *CommonTrackerPatternFilter) SQLArguments() pgx.StrictNamedArgs {
"filter_common_third_party_id": nil,
"filter_keyword": nil,
"filter_linked": nil,
"filter_described": nil,
"filter_state_queued": false,
"filter_state_enriched": false,
"filter_state_unenriched": false,
@@ -217,6 +233,10 @@ func (f *CommonTrackerPatternFilter) SQLArguments() pgx.StrictNamedArgs {
args["filter_linked"] = *f.linked
}
if f.described != nil {
args["filter_described"] = *f.described
}
if f.state != nil {
switch *f.state {
case CommonTrackerPatternEnrichmentStateQueued: