Files
GEOAgentArticleOptimizer/src/lib/db/repository.ts
T
2026-06-24 11:08:23 +08:00

71 lines
2.8 KiB
TypeScript

import type {
CalibrationEvent,
PerformanceSnapshot,
PublicationRecord,
RubricVersion,
ScoringRun,
} from "../calibration/types";
import type { ConfirmedFactCard, OptimizedArticle, QaReport } from "../domain/types";
import type {
ArticleJob,
BrandTemplate,
NewArticleJob,
NewBrandTemplate,
} from "./repositories";
import { getAppCloudflareEnv, type AppCloudflareEnv } from "../runtime/cloudflare";
import { createD1Repository } from "./d1-repository";
import { createSqliteRepository } from "./sqlite-repository";
export interface AppRepository {
createBrandTemplate(input: NewBrandTemplate): Promise<BrandTemplate>;
listBrandTemplates(): Promise<BrandTemplate[]>;
getBrandTemplate(id: string): Promise<BrandTemplate | null>;
createArticleJob(input: NewArticleJob): Promise<ArticleJob>;
getArticleJob(id: string): Promise<ArticleJob | null>;
updateArticleJob(
id: string,
changes: Partial<Pick<ArticleJob, "brand_template_id" | "status" | "export_paths">>,
): Promise<ArticleJob | null>;
saveFactCard(
jobId: string,
factCard: ConfirmedFactCard,
): Promise<{ job_id: string } & ConfirmedFactCard>;
getFactCard(jobId: string): Promise<({ job_id: string } & ConfirmedFactCard) | null>;
saveOptimizedArticle(jobId: string, article: OptimizedArticle): Promise<OptimizedArticle>;
getLatestOptimizedArticle(jobId: string): Promise<OptimizedArticle | null>;
saveQaReport(jobId: string, revision: number, report: QaReport): Promise<QaReport>;
getLatestQaReport(jobId: string): Promise<QaReport | null>;
saveRubricVersion(rubric: RubricVersion): Promise<RubricVersion>;
saveScoringRun(run: ScoringRun): Promise<ScoringRun>;
getLatestScoringRun(jobId: string, revision: number): Promise<ScoringRun | null>;
createPublicationRecord(
input: Omit<PublicationRecord, "id" | "created_at" | "updated_at">,
): Promise<PublicationRecord>;
listPublicationRecords(jobId: string): Promise<PublicationRecord[]>;
getPublicationRecord(id: string): Promise<PublicationRecord | null>;
savePerformanceSnapshot(snapshot: PerformanceSnapshot): Promise<PerformanceSnapshot>;
listPerformanceSnapshots(publicationId: string): Promise<PerformanceSnapshot[]>;
saveCalibrationEvent(event: CalibrationEvent): Promise<CalibrationEvent>;
}
interface RuntimeRepositoryOptions {
appRuntime?: string;
dbPath?: string;
cloudflareEnv?: AppCloudflareEnv;
}
export function getRepositoryFromRuntime(
options: RuntimeRepositoryOptions = {},
): AppRepository {
const appRuntime = options.appRuntime ?? process.env.APP_RUNTIME;
if (appRuntime === "cloudflare") {
const env = options.cloudflareEnv ?? getAppCloudflareEnv();
if (!env?.DB) {
throw new Error("Cloudflare D1 binding DB is required");
}
return createD1Repository(env.DB);
}
return createSqliteRepository(options.dbPath);
}