Add common third party reenrich and stats CLIs

Add `proboctl common-third-party reenrich` to re-arm the async
enrichment worker for selected catalog rows, and `stats` to summarize
the catalog by enrichment state and last run status. Rows are selected
verbatim via --id/--slug or across the catalog via
--category/--keyword/--state/--status, gated by --dry-run and --yes.

Extend `list` with --state/--status filters and STATE/STATUS columns,
and `show` with enrichment state, attempts, last run status, error,
per-field provenance, and discovered domains.

Back these with CommonThirdPartyFilter state/status/IDs filters plus
CommonThirdParties.LoadAllIDs and RequestEnrichmentByIDs. The latter
stamps enrichment_requested_at and resets the attempt counter while
preserving the existing payload, so the worker merge keeps curated and
human-edited provenance.

Also simplify exactLabelMatch to use slices.Contains.

Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
Émile Ré
2026-06-11 18:20:36 +02:00
parent 968895bdfd
commit b617741feb
8 changed files with 780 additions and 18 deletions

View File

@@ -31,6 +31,8 @@ func newCmdList(f *cmdutil.Factory) *cobra.Command {
flagName string
flagCategory string
flagKeyword string
flagState string
flagStatus string
flagSort string
flagOrder string
)
@@ -46,6 +48,8 @@ func newCmdList(f *cmdutil.Factory) *cobra.Command {
cmd.Flags().StringVar(&flagName, "name", "", "Filter by name substring")
cmd.Flags().StringVar(&flagCategory, "category", "", "Filter by category")
cmd.Flags().StringVar(&flagKeyword, "keyword", "", "Filter by name/slug substring")
cmd.Flags().StringVar(&flagState, "state", "", "Filter by enrichment state (queued, enriched, unenriched)")
cmd.Flags().StringVar(&flagStatus, "status", "", "Filter by last enrichment status (done, partial, failed)")
cmd.Flags().StringVar(&flagSort, "sort", "name", "Sort field: name, created, updated")
cmd.Flags().StringVar(&flagOrder, "order", "", "Sort order: asc, desc (default depends on field)")
@@ -81,6 +85,23 @@ func newCmdList(f *cmdutil.Factory) *cobra.Command {
filter.WithKeyword(&flagKeyword)
}
if flagState != "" {
st, err := parseEnrichmentState(flagState)
if err != nil {
return err
}
filter.WithState(&st)
}
if flagStatus != "" {
if _, ok := validEnrichmentStatuses[flagStatus]; !ok {
return fmt.Errorf("invalid --status value %q: valid values are done, partial, failed", flagStatus)
}
filter.WithEnrichmentStatus(&flagStatus)
}
pgClient, err := f.PgClient()
if err != nil {
return err
@@ -128,14 +149,15 @@ func newCmdList(f *cmdutil.Factory) *cobra.Command {
return nil
}
table := clicmdutil.NewTable("ID", "NAME", "SLUG", "CATEGORY", "CREATED", "UPDATED")
table := clicmdutil.NewTable("ID", "NAME", "SLUG", "CATEGORY", "STATE", "STATUS", "UPDATED")
for _, p := range parties {
table.Row(
p.ID.String(),
p.Name,
p.Slug,
string(p.Category),
p.CreatedAt.Format("2006-01-02 15:04:05"),
enrichmentState(p),
enrichmentStatus(p),
p.UpdatedAt.Format("2006-01-02 15:04:05"),
)
}