feat: add hash and thumbnail columns to file, sort column and order method to manifestattachment
This commit is contained in:
@@ -18,10 +18,15 @@ Attaches a file to an existing manifest.
|
||||
| `input.mimetype` | `string` | The MIME type of the file (e.g. `'application/pdf'`). |
|
||||
| `input.name` | `string` | The file name. |
|
||||
| `input.content` | `Buffer` | The file content. |
|
||||
| `[input.sort]` | `number` | Optional display sort order. |
|
||||
| `[input.hash]` | `string` | The file hash (auto-computed SHA-256 if omitted). |
|
||||
| `[input.thumbavif]` | `Buffer` | Optional AVIF thumbnail buffer. |
|
||||
| `[input.thumbx]` | `number` | Optional thumbnail width. |
|
||||
| `[input.thumby]` | `number` | Optional thumbnail height. |
|
||||
|
||||
**Returns**
|
||||
|
||||
`Promise<{id: number, manifestId: number, fileId: number, mimetype: string, name: string}>` — The created attachment record.
|
||||
`Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>` — The created attachment record.
|
||||
|
||||
**Throws**
|
||||
|
||||
@@ -35,7 +40,7 @@ const attachment = await store.manifestattachment.add(42, 1, {
|
||||
name: 'invoice.pdf',
|
||||
content: fileBuffer,
|
||||
});
|
||||
// => { id, manifestId, fileId, mimetype, name }
|
||||
// => { id, manifestId, fileId, sort, hash, mimetype, name, thumbavif, thumbx, thumby }
|
||||
```
|
||||
|
||||
## `manifestattachment.getById`
|
||||
@@ -54,7 +59,7 @@ Gets an attachment for a manifest by its attachment ID or file ID, including ful
|
||||
|
||||
**Returns**
|
||||
|
||||
`Promise<{id: number, manifestId: number, fileId: number, mimetype: string, name: string, content: Buffer}>` — The attachment record with binary content.
|
||||
`Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, content: Buffer, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>` — The attachment record with binary content.
|
||||
|
||||
**Throws**
|
||||
|
||||
@@ -64,7 +69,7 @@ Gets an attachment for a manifest by its attachment ID or file ID, including ful
|
||||
|
||||
```js
|
||||
const attachment = await store.manifestattachment.getById(42, 1, 5);
|
||||
// => { id, manifestId, fileId, mimetype, name, content }
|
||||
// => { id, manifestId, fileId, sort, hash, mimetype, name, content, thumbavif, thumbx, thumby }
|
||||
```
|
||||
|
||||
## `manifestattachment.listByManifestId`
|
||||
@@ -82,7 +87,7 @@ Lists all attachments for a given manifest, without loading their full binary co
|
||||
|
||||
**Returns**
|
||||
|
||||
`Promise<Array<{id: number, manifestId: number, fileId: number, mimetype: string, name: string, size: number}>>` — A list of attachment metadata objects.
|
||||
`Promise<Array<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>>` — A list of attachment metadata objects.
|
||||
|
||||
**Throws**
|
||||
|
||||
@@ -92,7 +97,37 @@ Lists all attachments for a given manifest, without loading their full binary co
|
||||
|
||||
```js
|
||||
const attachments = await store.manifestattachment.listByManifestId(42, 1);
|
||||
// => [{ id, manifestId, fileId, mimetype, name, size }]
|
||||
// => [{ id, manifestId, fileId, sort, hash, mimetype, name, size, thumbavif, thumbx, thumby }]
|
||||
```
|
||||
|
||||
## `manifestattachment.order`
|
||||
|
||||
*Source: `src/store/manifestattachment/order.js`*
|
||||
|
||||
Reorders the attachments of a manifest.
|
||||
|
||||
**Parameters**
|
||||
|
||||
| Name | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `googleAuthId` | `number` | The id of the Google auth user. |
|
||||
| `manifestId` | `number` | The manifest ID. |
|
||||
| `input` | `object|Array<number>` | The reorder input or array of IDs. |
|
||||
| `[input.ids]` | `Array<number>` | The attachment ids in their new order. |
|
||||
|
||||
**Returns**
|
||||
|
||||
`Promise<{ids: Array<number>}>` — The applied order.
|
||||
|
||||
**Throws**
|
||||
|
||||
`Error` — If the order is invalid.
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
const result = await store.manifestattachment.order(42, 1, { ids: [12, 10, 15] });
|
||||
// => { ids: [12, 10, 15] }
|
||||
```
|
||||
|
||||
## `manifestattachment.remove`
|
||||
|
||||
7
API.md
7
API.md
@@ -123,9 +123,10 @@ The store is exposed as a `LibDashStore` instance (see `src/index.js`). Each met
|
||||
- `list(googleAuthId: number): Promise<Array<{id: number, number: string, type: string, entityId: number|null, externalNumber: string|null, date: string}>>`
|
||||
- `update(googleAuthId: number, id: number, patch: {number?: string, date?: string, entityId?: number, externalNumber?: string, lines?: Array<{sku?: string, name?: string, pu?: number, amount: number, net: number, rebate?: number, taxrate: number, comment?: string|null}>}): Promise<{id: number, number: string, type: string, entityId: number|null, externalNumber: string|null, date: string, lines: Array<{id: number, sku: string|null, name: string|null, pu: number, amount: number, net: number, rebate: number, taxrate: number, comment: string|null}>}>`
|
||||
- [manifestattachment](API.manifestattachment.md)
|
||||
- `add(googleAuthId: number, manifestId: number, input: {mimetype: string, name: string, content: Buffer}): Promise<{id: number, manifestId: number, fileId: number, mimetype: string, name: string}>`
|
||||
- `getById(googleAuthId: number, manifestId: number, id: number): Promise<{id: number, manifestId: number, fileId: number, mimetype: string, name: string, content: Buffer}>`
|
||||
- `listByManifestId(googleAuthId: number, manifestId: number): Promise<Array<{id: number, manifestId: number, fileId: number, mimetype: string, name: string, size: number}>>`
|
||||
- `add(googleAuthId: number, manifestId: number, input: {mimetype: string, name: string, content: Buffer, sort?: number, hash?: string, thumbavif?: Buffer, thumbx?: number, thumby?: number}): Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>`
|
||||
- `getById(googleAuthId: number, manifestId: number, id: number): Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, content: Buffer, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>`
|
||||
- `listByManifestId(googleAuthId: number, manifestId: number): Promise<Array<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>>`
|
||||
- `order(googleAuthId: number, manifestId: number, input: {ids?: Array<number>}): Promise<{ids: Array<number>}>`
|
||||
- `remove(googleAuthId: number, manifestId: number, id: number): Promise<void>`
|
||||
- [posterminal](API.posterminal.md)
|
||||
- `delete(googleAuthId: number, id: number): Promise<void>`
|
||||
|
||||
@@ -55,7 +55,7 @@ digraph schema {
|
||||
pic [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4" COLOR="#3f4c5f"><TR><TD COLSPAN="2" BGCOLOR="#33415c" ALIGN="CENTER" CELLPADDING="1" BORDER="1"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD PORT="in0" BGCOLOR="#33415c" BORDER="0" WIDTH="10" HEIGHT="4" CELLPADDING="0"></TD><TD PORT="in1" BGCOLOR="#33415c" BORDER="0" WIDTH="10" HEIGHT="4" CELLPADDING="0"></TD><TD PORT="in2" BGCOLOR="#33415c" BORDER="0" WIDTH="10" HEIGHT="4" CELLPADDING="0"></TD></TR><TR><TD COLSPAN="3" ALIGN="CENTER" CELLPADDING="3"><FONT COLOR="#e2e8f0" POINT-SIZE="12"><B>pic</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>PK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="w" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">w</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="h" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">h</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="size" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">size</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">BIGINT</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="hash" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">hash</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(64)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="thumbw" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">thumbw</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="thumbh" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">thumbh</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="thumbhash" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">thumbhash</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(64)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="source" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">source</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(MAX)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="fullbinary" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">fullbinary</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">VARBINARY(MAX)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="thumbbinary" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">thumbbinary</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">VARBINARY(MAX)</FONT></TD></TR></TABLE></TD></TR></TABLE>>];
|
||||
brandpic [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4" COLOR="#3f4c5f"><TR><TD COLSPAN="2" BGCOLOR="#33415c" ALIGN="CENTER" CELLPADDING="4" BORDER="1"><FONT COLOR="#e2e8f0" POINT-SIZE="12"><B>brandpic</B></FONT></TD></TR><TR><TD PORT="id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>PK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="brand_id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>brand_id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>FK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="pic_id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>pic_id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>FK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="sort" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">sort</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT</FONT></TD></TR></TABLE></TD></TR></TABLE>>];
|
||||
articlepic [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4" COLOR="#3f4c5f"><TR><TD COLSPAN="2" BGCOLOR="#33415c" ALIGN="CENTER" CELLPADDING="4" BORDER="1"><FONT COLOR="#e2e8f0" POINT-SIZE="12"><B>articlepic</B></FONT></TD></TR><TR><TD PORT="id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>PK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="article_id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>article_id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>FK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="pic_id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>pic_id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>FK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="sort" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">sort</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT</FONT></TD></TR></TABLE></TD></TR></TABLE>>];
|
||||
file [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4" COLOR="#3f4c5f"><TR><TD COLSPAN="2" BGCOLOR="#33415c" ALIGN="CENTER" CELLPADDING="1" BORDER="1"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD PORT="in0" BGCOLOR="#33415c" BORDER="0" WIDTH="10" HEIGHT="4" CELLPADDING="0"></TD></TR><TR><TD COLSPAN="1" ALIGN="CENTER" CELLPADDING="3"><FONT COLOR="#e2e8f0" POINT-SIZE="12"><B>file</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>PK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="mimetype" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">mimetype</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(255)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="name" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">name</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(255)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="content" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">content</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">VARBINARY(MAX)</FONT></TD></TR></TABLE></TD></TR></TABLE>>];
|
||||
file [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4" COLOR="#3f4c5f"><TR><TD COLSPAN="2" BGCOLOR="#33415c" ALIGN="CENTER" CELLPADDING="1" BORDER="1"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD PORT="in0" BGCOLOR="#33415c" BORDER="0" WIDTH="10" HEIGHT="4" CELLPADDING="0"></TD></TR><TR><TD COLSPAN="1" ALIGN="CENTER" CELLPADDING="3"><FONT COLOR="#e2e8f0" POINT-SIZE="12"><B>file</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>PK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="hash" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">hash</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(64)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="mimetype" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">mimetype</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(255)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="name" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">name</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(255)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="content" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">content</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">VARBINARY(MAX)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="thumbavif" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">thumbavif?</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">VARBINARY(MAX)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="thumbx" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">thumbx?</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="thumby" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">thumby?</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT</FONT></TD></TR></TABLE></TD></TR></TABLE>>];
|
||||
}
|
||||
subgraph cluster_manifests {
|
||||
label="Documents"; labeljust="l"; fontsize=15;
|
||||
@@ -64,7 +64,7 @@ digraph schema {
|
||||
manifestarticle [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4" COLOR="#3f4c5f"><TR><TD COLSPAN="2" BGCOLOR="#33415c" ALIGN="CENTER" CELLPADDING="1" BORDER="1"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD PORT="in0" BGCOLOR="#33415c" BORDER="0" WIDTH="10" HEIGHT="4" CELLPADDING="0"></TD></TR><TR><TD COLSPAN="1" ALIGN="CENTER" CELLPADDING="3"><FONT COLOR="#e2e8f0" POINT-SIZE="12"><B>manifestarticle</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>PK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="manifest_id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>manifest_id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>FK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="sku" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">sku?</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(100)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="name" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">name?</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(255)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="pu" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">pu</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">FLOAT</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="amount" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">amount</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">FLOAT</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="net" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">net</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">FLOAT</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="comment" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">comment?</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(MAX)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="rebate" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">rebate</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">FLOAT</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="taxrate" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">taxrate</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">FLOAT</FONT></TD></TR></TABLE></TD></TR></TABLE>>];
|
||||
ledger [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4" COLOR="#3f4c5f"><TR><TD COLSPAN="2" BGCOLOR="#33415c" ALIGN="CENTER" CELLPADDING="4" BORDER="1"><FONT COLOR="#e2e8f0" POINT-SIZE="12"><B>ledger</B></FONT></TD></TR><TR><TD PORT="id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>PK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="manifestarticle_id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>manifestarticle_id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>FK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="transaction_type" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">transaction_type</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(100)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="amount" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">amount</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">FLOAT</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="transaction_text" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">transaction_text</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(MAX)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="hash_version" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">hash_version</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="prev_hash" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">prev_hash?</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(128)</FONT></TD></TR></TABLE></TD></TR></TABLE>>];
|
||||
manifest [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4" COLOR="#3f4c5f"><TR><TD COLSPAN="2" BGCOLOR="#33415c" ALIGN="CENTER" CELLPADDING="1" BORDER="1"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD PORT="in0" BGCOLOR="#33415c" BORDER="0" WIDTH="10" HEIGHT="4" CELLPADDING="0"></TD><TD PORT="in1" BGCOLOR="#33415c" BORDER="0" WIDTH="10" HEIGHT="4" CELLPADDING="0"></TD></TR><TR><TD COLSPAN="2" ALIGN="CENTER" CELLPADDING="3"><FONT COLOR="#e2e8f0" POINT-SIZE="12"><B>manifest</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>PK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="entity_id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>entity_id</B>?</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>FK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="company_id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>company_id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>FK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="number" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">number</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(100)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="type" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">type</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(100)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="external_number" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">external_number?</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">NVARCHAR(100)</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="date" COLSPAN="2" BGCOLOR="#2a3242" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">date</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">DATETIME2</FONT></TD></TR></TABLE></TD></TR></TABLE>>];
|
||||
manifestattachment [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4" COLOR="#3f4c5f"><TR><TD COLSPAN="2" BGCOLOR="#33415c" ALIGN="CENTER" CELLPADDING="4" BORDER="1"><FONT COLOR="#e2e8f0" POINT-SIZE="12"><B>manifestattachment</B></FONT></TD></TR><TR><TD PORT="id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>PK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="manifest_id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>manifest_id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>FK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="file_id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>file_id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>FK</B></FONT></TD></TR></TABLE></TD></TR></TABLE>>];
|
||||
manifestattachment [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4" COLOR="#3f4c5f"><TR><TD COLSPAN="2" BGCOLOR="#33415c" ALIGN="CENTER" CELLPADDING="4" BORDER="1"><FONT COLOR="#e2e8f0" POINT-SIZE="12"><B>manifestattachment</B></FONT></TD></TR><TR><TD PORT="id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>PK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="manifest_id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>manifest_id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>FK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="file_id" COLSPAN="2" BGCOLOR="#2b3a52" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9"><B>file_id</B></FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT <B>FK</B></FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="sort" COLSPAN="2" BGCOLOR="#272e3d" BORDER="1" CELLPADDING="0"><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" FIXEDSIZE="FALSE"><TR><TD ALIGN="LEFT" CELLPADDING="4"><FONT COLOR="#d8dee9">sort</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">INT</FONT></TD></TR></TABLE></TD></TR></TABLE>>];
|
||||
}
|
||||
subgraph cluster_commerce {
|
||||
label="Pricing"; labeljust="l"; fontsize=15;
|
||||
@@ -139,7 +139,7 @@ digraph schema {
|
||||
articlesupplier:price_id:e -> price:in0:n [color="#c79bff", fontcolor="#c79bff", tooltip="FK_articlesupplier_price", constraint=false, weight=1];
|
||||
manifest:company_id:e -> company:in1:n [color="#ff6b6b", fontcolor="#ff6b6b", tooltip="FK_manifest_company", weight=3];
|
||||
manifest:entity_id:e -> entity:in0:n [color="#6bdf9a", fontcolor="#6bdf9a", tooltip="FK_manifest_entity", constraint=false, weight=1];
|
||||
manifestarticle:manifest_id:ne -> manifest:in0:n [color="#5aa7ff", fontcolor="#5aa7ff", tooltip="FK_manifestarticle_manifest", weight=3];
|
||||
manifestarticle:manifest_id:se -> manifest:in0:n [color="#5aa7ff", fontcolor="#5aa7ff", tooltip="FK_manifestarticle_manifest", weight=3];
|
||||
ledger:manifestarticle_id:sw -> manifestarticle:in0:n [color="#f5c15c", fontcolor="#f5c15c", tooltip="FK_ledger_manifestarticle", weight=3];
|
||||
numbers:company_id:e -> company:in3:n [color="#c79bff", fontcolor="#c79bff", tooltip="FK_numbers_company", weight=3];
|
||||
companyuser:google_auth_id:e -> google_auth:in0:n [color="#ff9f5a", fontcolor="#ff9f5a", tooltip="FK_companyuser_google_auth", constraint=false, weight=1];
|
||||
|
||||
170
schema-graph.svg
170
schema-graph.svg
@@ -4,11 +4,11 @@
|
||||
<!-- Generated by graphviz version 16.1.0 (0)
|
||||
-->
|
||||
<!-- Title: schema Pages: 1 -->
|
||||
<svg width="4949pt" height="1786pt"
|
||||
viewBox="0.00 0.00 4949.00 1786.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background-color:#1e2430;">
|
||||
<svg width="4963pt" height="1786pt"
|
||||
viewBox="0.00 0.00 4963.00 1786.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background-color:#1e2430;">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(36 1749.6)">
|
||||
<title>schema</title>
|
||||
<polygon fill="#1e2430" stroke="none" points="-36,36 -36,-1749.6 4913.27,-1749.6 4913.27,36 -36,36"/>
|
||||
<polygon fill="#1e2430" stroke="none" points="-36,36 -36,-1749.6 4927.27,-1749.6 4927.27,36 -36,36"/>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>cluster_identity</title>
|
||||
<path fill="#202a3a" stroke="#3f4c5f" d="M670,-196.8C670,-196.8 1976,-196.8 1976,-196.8 1982,-196.8 1988,-202.8 1988,-208.8 1988,-208.8 1988,-1643.6 1988,-1643.6 1988,-1649.6 1982,-1655.6 1976,-1655.6 1976,-1655.6 670,-1655.6 670,-1655.6 664,-1655.6 658,-1649.6 658,-1643.6 658,-1643.6 658,-208.8 658,-208.8 658,-202.8 664,-196.8 670,-196.8"/>
|
||||
@@ -26,7 +26,7 @@
|
||||
</g>
|
||||
<g id="clust4" class="cluster">
|
||||
<title>cluster_media</title>
|
||||
<path fill="#202a3a" stroke="#3f4c5f" d="M3986,-252.4C3986,-252.4 4605,-252.4 4605,-252.4 4611,-252.4 4617,-258.4 4617,-264.4 4617,-264.4 4617,-1645.6 4617,-1645.6 4617,-1651.6 4611,-1657.6 4605,-1657.6 4605,-1657.6 3986,-1657.6 3986,-1657.6 3980,-1657.6 3974,-1651.6 3974,-1645.6 3974,-1645.6 3974,-264.4 3974,-264.4 3974,-258.4 3980,-252.4 3986,-252.4"/>
|
||||
<path fill="#202a3a" stroke="#3f4c5f" d="M3986,-252.4C3986,-252.4 4619,-252.4 4619,-252.4 4625,-252.4 4631,-258.4 4631,-264.4 4631,-264.4 4631,-1645.6 4631,-1645.6 4631,-1651.6 4625,-1657.6 4619,-1657.6 4619,-1657.6 3986,-1657.6 3986,-1657.6 3980,-1657.6 3974,-1651.6 3974,-1645.6 3974,-1645.6 3974,-264.4 3974,-264.4 3974,-258.4 3980,-252.4 3986,-252.4"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="4002.43" y="-1640.1" font-family="Helvetica,sans-Serif" font-size="15.00" fill="#e2e8f0">Media</text>
|
||||
</g>
|
||||
<g id="clust5" class="cluster">
|
||||
@@ -1597,27 +1597,43 @@
|
||||
<!-- file -->
|
||||
<g id="node32" class="node">
|
||||
<title>file</title>
|
||||
<polygon fill="#33415c" stroke="none" points="4444.9,-1491.4 4444.9,-1519.8 4595.1,-1519.8 4595.1,-1491.4 4444.9,-1491.4"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4444.9,-1491.4 4444.9,-1519.8 4595.1,-1519.8 4595.1,-1491.4 4444.9,-1491.4"/>
|
||||
<polygon fill="#33415c" stroke="none" points="4446.9,-1513.8 4446.9,-1517.8 4593.1,-1517.8 4593.1,-1513.8 4446.9,-1513.8"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4511.33" y="-1501" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="12.00" fill="#e2e8f0">file</text>
|
||||
<polygon fill="#2b3a52" stroke="none" points="4444.9,-1464.6 4444.9,-1491.4 4595.1,-1491.4 4595.1,-1464.6 4444.9,-1464.6"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4444.9,-1464.6 4444.9,-1491.4 4595.1,-1491.4 4595.1,-1464.6 4444.9,-1464.6"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4449.9" y="-1474.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="14.00" fill="#d8dee9">id</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="4560.6" y="-1476.3" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">INT </text>
|
||||
<text xml:space="preserve" text-anchor="start" x="4577.6" y="-1476.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="9.00" fill="#8b95a7">PK</text>
|
||||
<polygon fill="#272e3d" stroke="none" points="4444.9,-1437.8 4444.9,-1464.6 4595.1,-1464.6 4595.1,-1437.8 4444.9,-1437.8"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4444.9,-1437.8 4444.9,-1464.6 4595.1,-1464.6 4595.1,-1437.8 4444.9,-1437.8"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4449.9" y="-1445.6" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">mimetype</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="4518.58" y="-1447.6" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">NVARCHAR(255)</text>
|
||||
<polygon fill="#2a3242" stroke="none" points="4444.9,-1411 4444.9,-1437.8 4595.1,-1437.8 4595.1,-1411 4444.9,-1411"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4444.9,-1411 4444.9,-1437.8 4595.1,-1437.8 4595.1,-1411 4444.9,-1411"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4449.9" y="-1418.8" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">name</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="4518.58" y="-1420.8" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">NVARCHAR(255)</text>
|
||||
<polygon fill="#272e3d" stroke="none" points="4444.9,-1384.2 4444.9,-1411 4595.1,-1411 4595.1,-1384.2 4444.9,-1384.2"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4444.9,-1384.2 4444.9,-1411 4595.1,-1411 4595.1,-1384.2 4444.9,-1384.2"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4449.9" y="-1392" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">content</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="4512.59" y="-1394" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">VARBINARY(MAX)</text>
|
||||
<polygon fill="#33415c" stroke="none" points="4445,-1545 4445,-1573.4 4609,-1573.4 4609,-1545 4445,-1545"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4445,-1545 4445,-1573.4 4609,-1573.4 4609,-1545 4445,-1545"/>
|
||||
<polygon fill="#33415c" stroke="none" points="4447,-1567.4 4447,-1571.4 4607,-1571.4 4607,-1567.4 4447,-1567.4"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4518.33" y="-1554.6" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="12.00" fill="#e2e8f0">file</text>
|
||||
<polygon fill="#2b3a52" stroke="none" points="4445,-1518.2 4445,-1545 4609,-1545 4609,-1518.2 4445,-1518.2"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4445,-1518.2 4445,-1545 4609,-1545 4609,-1518.2 4445,-1518.2"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4450" y="-1528.4" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="14.00" fill="#d8dee9">id</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="4574.5" y="-1529.9" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">INT </text>
|
||||
<text xml:space="preserve" text-anchor="start" x="4591.49" y="-1529.9" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="9.00" fill="#8b95a7">PK</text>
|
||||
<polygon fill="#272e3d" stroke="none" points="4445,-1491.4 4445,-1518.2 4609,-1518.2 4609,-1491.4 4445,-1491.4"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4445,-1491.4 4445,-1518.2 4609,-1518.2 4609,-1491.4 4445,-1491.4"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4450" y="-1499.2" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">hash</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="4537.49" y="-1501.2" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">NVARCHAR(64)</text>
|
||||
<polygon fill="#2a3242" stroke="none" points="4445,-1464.6 4445,-1491.4 4609,-1491.4 4609,-1464.6 4445,-1464.6"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4445,-1464.6 4445,-1491.4 4609,-1491.4 4609,-1464.6 4445,-1464.6"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4450" y="-1472.4" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">mimetype</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="4532.48" y="-1474.4" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">NVARCHAR(255)</text>
|
||||
<polygon fill="#272e3d" stroke="none" points="4445,-1437.8 4445,-1464.6 4609,-1464.6 4609,-1437.8 4445,-1437.8"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4445,-1437.8 4445,-1464.6 4609,-1464.6 4609,-1437.8 4445,-1437.8"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4450" y="-1445.6" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">name</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="4532.48" y="-1447.6" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">NVARCHAR(255)</text>
|
||||
<polygon fill="#2a3242" stroke="none" points="4445,-1411 4445,-1437.8 4609,-1437.8 4609,-1411 4445,-1411"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4445,-1411 4445,-1437.8 4609,-1437.8 4609,-1411 4445,-1411"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4450" y="-1418.8" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">content</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="4526.49" y="-1420.8" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">VARBINARY(MAX)</text>
|
||||
<polygon fill="#272e3d" stroke="none" points="4445,-1384.2 4445,-1411 4609,-1411 4609,-1384.2 4445,-1384.2"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4445,-1384.2 4445,-1411 4609,-1411 4609,-1384.2 4445,-1384.2"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4450" y="-1392" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">thumbavif?</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="4526.49" y="-1394" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">VARBINARY(MAX)</text>
|
||||
<polygon fill="#2a3242" stroke="none" points="4445,-1357.4 4445,-1384.2 4609,-1384.2 4609,-1357.4 4445,-1357.4"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4445,-1357.4 4445,-1384.2 4609,-1384.2 4609,-1357.4 4445,-1357.4"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4450" y="-1365.2" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">thumbx?</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="4589.5" y="-1367.2" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">INT</text>
|
||||
<polygon fill="#272e3d" stroke="none" points="4445,-1330.6 4445,-1357.4 4609,-1357.4 4609,-1330.6 4445,-1330.6"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4445,-1330.6 4445,-1357.4 4609,-1357.4 4609,-1330.6 4445,-1330.6"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4450" y="-1338.4" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">thumby?</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="4589.5" y="-1340.4" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">INT</text>
|
||||
</g>
|
||||
<!-- manifestarticle -->
|
||||
<g id="node33" class="node">
|
||||
@@ -1712,10 +1728,10 @@
|
||||
</g>
|
||||
<!-- manifestarticle->manifest -->
|
||||
<g id="edge51" class="edge">
|
||||
<title>manifestarticle:ne->manifest:n</title>
|
||||
<title>manifestarticle:se->manifest:n</title>
|
||||
<g id="a_edge51"><a xlink:title="FK_manifestarticle_manifest">
|
||||
<path fill="none" stroke="#5aa7ff" stroke-width="1.4" d="M420.68,-1115C420.68,-1115 419.64,-817.36 419.44,-761.56"/>
|
||||
<polygon fill="#5aa7ff" stroke="#5aa7ff" stroke-width="1.4" points="421.89,-761.71 419.42,-754.72 416.99,-761.73 421.89,-761.71"/>
|
||||
<path fill="none" stroke="#5aa7ff" stroke-width="1.4" d="M420.68,-1088.2C471.46,-1037.42 423.27,-842.42 419.62,-761.44"/>
|
||||
<polygon fill="#5aa7ff" stroke="#5aa7ff" stroke-width="1.4" points="422.08,-761.66 419.46,-754.72 417.18,-761.78 422.08,-761.66"/>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
@@ -1786,31 +1802,35 @@
|
||||
<!-- manifestattachment -->
|
||||
<g id="node36" class="node">
|
||||
<title>manifestattachment</title>
|
||||
<polygon fill="#33415c" stroke="none" points="503.6,-1050 503.6,-1074.4 628.4,-1074.4 628.4,-1050 503.6,-1050"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="503.6,-1050 503.6,-1074.4 628.4,-1074.4 628.4,-1050 503.6,-1050"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="509.32" y="-1059.6" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="12.00" fill="#e2e8f0">manifestattachment</text>
|
||||
<polygon fill="#2b3a52" stroke="none" points="503.6,-1023.2 503.6,-1050 628.4,-1050 628.4,-1023.2 503.6,-1023.2"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="503.6,-1023.2 503.6,-1050 628.4,-1050 628.4,-1023.2 503.6,-1023.2"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="508.6" y="-1033.4" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="14.00" fill="#d8dee9">id</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="593.9" y="-1034.9" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">INT </text>
|
||||
<text xml:space="preserve" text-anchor="start" x="610.9" y="-1034.9" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="9.00" fill="#8b95a7">PK</text>
|
||||
<polygon fill="#2b3a52" stroke="none" points="503.6,-996.4 503.6,-1023.2 628.4,-1023.2 628.4,-996.4 503.6,-996.4"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="503.6,-996.4 503.6,-1023.2 628.4,-1023.2 628.4,-996.4 503.6,-996.4"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="508.6" y="-1006.6" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="14.00" fill="#d8dee9">manifest_id</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="594.4" y="-1008.1" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">INT </text>
|
||||
<text xml:space="preserve" text-anchor="start" x="611.4" y="-1008.1" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="9.00" fill="#8b95a7">FK</text>
|
||||
<polygon fill="#2b3a52" stroke="none" points="503.6,-969.6 503.6,-996.4 628.4,-996.4 628.4,-969.6 503.6,-969.6"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="503.6,-969.6 503.6,-996.4 628.4,-996.4 628.4,-969.6 503.6,-969.6"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="508.6" y="-979.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="14.00" fill="#d8dee9">file_id</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="594.4" y="-981.3" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">INT </text>
|
||||
<text xml:space="preserve" text-anchor="start" x="611.4" y="-981.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="9.00" fill="#8b95a7">FK</text>
|
||||
<polygon fill="#33415c" stroke="none" points="503.6,-1063.4 503.6,-1087.8 628.4,-1087.8 628.4,-1063.4 503.6,-1063.4"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="503.6,-1063.4 503.6,-1087.8 628.4,-1087.8 628.4,-1063.4 503.6,-1063.4"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="509.32" y="-1073" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="12.00" fill="#e2e8f0">manifestattachment</text>
|
||||
<polygon fill="#2b3a52" stroke="none" points="503.6,-1036.6 503.6,-1063.4 628.4,-1063.4 628.4,-1036.6 503.6,-1036.6"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="503.6,-1036.6 503.6,-1063.4 628.4,-1063.4 628.4,-1036.6 503.6,-1036.6"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="508.6" y="-1046.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="14.00" fill="#d8dee9">id</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="593.9" y="-1048.3" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">INT </text>
|
||||
<text xml:space="preserve" text-anchor="start" x="610.9" y="-1048.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="9.00" fill="#8b95a7">PK</text>
|
||||
<polygon fill="#2b3a52" stroke="none" points="503.6,-1009.8 503.6,-1036.6 628.4,-1036.6 628.4,-1009.8 503.6,-1009.8"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="503.6,-1009.8 503.6,-1036.6 628.4,-1036.6 628.4,-1009.8 503.6,-1009.8"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="508.6" y="-1020" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="14.00" fill="#d8dee9">manifest_id</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="594.4" y="-1021.5" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">INT </text>
|
||||
<text xml:space="preserve" text-anchor="start" x="611.4" y="-1021.5" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="9.00" fill="#8b95a7">FK</text>
|
||||
<polygon fill="#2b3a52" stroke="none" points="503.6,-983 503.6,-1009.8 628.4,-1009.8 628.4,-983 503.6,-983"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="503.6,-983 503.6,-1009.8 628.4,-1009.8 628.4,-983 503.6,-983"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="508.6" y="-993.2" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="14.00" fill="#d8dee9">file_id</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="594.4" y="-994.7" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">INT </text>
|
||||
<text xml:space="preserve" text-anchor="start" x="611.4" y="-994.7" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="9.00" fill="#8b95a7">FK</text>
|
||||
<polygon fill="#272e3d" stroke="none" points="503.6,-956.2 503.6,-983 628.4,-983 628.4,-956.2 503.6,-956.2"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="503.6,-956.2 503.6,-983 628.4,-983 628.4,-956.2 503.6,-956.2"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="508.6" y="-964" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">sort</text>
|
||||
<text xml:space="preserve" text-anchor="start" x="608.9" y="-966" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">INT</text>
|
||||
</g>
|
||||
<!-- manifestattachment->file -->
|
||||
<g id="edge62" class="edge">
|
||||
<title>manifestattachment:e->file:n</title>
|
||||
<g id="a_edge62"><a xlink:title="FK_manifestattachment_file">
|
||||
<path fill="none" stroke="#ff6f6f" stroke-width="1.4" d="M629.4,-983C655.14,-983 622.52,-1196.48 641,-1214.4 716.04,-1287.15 4301.2,-1262.7 4403,-1286.4 4498.66,-1308.67 4550.41,-1297.31 4603.1,-1380.2 4635.91,-1431.81 4646.08,-1474.3 4603.1,-1517.8 4579.47,-1541.71 4530.02,-1553.52 4521.32,-1527.6"/>
|
||||
<polygon fill="#ff6f6f" stroke="#ff6f6f" stroke-width="1.4" points="4523.77,-1527.45 4520.31,-1520.9 4518.93,-1528.18 4523.77,-1527.45"/>
|
||||
<path fill="none" stroke="#ff6f6f" stroke-width="1.4" d="M629.4,-996.4C653.65,-996.4 623.56,-1197.54 641,-1214.4 716.15,-1287.04 4299.03,-1275.71 4403,-1286.4 4499.27,-1296.29 4555.21,-1252.12 4617,-1326.6 4651.73,-1368.47 4655.25,-1532.72 4617,-1571.4 4591.18,-1597.51 4536.92,-1610.23 4528.2,-1581.2"/>
|
||||
<polygon fill="#ff6f6f" stroke="#ff6f6f" stroke-width="1.4" points="4530.66,-1581.11 4527.29,-1574.5 4525.8,-1581.77 4530.66,-1581.11"/>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
@@ -1818,8 +1838,8 @@
|
||||
<g id="edge61" class="edge">
|
||||
<title>manifestattachment:sw->manifest:n</title>
|
||||
<g id="a_edge61"><a xlink:title="FK_manifestattachment_manifest">
|
||||
<path fill="none" stroke="#a98cff" stroke-width="1.4" d="M502.6,-996.4C427.99,-921.79 513.47,-864.51 518.37,-761.71"/>
|
||||
<polygon fill="#a98cff" stroke="#a98cff" stroke-width="1.4" points="520.82,-761.77 518.54,-754.72 515.92,-761.66 520.82,-761.77"/>
|
||||
<path fill="none" stroke="#a98cff" stroke-width="1.4" d="M502.6,-1009.8C484.5,-991.7 502.42,-977.78 503.6,-952.2 507.57,-866.28 517.88,-843.08 518.56,-761.24"/>
|
||||
<polygon fill="#a98cff" stroke="#a98cff" stroke-width="1.4" points="521,-761.73 518.58,-754.72 516.1,-761.71 521,-761.73"/>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
@@ -1924,7 +1944,7 @@
|
||||
<g id="edge60" class="edge">
|
||||
<title>posterminalcategory:e->category:n</title>
|
||||
<g id="a_edge60"><a xlink:title="FK_posterminalcategory_category">
|
||||
<path fill="none" stroke="#4fc4e8" stroke-width="1.4" d="M177.29,-983C248.18,-983 166.25,-874.63 221,-829.6 979.85,-205.51 3961.79,-1184.68 4627,-461.6 4706.68,-374.99 4708.85,-281.36 4627,-196.8 4554.3,-121.69 2792.26,-234.89 2699.39,-141.82"/>
|
||||
<path fill="none" stroke="#4fc4e8" stroke-width="1.4" d="M177.29,-983C248.18,-983 166.24,-874.62 221,-829.6 982.33,-203.64 3973.6,-1186.88 4641,-461.6 4720.69,-375 4722.86,-281.35 4641,-196.8 4567.77,-121.16 2792.96,-235.6 2699.42,-141.88"/>
|
||||
<polygon fill="#4fc4e8" stroke="#4fc4e8" stroke-width="1.4" points="2701.71,-140.99 2696.49,-135.71 2697.28,-143.09 2701.71,-140.99"/>
|
||||
</a>
|
||||
</g>
|
||||
@@ -1941,30 +1961,30 @@
|
||||
<!-- __legend -->
|
||||
<g id="node42" class="node">
|
||||
<title>__legend</title>
|
||||
<polygon fill="#2a3242" stroke="none" points="4678.73,-1373.4 4678.73,-1530.6 4869.27,-1530.6 4869.27,-1373.4 4678.73,-1373.4"/>
|
||||
<polygon fill="#33415c" stroke="none" points="4678.73,-1507.4 4678.73,-1530.6 4869.27,-1530.6 4869.27,-1507.4 4678.73,-1507.4"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4678.73,-1507.4 4678.73,-1530.6 4869.27,-1530.6 4869.27,-1507.4 4678.73,-1507.4"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4754.44" y="-1516.7" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="11.00" fill="#e2e8f0">Legend</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4678.73,-1480.6 4678.73,-1507.4 4708.18,-1507.4 4708.18,-1480.6 4678.73,-1480.6"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4683.73" y="-1490.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="14.00" fill="#d8dee9">PK</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4708.18,-1480.6 4708.18,-1507.4 4869.27,-1507.4 4869.27,-1480.6 4708.18,-1480.6"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4713.18" y="-1490.4" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#d8dee9">primary key</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4678.73,-1453.8 4678.73,-1480.6 4708.18,-1480.6 4708.18,-1453.8 4678.73,-1453.8"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4683.73" y="-1464" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="14.00" fill="#d8dee9">FK</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4708.18,-1453.8 4708.18,-1480.6 4869.27,-1480.6 4869.27,-1453.8 4708.18,-1453.8"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4713.18" y="-1463.6" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#d8dee9">foreign key</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4678.73,-1427 4678.73,-1453.8 4708.18,-1453.8 4708.18,-1427 4678.73,-1427"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4683.73" y="-1437.2" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="14.00" fill="#d8dee9">?</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4708.18,-1427 4708.18,-1453.8 4869.27,-1453.8 4869.27,-1427 4708.18,-1427"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4713.18" y="-1436.8" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#d8dee9">nullable column</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4678.73,-1400.2 4678.73,-1427 4708.18,-1427 4708.18,-1400.2 4678.73,-1400.2"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4683.73" y="-1408" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#8b95a7">—</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4708.18,-1400.2 4708.18,-1427 4869.27,-1427 4869.27,-1400.2 4708.18,-1400.2"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4713.18" y="-1410" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#d8dee9">FOREIGN KEY constraint</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4678.73,-1373.4 4678.73,-1400.2 4708.18,-1400.2 4708.18,-1373.4 4678.73,-1373.4"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4683.73" y="-1381.2" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#8b95a7">- -</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4708.18,-1373.4 4708.18,-1400.2 4869.27,-1400.2 4869.27,-1373.4 4708.18,-1373.4"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4713.18" y="-1383.2" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#d8dee9">naming convention only, no constraint</text>
|
||||
<polygon fill="#2a3242" stroke="none" points="4692.73,-1373.4 4692.73,-1530.6 4883.27,-1530.6 4883.27,-1373.4 4692.73,-1373.4"/>
|
||||
<polygon fill="#33415c" stroke="none" points="4692.73,-1507.4 4692.73,-1530.6 4883.27,-1530.6 4883.27,-1507.4 4692.73,-1507.4"/>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4692.73,-1507.4 4692.73,-1530.6 4883.27,-1530.6 4883.27,-1507.4 4692.73,-1507.4"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4768.44" y="-1516.7" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="11.00" fill="#e2e8f0">Legend</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4692.73,-1480.6 4692.73,-1507.4 4722.18,-1507.4 4722.18,-1480.6 4692.73,-1480.6"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4697.73" y="-1490.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="14.00" fill="#d8dee9">PK</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4722.18,-1480.6 4722.18,-1507.4 4883.27,-1507.4 4883.27,-1480.6 4722.18,-1480.6"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4727.18" y="-1490.4" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#d8dee9">primary key</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4692.73,-1453.8 4692.73,-1480.6 4722.18,-1480.6 4722.18,-1453.8 4692.73,-1453.8"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4697.73" y="-1464" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="14.00" fill="#d8dee9">FK</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4722.18,-1453.8 4722.18,-1480.6 4883.27,-1480.6 4883.27,-1453.8 4722.18,-1453.8"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4727.18" y="-1463.6" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#d8dee9">foreign key</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4692.73,-1427 4692.73,-1453.8 4722.18,-1453.8 4722.18,-1427 4692.73,-1427"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4697.73" y="-1437.2" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="14.00" fill="#d8dee9">?</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4722.18,-1427 4722.18,-1453.8 4883.27,-1453.8 4883.27,-1427 4722.18,-1427"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4727.18" y="-1436.8" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#d8dee9">nullable column</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4692.73,-1400.2 4692.73,-1427 4722.18,-1427 4722.18,-1400.2 4692.73,-1400.2"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4697.73" y="-1408" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#8b95a7">—</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4722.18,-1400.2 4722.18,-1427 4883.27,-1427 4883.27,-1400.2 4722.18,-1400.2"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4727.18" y="-1410" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#d8dee9">FOREIGN KEY constraint</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4692.73,-1373.4 4692.73,-1400.2 4722.18,-1400.2 4722.18,-1373.4 4692.73,-1373.4"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4697.73" y="-1381.2" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#8b95a7">- -</text>
|
||||
<polygon fill="none" stroke="#3f4c5f" points="4722.18,-1373.4 4722.18,-1400.2 4883.27,-1400.2 4883.27,-1373.4 4722.18,-1373.4"/>
|
||||
<text xml:space="preserve" text-anchor="start" x="4727.18" y="-1383.2" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#d8dee9">naming convention only, no constraint</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 203 KiB After Width: | Height: | Size: 206 KiB |
@@ -119,6 +119,7 @@ import manifestattachmentAdd from './store/manifestattachment/add.js';
|
||||
import manifestattachmentRemove from './store/manifestattachment/remove.js';
|
||||
import manifestattachmentListByManifestId from './store/manifestattachment/listByManifestId.js';
|
||||
import manifestattachmentGetById from './store/manifestattachment/getById.js';
|
||||
import manifestattachmentOrder from './store/manifestattachment/order.js';
|
||||
|
||||
export default class LibDashStore {
|
||||
constructor(pool) {
|
||||
@@ -310,6 +311,7 @@ export default class LibDashStore {
|
||||
remove: manifestattachmentRemove(pool),
|
||||
listByManifestId: manifestattachmentListByManifestId(pool),
|
||||
getById: manifestattachmentGetById(pool),
|
||||
order: manifestattachmentOrder(pool),
|
||||
};
|
||||
|
||||
this.purge = storePurge(pool);
|
||||
|
||||
@@ -773,9 +773,13 @@ IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'file')
|
||||
BEGIN
|
||||
CREATE TABLE [file] (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
hash NVARCHAR(64) NOT NULL,
|
||||
mimetype NVARCHAR(255) NOT NULL,
|
||||
name NVARCHAR(255) NOT NULL,
|
||||
content VARBINARY(MAX) NOT NULL
|
||||
content VARBINARY(MAX) NOT NULL,
|
||||
thumbavif VARBINARY(MAX) NULL,
|
||||
thumbx INT NULL,
|
||||
thumby INT NULL
|
||||
);
|
||||
END
|
||||
`;
|
||||
@@ -787,8 +791,10 @@ BEGIN
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
manifest_id INT NOT NULL,
|
||||
file_id INT NOT NULL,
|
||||
sort INT NOT NULL CONSTRAINT DF_manifestattachment_sort DEFAULT 0,
|
||||
CONSTRAINT FK_manifestattachment_manifest FOREIGN KEY (manifest_id) REFERENCES manifest(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_manifestattachment_file FOREIGN KEY (file_id) REFERENCES [file](id) ON DELETE CASCADE
|
||||
CONSTRAINT FK_manifestattachment_file FOREIGN KEY (file_id) REFERENCES [file](id) ON DELETE CASCADE,
|
||||
CONSTRAINT UQ_manifestattachment_manifest_sort UNIQUE (manifest_id, sort)
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
@@ -5,15 +5,21 @@ WHERE id = @manifestId AND company_id = @companyId
|
||||
`;
|
||||
|
||||
export const CREATE_FILE = `
|
||||
INSERT INTO [file] (mimetype, name, content)
|
||||
INSERT INTO [file] (hash, mimetype, name, content, thumbavif, thumbx, thumby)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@mimetype, @name, @content)
|
||||
VALUES (@hash, @mimetype, @name, @content, CONVERT(VARBINARY(MAX), @thumbavif), @thumbx, @thumby)
|
||||
`;
|
||||
|
||||
export const GET_NEXT_SORT = `
|
||||
SELECT ISNULL(MAX(sort), -1) + 1 AS sort
|
||||
FROM manifestattachment
|
||||
WHERE manifest_id = @manifestId;
|
||||
`;
|
||||
|
||||
export const CREATE_ATTACHMENT = `
|
||||
INSERT INTO manifestattachment (manifest_id, file_id)
|
||||
INSERT INTO manifestattachment (manifest_id, file_id, sort)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@manifestId, @fileId)
|
||||
VALUES (@manifestId, @fileId, @sort)
|
||||
`;
|
||||
|
||||
export const LIST_BY_MANIFEST = `
|
||||
@@ -21,13 +27,18 @@ SELECT
|
||||
ma.id,
|
||||
ma.manifest_id AS manifestId,
|
||||
ma.file_id AS fileId,
|
||||
ma.sort,
|
||||
f.hash,
|
||||
f.mimetype,
|
||||
f.name,
|
||||
DATALENGTH(f.content) AS size
|
||||
DATALENGTH(f.content) AS size,
|
||||
f.thumbavif,
|
||||
f.thumbx,
|
||||
f.thumby
|
||||
FROM manifestattachment ma
|
||||
INNER JOIN [file] f ON f.id = ma.file_id
|
||||
WHERE ma.manifest_id = @manifestId
|
||||
ORDER BY ma.id ASC
|
||||
ORDER BY ma.sort ASC, ma.id ASC
|
||||
`;
|
||||
|
||||
export const GET_BY_ID = `
|
||||
@@ -35,9 +46,14 @@ SELECT
|
||||
ma.id,
|
||||
ma.manifest_id AS manifestId,
|
||||
ma.file_id AS fileId,
|
||||
ma.sort,
|
||||
f.hash,
|
||||
f.mimetype,
|
||||
f.name,
|
||||
f.content
|
||||
f.content,
|
||||
f.thumbavif,
|
||||
f.thumbx,
|
||||
f.thumby
|
||||
FROM manifestattachment ma
|
||||
INNER JOIN [file] f ON f.id = ma.file_id
|
||||
WHERE ma.manifest_id = @manifestId
|
||||
@@ -60,3 +76,22 @@ export const DELETE_FILE = `
|
||||
DELETE FROM [file]
|
||||
WHERE id = @fileId
|
||||
`;
|
||||
|
||||
export const LIST_IDS_BY_MANIFEST = `
|
||||
SELECT id
|
||||
FROM manifestattachment
|
||||
WHERE manifest_id = @manifestId
|
||||
ORDER BY sort ASC, id ASC;
|
||||
`;
|
||||
|
||||
export const SET_TEMP_SORTS = `
|
||||
UPDATE manifestattachment
|
||||
SET sort = -id
|
||||
WHERE manifest_id = @manifestId;
|
||||
`;
|
||||
|
||||
export const UPDATE_SORT = `
|
||||
UPDATE manifestattachment
|
||||
SET sort = @sort
|
||||
WHERE id = @id AND manifest_id = @manifestId;
|
||||
`;
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { CREATE_FILE, CREATE_ATTACHMENT } from '../../sql/manifestattachment.js';
|
||||
import { createHash } from 'node:crypto';
|
||||
import sharp from 'sharp';
|
||||
import {
|
||||
CREATE_FILE,
|
||||
CREATE_ATTACHMENT,
|
||||
GET_NEXT_SORT,
|
||||
} from '../../sql/manifestattachment.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import resolveManifestAccess from './resolveManifestAccess.js';
|
||||
import request from '../request.js';
|
||||
@@ -16,7 +22,12 @@ export default function add(pool) {
|
||||
* @param {string} input.mimetype - The MIME type of the file (e.g. `'application/pdf'`).
|
||||
* @param {string} input.name - The file name.
|
||||
* @param {Buffer} input.content - The file content.
|
||||
* @returns {Promise<{id: number, manifestId: number, fileId: number, mimetype: string, name: string}>} The created attachment record.
|
||||
* @param {number} [input.sort] - Optional display sort order.
|
||||
* @param {string} [input.hash] - The file hash (auto-computed SHA-256 if omitted).
|
||||
* @param {Buffer} [input.thumbavif] - Optional AVIF thumbnail buffer.
|
||||
* @param {number} [input.thumbx] - Optional thumbnail width.
|
||||
* @param {number} [input.thumby] - Optional thumbnail height.
|
||||
* @returns {Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>} The created attachment record.
|
||||
* @throws {Error} If the manifest is not found or file input is invalid.
|
||||
*
|
||||
* @example
|
||||
@@ -25,14 +36,19 @@ export default function add(pool) {
|
||||
* name: 'invoice.pdf',
|
||||
* content: fileBuffer,
|
||||
* });
|
||||
* // => { id, manifestId, fileId, mimetype, name }
|
||||
* // => { id, manifestId, fileId, sort, hash, mimetype, name, thumbavif, thumbx, thumby }
|
||||
*/
|
||||
return async (googleAuthId, manifestId, input, ...rest) => {
|
||||
let rawMimetype, rawName, rawContent;
|
||||
let rawMimetype, rawName, rawContent, rawHash, rawThumbavif, rawThumbx, rawThumby, rawSort;
|
||||
if (typeof input === 'object' && input !== null && !Buffer.isBuffer(input)) {
|
||||
rawMimetype = input.mimetype;
|
||||
rawName = input.name;
|
||||
rawContent = input.content;
|
||||
rawHash = input.hash;
|
||||
rawThumbavif = input.thumbavif;
|
||||
rawThumbx = input.thumbx ?? input.thumbw;
|
||||
rawThumby = input.thumby ?? input.thumbh;
|
||||
rawSort = input.sort;
|
||||
} else {
|
||||
rawMimetype = input;
|
||||
rawName = rest[0];
|
||||
@@ -56,6 +72,49 @@ export default function add(pool) {
|
||||
? rawContent
|
||||
: Buffer.from(rawContent);
|
||||
|
||||
if (rawSort !== undefined && rawSort !== null) {
|
||||
if (!Number.isFinite(rawSort)) {
|
||||
throw new Error('Invalid sort');
|
||||
}
|
||||
}
|
||||
|
||||
const hash =
|
||||
typeof rawHash === 'string' && rawHash.trim()
|
||||
? rawHash.trim()
|
||||
: createHash('sha256').update(content).digest('hex');
|
||||
|
||||
let thumbavif = rawThumbavif
|
||||
? (Buffer.isBuffer(rawThumbavif) ? rawThumbavif : Buffer.from(rawThumbavif))
|
||||
: null;
|
||||
let thumbx = Number.isFinite(rawThumbx) ? Number(rawThumbx) : null;
|
||||
let thumby = Number.isFinite(rawThumby) ? Number(rawThumby) : null;
|
||||
|
||||
if (thumbavif && (!thumbx || !thumby)) {
|
||||
try {
|
||||
const meta = await sharp(thumbavif).metadata();
|
||||
thumbx = thumbx ?? meta.width ?? null;
|
||||
thumby = thumby ?? meta.height ?? null;
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
if (!thumbavif) {
|
||||
try {
|
||||
const thumbResult = await sharp(content)
|
||||
.resize(200, 200, { fit: 'inside', withoutEnlargement: true })
|
||||
.avif({ effort: 4 })
|
||||
.toBuffer({ resolveWithObject: true });
|
||||
thumbavif = thumbResult.data;
|
||||
thumbx = thumbResult.info.width;
|
||||
thumby = thumbResult.info.height;
|
||||
} catch {
|
||||
thumbavif = null;
|
||||
thumbx = null;
|
||||
thumby = null;
|
||||
}
|
||||
}
|
||||
|
||||
const { companyId } = await access(googleAuthId);
|
||||
await manifestAccess(companyId, manifestId);
|
||||
|
||||
@@ -63,10 +122,22 @@ export default function add(pool) {
|
||||
await tx.begin();
|
||||
|
||||
try {
|
||||
let sort = rawSort;
|
||||
if (sort === undefined || sort === null) {
|
||||
const sortRes = await request(pool, tx)
|
||||
.input('manifestId', manifestId)
|
||||
.query(GET_NEXT_SORT);
|
||||
sort = sortRes.recordset[0].sort;
|
||||
}
|
||||
|
||||
const fileRes = await request(pool, tx)
|
||||
.input('hash', hash)
|
||||
.input('mimetype', mimetype)
|
||||
.input('name', name)
|
||||
.input('content', content)
|
||||
.input('thumbavif', thumbavif)
|
||||
.input('thumbx', thumbx)
|
||||
.input('thumby', thumby)
|
||||
.query(CREATE_FILE);
|
||||
|
||||
const fileId = fileRes.recordset[0].id;
|
||||
@@ -74,6 +145,7 @@ export default function add(pool) {
|
||||
const attachmentRes = await request(pool, tx)
|
||||
.input('manifestId', manifestId)
|
||||
.input('fileId', fileId)
|
||||
.input('sort', sort)
|
||||
.query(CREATE_ATTACHMENT);
|
||||
|
||||
const attachmentId = attachmentRes.recordset[0].id;
|
||||
@@ -84,8 +156,13 @@ export default function add(pool) {
|
||||
id: attachmentId,
|
||||
manifestId,
|
||||
fileId,
|
||||
sort,
|
||||
hash,
|
||||
mimetype,
|
||||
name,
|
||||
thumbavif,
|
||||
thumbx,
|
||||
thumby,
|
||||
};
|
||||
} catch (err) {
|
||||
try {
|
||||
|
||||
@@ -13,12 +13,12 @@ export default function getById(pool) {
|
||||
* @param {number} googleAuthId - The id of the Google auth user.
|
||||
* @param {number} manifestId - The manifest ID.
|
||||
* @param {number} id - The attachment ID or file ID.
|
||||
* @returns {Promise<{id: number, manifestId: number, fileId: number, mimetype: string, name: string, content: Buffer}>} The attachment record with binary content.
|
||||
* @returns {Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, content: Buffer, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>} The attachment record with binary content.
|
||||
* @throws {Error} If the manifest or attachment is not found, or user is not authorized.
|
||||
*
|
||||
* @example
|
||||
* const attachment = await store.manifestattachment.getById(42, 1, 5);
|
||||
* // => { id, manifestId, fileId, mimetype, name, content }
|
||||
* // => { id, manifestId, fileId, sort, hash, mimetype, name, content, thumbavif, thumbx, thumby }
|
||||
*/
|
||||
return async (googleAuthId, manifestId, id) => {
|
||||
if (!Number.isFinite(id)) {
|
||||
@@ -42,9 +42,14 @@ export default function getById(pool) {
|
||||
id: row.id,
|
||||
manifestId: row.manifestId,
|
||||
fileId: row.fileId,
|
||||
sort: row.sort,
|
||||
hash: row.hash,
|
||||
mimetype: row.mimetype,
|
||||
name: row.name,
|
||||
content: row.content,
|
||||
thumbavif: row.thumbavif ?? null,
|
||||
thumbx: row.thumbx ?? null,
|
||||
thumby: row.thumby ?? null,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,9 +8,14 @@ function shape(row) {
|
||||
id: row.id,
|
||||
manifestId: row.manifestId,
|
||||
fileId: row.fileId,
|
||||
sort: row.sort,
|
||||
hash: row.hash,
|
||||
mimetype: row.mimetype,
|
||||
name: row.name,
|
||||
size: row.size,
|
||||
thumbavif: row.thumbavif ?? null,
|
||||
thumbx: row.thumbx ?? null,
|
||||
thumby: row.thumby ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -23,12 +28,12 @@ export default function listByManifestId(pool) {
|
||||
*
|
||||
* @param {number} googleAuthId - The id of the Google auth user.
|
||||
* @param {number} manifestId - The manifest ID.
|
||||
* @returns {Promise<Array<{id: number, manifestId: number, fileId: number, mimetype: string, name: string, size: number}>>} A list of attachment metadata objects.
|
||||
* @returns {Promise<Array<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>>} A list of attachment metadata objects.
|
||||
* @throws {Error} If the manifest is not found or the user is not authorized.
|
||||
*
|
||||
* @example
|
||||
* const attachments = await store.manifestattachment.listByManifestId(42, 1);
|
||||
* // => [{ id, manifestId, fileId, mimetype, name, size }]
|
||||
* // => [{ id, manifestId, fileId, sort, hash, mimetype, name, size, thumbavif, thumbx, thumby }]
|
||||
*/
|
||||
return async (googleAuthId, manifestId) => {
|
||||
const { companyId } = await access(googleAuthId);
|
||||
|
||||
88
src/store/manifestattachment/order.js
Normal file
88
src/store/manifestattachment/order.js
Normal file
@@ -0,0 +1,88 @@
|
||||
import {
|
||||
LIST_IDS_BY_MANIFEST,
|
||||
SET_TEMP_SORTS,
|
||||
UPDATE_SORT,
|
||||
} from '../../sql/manifestattachment.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import resolveManifestAccess from './resolveManifestAccess.js';
|
||||
import request from '../request.js';
|
||||
|
||||
export default function order(pool) {
|
||||
const access = resolveSelectedCompanyAccess(pool);
|
||||
const manifestAccess = resolveManifestAccess(pool);
|
||||
|
||||
/**
|
||||
* Reorders the attachments of a manifest.
|
||||
*
|
||||
* @param {number} googleAuthId - The id of the Google auth user.
|
||||
* @param {number} manifestId - The manifest ID.
|
||||
* @param {object|Array<number>} input - The reorder input or array of IDs.
|
||||
* @param {Array<number>} [input.ids] - The attachment ids in their new order.
|
||||
* @returns {Promise<{ids: Array<number>}>} The applied order.
|
||||
* @throws {Error} If the order is invalid.
|
||||
*
|
||||
* @example
|
||||
* const result = await store.manifestattachment.order(42, 1, { ids: [12, 10, 15] });
|
||||
* // => { ids: [12, 10, 15] }
|
||||
*/
|
||||
return async (googleAuthId, manifestId, input) => {
|
||||
const rawIds = Array.isArray(input) ? input : input?.ids;
|
||||
if (!Array.isArray(rawIds)) {
|
||||
throw new Error('Invalid attachment order');
|
||||
}
|
||||
|
||||
const { companyId } = await access(googleAuthId);
|
||||
await manifestAccess(companyId, manifestId);
|
||||
|
||||
const current = await pool
|
||||
.request()
|
||||
.input('manifestId', manifestId)
|
||||
.query(LIST_IDS_BY_MANIFEST);
|
||||
|
||||
const existing = new Set(current.recordset.map((r) => r.id));
|
||||
|
||||
if (rawIds.length !== existing.size) {
|
||||
throw new Error('Invalid attachment order');
|
||||
}
|
||||
|
||||
const seen = new Set();
|
||||
for (const id of rawIds) {
|
||||
if (!Number.isFinite(id) || !existing.has(id) || seen.has(id)) {
|
||||
throw new Error('Invalid attachment order');
|
||||
}
|
||||
seen.add(id);
|
||||
}
|
||||
|
||||
const tx = pool.transaction();
|
||||
await tx.begin();
|
||||
|
||||
try {
|
||||
await request(pool, tx)
|
||||
.input('manifestId', manifestId)
|
||||
.query(SET_TEMP_SORTS);
|
||||
|
||||
for (let sort = 0; sort < rawIds.length; sort++) {
|
||||
const updateRes = await request(pool, tx)
|
||||
.input('id', rawIds[sort])
|
||||
.input('manifestId', manifestId)
|
||||
.input('sort', sort)
|
||||
.query(UPDATE_SORT);
|
||||
|
||||
if (!updateRes.rowsAffected[0]) {
|
||||
throw new Error('Invalid attachment order');
|
||||
}
|
||||
}
|
||||
|
||||
await tx.commit();
|
||||
|
||||
return { ids: rawIds };
|
||||
} catch (err) {
|
||||
try {
|
||||
await tx.rollback();
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user