Merge branch 'feat/step6-success-rate' into feat/step3-missing-guidance

This commit is contained in:
uncle6me-web
2026-07-31 14:54:25 +08:00
10 changed files with 490 additions and 52 deletions
+37
View File
@@ -0,0 +1,37 @@
// POST /analytics/record — 零件執行結果回寫端點
// SDD: system-dev/docs/3-specs/arcrun-core-mvp/design.md「執行統計設計」
// 呼叫方:cypher-executor 執行收尾(fire-and-forget,統計失敗不影響執行)
import { Hono } from 'hono';
import type { Bindings } from '../types';
import { recordAnalytics } from '../actions/recordAnalytics';
const app = new Hono<{ Bindings: Bindings }>();
app.post('/record', async c => {
const body = await c.req.json().catch(() => null) as {
canonical_id?: unknown;
version?: unknown;
success?: unknown;
duration_ms?: unknown;
} | null;
if (!body || typeof body.canonical_id !== 'string' || body.canonical_id.trim() === '') {
return c.json({ ok: false, error: 'canonical_id 必填' }, 400);
}
if (typeof body.success !== 'boolean') {
return c.json({ ok: false, error: 'success 必須為 boolean' }, 400);
}
const result = await recordAnalytics({
canonical_id: body.canonical_id.trim(),
version: typeof body.version === 'string' && body.version !== '' ? body.version : undefined,
success: body.success,
duration_ms: typeof body.duration_ms === 'number' ? body.duration_ms : 0,
}, c.env);
if (!result.ok) return c.json(result, 404);
return c.json(result);
});
export default app;