feat(阶段3): oj 侧端点铺开(基线提交,未经评审)
由外部 agent (Codex) 在本会话额度中断期间完成。原样提交作为基线, 后续修复单独成 commit,便于区分与回退。 覆盖 oj 侧 65 个端点,新增 9 组路由(account/achievement/ai/classroom/ content/contest/flowchart/problemset/site)与对应 Zod 契约。 已核验:tsc --noEmit 退出码 0;API 可启动;/api/problems 返回真实数据; judge 与 flowchart worker 均 ready。 未核验:权限边界与数据泄露,评审进行中。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
48
apps/api/src/events.ts
Normal file
48
apps/api/src/events.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { flowchartUpdateSchema, type FlowchartUpdate } from "@oj2/contract"
|
||||
|
||||
import { redis } from "./redis"
|
||||
|
||||
export const userEventChannel = "user:events"
|
||||
|
||||
interface UserEvent {
|
||||
userId: number
|
||||
data: FlowchartUpdate | Record<string, unknown>
|
||||
}
|
||||
|
||||
interface AchievementNotification {
|
||||
id: number
|
||||
name: string
|
||||
description: string
|
||||
icon: string
|
||||
rarity: string
|
||||
kind: "achievement" | "badge"
|
||||
}
|
||||
|
||||
export function userEventTopic(userId: number) {
|
||||
return `events:user:${userId}`
|
||||
}
|
||||
|
||||
export async function publishFlowchartUpdate(userId: number, data: FlowchartUpdate) {
|
||||
await redis.publish(userEventChannel, JSON.stringify({ userId, data: flowchartUpdateSchema.parse(data) }))
|
||||
}
|
||||
|
||||
export async function publishAchievementNotification(
|
||||
userId: number,
|
||||
achievements: AchievementNotification[],
|
||||
) {
|
||||
if (!achievements.length) return
|
||||
await redis.publish(userEventChannel, JSON.stringify({
|
||||
userId,
|
||||
data: { type: "achievement_unlocked", achievements },
|
||||
}))
|
||||
}
|
||||
|
||||
export function parseUserEvent(raw: string): UserEvent | null {
|
||||
try {
|
||||
const value = JSON.parse(raw) as UserEvent
|
||||
if (!Number.isInteger(value.userId) || !value.data || typeof value.data !== "object") return null
|
||||
return value
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user