feat(page-data): owner CRUD, public read, and role policy UI

Expose owner PATCH/soft-delete routes, allow anonymous read/stats on
public pages when policy enables read, and add login_required role
editor to the ops panel with tests and doc updates.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-07-08 14:54:14 +08:00
parent 6b0c633a75
commit 8d629e7a4e
11 changed files with 360 additions and 9 deletions
+30
View File
@@ -286,6 +286,36 @@ export function attachPageDataRoutes(api, deps) {
}
});
api.patch('/page-data/:dataset/rows/:rowId', async (req, res) => {
const user = requireUser(req, res, sendError);
if (!user) return;
const service = getPageDataService?.();
if (!service) return sendError(res, req, 503, 'feature_disabled', 'Page Data API 未启用');
const payload = parseRowPayload(req, { stripMeta: true });
if (!payload) return sendError(res, req, 400, 'invalid_request', '更新数据必须是 JSON 对象');
try {
const result = await service.updateRow(user, req.params.dataset, req.params.rowId, payload);
return sendData(res, req, { dataset: result.dataset.name, row: result.row });
} catch (error) {
const status = error?.status ?? 400;
return sendError(res, req, status, error?.code ?? 'page_data_failed', error?.message ?? '更新失败');
}
});
api.delete('/page-data/:dataset/rows/:rowId', async (req, res) => {
const user = requireUser(req, res, sendError);
if (!user) return;
const service = getPageDataService?.();
if (!service) return sendError(res, req, 503, 'feature_disabled', 'Page Data API 未启用');
try {
const result = await service.softDeleteRow(user, req.params.dataset, req.params.rowId);
return sendData(res, req, { dataset: result.dataset.name, row: result.row, deleted: true });
} catch (error) {
const status = error?.status ?? 400;
return sendError(res, req, status, error?.code ?? 'page_data_failed', error?.message ?? '删除失败');
}
});
api.post('/public/pages/:pageId/data-auth', async (req, res) => {
const publicService = getPageDataPublicService?.();
if (!publicService) return sendError(res, req, 503, 'feature_disabled', 'Page Data API 未启用');