/** * 入站路由 —— 模拟邮件通道的注入口(编码规范 §3;README MVP 完成判据)。 * * mock 只允许出现在**外界**:这条路由代替真实 IMAP 拉件, * 之后的归属解析、事件流、三级消费、系统写全部是真机制。 */ import type { Hono } from 'hono'; import type { ApiError } from '@contracts'; import { ingestMailRoute } from '@contracts'; import { ChannelDisabledError, ChannelNotFoundError } from '@modules/channel'; import type { Container } from '../container.ts'; import type { AppEnv } from '../http-env.ts'; export function registerIngestRoutes(app: Hono, container: Container): void { app.post(ingestMailRoute.path, async (c) => { const parsed = ingestMailRoute.body.safeParse(await c.req.json()); if (!parsed.success) { const body: ApiError = { code: 'validation-failed', message: '入站邮件不合 schema', detail: parsed.error.issues }; return c.json(body, 400); } try { const outcome = await container.channel.ingestMail(c.req.param('channelId'), parsed.data); return c.json({ eventId: outcome.eventId, resolution: outcome.resolution, listenersHit: outcome.listenersHit, triggersHit: outcome.triggersHit, fellBackToMessage: outcome.fellBackToMessage, }); } catch (error) { if (error instanceof ChannelNotFoundError) { const body: ApiError = { code: 'not-found', message: error.message }; return c.json(body, 404); } if (error instanceof ChannelDisabledError) { const body: ApiError = { code: 'precondition-failed', message: error.message }; return c.json(body, 412); } throw error; } }); }