u
This commit is contained in:
@@ -120,8 +120,7 @@ Backend mapping:
|
|||||||
| Method | Signature | Returns |
|
| Method | Signature | Returns |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `createUnderParent` | `({ googleAuthId, parentId, name })` | `{ id, parentId, sort, name }` |
|
| `createUnderParent` | `({ googleAuthId, parentId, name })` | `{ id, parentId, sort, name }` |
|
||||||
| `updateParentId` | `(id, parentId)` | `void` |
|
| `delete` | `({ googleAuthId, id })` | `void` — blocked by FK if `categoryarticle` or child categories remain |
|
||||||
| `delete` | `(id)` | `void` — blocked by FK if `categoryarticle` (or child categories) still reference it |
|
|
||||||
| `getTreeForCompany` | `(googleAuthId, companyId)` | `{ languageId, tree, articles }` |
|
| `getTreeForCompany` | `(googleAuthId, companyId)` | `{ languageId, tree, articles }` |
|
||||||
|
|
||||||
### `createUnderParent` (transaction)
|
### `createUnderParent` (transaction)
|
||||||
@@ -131,6 +130,8 @@ Backend mapping:
|
|||||||
3. `companyuser` for `(googleAuthId, companyId)`, else `Not authorized`
|
3. `companyuser` for `(googleAuthId, companyId)`, else `Not authorized`
|
||||||
4. Insert `category` (next sibling `sort`) + `categorytext` (`name`, slugified `slug`, company default language)
|
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`.
|
`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)` |
|
| `PUT /api/auth/selected-company` | `google_auth.setSelectedCompany(googleAuthId, companyId)` |
|
||||||
| `GET /api/category/tree?companyId=` | `category.getTreeForCompany(googleAuthId, companyId)` |
|
| `GET /api/category/tree?companyId=` | `category.getTreeForCompany(googleAuthId, companyId)` |
|
||||||
| `POST /api/category` | `category.createUnderParent({ googleAuthId, parentId, name })` |
|
| `POST /api/category` | `category.createUnderParent({ googleAuthId, parentId, name })` |
|
||||||
|
| `DELETE /api/category/:id` | `category.delete({ googleAuthId, id })` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -96,8 +96,7 @@ const MENU = {
|
|||||||
label: 'category',
|
label: 'category',
|
||||||
items: [
|
items: [
|
||||||
{ value: 'category.createUnderParent', label: 'createUnderParent', hint: 'googleAuthId, parentId, name → row' },
|
{ value: 'category.createUnderParent', label: 'createUnderParent', hint: 'googleAuthId, parentId, name → row' },
|
||||||
{ value: 'category.updateParentId', label: 'updateParentId', hint: 'id, parentId' },
|
{ value: 'category.delete', label: 'delete', hint: 'googleAuthId, id' },
|
||||||
{ value: 'category.delete', label: 'delete', hint: 'id' },
|
|
||||||
{ value: 'category.getTreeForCompany', label: 'getTreeForCompany', hint: 'googleAuthId, companyId → rows' },
|
{ 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': {
|
case 'category.delete': {
|
||||||
|
const googleAuthId = await askInt('google_auth id');
|
||||||
|
if (googleAuthId == null) return;
|
||||||
const id = await askInt('Category id');
|
const id = await askInt('Category id');
|
||||||
if (id == null) return;
|
if (id == null) return;
|
||||||
await client.category.delete(Number(id));
|
await client.category.delete({
|
||||||
|
googleAuthId: Number(googleAuthId),
|
||||||
|
id: Number(id),
|
||||||
|
});
|
||||||
return ['ok', true];
|
return ['ok', true];
|
||||||
}
|
}
|
||||||
case 'category.getTreeForCompany': {
|
case 'category.getTreeForCompany': {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import companyDelete from './store/company/delete.js';
|
|||||||
import companyList from './store/company/list.js';
|
import companyList from './store/company/list.js';
|
||||||
import categoryGetTreeForCompany from './store/category/getTreeForCompany.js';
|
import categoryGetTreeForCompany from './store/category/getTreeForCompany.js';
|
||||||
import categoryCreateUnderParent from './store/category/createUnderParent.js';
|
import categoryCreateUnderParent from './store/category/createUnderParent.js';
|
||||||
import categoryUpdateParentId from './store/category/updateParentId.js';
|
|
||||||
import categoryDelete from './store/category/delete.js';
|
import categoryDelete from './store/category/delete.js';
|
||||||
import langCreate from './store/lang/create.js';
|
import langCreate from './store/lang/create.js';
|
||||||
import langDelete from './store/lang/delete.js';
|
import langDelete from './store/lang/delete.js';
|
||||||
@@ -46,7 +45,6 @@ export default class LibDashStore {
|
|||||||
this.category = {
|
this.category = {
|
||||||
getTreeForCompany: categoryGetTreeForCompany(pool),
|
getTreeForCompany: categoryGetTreeForCompany(pool),
|
||||||
createUnderParent: categoryCreateUnderParent(pool),
|
createUnderParent: categoryCreateUnderParent(pool),
|
||||||
updateParentId: categoryUpdateParentId(pool),
|
|
||||||
delete: categoryDelete(pool),
|
delete: categoryDelete(pool),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -126,12 +126,6 @@ FROM category
|
|||||||
WHERE parent_id = @parentId
|
WHERE parent_id = @parentId
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const UPDATE_PARENT_ID = `
|
|
||||||
UPDATE category
|
|
||||||
SET parent_id = @parentId
|
|
||||||
WHERE id = @id
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const DELETE = `
|
export const DELETE = `
|
||||||
DELETE FROM category
|
DELETE FROM category
|
||||||
WHERE id = @id
|
WHERE id = @id
|
||||||
|
|||||||
@@ -1,7 +1,16 @@
|
|||||||
import { DELETE } from '../../sql/category.js';
|
import { DELETE } from '../../sql/category.js';
|
||||||
|
import resolveCategoryAccess from './resolveCategoryAccess.js';
|
||||||
|
|
||||||
export default function del(pool) {
|
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);
|
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