feat(numbers): add number sequences store; restrict companysetting keys
- Add `numbers` store module with `list` and `update` methods backed by the `numbers` table (prefix, padding, next) per company. - Add sql queries LIST_BY_COMPANY, GET_BY_COMPANY_AND_ID, UPDATE_... - Regenerate and wire API docs for `numbers`. companysetting: - Remove the `delete` endpoint (settings are now upsert/read only). - Restrict `set` to a fixed allow-list of keys: ui.theme, keys.tavily, keys.openrouter, labelprinter.addr, labelprinter.type. - Drop DELETE_BY_COMPANY_AND_KEY sql and the delete store file. Docs: update README, API.md, API.companysetting.md, API.numbers.md.
This commit is contained in:
19
README.md
19
README.md
@@ -163,13 +163,14 @@ Company-scoped key/value settings. Auth via selected company (`google_auth.selec
|
||||
| `list` | `(googleAuthId, { frontendOnly? })` | `{ key, value, frontend }[]` |
|
||||
| `get` | `(googleAuthId, key, { frontendOnly? })` | `{ key, value, frontend } \| undefined` |
|
||||
| `set` | `(googleAuthId, { key, value, frontend? })` | `{ key, value, frontend }` |
|
||||
| `delete` | `(googleAuthId, key)` | `void` |
|
||||
|
||||
- `value` is always a string (`NVARCHAR(MAX)`).
|
||||
- `frontend: true` → readable by frontend routes (`frontendOnly: true`). Default on `set` is `false` (backend-only).
|
||||
- With `frontendOnly: true`, backend-only keys are omitted / `get` returns `undefined` (no leak via error type beyond missing).
|
||||
- `set` only allows a fixed allow-list of keys: `ui.theme`, `keys.tavily`, `keys.openrouter`, `labelprinter.addr`, `labelprinter.type`.
|
||||
- No delete endpoint — settings are upsert / read only.
|
||||
|
||||
Errors: `No company selected`, `Company not found`, `Not authorized`, `Invalid setting`, `Setting not found`.
|
||||
Errors: `No company selected`, `Company not found`, `Not authorized`, `Invalid setting`.
|
||||
|
||||
---
|
||||
|
||||
@@ -660,6 +661,19 @@ res.set('Content-Type', thumb.contentType).send(thumb.buffer);
|
||||
|
||||
---
|
||||
|
||||
## `numbers`
|
||||
|
||||
Company-scoped number sequences (`numbers` table). Auth via selected company (`google_auth.selected_company` + membership).
|
||||
|
||||
| Method | Signature | Returns |
|
||||
| --- | --- | --- |
|
||||
| `list` | `(googleAuthId)` | `{ id, type, prefix, padding, next }[]` |
|
||||
| `update` | `(googleAuthId, id, { prefix?, padding?, next? })` | `{ id, type, prefix, padding, next }` |
|
||||
|
||||
`list` returns every sequence for the company, ordered by `type`. `update` updates only the provided fields: `prefix` is trimmed (max 50 chars), `padding` must be an integer `>= 0`, `next` must be an integer `>= 1`. Errors: `No company selected`, `Company not found`, `Not authorized`, `Number not found`, `Invalid number`.
|
||||
|
||||
---
|
||||
|
||||
## Backend route cheatsheet
|
||||
|
||||
| Route | Store call |
|
||||
@@ -683,7 +697,6 @@ res.set('Content-Type', thumb.contentType).send(thumb.buffer);
|
||||
| `DELETE /api/unit` | `unit.delete(googleAuthId, si)` |
|
||||
| `GET /api/company/:id/settings` | `companysetting.list(googleAuthId, { frontendOnly: true })` |
|
||||
| `PUT /api/company/:id/settings` | `companysetting.set(googleAuthId, { key, value, frontend? })` |
|
||||
| `DELETE /api/company/:id/settings/:key` | `companysetting.delete(googleAuthId, key)` |
|
||||
| `GET /api/brand` | `brand.list(googleAuthId)` |
|
||||
| `PUT /api/brand` | `brand.upsert(googleAuthId, { name, gsprpinfo? })` |
|
||||
| `DELETE /api/brand/:id` | `brand.delete(googleAuthId, id)` |
|
||||
|
||||
Reference in New Issue
Block a user