Skip to content
File

Blob: src/worker/repositories/routeCache.ts

typescript64 lines
1import { createLogger } from "@/worker/common";
2import { z } from "zod";
3 
4// Workers KV `ROUTES` candidate cache. Backfill and repo-mutation flows
5// write here; the resolver reads here as a hint and re-confirms against
6// D1. The payload deliberately omits `visibility` because KV is
7// eventually consistent and must not be an authorization source.
8 
9export const RouteCacheRecordSchema = z.object({
10 repositoryId: z.string(),
11 namespaceId: z.string(),
12 doName: z.string(),
13 updatedAt: z.number(),
14});
15 
16export type RouteCacheRecord = z.infer<typeof RouteCacheRecordSchema>;
17 
18export function routeCacheKey(namespaceSlug: string, repoSlug: string): string {
19 return `repo-route:v1:${namespaceSlug}/${repoSlug}`;
20}
21 
22// Writes/deletes log only on success. Failures throw to the caller so
23// surrounding handlers can attach their own context (legacyBackfill,
24// repo create/rename/delete) - duplicating a generic error log here
25// would just bury the operational signal.
26export async function putRouteCacheRecord(
27 env: Env,
28 namespaceSlug: string,
29 repoSlug: string,
30 record: RouteCacheRecord
31): Promise<void> {
32 await env.ROUTES.put(routeCacheKey(namespaceSlug, repoSlug), JSON.stringify(record));
33 const log = createLogger(env.LOG_LEVEL, { service: "RouteCache" });
34 log.debug("routes:put-ok", {
35 namespaceSlug,
36 repoSlug,
37 repositoryId: record.repositoryId,
38 });
39}
40 
41export async function getRouteCacheRecord(
42 env: Env,
43 namespaceSlug: string,
44 repoSlug: string
45): Promise<RouteCacheRecord | null> {
46 const raw = await env.ROUTES.get(routeCacheKey(namespaceSlug, repoSlug));
47 if (!raw) return null;
48 try {
49 const parsed = RouteCacheRecordSchema.safeParse(JSON.parse(raw));
50 if (parsed.success) return parsed.data;
51 } catch {}
52 return null;
53}
54 
55export async function deleteRouteCacheRecord(
56 env: Env,
57 namespaceSlug: string,
58 repoSlug: string
59): Promise<void> {
60 await env.ROUTES.delete(routeCacheKey(namespaceSlug, repoSlug));
61 const log = createLogger(env.LOG_LEVEL, { service: "RouteCache" });
62 log.debug("routes:delete-ok", { namespaceSlug, repoSlug });
63}