u
This commit is contained in:
@@ -120,8 +120,7 @@ Backend mapping:
|
||||
| Method | Signature | Returns |
|
||||
| --- | --- | --- |
|
||||
| `createUnderParent` | `({ googleAuthId, parentId, name })` | `{ id, parentId, sort, name }` |
|
||||
| `updateParentId` | `(id, parentId)` | `void` |
|
||||
| `delete` | `(id)` | `void` — blocked by FK if `categoryarticle` (or child categories) still reference it |
|
||||
| `delete` | `({ googleAuthId, id })` | `void` — blocked by FK if `categoryarticle` or child categories remain |
|
||||
| `getTreeForCompany` | `(googleAuthId, companyId)` | `{ languageId, tree, articles }` |
|
||||
|
||||
### `createUnderParent` (transaction)
|
||||
@@ -131,6 +130,8 @@ Backend mapping:
|
||||
3. `companyuser` for `(googleAuthId, companyId)`, else `Not authorized`
|
||||
4. Insert `category` (next sibling `sort`) + `categorytext` (`name`, slugified `slug`, company default language)
|
||||
|
||||
All category mutations use `resolveCategoryAccess(googleAuthId, categoryId)` internally. Root category cannot be deleted.
|
||||
|
||||
`getTreeForCompany` throws `Not authorized` if `googleAuthId` is not a `companyuser` of `companyId`, and `Company not found` if the company is missing, has no `root_category_id`, or no `default_language_id`.
|
||||
|
||||
---
|
||||
@@ -146,6 +147,7 @@ Backend mapping:
|
||||
| `PUT /api/auth/selected-company` | `google_auth.setSelectedCompany(googleAuthId, companyId)` |
|
||||
| `GET /api/category/tree?companyId=` | `category.getTreeForCompany(googleAuthId, companyId)` |
|
||||
| `POST /api/category` | `category.createUnderParent({ googleAuthId, parentId, name })` |
|
||||
| `DELETE /api/category/:id` | `category.delete({ googleAuthId, id })` |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -96,8 +96,7 @@ const MENU = {
|
||||
label: 'category',
|
||||
items: [
|
||||
{ value: 'category.createUnderParent', label: 'createUnderParent', hint: 'googleAuthId, parentId, name → row' },
|
||||
{ value: 'category.updateParentId', label: 'updateParentId', hint: 'id, parentId' },
|
||||
{ value: 'category.delete', label: 'delete', hint: 'id' },
|
||||
{ value: 'category.delete', label: 'delete', hint: 'googleAuthId, id' },
|
||||
{ value: 'category.getTreeForCompany', label: 'getTreeForCompany', hint: 'googleAuthId, companyId → rows' },
|
||||
],
|
||||
},
|
||||
@@ -320,23 +319,15 @@ async function runMethod(client, action) {
|
||||
}),
|
||||
];
|
||||
}
|
||||
case 'category.updateParentId': {
|
||||
const id = await askInt('Category id');
|
||||
if (id == null) return;
|
||||
const parentRaw = await askText('parentId (null as empty)', {
|
||||
placeholder: '',
|
||||
validate: (v) =>
|
||||
v?.trim() && !/^\d+$/.test(v.trim()) ? 'Integer or empty' : undefined,
|
||||
});
|
||||
if (parentRaw == null) return;
|
||||
const parentId = parentRaw === '' ? null : Number(parentRaw);
|
||||
await client.category.updateParentId(Number(id), parentId);
|
||||
return ['ok', true];
|
||||
}
|
||||
case 'category.delete': {
|
||||
const googleAuthId = await askInt('google_auth id');
|
||||
if (googleAuthId == null) return;
|
||||
const id = await askInt('Category id');
|
||||
if (id == null) return;
|
||||
await client.category.delete(Number(id));
|
||||
await client.category.delete({
|
||||
googleAuthId: Number(googleAuthId),
|
||||
id: Number(id),
|
||||
});
|
||||
return ['ok', true];
|
||||
}
|
||||
case 'category.getTreeForCompany': {
|
||||
|
||||
@@ -7,7 +7,6 @@ import companyDelete from './store/company/delete.js';
|
||||
import companyList from './store/company/list.js';
|
||||
import categoryGetTreeForCompany from './store/category/getTreeForCompany.js';
|
||||
import categoryCreateUnderParent from './store/category/createUnderParent.js';
|
||||
import categoryUpdateParentId from './store/category/updateParentId.js';
|
||||
import categoryDelete from './store/category/delete.js';
|
||||
import langCreate from './store/lang/create.js';
|
||||
import langDelete from './store/lang/delete.js';
|
||||
@@ -46,7 +45,6 @@ export default class LibDashStore {
|
||||
this.category = {
|
||||
getTreeForCompany: categoryGetTreeForCompany(pool),
|
||||
createUnderParent: categoryCreateUnderParent(pool),
|
||||
updateParentId: categoryUpdateParentId(pool),
|
||||
delete: categoryDelete(pool),
|
||||
};
|
||||
|
||||
|
||||
@@ -126,12 +126,6 @@ FROM category
|
||||
WHERE parent_id = @parentId
|
||||
`;
|
||||
|
||||
export const UPDATE_PARENT_ID = `
|
||||
UPDATE category
|
||||
SET parent_id = @parentId
|
||||
WHERE id = @id
|
||||
`;
|
||||
|
||||
export const DELETE = `
|
||||
DELETE FROM category
|
||||
WHERE id = @id
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
import { DELETE } from '../../sql/category.js';
|
||||
import resolveCategoryAccess from './resolveCategoryAccess.js';
|
||||
|
||||
export default function del(pool) {
|
||||
return async (id) => {
|
||||
const access = resolveCategoryAccess(pool);
|
||||
|
||||
return async ({ googleAuthId, id }) => {
|
||||
const { rootCategoryId } = await access(googleAuthId, id);
|
||||
|
||||
if (id === rootCategoryId) {
|
||||
throw new Error('Cannot delete root category');
|
||||
}
|
||||
|
||||
await pool.request().input('id', id).query(DELETE);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import { UPDATE_PARENT_ID } from '../../sql/category.js';
|
||||
|
||||
export default function updateParentId(pool) {
|
||||
return async (id, parentId) => {
|
||||
await pool
|
||||
.request()
|
||||
.input('id', id)
|
||||
.input('parentId', parentId)
|
||||
.query(UPDATE_PARENT_ID);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user