接入发布校准仓储接口
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
import { nanoid } from "nanoid";
|
||||
|
||||
import type {
|
||||
PerformanceSnapshot,
|
||||
PublicationRecord,
|
||||
ScoringRun,
|
||||
} from "../calibration/types";
|
||||
import type {
|
||||
ConfirmedFactCard,
|
||||
ImageInput,
|
||||
@@ -58,6 +63,41 @@ interface QaReportRow {
|
||||
report: string;
|
||||
}
|
||||
|
||||
interface ScoringRunRow {
|
||||
id: string;
|
||||
job_id: string;
|
||||
revision: number;
|
||||
rubric_version_id: string;
|
||||
dimension_scores: string;
|
||||
composite_score: number;
|
||||
rationale: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
interface PublicationRecordRow {
|
||||
id: string;
|
||||
job_id: string;
|
||||
revision: number;
|
||||
platform: PublishPlatform;
|
||||
url: string;
|
||||
published_at: string;
|
||||
status: "draft" | "published" | "archived";
|
||||
notes: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
interface PerformanceSnapshotRow {
|
||||
id: string;
|
||||
publication_id: string;
|
||||
source: "manual" | `adapter:${string}`;
|
||||
window_label: string;
|
||||
metrics: string;
|
||||
feedback_summary: string;
|
||||
raw_reference: string | null;
|
||||
snapshot_at: string;
|
||||
}
|
||||
|
||||
function nowIso() {
|
||||
return new Date().toISOString();
|
||||
}
|
||||
@@ -91,6 +131,21 @@ function toArticleJob(row: ArticleJobRow): ArticleJob {
|
||||
};
|
||||
}
|
||||
|
||||
function toScoringRun(row: ScoringRunRow): ScoringRun {
|
||||
return {
|
||||
...row,
|
||||
dimension_scores: parseJson<Record<string, number>>(row.dimension_scores),
|
||||
};
|
||||
}
|
||||
|
||||
function toPerformanceSnapshot(row: PerformanceSnapshotRow): PerformanceSnapshot {
|
||||
return {
|
||||
...row,
|
||||
raw_reference: row.raw_reference ?? undefined,
|
||||
metrics: parseJson<PerformanceSnapshot["metrics"]>(row.metrics),
|
||||
};
|
||||
}
|
||||
|
||||
export function createD1Repository(db: D1Database): AppRepository {
|
||||
return {
|
||||
async createBrandTemplate(input) {
|
||||
@@ -299,5 +354,159 @@ export function createD1Repository(db: D1Database): AppRepository {
|
||||
.first<QaReportRow>();
|
||||
return row ? parseJson<QaReport>(row.report) : null;
|
||||
},
|
||||
async saveRubricVersion(rubric) {
|
||||
await db
|
||||
.prepare(
|
||||
`insert into rubric_versions (
|
||||
id, version, name, dimensions, formula, is_active, created_at
|
||||
) values (?, ?, ?, ?, ?, ?, ?)
|
||||
on conflict(id) do update set
|
||||
version = excluded.version,
|
||||
name = excluded.name,
|
||||
dimensions = excluded.dimensions,
|
||||
formula = excluded.formula,
|
||||
is_active = excluded.is_active`,
|
||||
)
|
||||
.bind(
|
||||
rubric.id,
|
||||
rubric.version,
|
||||
rubric.name,
|
||||
serialize(rubric.dimensions),
|
||||
rubric.formula,
|
||||
rubric.is_active ? 1 : 0,
|
||||
rubric.created_at,
|
||||
)
|
||||
.run();
|
||||
return rubric;
|
||||
},
|
||||
async saveScoringRun(run) {
|
||||
await db
|
||||
.prepare(
|
||||
`insert into scoring_runs (
|
||||
id, job_id, revision, rubric_version_id, dimension_scores,
|
||||
composite_score, rationale, created_at
|
||||
) values (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
)
|
||||
.bind(
|
||||
run.id,
|
||||
run.job_id,
|
||||
run.revision,
|
||||
run.rubric_version_id,
|
||||
serialize(run.dimension_scores),
|
||||
run.composite_score,
|
||||
run.rationale,
|
||||
run.created_at,
|
||||
)
|
||||
.run();
|
||||
return run;
|
||||
},
|
||||
async getLatestScoringRun(jobId, revision) {
|
||||
const row = await db
|
||||
.prepare(
|
||||
`select * from scoring_runs
|
||||
where job_id = ? and revision = ?
|
||||
order by created_at desc
|
||||
limit 1`,
|
||||
)
|
||||
.bind(jobId, revision)
|
||||
.first<ScoringRunRow>();
|
||||
return row ? toScoringRun(row) : null;
|
||||
},
|
||||
async createPublicationRecord(input) {
|
||||
const timestamp = nowIso();
|
||||
const record: PublicationRecord = {
|
||||
id: `pub_${nanoid(10)}`,
|
||||
...input,
|
||||
created_at: timestamp,
|
||||
updated_at: timestamp,
|
||||
};
|
||||
await db
|
||||
.prepare(
|
||||
`insert into publication_records (
|
||||
id, job_id, revision, platform, url, published_at, status,
|
||||
notes, created_at, updated_at
|
||||
) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
)
|
||||
.bind(
|
||||
record.id,
|
||||
record.job_id,
|
||||
record.revision,
|
||||
record.platform,
|
||||
record.url,
|
||||
record.published_at,
|
||||
record.status,
|
||||
record.notes,
|
||||
record.created_at,
|
||||
record.updated_at,
|
||||
)
|
||||
.run();
|
||||
return record;
|
||||
},
|
||||
async listPublicationRecords(jobId) {
|
||||
const result = await db
|
||||
.prepare(
|
||||
"select * from publication_records where job_id = ? order by published_at desc",
|
||||
)
|
||||
.bind(jobId)
|
||||
.all<PublicationRecordRow>();
|
||||
return result.results;
|
||||
},
|
||||
async getPublicationRecord(id) {
|
||||
return db
|
||||
.prepare("select * from publication_records where id = ?")
|
||||
.bind(id)
|
||||
.first<PublicationRecordRow>();
|
||||
},
|
||||
async savePerformanceSnapshot(snapshot) {
|
||||
await db
|
||||
.prepare(
|
||||
`insert into performance_snapshots (
|
||||
id, publication_id, source, window_label, metrics,
|
||||
feedback_summary, raw_reference, snapshot_at
|
||||
) values (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
)
|
||||
.bind(
|
||||
snapshot.id,
|
||||
snapshot.publication_id,
|
||||
snapshot.source,
|
||||
snapshot.window_label,
|
||||
serialize(snapshot.metrics),
|
||||
snapshot.feedback_summary,
|
||||
snapshot.raw_reference ?? null,
|
||||
snapshot.snapshot_at,
|
||||
)
|
||||
.run();
|
||||
return snapshot;
|
||||
},
|
||||
async listPerformanceSnapshots(publicationId) {
|
||||
const result = await db
|
||||
.prepare(
|
||||
"select * from performance_snapshots where publication_id = ? order by snapshot_at desc",
|
||||
)
|
||||
.bind(publicationId)
|
||||
.all<PerformanceSnapshotRow>();
|
||||
return result.results.map(toPerformanceSnapshot);
|
||||
},
|
||||
async saveCalibrationEvent(event) {
|
||||
await db
|
||||
.prepare(
|
||||
`insert into calibration_events (
|
||||
id, publication_id, scoring_run_id, performance_snapshot_id,
|
||||
direction, observations, recommended_action, created_at
|
||||
) values (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
)
|
||||
.bind(
|
||||
event.id,
|
||||
event.publication_id,
|
||||
event.scoring_run_id,
|
||||
event.performance_snapshot_id,
|
||||
event.direction,
|
||||
serialize(event.observations),
|
||||
event.recommended_action,
|
||||
event.created_at,
|
||||
)
|
||||
.run();
|
||||
return event;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user