Add entity address/contact tables and CRUD for entity resources

This commit is contained in:
seb
2026-08-06 05:43:50 +02:00
parent 0b7e40ac9c
commit 3b77a1c946
32 changed files with 3078 additions and 1363 deletions

View File

@@ -187,6 +187,78 @@ Company-scoped brands. Auth via `resolveCompanyAccess`.
---
## `customergroup`
Company-scoped customer groups. Auth via `resolveCompanyAccess`.
| Method | Signature | Returns |
| --- | --- | --- |
| `list` | `(googleAuthId, companyId)` | `{ id, name }[]` |
| `create` | `(googleAuthId, companyId, { name })` | `{ id, name }` |
| `update` | `(googleAuthId, companyId, id, { name })` | `{ id, name }` |
| `delete` | `(googleAuthId, companyId, id)` | `void` |
Empty name → `Name required`. Deleting the POS group (or any group still referenced with `NO ACTION`) → `Customer group in use`. Cascades entities when the group is deleted. Errors: `Company not found`, `Not authorized`, `Name required`, `Customer group not found`, `Customer group in use`.
---
## `entity`
Entities belong to a `customergroup` of the company. Auth via `resolveCompanyAccess`.
| Method | Signature | Returns |
| --- | --- | --- |
| `list` | `(googleAuthId, companyId, { customergroupId? })` | `Entity[]` |
| `getById` | `(googleAuthId, companyId, id)` | `Entity` |
| `create` | `(googleAuthId, companyId, { customergroupId, name, firstName? })` | `Entity` |
| `update` | `(googleAuthId, companyId, id, { name?, firstName? })` | `Entity` |
| `delete` | `(googleAuthId, companyId, id)` | `void` |
```ts
type Entity = {
id: number,
customergroupId: number,
firstName: string | null,
name: string,
createdAt: Date,
updatedAt: Date,
}
```
`create` / `update` write `entityhistory` (`Erstellt`, or name/firstName change lines). `customergroupId` must belong to the company. Errors: `Company not found`, `Not authorized`, `Name required`, `Customer group not found`, `Entity not found`.
---
## `entityaddress`
Addresses for an entity. Auth via company + entity ownership.
| Method | Signature | Returns |
| --- | --- | --- |
| `list` | `(googleAuthId, companyId, entityId)` | `EntityAddress[]` |
| `create` | `(googleAuthId, companyId, entityId, { addressType, firstName?, name?, street?, streetNumber?, zip?, city?, county? })` | `EntityAddress` |
| `update` | `(googleAuthId, companyId, entityId, id, patch)` | `EntityAddress` |
| `delete` | `(googleAuthId, companyId, entityId, id)` | `void` |
`addressType` required. Errors: `Company not found`, `Not authorized`, `Entity not found`, `Address type required`, `Address not found`.
---
## `entitycontact`
Contacts for an entity (`contactType` e.g. `email`, `phone`). Auth via company + entity ownership.
| Method | Signature | Returns |
| --- | --- | --- |
| `list` | `(googleAuthId, companyId, entityId)` | `{ id, entityId, contactType, contact }[]` |
| `create` | `(googleAuthId, companyId, entityId, { contactType, contact })` | row |
| `update` | `(googleAuthId, companyId, entityId, id, { contactType?, contact? })` | row |
| `delete` | `(googleAuthId, companyId, entityId, id)` | `void` |
Errors: `Company not found`, `Not authorized`, `Entity not found`, `Contact required`, `Contact not found`.
---
## `supplier`
Suppliers are `entity` rows in the company `customergroup` named `Lieferanten` (created implicitly on first supplier). Auth via `resolveCompanyAccess`.
@@ -519,6 +591,23 @@ res.set('Content-Type', thumb.contentType).send(thumb.buffer);
| `GET /api/brand` | `brand.list(googleAuthId, companyId)` |
| `PUT /api/brand` | `brand.upsert(googleAuthId, companyId, { name, gsprpinfo? })` |
| `DELETE /api/brand/:id` | `brand.delete(googleAuthId, companyId, id)` |
| `GET /api/customergroup` | `customergroup.list(googleAuthId, companyId)` |
| `POST /api/customergroup` | `customergroup.create(googleAuthId, companyId, { name })` |
| `PATCH /api/customergroup/:id` | `customergroup.update(googleAuthId, companyId, id, { name })` |
| `DELETE /api/customergroup/:id` | `customergroup.delete(googleAuthId, companyId, id)` |
| `GET /api/entity` | `entity.list(googleAuthId, companyId, { customergroupId? })` |
| `GET /api/entity/:id` | `entity.getById(googleAuthId, companyId, id)` |
| `POST /api/entity` | `entity.create(googleAuthId, companyId, { customergroupId, name, firstName? })` |
| `PATCH /api/entity/:id` | `entity.update(googleAuthId, companyId, id, { name?, firstName? })` |
| `DELETE /api/entity/:id` | `entity.delete(googleAuthId, companyId, id)` |
| `GET /api/entity/:entityId/address` | `entityaddress.list(googleAuthId, companyId, entityId)` |
| `POST /api/entity/:entityId/address` | `entityaddress.create(googleAuthId, companyId, entityId, { addressType, … })` |
| `PATCH /api/entity/:entityId/address/:id` | `entityaddress.update(googleAuthId, companyId, entityId, id, patch)` |
| `DELETE /api/entity/:entityId/address/:id` | `entityaddress.delete(googleAuthId, companyId, entityId, id)` |
| `GET /api/entity/:entityId/contact` | `entitycontact.list(googleAuthId, companyId, entityId)` |
| `POST /api/entity/:entityId/contact` | `entitycontact.create(googleAuthId, companyId, entityId, { contactType, contact })` |
| `PATCH /api/entity/:entityId/contact/:id` | `entitycontact.update(googleAuthId, companyId, entityId, id, patch)` |
| `DELETE /api/entity/:entityId/contact/:id` | `entitycontact.delete(googleAuthId, companyId, entityId, id)` |
| `GET /api/supplier` | `supplier.list(googleAuthId, companyId)` |
| `POST /api/supplier` | `supplier.create(googleAuthId, companyId, { name })` |
| `PATCH /api/supplier/:id` | `supplier.update(googleAuthId, companyId, id, { name })` |