Add ledger, address/contact sort, and tighter schema-graph layout.
Replace manifestarticle.transactedamount with an append-only ledger, add sort on entity address/contact, and allow same-rank FKs with crossing-aware exits in the graph.
This commit is contained in:
32
README.md
32
README.md
@@ -236,11 +236,11 @@ 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` |
|
||||
| `create` | `(googleAuthId, companyId, entityId, { addressType, firstName?, name?, street?, streetNumber?, zip?, city?, county?, sort? })` | `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`.
|
||||
`addressType` required. `sort` defaults to next index for the entity (`0…n`). List ordered by `sort`, `id`. Errors: `Company not found`, `Not authorized`, `Entity not found`, `Address type required`, `Address not found`, `Invalid sort`.
|
||||
|
||||
---
|
||||
|
||||
@@ -250,12 +250,12 @@ Contacts for an entity (`contactType` e.g. `email`, `phone`). Auth via company +
|
||||
|
||||
| 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 |
|
||||
| `list` | `(googleAuthId, companyId, entityId)` | `{ id, entityId, contactType, contact, sort }[]` |
|
||||
| `create` | `(googleAuthId, companyId, entityId, { contactType, contact, sort? })` | row |
|
||||
| `update` | `(googleAuthId, companyId, entityId, id, { contactType?, contact?, sort? })` | row |
|
||||
| `delete` | `(googleAuthId, companyId, entityId, id)` | `void` |
|
||||
|
||||
Errors: `Company not found`, `Not authorized`, `Entity not found`, `Contact required`, `Contact not found`.
|
||||
`sort` defaults to next index for the entity. List ordered by `sort`, `id`. Errors: `Company not found`, `Not authorized`, `Entity not found`, `Contact required`, `Contact not found`, `Invalid sort`.
|
||||
|
||||
---
|
||||
|
||||
@@ -301,7 +301,6 @@ type DeliveryLine = {
|
||||
sku: string | null,
|
||||
amount: number,
|
||||
net: number,
|
||||
transactedAmount: number,
|
||||
rebate: number,
|
||||
tax: number, // tax.rate
|
||||
comment: string | null,
|
||||
@@ -310,7 +309,7 @@ type DeliveryLine = {
|
||||
type Delivery = DeliverySummary & { lines: DeliveryLine[] }
|
||||
```
|
||||
|
||||
`create` inserts header + lines in one transaction. `supplierId` null or a Lieferanten `entity` of the company (else `Supplier not found`). Each line requires `sku` (resolved in the company category tree → `Article not found`), `amount`, `net`, `tax` (rate → `tax.ensure`); `rebate` defaults `0`; `transactedAmount` defaults to `amount`. Empty/invalid `number` or `date` → `Invalid delivery`; bad line payload → `Invalid lines`.
|
||||
`create` inserts header + lines in one transaction. `supplierId` null or a Lieferanten `entity` of the company (else `Supplier not found`). Each line requires `sku` (resolved in the company category tree → `Article not found`), `amount`, `net`, `tax` (rate → `tax.ensure`); `rebate` defaults `0`. Empty/invalid `number` or `date` → `Invalid delivery`; bad line payload → `Invalid lines`.
|
||||
|
||||
`update` patches header fields that are present. If `lines` is present, replace-all lines; if omitted, leave lines unchanged. Returns full `Delivery`.
|
||||
|
||||
@@ -318,6 +317,23 @@ type Delivery = DeliverySummary & { lines: DeliveryLine[] }
|
||||
|
||||
---
|
||||
|
||||
## `ledger`
|
||||
|
||||
Append-only SQL Server ledger table (`WITH (LEDGER = ON (APPEND_ONLY = ON))`). Rows cannot be updated or deleted. References `manifestarticle` with `ON DELETE NO ACTION` (a line with ledger entries cannot be removed). No store API yet — INSERT only via future store methods / direct SQL.
|
||||
|
||||
| Column | Type | Notes |
|
||||
| --- | --- | --- |
|
||||
| `id` | `INT IDENTITY` | PK |
|
||||
| `manifestarticle_id` | `INT` | FK → `manifestarticle` |
|
||||
| `transaction_type` | `NVARCHAR(100)` | |
|
||||
| `amount` | `FLOAT` | |
|
||||
| `transaction_text` | `NVARCHAR(MAX)` | |
|
||||
| `prev_hash` | `NVARCHAR(128)` | nullable (genesis row) |
|
||||
|
||||
Engine also maintains `ledger_start_transaction_id` / `ledger_start_sequence_number`. `purge`/`reset-db` soft-drops the table (`MSSQL_DroppedLedgerTable_*` remains; a new `ledger` can still be created).
|
||||
|
||||
---
|
||||
|
||||
## `posterminal`
|
||||
|
||||
Company-scoped POS terminals. Auth via `resolveCompanyAccess`.
|
||||
|
||||
Reference in New Issue
Block a user