mirror of
https://github.com/openclaw/clawhub.git
synced 2026-08-14 00:47:57 +00:00
fix: refresh Trending download snapshots (#3355)
This commit is contained in:
@@ -215,7 +215,7 @@ describe("canonical Trending snapshot storage", () => {
|
||||
snapshotId: "skills-1000",
|
||||
generatedAt: new Date(now - 1_000).toISOString(),
|
||||
windowHours: 24,
|
||||
rankingVersion: "skills-trending-v2",
|
||||
rankingVersion: "skills-trending-v3",
|
||||
items: [
|
||||
{ id: "clawhub:one", rank: 1, lane: "clawhub-trending" },
|
||||
{ id: "clawhub:two", rank: 2, lane: "clawhub-trending" },
|
||||
@@ -556,6 +556,7 @@ describe("canonical Trending snapshot storage", () => {
|
||||
it("returns the current native-only snapshot for guarded preflight reuse", async () => {
|
||||
const t = convexTest(schema, modules);
|
||||
const now = Date.now();
|
||||
const source = await insertEligibleNativeSource(t, "native-preflight-ready");
|
||||
await t.mutation(internal.canonicalTrending.startSnapshotInternal, {
|
||||
snapshotId: "skills-native-preflight-ready",
|
||||
generatedAt: now - 1_000,
|
||||
@@ -563,11 +564,28 @@ describe("canonical Trending snapshot storage", () => {
|
||||
windowStartDay: 40,
|
||||
windowEndDay: 40,
|
||||
});
|
||||
await t.mutation(internal.canonicalTrending.writeItemsInternal, {
|
||||
snapshotId: "skills-native-preflight-ready",
|
||||
items: [
|
||||
{
|
||||
position: 0,
|
||||
lane: "clawhub-trending",
|
||||
sourceRef: { kind: "clawhub", skillId: source.skillId },
|
||||
card: {
|
||||
...nativeCard("clawhub:native-preflight-ready", 8),
|
||||
metrics: {
|
||||
...nativeCard("clawhub:native-preflight-ready", 8).metrics,
|
||||
trending24hDownloads: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
await t.mutation(internal.canonicalTrending.finalizeSnapshotInternal, {
|
||||
snapshotId: "skills-native-preflight-ready",
|
||||
completedAt: now - 500,
|
||||
totalItems: 0,
|
||||
sourceCounts: { clawhubTrending: 3, clawhubRising: 2, skillsShTrending: 0 },
|
||||
totalItems: 1,
|
||||
sourceCounts: { clawhubTrending: 1, clawhubRising: 0, skillsShTrending: 0 },
|
||||
operations: { documentsRead: 10, documentsWritten: 2, functionCalls: 3 },
|
||||
});
|
||||
|
||||
@@ -578,14 +596,63 @@ describe("canonical Trending snapshot storage", () => {
|
||||
snapshotId: "skills-native-preflight-ready",
|
||||
generatedAt: new Date(now - 1_000).toISOString(),
|
||||
windowHours: 24,
|
||||
rankingVersion: "skills-trending-v2",
|
||||
totalItems: 0,
|
||||
sourceCounts: { clawhubTrending: 3, clawhubRising: 2, skillsShTrending: 0 },
|
||||
rankingVersion: "skills-trending-v3",
|
||||
totalItems: 1,
|
||||
sourceCounts: { clawhubTrending: 1, clawhubRising: 0, skillsShTrending: 0 },
|
||||
operations: { documentsRead: 10, documentsWritten: 2, functionCalls: 3 },
|
||||
reused: true,
|
||||
});
|
||||
});
|
||||
|
||||
it("does not reuse a native-only snapshot from the pre-download ranking version", async () => {
|
||||
const t = convexTest(schema, modules);
|
||||
const now = Date.now();
|
||||
const source = await insertEligibleNativeSource(t, "legacy-native-preflight");
|
||||
await t.mutation(internal.canonicalTrending.startSnapshotInternal, {
|
||||
snapshotId: "skills-legacy-native-preflight",
|
||||
generatedAt: now - 1_000,
|
||||
expiresAt: now + 24 * 60 * 60 * 1_000,
|
||||
windowStartDay: 40,
|
||||
windowEndDay: 40,
|
||||
});
|
||||
await t.mutation(internal.canonicalTrending.writeItemsInternal, {
|
||||
snapshotId: "skills-legacy-native-preflight",
|
||||
items: [
|
||||
{
|
||||
position: 0,
|
||||
lane: "clawhub-trending",
|
||||
sourceRef: { kind: "clawhub", skillId: source.skillId },
|
||||
card: {
|
||||
...nativeCard("clawhub:legacy-native-preflight", 8),
|
||||
metrics: {
|
||||
...nativeCard("clawhub:legacy-native-preflight", 8).metrics,
|
||||
trending24hDownloads: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
await t.mutation(internal.canonicalTrending.finalizeSnapshotInternal, {
|
||||
snapshotId: "skills-legacy-native-preflight",
|
||||
completedAt: now - 500,
|
||||
totalItems: 1,
|
||||
sourceCounts: { clawhubTrending: 1, clawhubRising: 0, skillsShTrending: 0 },
|
||||
operations: { documentsRead: 10, documentsWritten: 2, functionCalls: 3 },
|
||||
});
|
||||
await t.run(async (ctx) => {
|
||||
const snapshot = await ctx.db
|
||||
.query("canonicalTrendingSnapshots")
|
||||
.withIndex("by_snapshot_id", (q) => q.eq("snapshotId", "skills-legacy-native-preflight"))
|
||||
.unique();
|
||||
if (!snapshot) throw new Error("Expected legacy native snapshot");
|
||||
await ctx.db.patch(snapshot._id, { rankingVersion: "skills-trending-v2" });
|
||||
});
|
||||
|
||||
await expect(
|
||||
t.query(internal.canonicalTrending.getReadyNativeSnapshotInternal, { now }),
|
||||
).resolves.toBeNull();
|
||||
});
|
||||
|
||||
it("never serves a snapshot produced by the legacy ranking algorithm", async () => {
|
||||
const t = convexTest(schema, modules);
|
||||
const now = Date.now();
|
||||
|
||||
@@ -122,7 +122,7 @@ describe("CLAW-590 permanent Test snapshot ownership", () => {
|
||||
snapshotId: SNAPSHOT_ID,
|
||||
kind: "skills",
|
||||
status: "failed",
|
||||
rankingVersion: "skills-trending-v2",
|
||||
rankingVersion: "skills-trending-v3",
|
||||
generatedAt: 1_000,
|
||||
completedAt: 2_000,
|
||||
expiresAt: Date.now() + 100_000,
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
internalQuery,
|
||||
type QueryCtx,
|
||||
} from "./_generated/server";
|
||||
import { CANONICAL_TRENDING_RANKING_VERSION } from "./lib/canonicalTrending";
|
||||
import { getCompletedRolling24HourWindow } from "./lib/skillHourlyStats";
|
||||
import { assertTestSeedAllowed } from "./lib/testSeed";
|
||||
|
||||
@@ -311,7 +312,7 @@ function assertOwnedSnapshot(snapshot: Doc<"canonicalTrendingSnapshots">, snapsh
|
||||
if (
|
||||
snapshot.snapshotId !== snapshotId ||
|
||||
snapshot.kind !== "skills" ||
|
||||
snapshot.rankingVersion !== "skills-trending-v2" ||
|
||||
snapshot.rankingVersion !== CANONICAL_TRENDING_RANKING_VERSION ||
|
||||
snapshot.windowHours !== 24
|
||||
) {
|
||||
throw new Error("CLAW-590 proof snapshot ownership mismatch");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { type Infer, v } from "convex/values";
|
||||
import type { Doc } from "../_generated/dataModel";
|
||||
|
||||
export const CANONICAL_TRENDING_RANKING_VERSION = "skills-trending-v2";
|
||||
export const CANONICAL_TRENDING_RANKING_VERSION = "skills-trending-v3";
|
||||
export const CANONICAL_TRENDING_WINDOW_HOURS = 24;
|
||||
export const CANONICAL_TRENDING_FIRST_PAGE_SIZE = 20;
|
||||
export const CANONICAL_TRENDING_PUBLISHER_CAP = 2;
|
||||
|
||||
Reference in New Issue
Block a user