feat(prefetch): kalıcı vehicles.fully_fetched kolonu (güvenilir tamlık ölçümü)
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled

Redis prefetch:complete:* 21g TTL'li → "% tam çekilmiş"i güvenilir ölçemiyorduk.
Migration 0034: vehicles'a fully_fetched (bool, default false) + fully_fetched_at
(ts) + index. incrementCompleted chain parça ile bitince kalıcı flag'i set eder
(Redis marker'a EK — operasyonel skip mantığı değişmedi). fully_fetched_at her
re-drill tamamlanışında güncellenir (son-doğrulanma). Idempotent SQL.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-25 10:40:40 +03:00
parent 8c1ee15fac
commit 6610bdf720
4 changed files with 34 additions and 1 deletions

View File

@@ -419,10 +419,20 @@ export const vehicles = pgTable(
market: varchar("market", { length: 100 }),
rawData: jsonb("raw_data"),
source: varchar("source", { length: 20 }).default("pl24").notNull(),
// Durable completeness marker: set true when the prefetch chain finishes with
// parts (see PrefetchWorkerService.incrementCompleted). Unlike the ephemeral
// Redis `prefetch:complete:*` marker (21-day TTL, operational skip logic) this
// never expires — it's the reliable "% fully fetched" measurement. `_at` tracks
// the last time completion was confirmed (re-set on each re-drill completion).
fullyFetched: boolean("fully_fetched").default(false).notNull(),
fullyFetchedAt: timestamp("fully_fetched_at", { withTimezone: true }),
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(),
},
(table) => [uniqueIndex("vehicles_vin_unique_idx").on(table.vin)],
(table) => [
uniqueIndex("vehicles_vin_unique_idx").on(table.vin),
index("vehicles_fully_fetched_idx").on(table.fullyFetched),
],
);
// ─── User Vehicles (junction — user ↔ shared vehicle) ─

View File

@@ -841,6 +841,13 @@ export class PrefetchWorkerService implements OnModuleInit, OnModuleDestroy {
// isFinished, so partially-fetched vehicles are never marked — they keep
// getting gap-filled.
await this.redis.set(this.completeKey(vehicleId), "1", COMPLETE_TTL_S);
// Durable completeness flag (never expires) — the reliable "% fully
// fetched" measurement, independent of the ephemeral Redis marker.
// Re-set on every re-drill completion so fullyFetchedAt tracks last-verified.
await this.db
.update(vehicles)
.set({ fullyFetched: true, fullyFetchedAt: new Date() })
.where(eq(vehicles.id, vehicleId));
} else {
await this.markNoResult(vehicleId);
}