@@ -259,11 +259,14 @@ export interface PackagistStatsUpdateInput {
259259 declaredRepositoryUrl : string | null
260260 repositoryUrl : string | null
261261 status : string
262- downloadsLast30d : number | null
263262 totalDownloads : number | null
264263 dependentCount : number | null
265264}
266265
266+ // downloads_last_30d is NOT written here — it belongs exclusively to the dedicated
267+ // downloads-30d lane's boundary-anchored, insert-if-absent snapshot. The metadata
268+ // lane's live rolling `downloads.monthly` value is a different, unanchored reading;
269+ // writing it here would silently overwrite that snapshot every weekly refresh.
267270export async function updatePackagistPackageStats (
268271 qx : QueryExecutor ,
269272 input : PackagistStatsUpdateInput ,
@@ -272,7 +275,7 @@ export async function updatePackagistPackageStats(
272275 await qx . selectOneOrNone (
273276 `WITH old AS (
274277 SELECT description, declared_repository_url, repository_url, status,
275- downloads_last_30d, total_downloads, dependent_count, ingestion_source
278+ total_downloads, dependent_count, ingestion_source
276279 FROM packages WHERE purl = $(purl) AND ecosystem = 'packagist'
277280 ),
278281 ins AS (
@@ -281,21 +284,19 @@ export async function updatePackagistPackageStats(
281284 declared_repository_url = $(declaredRepositoryUrl),
282285 repository_url = $(repositoryUrl),
283286 status = $(status),
284- downloads_last_30d = COALESCE($(downloadsLast30d), downloads_last_30d),
285287 total_downloads = COALESCE($(totalDownloads), total_downloads),
286288 dependent_count = COALESCE($(dependentCount), dependent_count),
287289 last_synced_at = NOW()
288290 WHERE purl = $(purl) AND ecosystem = 'packagist'
289291 RETURNING id, is_critical, description, declared_repository_url, repository_url, status,
290- downloads_last_30d, total_downloads, dependent_count, ingestion_source
292+ total_downloads, dependent_count, ingestion_source
291293 )
292294 SELECT ins.id::text AS id, ins.is_critical,
293295 array_remove(ARRAY[
294296 CASE WHEN o.description IS DISTINCT FROM ins.description THEN 'packages.description' END,
295297 CASE WHEN o.declared_repository_url IS DISTINCT FROM ins.declared_repository_url THEN 'packages.declared_repository_url' END,
296298 CASE WHEN o.repository_url IS DISTINCT FROM ins.repository_url THEN 'packages.repository_url' END,
297299 CASE WHEN o.status IS DISTINCT FROM ins.status THEN 'packages.status' END,
298- CASE WHEN o.downloads_last_30d IS DISTINCT FROM ins.downloads_last_30d THEN 'packages.downloads_last_30d' END,
299300 CASE WHEN o.total_downloads IS DISTINCT FROM ins.total_downloads THEN 'packages.total_downloads' END,
300301 CASE WHEN o.dependent_count IS DISTINCT FROM ins.dependent_count THEN 'packages.dependent_count' END,
301302 CASE WHEN o.ingestion_source IS DISTINCT FROM ins.ingestion_source THEN 'packages.ingestion_source' END
0 commit comments