Archived
app 装配 mail:channel 作首个订阅方、出站经 mail.send、mail.send 工具真发信(dryRun 只校验)、轮询工作者;上传件存取抽出共用
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TM4kUBvekALu9qqmp7D3wr
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
* 「治理动作本身留痕入事件流 —— 治理也被治理。」
|
||||
*/
|
||||
import { sql } from 'drizzle-orm';
|
||||
import { extractText } from '../upload-extract.ts';
|
||||
import { readUpload, storeUpload, UPLOAD_CAP } from '../upload-store.ts';
|
||||
import type { Hono } from 'hono';
|
||||
import type { ApiError } from '@contracts';
|
||||
import {
|
||||
@@ -721,9 +721,6 @@ export function registerGovernanceOpsRoutes(app: Hono<AppEnv>, container: Contai
|
||||
|
||||
/* ── 上传件:附件要能真正进活动 ─────────────────────────────────── */
|
||||
|
||||
/** 上限 8MB —— 超了当场拒,不静默截断(截断过的文件比没有更害人) */
|
||||
const UPLOAD_CAP = 8 * 1024 * 1024;
|
||||
|
||||
app.post(uploadFileRoute.path, async (c) => {
|
||||
const parsed = uploadFileRoute.body.safeParse(await c.req.json());
|
||||
if (!parsed.success) {
|
||||
@@ -744,37 +741,16 @@ export function registerGovernanceOpsRoutes(app: Hono<AppEnv>, container: Contai
|
||||
return c.json(body, 400);
|
||||
}
|
||||
// 读文本就在入口这一步做完:活动那一侧读得懂的只有文字,读不出就如实记 note
|
||||
const got = extractText(name, contentType, bytes);
|
||||
const me = staffOf(c);
|
||||
const ref = crypto.randomUUID();
|
||||
await container.db.execute(sql`
|
||||
insert into sys.upload (id, name, content_type, size, bytes, text, note, uploaded_by)
|
||||
values (${ref}, ${name}, ${contentType}, ${bytes.length}, ${Buffer.from(bytes)},
|
||||
${got.text ?? null}, ${got.note}, ${me?.id ?? null})`);
|
||||
return c.json({
|
||||
ref,
|
||||
name,
|
||||
contentType,
|
||||
size: bytes.length,
|
||||
...(got.text === undefined ? {} : { text: got.text }),
|
||||
note: got.note,
|
||||
});
|
||||
return c.json(await storeUpload(container.db, { name, contentType, bytes, uploadedBy: staffOf(c)?.id ?? null }));
|
||||
});
|
||||
|
||||
app.get(downloadFileRoute.path, async (c) => {
|
||||
const rows = await container.db.execute<{ name: string; content_type: string; bytes: Buffer }>(
|
||||
sql`select name, content_type, bytes from sys.upload where id = ${c.req.param('id')}`,
|
||||
);
|
||||
const hit = rowsOf<{ name: string; content_type: string; bytes: Buffer }>(rows)[0];
|
||||
const hit = await readUpload(container.db, c.req.param('id'));
|
||||
if (hit === undefined) {
|
||||
const body: ApiError = { code: 'not-found', message: '这个文件不在了' };
|
||||
return c.json(body, 404);
|
||||
}
|
||||
return c.json({
|
||||
name: hit.name,
|
||||
contentType: hit.content_type,
|
||||
dataBase64: Buffer.from(hit.bytes).toString('base64'),
|
||||
});
|
||||
return c.json({ name: hit.name, contentType: hit.contentType, dataBase64: Buffer.from(hit.bytes).toString('base64') });
|
||||
});
|
||||
|
||||
/* ── 试跑日志:历次试跑的存档,按实例管理 ────────────────────────── */
|
||||
|
||||
Reference in New Issue
Block a user