feat: add size, created, and modified columns to file table and manifestattachment APIs

This commit is contained in:
seb
2026-09-18 01:45:27 +02:00
parent cfb7f86f0e
commit e3d30b296b
9 changed files with 127 additions and 66 deletions

View File

@@ -19,6 +19,9 @@ Attaches a file to an existing manifest.
| `input.name` | `string` | The file name. | | `input.name` | `string` | The file name. |
| `input.content` | `Buffer` | The file content. | | `input.content` | `Buffer` | The file content. |
| `[input.sort]` | `number` | Optional display sort order. | | `[input.sort]` | `number` | Optional display sort order. |
| `[input.size]` | `number` | Optional file size in bytes (defaults to content length). |
| `[input.created]` | `Date|string` | Optional creation timestamp (defaults to current date). |
| `[input.modified]` | `Date|string` | Optional modified timestamp (defaults to created date). |
| `[input.hash]` | `string` | The file hash (auto-computed SHA-256 if omitted). | | `[input.hash]` | `string` | The file hash (auto-computed SHA-256 if omitted). |
| `[input.thumbavif]` | `Buffer` | Optional AVIF thumbnail buffer. | | `[input.thumbavif]` | `Buffer` | Optional AVIF thumbnail buffer. |
| `[input.thumbx]` | `number` | Optional thumbnail width. | | `[input.thumbx]` | `number` | Optional thumbnail width. |
@@ -26,7 +29,7 @@ Attaches a file to an existing manifest.
**Returns** **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. `Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, created: Date, modified: Date, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>` — The created attachment record.
**Throws** **Throws**
@@ -40,7 +43,7 @@ const attachment = await store.manifestattachment.add(42, 1, {
name: 'invoice.pdf', name: 'invoice.pdf',
content: fileBuffer, content: fileBuffer,
}); });
// => { id, manifestId, fileId, sort, hash, mimetype, name, thumbavif, thumbx, thumby } // => { id, manifestId, fileId, sort, hash, mimetype, name, size, created, modified, thumbavif, thumbx, thumby }
``` ```
## `manifestattachment.getById` ## `manifestattachment.getById`
@@ -59,7 +62,7 @@ Gets an attachment for a manifest by its attachment ID or file ID, including ful
**Returns** **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. `Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, created: Date, modified: Date, content: Buffer, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>` — The attachment record with binary content.
**Throws** **Throws**
@@ -69,7 +72,7 @@ Gets an attachment for a manifest by its attachment ID or file ID, including ful
```js ```js
const attachment = await store.manifestattachment.getById(42, 1, 5); const attachment = await store.manifestattachment.getById(42, 1, 5);
// => { id, manifestId, fileId, sort, hash, mimetype, name, content, thumbavif, thumbx, thumby } // => { id, manifestId, fileId, sort, hash, mimetype, name, size, created, modified, content, thumbavif, thumbx, thumby }
``` ```
## `manifestattachment.listByManifestId` ## `manifestattachment.listByManifestId`
@@ -87,7 +90,7 @@ Lists all attachments for a given manifest, without loading their full binary co
**Returns** **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. `Promise<Array<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, created: Date, modified: Date, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>>` — A list of attachment metadata objects.
**Throws** **Throws**
@@ -97,7 +100,7 @@ Lists all attachments for a given manifest, without loading their full binary co
```js ```js
const attachments = await store.manifestattachment.listByManifestId(42, 1); const attachments = await store.manifestattachment.listByManifestId(42, 1);
// => [{ id, manifestId, fileId, sort, hash, mimetype, name, size, thumbavif, thumbx, thumby }] // => [{ id, manifestId, fileId, sort, hash, mimetype, name, size, created, modified, thumbavif, thumbx, thumby }]
``` ```
## `manifestattachment.order` ## `manifestattachment.order`

6
API.md
View File

@@ -123,9 +123,9 @@ 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}>>` - `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}>}>` - `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) - [manifestattachment](API.manifestattachment.md)
- `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}>` - `add(googleAuthId: number, manifestId: number, input: {mimetype: string, name: string, content: Buffer, sort?: number, size?: number, created?: Date|string, modified?: Date|string, hash?: string, thumbavif?: Buffer, thumbx?: number, thumby?: number}): Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, created: Date, modified: Date, 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}>` - `getById(googleAuthId: number, manifestId: number, id: number): Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, created: Date, modified: Date, 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}>>` - `listByManifestId(googleAuthId: number, manifestId: number): Promise<Array<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, created: Date, modified: Date, thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>>`
- `order(googleAuthId: number, manifestId: number, input: {ids?: Array<number>}): Promise<{ids: Array<number>}>` - `order(googleAuthId: number, manifestId: number, input: {ids?: Array<number>}): Promise<{ids: Array<number>}>`
- `remove(googleAuthId: number, manifestId: number, id: number): Promise<void>` - `remove(googleAuthId: number, manifestId: number, id: number): Promise<void>`
- [posterminal](API.posterminal.md) - [posterminal](API.posterminal.md)

View File

@@ -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>>]; 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>>]; 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>>]; 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="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>>]; 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="size" 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">size</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">BIGINT</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="created" 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">created</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">DATETIME2</FONT></TD></TR></TABLE></TD></TR><TR><TD PORT="modified" 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">modified</FONT></TD><TD ALIGN="RIGHT" CELLPADDING="4"><FONT COLOR="#8b95a7" POINT-SIZE="9">DATETIME2</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><TR><TD PORT="thumbavif" 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">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="#272e3d" 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="#2a3242" 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 { subgraph cluster_manifests {
label="Documents"; labeljust="l"; fontsize=15; label="Documents"; labeljust="l"; fontsize=15;
@@ -115,12 +115,12 @@ digraph schema {
articlehistory:article_id:ne -> article:in3:n [color="#c79bff", fontcolor="#c79bff", tooltip="FK_articlehistory_article", weight=3]; articlehistory:article_id:ne -> article:in3:n [color="#c79bff", fontcolor="#c79bff", tooltip="FK_articlehistory_article", weight=3];
articlehistory:companyuser_id:w -> companyuser:in1:n [color="#ff6b6b", fontcolor="#ff6b6b", tooltip="FK_articlehistory_companyuser", constraint=false, weight=1]; articlehistory:companyuser_id:w -> companyuser:in1:n [color="#ff6b6b", fontcolor="#ff6b6b", tooltip="FK_articlehistory_companyuser", constraint=false, weight=1];
articleean:article_id:sw -> article:in6:n [color="#6bdf9a", fontcolor="#6bdf9a", tooltip="FK_articleean_article", weight=3]; articleean:article_id:sw -> article:in6:n [color="#6bdf9a", fontcolor="#6bdf9a", tooltip="FK_articleean_article", weight=3];
articlepic:article_id:e -> article:in9:n [color="#5aa7ff", fontcolor="#5aa7ff", tooltip="FK_articlepic_article", weight=3]; articlepic:article_id:e -> article:in8:n [color="#5aa7ff", fontcolor="#5aa7ff", tooltip="FK_articlepic_article", weight=3];
articlepic:pic_id:w -> pic:in2:n [color="#f5c15c", fontcolor="#f5c15c", tooltip="FK_articlepic_pic", constraint=false, weight=1]; articlepic:pic_id:w -> pic:in2:n [color="#f5c15c", fontcolor="#f5c15c", tooltip="FK_articlepic_pic", constraint=false, weight=1];
brandpic:brand_id:w -> brand:in1:n [color="#c79bff", fontcolor="#c79bff", tooltip="FK_brandpic_brand", weight=3]; brandpic:brand_id:w -> brand:in1:n [color="#c79bff", fontcolor="#c79bff", tooltip="FK_brandpic_brand", weight=3];
brandpic:pic_id:ne -> pic:in1:n [color="#ff9f5a", fontcolor="#ff9f5a", tooltip="FK_brandpic_pic", constraint=false, weight=1]; brandpic:pic_id:ne -> pic:in1:n [color="#ff9f5a", fontcolor="#ff9f5a", tooltip="FK_brandpic_pic", constraint=false, weight=1];
articlelistarticle:articlelist_id:sw -> articlelist:in1:n [color="#5cd6d6", fontcolor="#5cd6d6", tooltip="FK_articlelistarticle_articlelist", weight=3]; articlelistarticle:articlelist_id:sw -> articlelist:in1:n [color="#5cd6d6", fontcolor="#5cd6d6", tooltip="FK_articlelistarticle_articlelist", weight=3];
articlelistarticle:article_id:w -> article:in8:n [color="#ff7fc2", fontcolor="#ff7fc2", tooltip="FK_articlelistarticle_article", constraint=false, weight=1]; articlelistarticle:article_id:w -> article:in9:n [color="#ff7fc2", fontcolor="#ff7fc2", tooltip="FK_articlelistarticle_article", constraint=false, weight=1];
optionslistarticle:optionslist_id:sw -> optionslist:in0:n [color="#8f95ff", fontcolor="#8f95ff", tooltip="FK_optionslistarticle_optionslist", weight=3]; optionslistarticle:optionslist_id:sw -> optionslist:in0:n [color="#8f95ff", fontcolor="#8f95ff", tooltip="FK_optionslistarticle_optionslist", weight=3];
optionslistarticle:article_id:se -> article:in2:n [color="#58d18a", fontcolor="#58d18a", tooltip="FK_optionslistarticle_article", constraint=false, weight=1]; optionslistarticle:article_id:se -> article:in2:n [color="#58d18a", fontcolor="#58d18a", tooltip="FK_optionslistarticle_article", constraint=false, weight=1];
categoryarticle:category_id:se -> category:in3:n [color="#ff8f66", fontcolor="#ff8f66", tooltip="FK_categoryarticle_category", weight=3]; categoryarticle:category_id:se -> category:in3:n [color="#ff8f66", fontcolor="#ff8f66", tooltip="FK_categoryarticle_category", weight=3];

View File

@@ -1277,8 +1277,8 @@
<g id="edge32" class="edge"> <g id="edge32" class="edge">
<title>articlelistarticle:w&#45;&gt;article:n</title> <title>articlelistarticle:w&#45;&gt;article:n</title>
<g id="a_edge32"><a xlink:title="FK_articlelistarticle_article"> <g id="a_edge32"><a xlink:title="FK_articlelistarticle_article">
<path fill="none" stroke="#ff7fc2" stroke-width="1.4" d="M3270.65,-1036.6C3183.81,-1036.6 3251.5,-1162.83 3177.58,-1208.4 3170.23,-1212.93 3160.09,-1217.55 3153.06,-1217.52"/> <path fill="none" stroke="#ff7fc2" stroke-width="1.4" d="M3270.65,-1036.6C3183.81,-1036.6 3250.89,-1161.86 3177.58,-1208.4 3175.62,-1209.64 3173.27,-1210.93 3170.95,-1211.91"/>
<polygon fill="#ff7fc2" stroke="#ff7fc2" stroke-width="1.4" points="3153.1,-1214.1 3146.41,-1210.89 3149.64,-1217.57 3153.1,-1214.1"/> <polygon fill="#ff7fc2" stroke="#ff7fc2" stroke-width="1.4" points="3169.45,-1209.05 3162.08,-1209.87 3168.36,-1213.83 3169.45,-1209.05"/>
</a> </a>
</g> </g>
</g> </g>
@@ -1580,8 +1580,8 @@
<g id="edge27" class="edge"> <g id="edge27" class="edge">
<title>articlepic:e&#45;&gt;article:n</title> <title>articlepic:e&#45;&gt;article:n</title>
<g id="a_edge27"><a xlink:title="FK_articlepic_article"> <g id="a_edge27"><a xlink:title="FK_articlepic_article">
<path fill="none" stroke="#5aa7ff" stroke-width="1.4" d="M4362.24,-1453.2C4393.79,-1453.2 4376.64,-1409.74 4361.24,-1382.2 4322.38,-1312.76 4285.55,-1311.35 4210,-1286.4 4101.85,-1250.69 3208.96,-1322.41 3161.94,-1218.25"/> <path fill="none" stroke="#5aa7ff" stroke-width="1.4" d="M4362.24,-1453.2C4393.79,-1453.2 4376.64,-1409.74 4361.24,-1382.2 4322.38,-1312.76 4285.57,-1311.31 4210,-1286.4 4100.17,-1250.2 3192.73,-1324.13 3146.72,-1218.06"/>
<polygon fill="#5aa7ff" stroke="#5aa7ff" stroke-width="1.4" points="3164.35,-1217.79 3160.47,-1211.47 3159.56,-1218.83 3164.35,-1217.79"/> <polygon fill="#5aa7ff" stroke="#5aa7ff" stroke-width="1.4" points="3149.17,-1217.82 3145.34,-1211.47 3144.37,-1218.83 3149.17,-1217.82"/>
</a> </a>
</g> </g>
</g> </g>
@@ -1597,43 +1597,55 @@
<!-- file --> <!-- file -->
<g id="node32" class="node"> <g id="node32" class="node">
<title>file</title> <title>file</title>
<polygon fill="#33415c" stroke="none" points="4445,-1545 4445,-1573.4 4609,-1573.4 4609,-1545 4445,-1545"/> <polygon fill="#33415c" stroke="none" points="4445,-1585.2 4445,-1613.6 4609,-1613.6 4609,-1585.2 4445,-1585.2"/>
<polygon fill="none" stroke="#3f4c5f" points="4445,-1545 4445,-1573.4 4609,-1573.4 4609,-1545 4445,-1545"/> <polygon fill="none" stroke="#3f4c5f" points="4445,-1585.2 4445,-1613.6 4609,-1613.6 4609,-1585.2 4445,-1585.2"/>
<polygon fill="#33415c" stroke="none" points="4447,-1567.4 4447,-1571.4 4607,-1571.4 4607,-1567.4 4447,-1567.4"/> <polygon fill="#33415c" stroke="none" points="4447,-1607.6 4447,-1611.6 4607,-1611.6 4607,-1607.6 4447,-1607.6"/>
<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> <text xml:space="preserve" text-anchor="start" x="4518.33" y="-1594.8" 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="#2b3a52" stroke="none" points="4445,-1558.4 4445,-1585.2 4609,-1585.2 4609,-1558.4 4445,-1558.4"/>
<polygon fill="none" stroke="#3f4c5f" points="4445,-1518.2 4445,-1545 4609,-1545 4609,-1518.2 4445,-1518.2"/> <polygon fill="none" stroke="#3f4c5f" points="4445,-1558.4 4445,-1585.2 4609,-1585.2 4609,-1558.4 4445,-1558.4"/>
<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="4450" y="-1568.6" 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="4574.5" y="-1570.1" 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> <text xml:space="preserve" text-anchor="start" x="4591.49" y="-1570.1" 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="#272e3d" stroke="none" points="4445,-1531.6 4445,-1558.4 4609,-1558.4 4609,-1531.6 4445,-1531.6"/>
<polygon fill="none" stroke="#3f4c5f" points="4445,-1491.4 4445,-1518.2 4609,-1518.2 4609,-1491.4 4445,-1491.4"/> <polygon fill="none" stroke="#3f4c5f" points="4445,-1531.6 4445,-1558.4 4609,-1558.4 4609,-1531.6 4445,-1531.6"/>
<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="4450" y="-1539.4" 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> <text xml:space="preserve" text-anchor="start" x="4537.49" y="-1541.4" 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="#2a3242" stroke="none" points="4445,-1504.8 4445,-1531.6 4609,-1531.6 4609,-1504.8 4445,-1504.8"/>
<polygon fill="none" stroke="#3f4c5f" points="4445,-1464.6 4445,-1491.4 4609,-1491.4 4609,-1464.6 4445,-1464.6"/> <polygon fill="none" stroke="#3f4c5f" points="4445,-1504.8 4445,-1531.6 4609,-1531.6 4609,-1504.8 4445,-1504.8"/>
<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="4450" y="-1512.6" 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> <text xml:space="preserve" text-anchor="start" x="4532.48" y="-1514.6" 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="#272e3d" stroke="none" points="4445,-1478 4445,-1504.8 4609,-1504.8 4609,-1478 4445,-1478"/>
<polygon fill="none" stroke="#3f4c5f" points="4445,-1437.8 4445,-1464.6 4609,-1464.6 4609,-1437.8 4445,-1437.8"/> <polygon fill="none" stroke="#3f4c5f" points="4445,-1478 4445,-1504.8 4609,-1504.8 4609,-1478 4445,-1478"/>
<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="4450" y="-1485.8" 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> <text xml:space="preserve" text-anchor="start" x="4532.48" y="-1487.8" 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="#2a3242" stroke="none" points="4445,-1451.2 4445,-1478 4609,-1478 4609,-1451.2 4445,-1451.2"/>
<polygon fill="none" stroke="#3f4c5f" points="4445,-1411 4445,-1437.8 4609,-1437.8 4609,-1411 4445,-1411"/> <polygon fill="none" stroke="#3f4c5f" points="4445,-1451.2 4445,-1478 4609,-1478 4609,-1451.2 4445,-1451.2"/>
<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="4450" y="-1459" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">size</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> <text xml:space="preserve" text-anchor="start" x="4574" y="-1461" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">BIGINT</text>
<polygon fill="#272e3d" stroke="none" points="4445,-1384.2 4445,-1411 4609,-1411 4609,-1384.2 4445,-1384.2"/> <polygon fill="#272e3d" stroke="none" points="4445,-1424.4 4445,-1451.2 4609,-1451.2 4609,-1424.4 4445,-1424.4"/>
<polygon fill="none" stroke="#3f4c5f" points="4445,-1384.2 4445,-1411 4609,-1411 4609,-1384.2 4445,-1384.2"/> <polygon fill="none" stroke="#3f4c5f" points="4445,-1424.4 4445,-1451.2 4609,-1451.2 4609,-1424.4 4445,-1424.4"/>
<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="4450" y="-1432.2" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">created</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> <text xml:space="preserve" text-anchor="start" x="4553.49" y="-1434.2" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">DATETIME2</text>
<polygon fill="#2a3242" stroke="none" points="4445,-1357.4 4445,-1384.2 4609,-1384.2 4609,-1357.4 4445,-1357.4"/> <polygon fill="#2a3242" stroke="none" points="4445,-1397.6 4445,-1424.4 4609,-1424.4 4609,-1397.6 4445,-1397.6"/>
<polygon fill="none" stroke="#3f4c5f" points="4445,-1357.4 4445,-1384.2 4609,-1384.2 4609,-1357.4 4445,-1357.4"/> <polygon fill="none" stroke="#3f4c5f" points="4445,-1397.6 4445,-1424.4 4609,-1424.4 4609,-1397.6 4445,-1397.6"/>
<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="4450" y="-1405.4" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">modified</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> <text xml:space="preserve" text-anchor="start" x="4553.49" y="-1407.4" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">DATETIME2</text>
<polygon fill="#272e3d" stroke="none" points="4445,-1330.6 4445,-1357.4 4609,-1357.4 4609,-1330.6 4445,-1330.6"/> <polygon fill="#272e3d" stroke="none" points="4445,-1370.8 4445,-1397.6 4609,-1397.6 4609,-1370.8 4445,-1370.8"/>
<polygon fill="none" stroke="#3f4c5f" points="4445,-1330.6 4445,-1357.4 4609,-1357.4 4609,-1330.6 4445,-1330.6"/> <polygon fill="none" stroke="#3f4c5f" points="4445,-1370.8 4445,-1397.6 4609,-1397.6 4609,-1370.8 4445,-1370.8"/>
<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="4450" y="-1378.6" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">content</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> <text xml:space="preserve" text-anchor="start" x="4526.49" y="-1380.6" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">VARBINARY(MAX)</text>
<polygon fill="#2a3242" stroke="none" points="4445,-1344 4445,-1370.8 4609,-1370.8 4609,-1344 4445,-1344"/>
<polygon fill="none" stroke="#3f4c5f" points="4445,-1344 4445,-1370.8 4609,-1370.8 4609,-1344 4445,-1344"/>
<text xml:space="preserve" text-anchor="start" x="4450" y="-1351.8" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">thumbavif?</text>
<text xml:space="preserve" text-anchor="start" x="4526.49" y="-1353.8" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">VARBINARY(MAX)</text>
<polygon fill="#272e3d" stroke="none" points="4445,-1317.2 4445,-1344 4609,-1344 4609,-1317.2 4445,-1317.2"/>
<polygon fill="none" stroke="#3f4c5f" points="4445,-1317.2 4445,-1344 4609,-1344 4609,-1317.2 4445,-1317.2"/>
<text xml:space="preserve" text-anchor="start" x="4450" y="-1325" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">thumbx?</text>
<text xml:space="preserve" text-anchor="start" x="4589.5" y="-1327" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">INT</text>
<polygon fill="#2a3242" stroke="none" points="4445,-1290.4 4445,-1317.2 4609,-1317.2 4609,-1290.4 4445,-1290.4"/>
<polygon fill="none" stroke="#3f4c5f" points="4445,-1290.4 4445,-1317.2 4609,-1317.2 4609,-1290.4 4445,-1290.4"/>
<text xml:space="preserve" text-anchor="start" x="4450" y="-1298.2" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#d8dee9">thumby?</text>
<text xml:space="preserve" text-anchor="start" x="4589.5" y="-1300.2" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8b95a7">INT</text>
</g> </g>
<!-- manifestarticle --> <!-- manifestarticle -->
<g id="node33" class="node"> <g id="node33" class="node">
@@ -1829,8 +1841,8 @@
<g id="edge62" class="edge"> <g id="edge62" class="edge">
<title>manifestattachment:e&#45;&gt;file:n</title> <title>manifestattachment:e&#45;&gt;file:n</title>
<g id="a_edge62"><a xlink:title="FK_manifestattachment_file"> <g id="a_edge62"><a xlink:title="FK_manifestattachment_file">
<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"/> <path fill="none" stroke="#ff6f6f" stroke-width="1.4" d="M629.4,-996.4C653.65,-996.4 623.55,-1197.55 641,-1214.4 799.93,-1367.85 4462.2,-1128.77 4617,-1286.4 4642.31,-1312.18 4642.4,-1585.91 4617,-1611.6 4591.18,-1637.71 4536.92,-1650.43 4528.2,-1621.4"/>
<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"/> <polygon fill="#ff6f6f" stroke="#ff6f6f" stroke-width="1.4" points="4530.66,-1621.31 4527.29,-1614.7 4525.8,-1621.97 4530.66,-1621.31"/>
</a> </a>
</g> </g>
</g> </g>

Before

Width:  |  Height:  |  Size: 206 KiB

After

Width:  |  Height:  |  Size: 207 KiB

View File

@@ -776,6 +776,9 @@ BEGIN
hash NVARCHAR(64) NOT NULL, hash NVARCHAR(64) NOT NULL,
mimetype NVARCHAR(255) NOT NULL, mimetype NVARCHAR(255) NOT NULL,
name NVARCHAR(255) NOT NULL, name NVARCHAR(255) NOT NULL,
size BIGINT NOT NULL,
created DATETIME2 NOT NULL CONSTRAINT DF_file_created DEFAULT SYSUTCDATETIME(),
modified DATETIME2 NOT NULL CONSTRAINT DF_file_modified DEFAULT SYSUTCDATETIME(),
content VARBINARY(MAX) NOT NULL, content VARBINARY(MAX) NOT NULL,
thumbavif VARBINARY(MAX) NULL, thumbavif VARBINARY(MAX) NULL,
thumbx INT NULL, thumbx INT NULL,

View File

@@ -5,9 +5,9 @@ WHERE id = @manifestId AND company_id = @companyId
`; `;
export const CREATE_FILE = ` export const CREATE_FILE = `
INSERT INTO [file] (hash, mimetype, name, content, thumbavif, thumbx, thumby) INSERT INTO [file] (hash, mimetype, name, size, created, modified, content, thumbavif, thumbx, thumby)
OUTPUT INSERTED.id OUTPUT INSERTED.id
VALUES (@hash, @mimetype, @name, @content, CONVERT(VARBINARY(MAX), @thumbavif), @thumbx, @thumby) VALUES (@hash, @mimetype, @name, @size, @created, @modified, @content, CONVERT(VARBINARY(MAX), @thumbavif), @thumbx, @thumby)
`; `;
export const GET_NEXT_SORT = ` export const GET_NEXT_SORT = `
@@ -31,7 +31,9 @@ SELECT
f.hash, f.hash,
f.mimetype, f.mimetype,
f.name, f.name,
DATALENGTH(f.content) AS size, f.size,
f.created,
f.modified,
f.thumbavif, f.thumbavif,
f.thumbx, f.thumbx,
f.thumby f.thumby
@@ -50,6 +52,9 @@ SELECT
f.hash, f.hash,
f.mimetype, f.mimetype,
f.name, f.name,
f.size,
f.created,
f.modified,
f.content, f.content,
f.thumbavif, f.thumbavif,
f.thumbx, f.thumbx,

View File

@@ -23,11 +23,14 @@ export default function add(pool) {
* @param {string} input.name - The file name. * @param {string} input.name - The file name.
* @param {Buffer} input.content - The file content. * @param {Buffer} input.content - The file content.
* @param {number} [input.sort] - Optional display sort order. * @param {number} [input.sort] - Optional display sort order.
* @param {number} [input.size] - Optional file size in bytes (defaults to content length).
* @param {Date|string} [input.created] - Optional creation timestamp (defaults to current date).
* @param {Date|string} [input.modified] - Optional modified timestamp (defaults to created date).
* @param {string} [input.hash] - The file hash (auto-computed SHA-256 if omitted). * @param {string} [input.hash] - The file hash (auto-computed SHA-256 if omitted).
* @param {Buffer} [input.thumbavif] - Optional AVIF thumbnail buffer. * @param {Buffer} [input.thumbavif] - Optional AVIF thumbnail buffer.
* @param {number} [input.thumbx] - Optional thumbnail width. * @param {number} [input.thumbx] - Optional thumbnail width.
* @param {number} [input.thumby] - Optional thumbnail height. * @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. * @returns {Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, created: Date, modified: Date, 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. * @throws {Error} If the manifest is not found or file input is invalid.
* *
* @example * @example
@@ -36,10 +39,10 @@ export default function add(pool) {
* name: 'invoice.pdf', * name: 'invoice.pdf',
* content: fileBuffer, * content: fileBuffer,
* }); * });
* // => { id, manifestId, fileId, sort, hash, mimetype, name, thumbavif, thumbx, thumby } * // => { id, manifestId, fileId, sort, hash, mimetype, name, size, created, modified, thumbavif, thumbx, thumby }
*/ */
return async (googleAuthId, manifestId, input, ...rest) => { return async (googleAuthId, manifestId, input, ...rest) => {
let rawMimetype, rawName, rawContent, rawHash, rawThumbavif, rawThumbx, rawThumby, rawSort; let rawMimetype, rawName, rawContent, rawHash, rawThumbavif, rawThumbx, rawThumby, rawSort, rawSize, rawCreated, rawModified;
if (typeof input === 'object' && input !== null && !Buffer.isBuffer(input)) { if (typeof input === 'object' && input !== null && !Buffer.isBuffer(input)) {
rawMimetype = input.mimetype; rawMimetype = input.mimetype;
rawName = input.name; rawName = input.name;
@@ -49,6 +52,9 @@ export default function add(pool) {
rawThumbx = input.thumbx ?? input.thumbw; rawThumbx = input.thumbx ?? input.thumbw;
rawThumby = input.thumby ?? input.thumbh; rawThumby = input.thumby ?? input.thumbh;
rawSort = input.sort; rawSort = input.sort;
rawSize = input.size;
rawCreated = input.created ?? input.createdAt;
rawModified = input.modified ?? input.modifiedAt ?? input.lastModified;
} else { } else {
rawMimetype = input; rawMimetype = input;
rawName = rest[0]; rawName = rest[0];
@@ -78,6 +84,27 @@ export default function add(pool) {
} }
} }
const size =
Number.isFinite(rawSize) && rawSize >= 0
? Number(rawSize)
: content.length;
const parsedCreated =
rawCreated instanceof Date && !isNaN(rawCreated)
? rawCreated
: typeof rawCreated === 'string' || typeof rawCreated === 'number'
? new Date(rawCreated)
: null;
const created = parsedCreated && !isNaN(parsedCreated) ? parsedCreated : new Date();
const parsedModified =
rawModified instanceof Date && !isNaN(rawModified)
? rawModified
: typeof rawModified === 'string' || typeof rawModified === 'number'
? new Date(rawModified)
: null;
const modified = parsedModified && !isNaN(parsedModified) ? parsedModified : created;
const hash = const hash =
typeof rawHash === 'string' && rawHash.trim() typeof rawHash === 'string' && rawHash.trim()
? rawHash.trim() ? rawHash.trim()
@@ -134,6 +161,9 @@ export default function add(pool) {
.input('hash', hash) .input('hash', hash)
.input('mimetype', mimetype) .input('mimetype', mimetype)
.input('name', name) .input('name', name)
.input('size', size)
.input('created', created)
.input('modified', modified)
.input('content', content) .input('content', content)
.input('thumbavif', thumbavif) .input('thumbavif', thumbavif)
.input('thumbx', thumbx) .input('thumbx', thumbx)
@@ -160,6 +190,9 @@ export default function add(pool) {
hash, hash,
mimetype, mimetype,
name, name,
size,
created,
modified,
thumbavif, thumbavif,
thumbx, thumbx,
thumby, thumby,

View File

@@ -13,12 +13,12 @@ export default function getById(pool) {
* @param {number} googleAuthId - The id of the Google auth user. * @param {number} googleAuthId - The id of the Google auth user.
* @param {number} manifestId - The manifest ID. * @param {number} manifestId - The manifest ID.
* @param {number} id - The attachment ID or file ID. * @param {number} id - The attachment ID or file ID.
* @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. * @returns {Promise<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, created: Date, modified: Date, 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. * @throws {Error} If the manifest or attachment is not found, or user is not authorized.
* *
* @example * @example
* const attachment = await store.manifestattachment.getById(42, 1, 5); * const attachment = await store.manifestattachment.getById(42, 1, 5);
* // => { id, manifestId, fileId, sort, hash, mimetype, name, content, thumbavif, thumbx, thumby } * // => { id, manifestId, fileId, sort, hash, mimetype, name, size, created, modified, content, thumbavif, thumbx, thumby }
*/ */
return async (googleAuthId, manifestId, id) => { return async (googleAuthId, manifestId, id) => {
if (!Number.isFinite(id)) { if (!Number.isFinite(id)) {
@@ -46,6 +46,9 @@ export default function getById(pool) {
hash: row.hash, hash: row.hash,
mimetype: row.mimetype, mimetype: row.mimetype,
name: row.name, name: row.name,
size: Number(row.size),
created: row.created,
modified: row.modified,
content: row.content, content: row.content,
thumbavif: row.thumbavif ?? null, thumbavif: row.thumbavif ?? null,
thumbx: row.thumbx ?? null, thumbx: row.thumbx ?? null,

View File

@@ -12,7 +12,9 @@ function shape(row) {
hash: row.hash, hash: row.hash,
mimetype: row.mimetype, mimetype: row.mimetype,
name: row.name, name: row.name,
size: row.size, size: Number(row.size),
created: row.created,
modified: row.modified,
thumbavif: row.thumbavif ?? null, thumbavif: row.thumbavif ?? null,
thumbx: row.thumbx ?? null, thumbx: row.thumbx ?? null,
thumby: row.thumby ?? null, thumby: row.thumby ?? null,
@@ -28,12 +30,12 @@ export default function listByManifestId(pool) {
* *
* @param {number} googleAuthId - The id of the Google auth user. * @param {number} googleAuthId - The id of the Google auth user.
* @param {number} manifestId - The manifest ID. * @param {number} manifestId - The manifest ID.
* @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. * @returns {Promise<Array<{id: number, manifestId: number, fileId: number, sort: number, hash: string, mimetype: string, name: string, size: number, created: Date, modified: Date, 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. * @throws {Error} If the manifest is not found or the user is not authorized.
* *
* @example * @example
* const attachments = await store.manifestattachment.listByManifestId(42, 1); * const attachments = await store.manifestattachment.listByManifestId(42, 1);
* // => [{ id, manifestId, fileId, sort, hash, mimetype, name, size, thumbavif, thumbx, thumby }] * // => [{ id, manifestId, fileId, sort, hash, mimetype, name, size, created, modified, thumbavif, thumbx, thumby }]
*/ */
return async (googleAuthId, manifestId) => { return async (googleAuthId, manifestId) => {
const { companyId } = await access(googleAuthId); const { companyId } = await access(googleAuthId);