fixes
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
package processing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/descrybe/descrybe-v2/apps/api/internal/aiprompts"
|
||||
"github.com/descrybe/descrybe-v2/apps/api/internal/catalog"
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
// FixCompanyCatalogOpts controls optional Fix A1 / catalog hygiene steps.
|
||||
type FixCompanyCatalogOpts struct {
|
||||
// BackfillCategories copies mapped_data category unique_ids onto empty
|
||||
// processed_products.category.
|
||||
BackfillCategories bool
|
||||
// ReprocessSampleLimit caps recommended raw_product_ids in the response
|
||||
// (0 = counts only, no sample ids).
|
||||
ReprocessSampleLimit int
|
||||
// AIPrompts optionally re-applies BuiltInDefaults product_enhance per content language.
|
||||
AIPrompts *aiprompts.Service
|
||||
}
|
||||
|
||||
// FixCompanyCatalogResult is the idempotent admin Fix A1 report.
|
||||
type FixCompanyCatalogResult struct {
|
||||
CompanyID uuid.UUID `json:"company_id"`
|
||||
CompanyName string `json:"company_name"`
|
||||
A1Cohort bool `json:"a1_cohort"`
|
||||
|
||||
CategoryAttributeOrphansRemoved int `json:"category_attribute_orphans_removed"`
|
||||
CategoryAttributeLinks int `json:"category_attribute_links"`
|
||||
|
||||
CategoryPromptsUpdated int `json:"category_prompts_updated"`
|
||||
CategoryPromptsAlreadyOK int `json:"category_prompts_already_ok"`
|
||||
CategoryPromptsEmpty int `json:"category_prompts_empty_skipped"`
|
||||
// Prompts aliases category_prompts_updated for flash.admin.fixA1Success {prompts}.
|
||||
Prompts int `json:"prompts"`
|
||||
|
||||
ProductEnhanceLanguages int `json:"product_enhance_languages"`
|
||||
|
||||
WeakHashesCleared int `json:"weak_hashes_cleared"`
|
||||
CategoriesBackfilled int `json:"categories_backfilled"`
|
||||
// Hashes / Categories alias the long names for flash.admin.fixA1Success.
|
||||
Hashes int `json:"hashes"`
|
||||
Categories int `json:"categories"`
|
||||
|
||||
DescriptionsNormalized int `json:"descriptions_normalized"`
|
||||
DescriptionsBackfilled int `json:"descriptions_backfilled"`
|
||||
MappedDescriptionsFlat int `json:"mapped_descriptions_flattened"`
|
||||
MetaBackfilled int `json:"meta_backfilled"`
|
||||
AttributesSanitized int64 `json:"attributes_sanitized"`
|
||||
ProductsScanned int `json:"products_scanned"`
|
||||
|
||||
ReprocessNeededCount int `json:"reprocess_needed_count"`
|
||||
ReprocessSampleRawProductIDs []uuid.UUID `json:"reprocess_sample_raw_product_ids,omitempty"`
|
||||
}
|
||||
|
||||
// FixCompanyCatalog runs the admin Fix A1 / catalog hygiene sequence in place.
|
||||
// Never clears the catalog or uses A1 as a clone destination.
|
||||
// Step 2 applies RepairCompanyCategoryEnhancePrompts (same repaired map as
|
||||
// RepairA1DemoCategoryEnhancePrompts / cmd/repair-category-prompts -apply).
|
||||
// Legacy converters + weak-hash clear live in FixCatalogHygieneWithIDs.
|
||||
func FixCompanyCatalog(ctx context.Context, pool *pgxpool.Pool, companyID uuid.UUID, companyName string, a1Cohort bool, opts FixCompanyCatalogOpts) (FixCompanyCatalogResult, error) {
|
||||
out := FixCompanyCatalogResult{
|
||||
CompanyID: companyID,
|
||||
CompanyName: companyName,
|
||||
A1Cohort: a1Cohort,
|
||||
}
|
||||
if pool == nil {
|
||||
return out, fmt.Errorf("nil pool")
|
||||
}
|
||||
|
||||
orphans, links, err := catalog.EnsureCategoryAttributeLinks(ctx, pool, companyID)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
out.CategoryAttributeOrphansRemoved = orphans
|
||||
out.CategoryAttributeLinks = links
|
||||
|
||||
updated, alreadyOK, emptySkipped, err := catalog.RepairCompanyCategoryEnhancePrompts(ctx, pool, companyID)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
out.CategoryPromptsUpdated = updated
|
||||
out.CategoryPromptsAlreadyOK = alreadyOK
|
||||
out.CategoryPromptsEmpty = emptySkipped
|
||||
|
||||
if opts.AIPrompts != nil {
|
||||
n, err := opts.AIPrompts.ApplyBuiltInProductEnhance(ctx, companyID)
|
||||
if err != nil {
|
||||
return out, fmt.Errorf("product_enhance templates: %w", err)
|
||||
}
|
||||
out.ProductEnhanceLanguages = n
|
||||
}
|
||||
|
||||
hygiene, clearedIDs, err := FixCatalogHygieneWithIDs(ctx, pool, companyID, opts.BackfillCategories)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
out.WeakHashesCleared = hygiene.WeakHashesCleared
|
||||
out.CategoriesBackfilled = hygiene.CategoriesBackfilled
|
||||
out.DescriptionsNormalized = hygiene.DescriptionsNormalized
|
||||
out.DescriptionsBackfilled = hygiene.DescriptionsBackfilled
|
||||
out.MappedDescriptionsFlat = hygiene.MappedDescriptionsFlat
|
||||
out.MetaBackfilled = hygiene.MetaBackfilled
|
||||
out.ProductsScanned = hygiene.ProductsScanned
|
||||
|
||||
sanitized, err := BackfillCompanyProcessedAttributes(ctx, pool, companyID)
|
||||
if err != nil {
|
||||
return out, fmt.Errorf("sanitize attributes: %w", err)
|
||||
}
|
||||
out.AttributesSanitized = sanitized
|
||||
|
||||
needed, sample, err := RecommendReprocessRawProductIDs(ctx, pool, companyID, clearedIDs, opts.ReprocessSampleLimit)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
out.ReprocessNeededCount = needed
|
||||
out.ReprocessSampleRawProductIDs = sample
|
||||
|
||||
// Short keys for flash.admin.fixA1Success {prompts,hashes,categories}.
|
||||
out.Prompts = out.CategoryPromptsUpdated
|
||||
out.Hashes = out.WeakHashesCleared
|
||||
out.Categories = out.CategoriesBackfilled
|
||||
return out, nil
|
||||
}
|
||||
Reference in New Issue
Block a user