forked from EduCraft/curriculum-project-hub
feat(filelib): 老师端左栏导航:回收站 + 最近打开(ADR-0031)
- 回收站:listBin(祖先全活跃的已删顶点;管理员/直连 MANAGE 可见)、 restore(与 D15 对称只清本节点,落审计)、purge(仅管理员,pathIds 枚举 子树按深度降序分批硬删,绕过 self-FK RESTRICT) - 最近打开:FileLibRecentVisit 表(filePath='' 兜底 PG 唯一索引),客户端 成功打开后上报(VIEW 门禁,upsert 刷新),列表 20 条,D8/D15 可见性过滤 - 前端:/app 左栏(文件库/最近打开/回收站);RecentView/BinView; GridLibraryView 埋点 + navTarget 跳转(breadcrumb 建栈,role 已捎带) - 测试:filelib-nav 集成 4 例;全套 79 例绿
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* /database/api/bin/* 回收站端点(ADR-0031)。
|
||||
* 约定:绝对路径;actorOrNull 前置;业务全走 binService;错误统一 sendRouteError。
|
||||
*/
|
||||
|
||||
import type { FastifyInstance } from "fastify";
|
||||
import { listBin, purgeBinEntry, restoreBinEntry } from "../filelib/binService.js";
|
||||
import { actorOrNull, sendRouteError, type FileLibRouteDeps } from "../filelib/routeShared.js";
|
||||
|
||||
export async function registerBinRoutes(app: FastifyInstance, deps: FileLibRouteDeps): Promise<void> {
|
||||
const svc = { prisma: deps.prisma, organizationId: deps.organizationId, groupResolver: deps.groupResolver };
|
||||
|
||||
app.get("/database/api/bin", async (request, reply) => {
|
||||
const actor = await actorOrNull(request, reply, deps);
|
||||
if (actor === null) return reply;
|
||||
try {
|
||||
return { entries: await listBin(svc, actor) };
|
||||
} catch (error) {
|
||||
return sendRouteError(reply, error);
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/database/api/bin/:id/restore", async (request, reply) => {
|
||||
const actor = await actorOrNull(request, reply, deps);
|
||||
if (actor === null) return reply;
|
||||
try {
|
||||
const { id } = request.params as { id: string };
|
||||
await restoreBinEntry(svc, actor, id);
|
||||
return reply.status(204).send();
|
||||
} catch (error) {
|
||||
return sendRouteError(reply, error);
|
||||
}
|
||||
});
|
||||
|
||||
app.delete("/database/api/bin/:id", async (request, reply) => {
|
||||
const actor = await actorOrNull(request, reply, deps);
|
||||
if (actor === null) return reply;
|
||||
try {
|
||||
const { id } = request.params as { id: string };
|
||||
return await purgeBinEntry(svc, actor, id);
|
||||
} catch (error) {
|
||||
return sendRouteError(reply, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user