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:
@@ -101,6 +101,54 @@ test('page data routes allow logged-in owner to read and insert dataset rows', a
|
||||
assert.equal(stats.body.data.total, 1);
|
||||
});
|
||||
|
||||
test('page data routes allow owner update and soft delete', async () => {
|
||||
const workspaceRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'page-data-api-crud-'));
|
||||
const service = createUserDataSpaceService({ workspaceRoot });
|
||||
await service.executeSql(`CREATE TABLE tasks (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
title TEXT NOT NULL,
|
||||
status TEXT DEFAULT 'open',
|
||||
created_at TEXT,
|
||||
deleted_at TEXT,
|
||||
deleted_by TEXT,
|
||||
updated_at TEXT
|
||||
);`);
|
||||
await service.upsertDataset({
|
||||
name: 'tasks',
|
||||
table: 'tasks',
|
||||
actions: ['read', 'insert', 'update', 'soft_delete'],
|
||||
columns: {
|
||||
read: ['id', 'title', 'status', 'created_at'],
|
||||
insert: ['title'],
|
||||
update: ['status'],
|
||||
soft_delete: ['id'],
|
||||
},
|
||||
});
|
||||
|
||||
const app = createApiApp({
|
||||
workspaceRoot,
|
||||
user: { id: 'user-1', workspaceRoot },
|
||||
});
|
||||
|
||||
const inserted = await requestJson(app, 'POST', '/api/page-data/tasks/rows', { title: '待办' });
|
||||
assert.equal(inserted.status, 201);
|
||||
const rowId = inserted.body.data.row.id;
|
||||
|
||||
const updated = await requestJson(app, 'PATCH', `/api/page-data/tasks/rows/${rowId}`, {
|
||||
status: 'done',
|
||||
});
|
||||
assert.equal(updated.status, 200);
|
||||
assert.equal(updated.body.data.row.status, 'done');
|
||||
|
||||
const deleted = await requestJson(app, 'DELETE', `/api/page-data/tasks/rows/${rowId}`);
|
||||
assert.equal(deleted.status, 200);
|
||||
assert.equal(deleted.body.data.deleted, true);
|
||||
|
||||
const listed = await requestJson(app, 'GET', '/api/page-data/tasks?limit=10');
|
||||
assert.equal(listed.status, 200);
|
||||
assert.equal(listed.body.data.rows.length, 0);
|
||||
});
|
||||
|
||||
test('page data routes reject unauthorized dataset action', async () => {
|
||||
const workspaceRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'page-data-api-deny-'));
|
||||
const service = createUserDataSpaceService({ workspaceRoot });
|
||||
|
||||
Reference in New Issue
Block a user