fix(publish): 入库实体键读错误 fail-closed,复用加 rejected 守卫,去重排除软删行

This commit is contained in:
toom1996
2026-09-23 10:41:16 +08:00
parent dba615d636
commit 8f8b06def7
3 changed files with 117 additions and 4 deletions

View File

@ -244,7 +244,13 @@ func (s *IngestService) processRunway(ctx context.Context, job model.IngestJob,
// 2) 实体键查重并决定分支(单表模型)
seasonCode := season.Derive(p.Year, p.CollectionType, p.Season)
reuseID, existStatus, exist, _ := s.repo.RunwayEntityState(ctx, brandID, seasonCode, p.CollectionType)
reuseID, existStatus, exist, err := s.repo.RunwayEntityState(ctx, brandID, seasonCode, p.CollectionType)
if err != nil {
// 读失败绝不能当成「未命中」:实体键上没有唯一约束兜底,误判为新建会给同一实体留两行,
// 破坏「一个实体一行」的不变式。fail-closed + 退避重试。
s.failOrRetry(ctx, job.ID, "entity lookup: "+err.Error())
return
}
action := decideIngestAction(exist, existStatus)
if action == ingestSkip {
log.Printf("[ingest] job=%d runway 实体已存在(status=%s),跳过", job.ID, existStatus)
@ -410,7 +416,12 @@ func (s *IngestService) fetchLookImages(ctx context.Context, looks []dto.RunwayL
// processStreet 街拍入库:实体键分三支(新建 / 放弃 / 复用驳回)→ 下载图 → 直写 street_snaps(无品牌)。
func (s *IngestService) processStreet(ctx context.Context, job model.IngestJob, p dto.RunwayIngest) {
// 1) 实体键查重并决定分支(单表模型,同 runway)
reuseID, existStatus, exist, _ := s.repo.StreetSnapEntityState(ctx, p.City, p.Year)
reuseID, existStatus, exist, err := s.repo.StreetSnapEntityState(ctx, p.City, p.Year)
if err != nil {
// 同 runway:读失败不得当「未命中」,否则会给同一实体留两行。fail-closed + 退避重试。
s.failOrRetry(ctx, job.ID, "entity lookup: "+err.Error())
return
}
action := decideIngestAction(exist, existStatus)
if action == ingestSkip {
log.Printf("[ingest] job=%d street 实体已存在(status=%s),跳过", job.ID, existStatus)