Compare commits
5 Commits
f3674edcb7
...
00cf5b418e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00cf5b418e | ||
|
|
f840a12b78 | ||
|
|
178055f1d8 | ||
|
|
07c4f0bff9 | ||
|
|
4ae3439289 |
@@ -32,7 +32,7 @@ Adds a child article to a parent article (creates and attaches with auto-generat
|
|||||||
|
|
||||||
*Source: `src/store/article/addImage.js`*
|
*Source: `src/store/article/addImage.js`*
|
||||||
|
|
||||||
Adds an image to an article by its SKU, processing it into AVIF variants.
|
Adds an image to an article by its SKU, processing full, thumb, and 40px-edge small-thumb AVIF variants.
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
@@ -45,13 +45,13 @@ Adds an image to an article by its SKU, processing it into AVIF variants.
|
|||||||
|
|
||||||
**Returns**
|
**Returns**
|
||||||
|
|
||||||
`Promise<{picId: number, sort: number, full: {w: number, h: number, size: number}, thumb: {w: number, h: number}, fullHash: string, thumbHash: string}>` — The added image info.
|
`Promise<{picId: number, sort: number, full: {w: number, h: number, size: number}, thumb: {w: number, h: number}, smallThumb: {w: number, h: number}, fullHash: string, thumbHash: string}>` — The added image info.
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const result = await store.article.addImage(42, 'SKU-1', imageBuffer);
|
const result = await store.article.addImage(42, 'SKU-1', imageBuffer);
|
||||||
// => { picId, sort, full: { w, h, size }, thumb: { w, h }, fullHash, thumbHash }
|
// => { picId, sort, full: { w, h, size }, thumb: { w, h }, smallThumb: { w, h }, fullHash, thumbHash }
|
||||||
```
|
```
|
||||||
|
|
||||||
## `article.attachChild`
|
## `article.attachChild`
|
||||||
|
|||||||
81
API.brand.md
81
API.brand.md
@@ -6,7 +6,7 @@ This document is auto-generated from the JSDoc comments in `src/store` by runnin
|
|||||||
|
|
||||||
*Source: `src/store/brand/addImage.js`*
|
*Source: `src/store/brand/addImage.js`*
|
||||||
|
|
||||||
Adds an image to a brand, processing it into AVIF full and thumb variants.
|
Adds an image to a brand, processing full, thumb, and 40px-edge small-thumb AVIF variants.
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
@@ -19,7 +19,38 @@ Adds an image to a brand, processing it into AVIF full and thumb variants.
|
|||||||
|
|
||||||
**Returns**
|
**Returns**
|
||||||
|
|
||||||
`Promise<{id: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string, pics: Array<object>}>`
|
`Promise<{id: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string, smallThumbW: number, smallThumbH: number, pics: Array<object>}>`
|
||||||
|
|
||||||
|
## `brand.create`
|
||||||
|
|
||||||
|
*Source: `src/store/brand/create.js`*
|
||||||
|
|
||||||
|
Creates a brand for the user's selected company.
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
| Name | Type | Description |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `googleAuthId` | `number` | The id of the Google auth user. |
|
||||||
|
| `input` | `object` | The brand input. |
|
||||||
|
| `input.name` | `string` | The brand name. |
|
||||||
|
| `[input.gsprpinfo]` | `string` | Optional GSPRP info. |
|
||||||
|
| `[tx]` | `object` | Optional transaction to run within. |
|
||||||
|
|
||||||
|
**Returns**
|
||||||
|
|
||||||
|
`Promise<{id: number, name: string, gsprpinfo: string|null, pics: Array<{fullHash: string, thumbW: number, thumbH: number, thumbHash: string}>}>` — The created brand.
|
||||||
|
|
||||||
|
**Throws**
|
||||||
|
|
||||||
|
`Error` — If the brand is invalid or already exists.
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
|
||||||
|
```js
|
||||||
|
const brand = await store.brand.create(42, { name: 'Coca-Cola', gsprpinfo: 'x' });
|
||||||
|
// => { id, name, gsprpinfo, pics: [] }
|
||||||
|
```
|
||||||
|
|
||||||
## `brand.delete`
|
## `brand.delete`
|
||||||
|
|
||||||
@@ -53,24 +84,60 @@ await store.brand.delete(42, 3);
|
|||||||
|
|
||||||
*Source: `src/store/brand/list.js`*
|
*Source: `src/store/brand/list.js`*
|
||||||
|
|
||||||
Lists the brands of the user's selected company.
|
Lists the brands of the user's selected company, sorted by name.
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
| Name | Type | Description |
|
| Name | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `googleAuthId` | `number` | The id of the Google auth user. |
|
| `googleAuthId` | `number` | The id of the Google auth user. |
|
||||||
|
| `[opts]` | `object` | Optional pagination options. |
|
||||||
|
| `[opts.offset=0]` | `number` | Number of brands to skip. |
|
||||||
|
| `[opts.limit=10]` | `number` | Number of brands to return (max 100). |
|
||||||
|
| `[opts.includeSmallThumbs=false]` | `boolean` | Include 40px-edge small thumbnail dimensions and base64 AVIF data. |
|
||||||
| `[tx]` | `object` | Optional transaction to run within. |
|
| `[tx]` | `object` | Optional transaction to run within. |
|
||||||
|
|
||||||
**Returns**
|
**Returns**
|
||||||
|
|
||||||
`Promise<Array<{id: number, name: string, gsprpinfo: string|null, pics: Array<{id: number, sort: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string}>}>>` — The brands.
|
`Promise<{brands: Array<{id: number, name: string, gsprpinfo: string|null, pics: Array<{fullHash: string, thumbW: number, thumbH: number, thumbHash: string, smallThumbW?: number|null, smallThumbH?: number|null, smallThumbBinary?: string|null}>}>, total: number, offset: number, limit: number}>` — The brands plus the total unpaged count. Small-thumbnail fields are present only when `includeSmallThumbs` is true; the binary is base64-encoded AVIF data.
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const brands = await store.brand.list(42);
|
const result = await store.brand.list(42, { offset: 0, limit: 10 });
|
||||||
// => [{ id, name, gsprpinfo, pics: [{ sort, fullHash, thumbW, thumbH, thumbHash }] }]
|
// => { brands: [{ id, name, gsprpinfo, pics: [...] }], total: 25, offset: 0, limit: 10 }
|
||||||
|
```
|
||||||
|
|
||||||
|
## `brand.update`
|
||||||
|
|
||||||
|
*Source: `src/store/brand/update.js`*
|
||||||
|
|
||||||
|
Renames/updates a brand for the user's selected company by id. Touching `article.updated_at` for all articles linked via `brand_id` when the name actually changes, so list caches invalidate.
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
| Name | Type | Description |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `googleAuthId` | `number` | The id of the Google auth user. |
|
||||||
|
| `id` | `number` | The id of the brand to update. |
|
||||||
|
| `input` | `object` | The update input. |
|
||||||
|
| `[input.name]` | `string` | The new brand name. |
|
||||||
|
| `[input.gsprpinfo]` | `string` | The new GSPRP info. |
|
||||||
|
| `[tx]` | `object` | Optional transaction to run within. |
|
||||||
|
|
||||||
|
**Returns**
|
||||||
|
|
||||||
|
`Promise<{id: number, name: string, gsprpinfo: string|null, touchedArticleCount: number}>` — The updated brand plus the number of linked articles whose `updated_at` was bumped.
|
||||||
|
|
||||||
|
**Throws**
|
||||||
|
|
||||||
|
`Error` — If the brand is not found, invalid, or the name is already taken.
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
|
||||||
|
```js
|
||||||
|
const brand = await store.brand.update(42, 3, { name: 'Coca-Cola GmbH' });
|
||||||
|
// => { id: 3, name, gsprpinfo, touchedArticleCount: 2 }
|
||||||
```
|
```
|
||||||
|
|
||||||
## `brand.upsert`
|
## `brand.upsert`
|
||||||
@@ -91,7 +158,7 @@ Creates or updates a brand for the user's selected company, keyed by name.
|
|||||||
|
|
||||||
**Returns**
|
**Returns**
|
||||||
|
|
||||||
`Promise<{id: number, name: string, gsprpinfo: string|null, pics: Array<{id: number, sort: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string}>}>` — The upserted brand.
|
`Promise<{id: number, name: string, gsprpinfo: string|null, pics: Array<{fullHash: string, thumbW: number, thumbH: number, thumbHash: string}>}>` — The upserted brand.
|
||||||
|
|
||||||
**Throws**
|
**Throws**
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ This document is auto-generated from the JSDoc comments in `src/store` by runnin
|
|||||||
|
|
||||||
*Source: `src/store/category/addImage.js`*
|
*Source: `src/store/category/addImage.js`*
|
||||||
|
|
||||||
Adds an image to a category, processing it into AVIF full and thumb variants.
|
Adds an image to a category, processing full, thumb, and 40px-edge small-thumb AVIF variants.
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ Adds an image to a category, processing it into AVIF full and thumb variants.
|
|||||||
|
|
||||||
**Returns**
|
**Returns**
|
||||||
|
|
||||||
`Promise<{id: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string}>` — The added image info.
|
`Promise<{id: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string, smallThumbW: number, smallThumbH: number}>` — The added image info.
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
|
|
||||||
|
|||||||
12
API.md
12
API.md
@@ -74,7 +74,7 @@ The store is exposed as a `LibDashStore` instance (see `src/index.js`). Each met
|
|||||||
- `list(googleAuthId: number, tx?: object): Promise<Array<object>>`
|
- `list(googleAuthId: number, tx?: object): Promise<Array<object>>`
|
||||||
- `update(id: number, input: {iso639: string, name: string, taxrate: number, reducedtaxrate: number}, tx?: object): Promise<{id: number, rootCategoryId: number, languageId: number, taxrateId: number, reducedtaxrateId: number, taxfreerateId: number}>`
|
- `update(id: number, input: {iso639: string, name: string, taxrate: number, reducedtaxrate: number}, tx?: object): Promise<{id: number, rootCategoryId: number, languageId: number, taxrateId: number, reducedtaxrateId: number, taxfreerateId: number}>`
|
||||||
- [category](API.category.md)
|
- [category](API.category.md)
|
||||||
- `addImage(googleAuthId: number, categoryId: number, image: Buffer, tx?: object): Promise<{id: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string}>`
|
- `addImage(googleAuthId: number, categoryId: number, image: Buffer, tx?: object): Promise<{id: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string, smallThumbW: number, smallThumbH: number}>`
|
||||||
- `createUnderParent(input: {googleAuthId: number, parentId: number, name: string}, tx?: object): Promise<{id: number, parentId: number, sort: number, name: string, slug: string}>`
|
- `createUnderParent(input: {googleAuthId: number, parentId: number, name: string}, tx?: object): Promise<{id: number, parentId: number, sort: number, name: string, slug: string}>`
|
||||||
- `delete(input: {googleAuthId: number, id: number, recursive?: boolean}, tx?: object): Promise<void>`
|
- `delete(input: {googleAuthId: number, id: number, recursive?: boolean}, tx?: object): Promise<void>`
|
||||||
- `deleteImage(googleAuthId: number, categoryId: number, tx?: object): Promise<{id: number, thumbW: null, thumbH: null, thumbHash: null}>`
|
- `deleteImage(googleAuthId: number, categoryId: number, tx?: object): Promise<{id: number, thumbW: null, thumbH: null, thumbHash: null}>`
|
||||||
@@ -86,7 +86,7 @@ The store is exposed as a `LibDashStore` instance (see `src/index.js`). Each met
|
|||||||
- `rename(input: {googleAuthId: number, id: number, name: string}, tx?: object): Promise<{id: number, name: string, slug: string}>`
|
- `rename(input: {googleAuthId: number, id: number, name: string}, tx?: object): Promise<{id: number, name: string, slug: string}>`
|
||||||
- [article](API.article.md)
|
- [article](API.article.md)
|
||||||
- `addChild(googleAuthId: number, parentSku: string, options: {attach?: boolean, attributeValueId?: number, value?: string, name?: string, unitamount?: number, weight?: number, track_stock?: boolean|number}, tx?: object): Promise<object>`
|
- `addChild(googleAuthId: number, parentSku: string, options: {attach?: boolean, attributeValueId?: number, value?: string, name?: string, unitamount?: number, weight?: number, track_stock?: boolean|number}, tx?: object): Promise<object>`
|
||||||
- `addImage(googleAuthId: number, sku: string, image: Buffer, tx?: object): Promise<{picId: number, sort: number, full: {w: number, h: number, size: number}, thumb: {w: number, h: number}, fullHash: string, thumbHash: string}>`
|
- `addImage(googleAuthId: number, sku: string, image: Buffer, tx?: object): Promise<{picId: number, sort: number, full: {w: number, h: number, size: number}, thumb: {w: number, h: number}, smallThumb: {w: number, h: number}, fullHash: string, thumbHash: string}>`
|
||||||
- `attachChild(googleAuthId: number, parentSku: string, options: {sku: string, childSku?: string, attributeValueId?: number, value?: string, reparent?: boolean, unitamount?: number, weight?: number, track_stock?: boolean|number}, tx?: object): Promise<{article: object, children: Array<object>}>`
|
- `attachChild(googleAuthId: number, parentSku: string, options: {sku: string, childSku?: string, attributeValueId?: number, value?: string, reparent?: boolean, unitamount?: number, weight?: number, track_stock?: boolean|number}, tx?: object): Promise<{article: object, children: Array<object>}>`
|
||||||
- `createUnderParent(input: {googleAuthId: number, parentId: number, name: string, desc?: string, seo?: string, track_stock?: boolean|number}, tx?: object): Promise<{id: number, parentId: number, name: string, sku: string, track_stock: boolean}>`
|
- `createUnderParent(input: {googleAuthId: number, parentId: number, name: string, desc?: string, seo?: string, track_stock?: boolean|number}, tx?: object): Promise<{id: number, parentId: number, name: string, sku: string, track_stock: boolean}>`
|
||||||
- `delete(googleAuthId: number, sku: string, optionsOrTx?: object|*, maybeTx?: object): Promise<void>`
|
- `delete(googleAuthId: number, sku: string, optionsOrTx?: object|*, maybeTx?: object): Promise<void>`
|
||||||
@@ -129,10 +129,12 @@ The store is exposed as a `LibDashStore` instance (see `src/index.js`). Each met
|
|||||||
- `list(googleAuthId: number, options?: {frontendOnly?: boolean, maskWriteonly?: boolean}, tx?: object): Promise<Array<{key: string, value: string, frontend: boolean, writeonly: boolean}>>`
|
- `list(googleAuthId: number, options?: {frontendOnly?: boolean, maskWriteonly?: boolean}, tx?: object): Promise<Array<{key: string, value: string, frontend: boolean, writeonly: boolean}>>`
|
||||||
- `set(googleAuthId: number, input: {key: string, value: string, frontend?: boolean, writeonly?: boolean}, tx?: object): Promise<{key: string, value: string, frontend: boolean, writeonly: boolean}>`
|
- `set(googleAuthId: number, input: {key: string, value: string, frontend?: boolean, writeonly?: boolean}, tx?: object): Promise<{key: string, value: string, frontend: boolean, writeonly: boolean}>`
|
||||||
- [brand](API.brand.md)
|
- [brand](API.brand.md)
|
||||||
- `addImage(googleAuthId: number, brandId: number, image: Buffer, tx?: object): Promise<{id: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string, pics: Array<object>}>`
|
- `addImage(googleAuthId: number, brandId: number, image: Buffer, tx?: object): Promise<{id: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string, smallThumbW: number, smallThumbH: number, pics: Array<object>}>`
|
||||||
|
- `create(googleAuthId: number, input: {name: string, gsprpinfo?: string}, tx?: object): Promise<{id: number, name: string, gsprpinfo: string|null, pics: Array<{fullHash: string, thumbW: number, thumbH: number, thumbHash: string}>}>`
|
||||||
- `delete(googleAuthId: number, id: number, tx?: object): Promise<void>`
|
- `delete(googleAuthId: number, id: number, tx?: object): Promise<void>`
|
||||||
- `list(googleAuthId: number, tx?: object): Promise<Array<{id: number, name: string, gsprpinfo: string|null, pics: Array<{id: number, sort: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string}>}>>`
|
- `list(googleAuthId: number, opts?: {offset?: number, limit?: number, includeSmallThumbs?: boolean}, tx?: object): Promise<{brands: Array<{id: number, name: string, gsprpinfo: string|null, pics: Array<{fullHash: string, thumbW: number, thumbH: number, thumbHash: string, smallThumbW?: number|null, smallThumbH?: number|null, smallThumbBinary?: string|null}>}>, total: number, offset: number, limit: number}>`
|
||||||
- `upsert(googleAuthId: number, input: {name: string, gsprpinfo?: string}, tx?: object): Promise<{id: number, name: string, gsprpinfo: string|null, pics: Array<{id: number, sort: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string}>}>`
|
- `update(googleAuthId: number, id: number, input: {name?: string, gsprpinfo?: string}, tx?: object): Promise<{id: number, name: string, gsprpinfo: string|null, touchedArticleCount: number}>`
|
||||||
|
- `upsert(googleAuthId: number, input: {name: string, gsprpinfo?: string}, tx?: object): Promise<{id: number, name: string, gsprpinfo: string|null, pics: Array<{fullHash: string, thumbW: number, thumbH: number, thumbHash: string}>}>`
|
||||||
- [customergroup](API.customergroup.md)
|
- [customergroup](API.customergroup.md)
|
||||||
- `create(googleAuthId: number, input: {name: string}, tx?: object): Promise<{id: number, name: string, sort: number}>`
|
- `create(googleAuthId: number, input: {name: string}, tx?: object): Promise<{id: number, name: string, sort: number}>`
|
||||||
- `delete(googleAuthId: number, id: number, tx?: object): Promise<void>`
|
- `delete(googleAuthId: number, id: number, tx?: object): Promise<void>`
|
||||||
|
|||||||
198
schema-graph.dot
198
schema-graph.dot
File diff suppressed because one or more lines are too long
4618
schema-graph.svg
4618
schema-graph.svg
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 294 KiB After Width: | Height: | Size: 312 KiB |
@@ -28,7 +28,7 @@ async function runTests() {
|
|||||||
assert(existsSync(join(storageDir, 'fullbinary')), 'fullbinary dir should exist');
|
assert(existsSync(join(storageDir, 'fullbinary')), 'fullbinary dir should exist');
|
||||||
assert(existsSync(join(storageDir, 'thumbbinary')), 'thumbbinary dir should exist');
|
assert(existsSync(join(storageDir, 'thumbbinary')), 'thumbbinary dir should exist');
|
||||||
|
|
||||||
// Verify sqlite tables do NOT contain blob columns
|
// Large file and image blobs stay on disk; the 40px small-thumb stays inline in pic.
|
||||||
const fileTableInfo = provider.db.pragma('table_info("file")');
|
const fileTableInfo = provider.db.pragma('table_info("file")');
|
||||||
const fileColNames = fileTableInfo.map((c) => c.name);
|
const fileColNames = fileTableInfo.map((c) => c.name);
|
||||||
console.log('file table columns:', fileColNames);
|
console.log('file table columns:', fileColNames);
|
||||||
@@ -40,6 +40,9 @@ async function runTests() {
|
|||||||
console.log('pic table columns:', picColNames);
|
console.log('pic table columns:', picColNames);
|
||||||
assert(!picColNames.includes('fullbinary'), 'pic table should NOT have fullbinary column');
|
assert(!picColNames.includes('fullbinary'), 'pic table should NOT have fullbinary column');
|
||||||
assert(!picColNames.includes('thumbbinary'), 'pic table should NOT have thumbbinary column');
|
assert(!picColNames.includes('thumbbinary'), 'pic table should NOT have thumbbinary column');
|
||||||
|
assert(picColNames.includes('smallthumbw'), 'pic table should have smallthumbw column');
|
||||||
|
assert(picColNames.includes('smallthumbh'), 'pic table should have smallthumbh column');
|
||||||
|
assert(picColNames.includes('smallthumbbinary'), 'pic table should have smallthumbbinary column');
|
||||||
|
|
||||||
// Setup base data: google_auth, company, unit, article, manifest
|
// Setup base data: google_auth, company, unit, article, manifest
|
||||||
const googleAuthId = await store.google_auth.add('test@example.com');
|
const googleAuthId = await store.google_auth.add('test@example.com');
|
||||||
@@ -199,6 +202,42 @@ async function runTests() {
|
|||||||
|
|
||||||
const picResult = await store.article.addImage(googleAuthId, article.sku, sampleImage);
|
const picResult = await store.article.addImage(googleAuthId, article.sku, sampleImage);
|
||||||
const fullHash = picResult.fullHash;
|
const fullHash = picResult.fullHash;
|
||||||
|
assert.equal(picResult.smallThumb.w, 40);
|
||||||
|
assert.equal(picResult.smallThumb.h, 27);
|
||||||
|
const smallThumbRow = provider.db.prepare(
|
||||||
|
'SELECT smallthumbw, smallthumbh, smallthumbbinary FROM pic WHERE hash = ?',
|
||||||
|
).get(fullHash);
|
||||||
|
assert.equal(smallThumbRow.smallthumbw, 40);
|
||||||
|
assert.equal(smallThumbRow.smallthumbh, 27);
|
||||||
|
assert(Buffer.isBuffer(smallThumbRow.smallthumbbinary), 'Small thumb AVIF must be stored in the pic row');
|
||||||
|
const smallThumbMetadata = await sharp(smallThumbRow.smallthumbbinary).metadata();
|
||||||
|
assert.equal(smallThumbMetadata.format, 'heif');
|
||||||
|
assert.equal(smallThumbMetadata.width, 40);
|
||||||
|
assert.equal(smallThumbMetadata.height, 27);
|
||||||
|
|
||||||
|
const brand = await store.brand.create(googleAuthId, { name: 'Small Thumb Test Brand' });
|
||||||
|
await store.brand.addImage(googleAuthId, brand.id, sampleImage);
|
||||||
|
const listedBrands = await store.brand.list(googleAuthId, { offset: 0, limit: 100 });
|
||||||
|
const listedBrand = listedBrands.brands.find((item) => item.id === brand.id);
|
||||||
|
assert(listedBrand, 'Brand list should include the created brand');
|
||||||
|
assert.equal(listedBrand.pics.length, 1);
|
||||||
|
assert(!('smallThumbW' in listedBrand.pics[0]), 'Small-thumb fields should be omitted by default');
|
||||||
|
|
||||||
|
const listedBrandsWithSmallThumbs = await store.brand.list(googleAuthId, {
|
||||||
|
offset: 0,
|
||||||
|
limit: 100,
|
||||||
|
includeSmallThumbs: true,
|
||||||
|
});
|
||||||
|
const listedBrandWithSmallThumbs = listedBrandsWithSmallThumbs.brands.find((item) => item.id === brand.id);
|
||||||
|
assert(listedBrandWithSmallThumbs, 'Brand list with thumbnails should include the created brand');
|
||||||
|
assert.equal(listedBrandWithSmallThumbs.pics.length, 1);
|
||||||
|
const listedPic = listedBrandWithSmallThumbs.pics[0];
|
||||||
|
assert.equal(listedPic.smallThumbW, 40);
|
||||||
|
assert.equal(listedPic.smallThumbH, 27);
|
||||||
|
assert.equal(typeof listedPic.smallThumbBinary, 'string');
|
||||||
|
const listedSmallThumb = Buffer.from(listedPic.smallThumbBinary, 'base64');
|
||||||
|
assert.deepEqual(listedSmallThumb, smallThumbRow.smallthumbbinary);
|
||||||
|
|
||||||
console.log('Article pic added with hash:', fullHash);
|
console.log('Article pic added with hash:', fullHash);
|
||||||
|
|
||||||
const fullPath = join(storageDir, 'fullbinary', fullHash + '.avif');
|
const fullPath = join(storageDir, 'fullbinary', fullHash + '.avif');
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ import companysettingList from './store/companysetting/list.js';
|
|||||||
import companysettingGet from './store/companysetting/get.js';
|
import companysettingGet from './store/companysetting/get.js';
|
||||||
import companysettingSet from './store/companysetting/set.js';
|
import companysettingSet from './store/companysetting/set.js';
|
||||||
import brandList from './store/brand/list.js';
|
import brandList from './store/brand/list.js';
|
||||||
|
import brandCreate from './store/brand/create.js';
|
||||||
|
import brandUpdate from './store/brand/update.js';
|
||||||
import brandUpsert from './store/brand/upsert.js';
|
import brandUpsert from './store/brand/upsert.js';
|
||||||
import brandDelete from './store/brand/delete.js';
|
import brandDelete from './store/brand/delete.js';
|
||||||
import brandAddImage from './store/brand/addImage.js';
|
import brandAddImage from './store/brand/addImage.js';
|
||||||
@@ -326,6 +328,8 @@ export default class LibDashStore {
|
|||||||
|
|
||||||
this.brand = {
|
this.brand = {
|
||||||
list: brandList(provider),
|
list: brandList(provider),
|
||||||
|
create: brandCreate(provider),
|
||||||
|
update: brandUpdate(provider),
|
||||||
upsert: brandUpsert(provider),
|
upsert: brandUpsert(provider),
|
||||||
delete: brandDelete(provider),
|
delete: brandDelete(provider),
|
||||||
addImage: brandAddImage(provider),
|
addImage: brandAddImage(provider),
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ SELECT
|
|||||||
b.gsprpinfo,
|
b.gsprpinfo,
|
||||||
(
|
(
|
||||||
SELECT
|
SELECT
|
||||||
bp.id,
|
|
||||||
bp.sort,
|
|
||||||
p.hash AS fullHash,
|
p.hash AS fullHash,
|
||||||
p.thumbw AS thumbW,
|
p.thumbw AS thumbW,
|
||||||
p.thumbh AS thumbH,
|
p.thumbh AS thumbH,
|
||||||
@@ -22,6 +20,61 @@ WHERE b.company_id = @companyId
|
|||||||
ORDER BY b.name
|
ORDER BY b.name
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const COUNT_BY_COMPANY = `
|
||||||
|
SELECT COUNT(*) AS total
|
||||||
|
FROM brand b
|
||||||
|
WHERE b.company_id = @companyId
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const LIST_BY_COMPANY_PAGED = `
|
||||||
|
SELECT
|
||||||
|
b.id,
|
||||||
|
b.name,
|
||||||
|
b.gsprpinfo,
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
p.hash AS fullHash,
|
||||||
|
p.thumbw AS thumbW,
|
||||||
|
p.thumbh AS thumbH,
|
||||||
|
p.thumbhash AS thumbHash
|
||||||
|
FROM brandpic bp
|
||||||
|
INNER JOIN pic p ON p.id = bp.pic_id
|
||||||
|
WHERE bp.brand_id = b.id
|
||||||
|
ORDER BY bp.sort ASC, bp.id ASC
|
||||||
|
FOR JSON PATH
|
||||||
|
) AS picsJson
|
||||||
|
FROM brand b
|
||||||
|
WHERE b.company_id = @companyId
|
||||||
|
ORDER BY b.name
|
||||||
|
OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const LIST_BY_COMPANY_PAGED_WITH_SMALL_THUMBS = `
|
||||||
|
SELECT
|
||||||
|
b.id,
|
||||||
|
b.name,
|
||||||
|
b.gsprpinfo,
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
p.hash AS fullHash,
|
||||||
|
p.thumbw AS thumbW,
|
||||||
|
p.thumbh AS thumbH,
|
||||||
|
p.thumbhash AS thumbHash,
|
||||||
|
p.smallthumbw AS smallThumbW,
|
||||||
|
p.smallthumbh AS smallThumbH,
|
||||||
|
p.smallthumbbinary AS smallThumbBinary
|
||||||
|
FROM brandpic bp
|
||||||
|
INNER JOIN pic p ON p.id = bp.pic_id
|
||||||
|
WHERE bp.brand_id = b.id
|
||||||
|
ORDER BY bp.sort ASC, bp.id ASC
|
||||||
|
FOR JSON PATH
|
||||||
|
) AS picsJson
|
||||||
|
FROM brand b
|
||||||
|
WHERE b.company_id = @companyId
|
||||||
|
ORDER BY b.name
|
||||||
|
OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY
|
||||||
|
`;
|
||||||
|
|
||||||
export const GET_BY_COMPANY_AND_NAME = `
|
export const GET_BY_COMPANY_AND_NAME = `
|
||||||
SELECT
|
SELECT
|
||||||
b.id,
|
b.id,
|
||||||
@@ -29,8 +82,6 @@ SELECT
|
|||||||
b.gsprpinfo,
|
b.gsprpinfo,
|
||||||
(
|
(
|
||||||
SELECT
|
SELECT
|
||||||
bp.id,
|
|
||||||
bp.sort,
|
|
||||||
p.hash AS fullHash,
|
p.hash AS fullHash,
|
||||||
p.thumbw AS thumbW,
|
p.thumbw AS thumbW,
|
||||||
p.thumbh AS thumbH,
|
p.thumbh AS thumbH,
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
export const CREATE = `
|
export const CREATE = `
|
||||||
INSERT INTO pic (
|
INSERT INTO pic (
|
||||||
w, h, size, hash, thumbw, thumbh, thumbhash, source, fullbinary, thumbbinary
|
w, h, size, hash, thumbw, thumbh, thumbhash,
|
||||||
|
smallthumbw, smallthumbh, smallthumbbinary,
|
||||||
|
source, fullbinary, thumbbinary
|
||||||
)
|
)
|
||||||
OUTPUT INSERTED.id
|
OUTPUT INSERTED.id
|
||||||
VALUES (
|
VALUES (
|
||||||
@w, @h, @size, @hash, @thumbw, @thumbh, @thumbhash, @source, @fullbinary, @thumbbinary
|
@w, @h, @size, @hash, @thumbw, @thumbh, @thumbhash,
|
||||||
|
@smallthumbw, @smallthumbh, @smallthumbbinary,
|
||||||
|
@source, @fullbinary, @thumbbinary
|
||||||
)
|
)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@@ -95,9 +95,12 @@ BEGIN
|
|||||||
thumbw INT NOT NULL,
|
thumbw INT NOT NULL,
|
||||||
thumbh INT NOT NULL,
|
thumbh INT NOT NULL,
|
||||||
thumbhash NVARCHAR(64) NOT NULL,
|
thumbhash NVARCHAR(64) NOT NULL,
|
||||||
|
smallthumbw INT NOT NULL,
|
||||||
|
smallthumbh INT NOT NULL,
|
||||||
source NVARCHAR(MAX) NOT NULL,
|
source NVARCHAR(MAX) NOT NULL,
|
||||||
fullbinary VARBINARY(MAX) NOT NULL,
|
fullbinary VARBINARY(MAX) NOT NULL,
|
||||||
thumbbinary VARBINARY(MAX) NOT NULL,
|
thumbbinary VARBINARY(MAX) NOT NULL,
|
||||||
|
smallthumbbinary VARBINARY(MAX) NOT NULL,
|
||||||
CONSTRAINT UQ_pic_hash UNIQUE (hash)
|
CONSTRAINT UQ_pic_hash UNIQUE (hash)
|
||||||
);
|
);
|
||||||
END
|
END
|
||||||
@@ -1220,4 +1223,3 @@ export const SCHEMA_SCRIPTS = [
|
|||||||
INIT_SHIPPING,
|
INIT_SHIPPING,
|
||||||
INIT_PACKAGE,
|
INIT_PACKAGE,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { translateQueries } from './translate.js';
|
|||||||
const queries = translateQueries(source, 'brand');
|
const queries = translateQueries(source, 'brand');
|
||||||
export const {
|
export const {
|
||||||
CREATE, DELETE_BY_COMPANY_AND_ID, UPDATE_BY_ID, GET_BY_ID_AND_COMPANY,
|
CREATE, DELETE_BY_COMPANY_AND_ID, UPDATE_BY_ID, GET_BY_ID_AND_COMPANY,
|
||||||
|
COUNT_BY_COMPANY,
|
||||||
} = queries;
|
} = queries;
|
||||||
|
|
||||||
export const LIST_BY_COMPANY = `
|
export const LIST_BY_COMPANY = `
|
||||||
@@ -13,15 +14,13 @@ SELECT
|
|||||||
b.gsprpinfo,
|
b.gsprpinfo,
|
||||||
(
|
(
|
||||||
SELECT COALESCE(json_group_array(json_object(
|
SELECT COALESCE(json_group_array(json_object(
|
||||||
'id', id,
|
|
||||||
'sort', sort,
|
|
||||||
'fullHash', hash,
|
'fullHash', hash,
|
||||||
'thumbW', thumbw,
|
'thumbW', thumbw,
|
||||||
'thumbH', thumbh,
|
'thumbH', thumbh,
|
||||||
'thumbHash', thumbhash
|
'thumbHash', thumbhash
|
||||||
)), '[]')
|
)), '[]')
|
||||||
FROM (
|
FROM (
|
||||||
SELECT bp.id, bp.sort, p.hash, p.thumbw, p.thumbh, p.thumbhash
|
SELECT p.hash, p.thumbw, p.thumbh, p.thumbhash
|
||||||
FROM brandpic bp
|
FROM brandpic bp
|
||||||
INNER JOIN pic p ON p.id = bp.pic_id
|
INNER JOIN pic p ON p.id = bp.pic_id
|
||||||
WHERE bp.brand_id = b.id
|
WHERE bp.brand_id = b.id
|
||||||
@@ -33,6 +32,65 @@ WHERE b.company_id = @companyId
|
|||||||
ORDER BY b.name
|
ORDER BY b.name
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const LIST_BY_COMPANY_PAGED = `
|
||||||
|
SELECT
|
||||||
|
b.id,
|
||||||
|
b.name,
|
||||||
|
b.gsprpinfo,
|
||||||
|
(
|
||||||
|
SELECT COALESCE(json_group_array(json_object(
|
||||||
|
'fullHash', hash,
|
||||||
|
'thumbW', thumbw,
|
||||||
|
'thumbH', thumbh,
|
||||||
|
'thumbHash', thumbhash
|
||||||
|
)), '[]')
|
||||||
|
FROM (
|
||||||
|
SELECT p.hash, p.thumbw, p.thumbh, p.thumbhash
|
||||||
|
FROM brandpic bp
|
||||||
|
INNER JOIN pic p ON p.id = bp.pic_id
|
||||||
|
WHERE bp.brand_id = b.id
|
||||||
|
ORDER BY bp.sort, bp.id
|
||||||
|
)
|
||||||
|
) AS picsJson
|
||||||
|
FROM brand b
|
||||||
|
WHERE b.company_id = @companyId
|
||||||
|
ORDER BY b.name
|
||||||
|
LIMIT @limit OFFSET @offset
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const LIST_BY_COMPANY_PAGED_WITH_SMALL_THUMBS = `
|
||||||
|
SELECT
|
||||||
|
b.id,
|
||||||
|
b.name,
|
||||||
|
b.gsprpinfo,
|
||||||
|
(
|
||||||
|
SELECT COALESCE(json_group_array(json_object(
|
||||||
|
'fullHash', hash,
|
||||||
|
'thumbW', thumbw,
|
||||||
|
'thumbH', thumbh,
|
||||||
|
'thumbHash', thumbhash,
|
||||||
|
'smallThumbW', smallthumbw,
|
||||||
|
'smallThumbH', smallthumbh,
|
||||||
|
'smallThumbBinaryHex', CASE
|
||||||
|
WHEN smallthumbbinary IS NULL THEN NULL
|
||||||
|
ELSE hex(smallthumbbinary)
|
||||||
|
END
|
||||||
|
)), '[]')
|
||||||
|
FROM (
|
||||||
|
SELECT p.hash, p.thumbw, p.thumbh, p.thumbhash,
|
||||||
|
p.smallthumbw, p.smallthumbh, p.smallthumbbinary
|
||||||
|
FROM brandpic bp
|
||||||
|
INNER JOIN pic p ON p.id = bp.pic_id
|
||||||
|
WHERE bp.brand_id = b.id
|
||||||
|
ORDER BY bp.sort, bp.id
|
||||||
|
)
|
||||||
|
) AS picsJson
|
||||||
|
FROM brand b
|
||||||
|
WHERE b.company_id = @companyId
|
||||||
|
ORDER BY b.name
|
||||||
|
LIMIT @limit OFFSET @offset
|
||||||
|
`;
|
||||||
|
|
||||||
export const GET_BY_COMPANY_AND_NAME = `
|
export const GET_BY_COMPANY_AND_NAME = `
|
||||||
SELECT
|
SELECT
|
||||||
b.id,
|
b.id,
|
||||||
@@ -40,15 +98,13 @@ SELECT
|
|||||||
b.gsprpinfo,
|
b.gsprpinfo,
|
||||||
(
|
(
|
||||||
SELECT COALESCE(json_group_array(json_object(
|
SELECT COALESCE(json_group_array(json_object(
|
||||||
'id', id,
|
|
||||||
'sort', sort,
|
|
||||||
'fullHash', hash,
|
'fullHash', hash,
|
||||||
'thumbW', thumbw,
|
'thumbW', thumbw,
|
||||||
'thumbH', thumbh,
|
'thumbH', thumbh,
|
||||||
'thumbHash', thumbhash
|
'thumbHash', thumbhash
|
||||||
)), '[]')
|
)), '[]')
|
||||||
FROM (
|
FROM (
|
||||||
SELECT bp.id, bp.sort, p.hash, p.thumbw, p.thumbh, p.thumbhash
|
SELECT p.hash, p.thumbw, p.thumbh, p.thumbhash
|
||||||
FROM brandpic bp
|
FROM brandpic bp
|
||||||
INNER JOIN pic p ON p.id = bp.pic_id
|
INNER JOIN pic p ON p.id = bp.pic_id
|
||||||
WHERE bp.brand_id = b.id
|
WHERE bp.brand_id = b.id
|
||||||
|
|||||||
@@ -8,10 +8,12 @@ export const {
|
|||||||
|
|
||||||
export const CREATE = `
|
export const CREATE = `
|
||||||
INSERT INTO pic (
|
INSERT INTO pic (
|
||||||
w, h, size, hash, thumbw, thumbh, thumbhash, source
|
w, h, size, hash, thumbw, thumbh, thumbhash,
|
||||||
|
smallthumbw, smallthumbh, smallthumbbinary, source
|
||||||
)
|
)
|
||||||
VALUES (
|
VALUES (
|
||||||
@w, @h, @size, @hash, @thumbw, @thumbh, @thumbhash, @source
|
@w, @h, @size, @hash, @thumbw, @thumbh, @thumbhash,
|
||||||
|
@smallthumbw, @smallthumbh, @smallthumbbinary, @source
|
||||||
)
|
)
|
||||||
RETURNING id
|
RETURNING id
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ INSERT OR IGNORE INTO meta ("key", value) VALUES ('version', '1');
|
|||||||
|
|
||||||
export const INIT_LANGUAGE = `
|
export const INIT_LANGUAGE = `
|
||||||
CREATE TABLE IF NOT EXISTS language (
|
CREATE TABLE IF NOT EXISTS language (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
iso639 TEXT NOT NULL COLLATE NOCASE UNIQUE
|
iso639 TEXT NOT NULL COLLATE NOCASE UNIQUE
|
||||||
);
|
);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const INIT_TAX = `
|
export const INIT_TAX = `
|
||||||
CREATE TABLE IF NOT EXISTS tax (
|
CREATE TABLE IF NOT EXISTS tax (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
rate NUMERIC NOT NULL UNIQUE
|
rate NUMERIC NOT NULL UNIQUE
|
||||||
);
|
);
|
||||||
INSERT OR IGNORE INTO tax (rate) VALUES (0), (7), (19);
|
INSERT OR IGNORE INTO tax (rate) VALUES (0), (7), (19);
|
||||||
@@ -25,7 +25,7 @@ INSERT OR IGNORE INTO tax (rate) VALUES (0), (7), (19);
|
|||||||
|
|
||||||
export const INIT_CATEGORY = `
|
export const INIT_CATEGORY = `
|
||||||
CREATE TABLE IF NOT EXISTS category (
|
CREATE TABLE IF NOT EXISTS category (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
parent_id INTEGER,
|
parent_id INTEGER,
|
||||||
sort INTEGER NOT NULL DEFAULT 0,
|
sort INTEGER NOT NULL DEFAULT 0,
|
||||||
updated_at TEXT NOT NULL DEFAULT (${UTC_NOW}),
|
updated_at TEXT NOT NULL DEFAULT (${UTC_NOW}),
|
||||||
@@ -35,7 +35,7 @@ CREATE TABLE IF NOT EXISTS category (
|
|||||||
|
|
||||||
export const INIT_PIC = `
|
export const INIT_PIC = `
|
||||||
CREATE TABLE IF NOT EXISTS pic (
|
CREATE TABLE IF NOT EXISTS pic (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
w INTEGER NOT NULL,
|
w INTEGER NOT NULL,
|
||||||
h INTEGER NOT NULL,
|
h INTEGER NOT NULL,
|
||||||
size INTEGER NOT NULL,
|
size INTEGER NOT NULL,
|
||||||
@@ -43,13 +43,16 @@ CREATE TABLE IF NOT EXISTS pic (
|
|||||||
thumbw INTEGER NOT NULL,
|
thumbw INTEGER NOT NULL,
|
||||||
thumbh INTEGER NOT NULL,
|
thumbh INTEGER NOT NULL,
|
||||||
thumbhash TEXT NOT NULL,
|
thumbhash TEXT NOT NULL,
|
||||||
|
smallthumbw INTEGER NOT NULL,
|
||||||
|
smallthumbh INTEGER NOT NULL,
|
||||||
|
smallthumbbinary BLOB NOT NULL,
|
||||||
source TEXT NOT NULL
|
source TEXT NOT NULL
|
||||||
);
|
);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const INIT_COMPANY = `
|
export const INIT_COMPANY = `
|
||||||
CREATE TABLE IF NOT EXISTS company (
|
CREATE TABLE IF NOT EXISTS company (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
name TEXT NOT NULL COLLATE NOCASE UNIQUE,
|
name TEXT NOT NULL COLLATE NOCASE UNIQUE,
|
||||||
root_category_id INTEGER,
|
root_category_id INTEGER,
|
||||||
default_language_id INTEGER,
|
default_language_id INTEGER,
|
||||||
@@ -68,7 +71,7 @@ CREATE TABLE IF NOT EXISTS company (
|
|||||||
|
|
||||||
export const INIT_GOOGLE_AUTH = `
|
export const INIT_GOOGLE_AUTH = `
|
||||||
CREATE TABLE IF NOT EXISTS google_auth (
|
CREATE TABLE IF NOT EXISTS google_auth (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
email TEXT NOT NULL COLLATE NOCASE UNIQUE,
|
email TEXT NOT NULL COLLATE NOCASE UNIQUE,
|
||||||
picture TEXT,
|
picture TEXT,
|
||||||
picturebinary BLOB,
|
picturebinary BLOB,
|
||||||
@@ -83,7 +86,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS UQ_google_auth_sub
|
|||||||
|
|
||||||
export const INIT_CUSTOMERGROUP = `
|
export const INIT_CUSTOMERGROUP = `
|
||||||
CREATE TABLE IF NOT EXISTS customergroup (
|
CREATE TABLE IF NOT EXISTS customergroup (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
sort INTEGER NOT NULL DEFAULT 0,
|
sort INTEGER NOT NULL DEFAULT 0,
|
||||||
company_id INTEGER,
|
company_id INTEGER,
|
||||||
@@ -97,7 +100,7 @@ export const INIT_COMPANY_POS_CUSTOMERGROUP_FK = '';
|
|||||||
|
|
||||||
export const INIT_ENTITY = `
|
export const INIT_ENTITY = `
|
||||||
CREATE TABLE IF NOT EXISTS entity (
|
CREATE TABLE IF NOT EXISTS entity (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
customergroup_id INTEGER NOT NULL,
|
customergroup_id INTEGER NOT NULL,
|
||||||
company_id INTEGER,
|
company_id INTEGER,
|
||||||
first_name TEXT,
|
first_name TEXT,
|
||||||
@@ -140,7 +143,7 @@ END;
|
|||||||
|
|
||||||
export const INIT_ENTITYADDRESS = `
|
export const INIT_ENTITYADDRESS = `
|
||||||
CREATE TABLE IF NOT EXISTS entityaddress (
|
CREATE TABLE IF NOT EXISTS entityaddress (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
entity_id INTEGER NOT NULL,
|
entity_id INTEGER NOT NULL,
|
||||||
first_name TEXT,
|
first_name TEXT,
|
||||||
name TEXT,
|
name TEXT,
|
||||||
@@ -157,7 +160,7 @@ CREATE TABLE IF NOT EXISTS entityaddress (
|
|||||||
|
|
||||||
export const INIT_ENTITYCONTACT = `
|
export const INIT_ENTITYCONTACT = `
|
||||||
CREATE TABLE IF NOT EXISTS entitycontact (
|
CREATE TABLE IF NOT EXISTS entitycontact (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
entity_id INTEGER NOT NULL,
|
entity_id INTEGER NOT NULL,
|
||||||
contacttype TEXT NOT NULL,
|
contacttype TEXT NOT NULL,
|
||||||
contact TEXT NOT NULL,
|
contact TEXT NOT NULL,
|
||||||
@@ -168,7 +171,7 @@ CREATE TABLE IF NOT EXISTS entitycontact (
|
|||||||
|
|
||||||
export const INIT_UNIT = `
|
export const INIT_UNIT = `
|
||||||
CREATE TABLE IF NOT EXISTS unit (
|
CREATE TABLE IF NOT EXISTS unit (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
si TEXT NOT NULL,
|
si TEXT NOT NULL,
|
||||||
basesi TEXT NOT NULL,
|
basesi TEXT NOT NULL,
|
||||||
@@ -180,7 +183,7 @@ CREATE TABLE IF NOT EXISTS unit (
|
|||||||
|
|
||||||
export const INIT_UNITTEXT = `
|
export const INIT_UNITTEXT = `
|
||||||
CREATE TABLE IF NOT EXISTS unittext (
|
CREATE TABLE IF NOT EXISTS unittext (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
unit_id INTEGER NOT NULL,
|
unit_id INTEGER NOT NULL,
|
||||||
language_id INTEGER NOT NULL,
|
language_id INTEGER NOT NULL,
|
||||||
symbol TEXT NOT NULL,
|
symbol TEXT NOT NULL,
|
||||||
@@ -192,16 +195,16 @@ CREATE TABLE IF NOT EXISTS unittext (
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const INIT_OPTIONSLIST = `
|
export const INIT_OPTIONSLIST = `
|
||||||
CREATE TABLE IF NOT EXISTS optionslist (id INTEGER PRIMARY KEY);
|
CREATE TABLE IF NOT EXISTS optionslist (id INTEGER PRIMARY KEY AUTOINCREMENT);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const INIT_ARTICLELIST = `
|
export const INIT_ARTICLELIST = `
|
||||||
CREATE TABLE IF NOT EXISTS articlelist (id INTEGER PRIMARY KEY);
|
CREATE TABLE IF NOT EXISTS articlelist (id INTEGER PRIMARY KEY AUTOINCREMENT);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const INIT_BRAND = `
|
export const INIT_BRAND = `
|
||||||
CREATE TABLE IF NOT EXISTS brand (
|
CREATE TABLE IF NOT EXISTS brand (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
name TEXT NOT NULL COLLATE NOCASE,
|
name TEXT NOT NULL COLLATE NOCASE,
|
||||||
gsprpinfo TEXT,
|
gsprpinfo TEXT,
|
||||||
@@ -212,7 +215,7 @@ CREATE TABLE IF NOT EXISTS brand (
|
|||||||
|
|
||||||
export const INIT_ARTICLE = `
|
export const INIT_ARTICLE = `
|
||||||
CREATE TABLE IF NOT EXISTS article (
|
CREATE TABLE IF NOT EXISTS article (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
sku TEXT COLLATE NOCASE,
|
sku TEXT COLLATE NOCASE,
|
||||||
unit_id INTEGER NOT NULL,
|
unit_id INTEGER NOT NULL,
|
||||||
@@ -244,7 +247,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS UQ_article_parentarticle_parentsort
|
|||||||
|
|
||||||
export const INIT_ARTICLEEAN = `
|
export const INIT_ARTICLEEAN = `
|
||||||
CREATE TABLE IF NOT EXISTS articleean (
|
CREATE TABLE IF NOT EXISTS articleean (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
article_id INTEGER NOT NULL,
|
article_id INTEGER NOT NULL,
|
||||||
ean TEXT NOT NULL,
|
ean TEXT NOT NULL,
|
||||||
FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE
|
FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE
|
||||||
@@ -257,7 +260,7 @@ CREATE INDEX IF NOT EXISTS IX_articleean_ean
|
|||||||
|
|
||||||
export const INIT_ARTICLEPIC = `
|
export const INIT_ARTICLEPIC = `
|
||||||
CREATE TABLE IF NOT EXISTS articlepic (
|
CREATE TABLE IF NOT EXISTS articlepic (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
article_id INTEGER NOT NULL,
|
article_id INTEGER NOT NULL,
|
||||||
pic_id INTEGER NOT NULL,
|
pic_id INTEGER NOT NULL,
|
||||||
sort INTEGER NOT NULL DEFAULT 0,
|
sort INTEGER NOT NULL DEFAULT 0,
|
||||||
@@ -270,7 +273,7 @@ CREATE TABLE IF NOT EXISTS articlepic (
|
|||||||
|
|
||||||
export const INIT_BRANDPIC = `
|
export const INIT_BRANDPIC = `
|
||||||
CREATE TABLE IF NOT EXISTS brandpic (
|
CREATE TABLE IF NOT EXISTS brandpic (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
brand_id INTEGER NOT NULL,
|
brand_id INTEGER NOT NULL,
|
||||||
pic_id INTEGER NOT NULL,
|
pic_id INTEGER NOT NULL,
|
||||||
sort INTEGER NOT NULL DEFAULT 0,
|
sort INTEGER NOT NULL DEFAULT 0,
|
||||||
@@ -283,7 +286,7 @@ CREATE TABLE IF NOT EXISTS brandpic (
|
|||||||
|
|
||||||
export const INIT_ARTICLELISTARTICLE = `
|
export const INIT_ARTICLELISTARTICLE = `
|
||||||
CREATE TABLE IF NOT EXISTS articlelistarticle (
|
CREATE TABLE IF NOT EXISTS articlelistarticle (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
articlelist_id INTEGER NOT NULL,
|
articlelist_id INTEGER NOT NULL,
|
||||||
article_id INTEGER NOT NULL,
|
article_id INTEGER NOT NULL,
|
||||||
count INTEGER NOT NULL DEFAULT 1,
|
count INTEGER NOT NULL DEFAULT 1,
|
||||||
@@ -297,7 +300,7 @@ CREATE TABLE IF NOT EXISTS articlelistarticle (
|
|||||||
|
|
||||||
export const INIT_OPTIONSLISTARTICLE = `
|
export const INIT_OPTIONSLISTARTICLE = `
|
||||||
CREATE TABLE IF NOT EXISTS optionslistarticle (
|
CREATE TABLE IF NOT EXISTS optionslistarticle (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
optionslist_id INTEGER NOT NULL,
|
optionslist_id INTEGER NOT NULL,
|
||||||
article_id INTEGER NOT NULL,
|
article_id INTEGER NOT NULL,
|
||||||
count INTEGER NOT NULL DEFAULT 1,
|
count INTEGER NOT NULL DEFAULT 1,
|
||||||
@@ -312,7 +315,7 @@ CREATE TABLE IF NOT EXISTS optionslistarticle (
|
|||||||
|
|
||||||
export const INIT_CATEGORYARTICLE = `
|
export const INIT_CATEGORYARTICLE = `
|
||||||
CREATE TABLE IF NOT EXISTS categoryarticle (
|
CREATE TABLE IF NOT EXISTS categoryarticle (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
category_id INTEGER NOT NULL,
|
category_id INTEGER NOT NULL,
|
||||||
article_id INTEGER NOT NULL,
|
article_id INTEGER NOT NULL,
|
||||||
UNIQUE (category_id, article_id),
|
UNIQUE (category_id, article_id),
|
||||||
@@ -325,7 +328,7 @@ CREATE INDEX IF NOT EXISTS IX_categoryarticle_article_category
|
|||||||
|
|
||||||
export const INIT_CATEGORYPIC = `
|
export const INIT_CATEGORYPIC = `
|
||||||
CREATE TABLE IF NOT EXISTS categorypic (
|
CREATE TABLE IF NOT EXISTS categorypic (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
category_id INTEGER NOT NULL,
|
category_id INTEGER NOT NULL,
|
||||||
pic_id INTEGER NOT NULL,
|
pic_id INTEGER NOT NULL,
|
||||||
sort INTEGER NOT NULL DEFAULT 0,
|
sort INTEGER NOT NULL DEFAULT 0,
|
||||||
@@ -338,7 +341,7 @@ CREATE TABLE IF NOT EXISTS categorypic (
|
|||||||
|
|
||||||
export const INIT_CATEGORYTEXT = `
|
export const INIT_CATEGORYTEXT = `
|
||||||
CREATE TABLE IF NOT EXISTS categorytext (
|
CREATE TABLE IF NOT EXISTS categorytext (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
category_id INTEGER NOT NULL,
|
category_id INTEGER NOT NULL,
|
||||||
language_id INTEGER NOT NULL,
|
language_id INTEGER NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
@@ -353,7 +356,7 @@ CREATE TABLE IF NOT EXISTS categorytext (
|
|||||||
|
|
||||||
export const INIT_ARTICLENAME = `
|
export const INIT_ARTICLENAME = `
|
||||||
CREATE TABLE IF NOT EXISTS articletext (
|
CREATE TABLE IF NOT EXISTS articletext (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
article_id INTEGER NOT NULL,
|
article_id INTEGER NOT NULL,
|
||||||
language_id INTEGER NOT NULL,
|
language_id INTEGER NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
@@ -368,7 +371,7 @@ CREATE TABLE IF NOT EXISTS articletext (
|
|||||||
|
|
||||||
export const INIT_PRICE = `
|
export const INIT_PRICE = `
|
||||||
CREATE TABLE IF NOT EXISTS price (
|
CREATE TABLE IF NOT EXISTS price (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
tax_id INTEGER NOT NULL,
|
tax_id INTEGER NOT NULL,
|
||||||
article_id INTEGER NOT NULL,
|
article_id INTEGER NOT NULL,
|
||||||
minmultiplier NUMERIC NOT NULL DEFAULT 1,
|
minmultiplier NUMERIC NOT NULL DEFAULT 1,
|
||||||
@@ -384,7 +387,7 @@ CREATE INDEX IF NOT EXISTS IX_price_article_cg_mult
|
|||||||
|
|
||||||
export const INIT_ARTICLE_SUPPLIER = `
|
export const INIT_ARTICLE_SUPPLIER = `
|
||||||
CREATE TABLE IF NOT EXISTS articlesupplier (
|
CREATE TABLE IF NOT EXISTS articlesupplier (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
article_id INTEGER NOT NULL,
|
article_id INTEGER NOT NULL,
|
||||||
entity_id INTEGER NOT NULL,
|
entity_id INTEGER NOT NULL,
|
||||||
net REAL,
|
net REAL,
|
||||||
@@ -405,7 +408,7 @@ CREATE INDEX IF NOT EXISTS IX_articlesupplier_article_entity
|
|||||||
|
|
||||||
export const INIT_MANIFEST = `
|
export const INIT_MANIFEST = `
|
||||||
CREATE TABLE IF NOT EXISTS manifest (
|
CREATE TABLE IF NOT EXISTS manifest (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
"number" TEXT NOT NULL,
|
"number" TEXT NOT NULL,
|
||||||
"type" TEXT NOT NULL,
|
"type" TEXT NOT NULL,
|
||||||
@@ -420,7 +423,7 @@ CREATE TABLE IF NOT EXISTS manifest (
|
|||||||
|
|
||||||
export const INIT_MANIFESTARTICLE = `
|
export const INIT_MANIFESTARTICLE = `
|
||||||
CREATE TABLE IF NOT EXISTS manifestarticle (
|
CREATE TABLE IF NOT EXISTS manifestarticle (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
manifest_id INTEGER NOT NULL,
|
manifest_id INTEGER NOT NULL,
|
||||||
sku TEXT,
|
sku TEXT,
|
||||||
name TEXT,
|
name TEXT,
|
||||||
@@ -436,7 +439,7 @@ CREATE TABLE IF NOT EXISTS manifestarticle (
|
|||||||
|
|
||||||
export const INIT_WAREHOUSE = `
|
export const INIT_WAREHOUSE = `
|
||||||
CREATE TABLE IF NOT EXISTS warehouse (
|
CREATE TABLE IF NOT EXISTS warehouse (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
name TEXT NOT NULL COLLATE NOCASE,
|
name TEXT NOT NULL COLLATE NOCASE,
|
||||||
sort INTEGER NOT NULL DEFAULT 0,
|
sort INTEGER NOT NULL DEFAULT 0,
|
||||||
@@ -448,7 +451,7 @@ CREATE TABLE IF NOT EXISTS warehouse (
|
|||||||
/* SQLite has no SQL Server ledger tables; constraints preserve the base shape. */
|
/* SQLite has no SQL Server ledger tables; constraints preserve the base shape. */
|
||||||
export const INIT_LEDGER = `
|
export const INIT_LEDGER = `
|
||||||
CREATE TABLE IF NOT EXISTS ledger (
|
CREATE TABLE IF NOT EXISTS ledger (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
manifestarticle_id INTEGER NOT NULL,
|
manifestarticle_id INTEGER NOT NULL,
|
||||||
warehouse_id INTEGER,
|
warehouse_id INTEGER,
|
||||||
transaction_type TEXT NOT NULL,
|
transaction_type TEXT NOT NULL,
|
||||||
@@ -464,7 +467,7 @@ CREATE TABLE IF NOT EXISTS ledger (
|
|||||||
|
|
||||||
export const INIT_NUMBERS = `
|
export const INIT_NUMBERS = `
|
||||||
CREATE TABLE IF NOT EXISTS numbers (
|
CREATE TABLE IF NOT EXISTS numbers (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
"type" TEXT NOT NULL,
|
"type" TEXT NOT NULL,
|
||||||
prefix TEXT NOT NULL DEFAULT '',
|
prefix TEXT NOT NULL DEFAULT '',
|
||||||
@@ -477,7 +480,7 @@ CREATE TABLE IF NOT EXISTS numbers (
|
|||||||
|
|
||||||
export const INIT_COMPANYUSER = `
|
export const INIT_COMPANYUSER = `
|
||||||
CREATE TABLE IF NOT EXISTS companyuser (
|
CREATE TABLE IF NOT EXISTS companyuser (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
google_auth_id INTEGER NOT NULL,
|
google_auth_id INTEGER NOT NULL,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
UNIQUE (google_auth_id, company_id),
|
UNIQUE (google_auth_id, company_id),
|
||||||
@@ -488,7 +491,7 @@ CREATE TABLE IF NOT EXISTS companyuser (
|
|||||||
|
|
||||||
export const INIT_MODELCONVERSATION = `
|
export const INIT_MODELCONVERSATION = `
|
||||||
CREATE TABLE IF NOT EXISTS modelconversation (
|
CREATE TABLE IF NOT EXISTS modelconversation (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
companyuser_id INTEGER NOT NULL,
|
companyuser_id INTEGER NOT NULL,
|
||||||
provider TEXT NOT NULL,
|
provider TEXT NOT NULL,
|
||||||
model TEXT NOT NULL,
|
model TEXT NOT NULL,
|
||||||
@@ -503,7 +506,7 @@ CREATE INDEX IF NOT EXISTS IX_modelconversation_companyuser ON modelconversation
|
|||||||
|
|
||||||
export const INIT_MODELVFS = `
|
export const INIT_MODELVFS = `
|
||||||
CREATE TABLE IF NOT EXISTS modelvfs (
|
CREATE TABLE IF NOT EXISTS modelvfs (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
mime TEXT NOT NULL,
|
mime TEXT NOT NULL,
|
||||||
@@ -518,7 +521,7 @@ CREATE INDEX IF NOT EXISTS IX_modelvfs_company_name ON modelvfs (company_id, nam
|
|||||||
|
|
||||||
export const INIT_MODELMESSAGE = `
|
export const INIT_MODELMESSAGE = `
|
||||||
CREATE TABLE IF NOT EXISTS modelmessage (
|
CREATE TABLE IF NOT EXISTS modelmessage (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
conversation_id INTEGER NOT NULL,
|
conversation_id INTEGER NOT NULL,
|
||||||
created_at TEXT NOT NULL DEFAULT (${UTC_NOW}),
|
created_at TEXT NOT NULL DEFAULT (${UTC_NOW}),
|
||||||
role TEXT NOT NULL CHECK (role IN ('system', 'user', 'assistant', 'tool', 'reasoning', 'usage')),
|
role TEXT NOT NULL CHECK (role IN ('system', 'user', 'assistant', 'tool', 'reasoning', 'usage')),
|
||||||
@@ -530,7 +533,7 @@ CREATE INDEX IF NOT EXISTS IX_modelmessage_conversation ON modelmessage (convers
|
|||||||
|
|
||||||
export const INIT_ARTICLEHISTORY = `
|
export const INIT_ARTICLEHISTORY = `
|
||||||
CREATE TABLE IF NOT EXISTS articlehistory (
|
CREATE TABLE IF NOT EXISTS articlehistory (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
article_id INTEGER NOT NULL,
|
article_id INTEGER NOT NULL,
|
||||||
companyuser_id INTEGER,
|
companyuser_id INTEGER,
|
||||||
"date" TEXT NOT NULL DEFAULT (${UTC_NOW}),
|
"date" TEXT NOT NULL DEFAULT (${UTC_NOW}),
|
||||||
@@ -541,7 +544,7 @@ CREATE TABLE IF NOT EXISTS articlehistory (
|
|||||||
`;
|
`;
|
||||||
export const INIT_COMPANYHISTORY = `
|
export const INIT_COMPANYHISTORY = `
|
||||||
CREATE TABLE IF NOT EXISTS companyhistory (
|
CREATE TABLE IF NOT EXISTS companyhistory (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
companyuser_id INTEGER,
|
companyuser_id INTEGER,
|
||||||
"date" TEXT NOT NULL DEFAULT (${UTC_NOW}),
|
"date" TEXT NOT NULL DEFAULT (${UTC_NOW}),
|
||||||
@@ -553,7 +556,7 @@ CREATE TABLE IF NOT EXISTS companyhistory (
|
|||||||
|
|
||||||
export const INIT_ARTICLETOMBSTONE = `
|
export const INIT_ARTICLETOMBSTONE = `
|
||||||
CREATE TABLE IF NOT EXISTS articletombstone (
|
CREATE TABLE IF NOT EXISTS articletombstone (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
article_id INTEGER,
|
article_id INTEGER,
|
||||||
sku TEXT COLLATE NOCASE,
|
sku TEXT COLLATE NOCASE,
|
||||||
@@ -570,7 +573,7 @@ CREATE INDEX IF NOT EXISTS IX_articletombstone_company_deleted
|
|||||||
|
|
||||||
export const INIT_ENTITYHISTORY = `
|
export const INIT_ENTITYHISTORY = `
|
||||||
CREATE TABLE IF NOT EXISTS entityhistory (
|
CREATE TABLE IF NOT EXISTS entityhistory (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
entity_id INTEGER NOT NULL,
|
entity_id INTEGER NOT NULL,
|
||||||
companyuser_id INTEGER,
|
companyuser_id INTEGER,
|
||||||
"date" TEXT NOT NULL DEFAULT (${UTC_NOW}),
|
"date" TEXT NOT NULL DEFAULT (${UTC_NOW}),
|
||||||
@@ -582,7 +585,7 @@ CREATE TABLE IF NOT EXISTS entityhistory (
|
|||||||
|
|
||||||
export const INIT_COMPANYSETTING = `
|
export const INIT_COMPANYSETTING = `
|
||||||
CREATE TABLE IF NOT EXISTS companysetting (
|
CREATE TABLE IF NOT EXISTS companysetting (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
"key" TEXT NOT NULL,
|
"key" TEXT NOT NULL,
|
||||||
value TEXT NOT NULL,
|
value TEXT NOT NULL,
|
||||||
@@ -595,7 +598,7 @@ CREATE TABLE IF NOT EXISTS companysetting (
|
|||||||
|
|
||||||
export const INIT_POSTERMINAL = `
|
export const INIT_POSTERMINAL = `
|
||||||
CREATE TABLE IF NOT EXISTS posterminal (
|
CREATE TABLE IF NOT EXISTS posterminal (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
token TEXT,
|
token TEXT,
|
||||||
@@ -616,7 +619,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS UQ_posterminal_token
|
|||||||
|
|
||||||
export const INIT_POSTERMINALCATEGORY = `
|
export const INIT_POSTERMINALCATEGORY = `
|
||||||
CREATE TABLE IF NOT EXISTS posterminalcategory (
|
CREATE TABLE IF NOT EXISTS posterminalcategory (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
posterminal_id INTEGER NOT NULL,
|
posterminal_id INTEGER NOT NULL,
|
||||||
category_id INTEGER NOT NULL,
|
category_id INTEGER NOT NULL,
|
||||||
UNIQUE (posterminal_id, category_id),
|
UNIQUE (posterminal_id, category_id),
|
||||||
@@ -627,7 +630,7 @@ CREATE TABLE IF NOT EXISTS posterminalcategory (
|
|||||||
|
|
||||||
export const INIT_PRINTER = `
|
export const INIT_PRINTER = `
|
||||||
CREATE TABLE IF NOT EXISTS printer (
|
CREATE TABLE IF NOT EXISTS printer (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
address TEXT NOT NULL,
|
address TEXT NOT NULL,
|
||||||
type TEXT NOT NULL CHECK (type IN ('esc/pos', 'zpl', 'ipp')),
|
type TEXT NOT NULL CHECK (type IN ('esc/pos', 'zpl', 'ipp')),
|
||||||
@@ -642,7 +645,7 @@ CREATE TABLE IF NOT EXISTS printer (
|
|||||||
|
|
||||||
export const INIT_LABELTEMPLATE = `
|
export const INIT_LABELTEMPLATE = `
|
||||||
CREATE TABLE IF NOT EXISTS labeltemplate (
|
CREATE TABLE IF NOT EXISTS labeltemplate (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
width INTEGER NOT NULL,
|
width INTEGER NOT NULL,
|
||||||
@@ -657,7 +660,7 @@ CREATE TABLE IF NOT EXISTS labeltemplate (
|
|||||||
|
|
||||||
export const INIT_FILE = `
|
export const INIT_FILE = `
|
||||||
CREATE TABLE IF NOT EXISTS "file" (
|
CREATE TABLE IF NOT EXISTS "file" (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
hash TEXT NOT NULL,
|
hash TEXT NOT NULL,
|
||||||
mimetype TEXT NOT NULL,
|
mimetype TEXT NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
@@ -672,7 +675,7 @@ CREATE TABLE IF NOT EXISTS "file" (
|
|||||||
|
|
||||||
export const INIT_MANIFESTATTACHMENT = `
|
export const INIT_MANIFESTATTACHMENT = `
|
||||||
CREATE TABLE IF NOT EXISTS manifestattachment (
|
CREATE TABLE IF NOT EXISTS manifestattachment (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
manifest_id INTEGER NOT NULL,
|
manifest_id INTEGER NOT NULL,
|
||||||
file_id INTEGER NOT NULL,
|
file_id INTEGER NOT NULL,
|
||||||
sort INTEGER NOT NULL DEFAULT 0,
|
sort INTEGER NOT NULL DEFAULT 0,
|
||||||
@@ -696,7 +699,7 @@ END;
|
|||||||
|
|
||||||
export const INIT_PROPERTYNAME = `
|
export const INIT_PROPERTYNAME = `
|
||||||
CREATE TABLE IF NOT EXISTS propertyname (
|
CREATE TABLE IF NOT EXISTS propertyname (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
sort INTEGER NOT NULL DEFAULT 0,
|
sort INTEGER NOT NULL DEFAULT 0,
|
||||||
@@ -708,7 +711,7 @@ CREATE TABLE IF NOT EXISTS propertyname (
|
|||||||
|
|
||||||
export const INIT_ARTICLEPROPERTY = `
|
export const INIT_ARTICLEPROPERTY = `
|
||||||
CREATE TABLE IF NOT EXISTS articleproperty (
|
CREATE TABLE IF NOT EXISTS articleproperty (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
article_id INTEGER NOT NULL,
|
article_id INTEGER NOT NULL,
|
||||||
property_id INTEGER NOT NULL,
|
property_id INTEGER NOT NULL,
|
||||||
value TEXT NOT NULL,
|
value TEXT NOT NULL,
|
||||||
@@ -720,7 +723,7 @@ CREATE TABLE IF NOT EXISTS articleproperty (
|
|||||||
|
|
||||||
export const INIT_ATTRIBUTENAME = `
|
export const INIT_ATTRIBUTENAME = `
|
||||||
CREATE TABLE IF NOT EXISTS attributename (
|
CREATE TABLE IF NOT EXISTS attributename (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
sort INTEGER NOT NULL DEFAULT 0,
|
sort INTEGER NOT NULL DEFAULT 0,
|
||||||
@@ -732,7 +735,7 @@ CREATE TABLE IF NOT EXISTS attributename (
|
|||||||
|
|
||||||
export const INIT_ATTRIBUTEVALUE = `
|
export const INIT_ATTRIBUTEVALUE = `
|
||||||
CREATE TABLE IF NOT EXISTS attributevalue (
|
CREATE TABLE IF NOT EXISTS attributevalue (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
attribute_id INTEGER NOT NULL,
|
attribute_id INTEGER NOT NULL,
|
||||||
value TEXT NOT NULL,
|
value TEXT NOT NULL,
|
||||||
sort INTEGER NOT NULL DEFAULT 0,
|
sort INTEGER NOT NULL DEFAULT 0,
|
||||||
@@ -743,7 +746,7 @@ CREATE TABLE IF NOT EXISTS attributevalue (
|
|||||||
|
|
||||||
export const INIT_ARTICLEATTRIBUTEVALUE = `
|
export const INIT_ARTICLEATTRIBUTEVALUE = `
|
||||||
CREATE TABLE IF NOT EXISTS articleattributevalue (
|
CREATE TABLE IF NOT EXISTS articleattributevalue (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
article_id INTEGER NOT NULL,
|
article_id INTEGER NOT NULL,
|
||||||
attributevalue_id INTEGER NOT NULL,
|
attributevalue_id INTEGER NOT NULL,
|
||||||
sort INTEGER NOT NULL DEFAULT 0,
|
sort INTEGER NOT NULL DEFAULT 0,
|
||||||
@@ -755,7 +758,7 @@ CREATE TABLE IF NOT EXISTS articleattributevalue (
|
|||||||
|
|
||||||
export const INIT_CATEGORYPROPERTY = `
|
export const INIT_CATEGORYPROPERTY = `
|
||||||
CREATE TABLE IF NOT EXISTS categoryproperty (
|
CREATE TABLE IF NOT EXISTS categoryproperty (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
category_id INTEGER NOT NULL,
|
category_id INTEGER NOT NULL,
|
||||||
property_id INTEGER NOT NULL,
|
property_id INTEGER NOT NULL,
|
||||||
value TEXT NOT NULL,
|
value TEXT NOT NULL,
|
||||||
@@ -767,7 +770,7 @@ CREATE TABLE IF NOT EXISTS categoryproperty (
|
|||||||
|
|
||||||
export const INIT_CATEGORYATTRIBUTEVALUE = `
|
export const INIT_CATEGORYATTRIBUTEVALUE = `
|
||||||
CREATE TABLE IF NOT EXISTS categoryattributevalue (
|
CREATE TABLE IF NOT EXISTS categoryattributevalue (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
category_id INTEGER NOT NULL,
|
category_id INTEGER NOT NULL,
|
||||||
attributevalue_id INTEGER NOT NULL,
|
attributevalue_id INTEGER NOT NULL,
|
||||||
sort INTEGER NOT NULL DEFAULT 0,
|
sort INTEGER NOT NULL DEFAULT 0,
|
||||||
@@ -779,7 +782,7 @@ CREATE TABLE IF NOT EXISTS categoryattributevalue (
|
|||||||
|
|
||||||
export const INIT_ACCOUNT = `
|
export const INIT_ACCOUNT = `
|
||||||
CREATE TABLE IF NOT EXISTS account (
|
CREATE TABLE IF NOT EXISTS account (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
company_id INTEGER NOT NULL,
|
company_id INTEGER NOT NULL,
|
||||||
"type" TEXT NOT NULL,
|
"type" TEXT NOT NULL,
|
||||||
"name" TEXT NOT NULL,
|
"name" TEXT NOT NULL,
|
||||||
@@ -789,7 +792,7 @@ CREATE TABLE IF NOT EXISTS account (
|
|||||||
|
|
||||||
export const INIT_PAYMENT = `
|
export const INIT_PAYMENT = `
|
||||||
CREATE TABLE IF NOT EXISTS payment (
|
CREATE TABLE IF NOT EXISTS payment (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
account_id INTEGER NOT NULL,
|
account_id INTEGER NOT NULL,
|
||||||
manifest_id INTEGER NOT NULL,
|
manifest_id INTEGER NOT NULL,
|
||||||
"type" TEXT NOT NULL,
|
"type" TEXT NOT NULL,
|
||||||
@@ -801,7 +804,7 @@ CREATE TABLE IF NOT EXISTS payment (
|
|||||||
|
|
||||||
export const INIT_SHIPPING = `
|
export const INIT_SHIPPING = `
|
||||||
CREATE TABLE IF NOT EXISTS shipping (
|
CREATE TABLE IF NOT EXISTS shipping (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
manifest_id INTEGER NOT NULL,
|
manifest_id INTEGER NOT NULL,
|
||||||
"number" TEXT NOT NULL,
|
"number" TEXT NOT NULL,
|
||||||
"type" TEXT NOT NULL,
|
"type" TEXT NOT NULL,
|
||||||
@@ -812,7 +815,7 @@ CREATE TABLE IF NOT EXISTS shipping (
|
|||||||
|
|
||||||
export const INIT_PACKAGE = `
|
export const INIT_PACKAGE = `
|
||||||
CREATE TABLE IF NOT EXISTS package (
|
CREATE TABLE IF NOT EXISTS package (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
shipping_id INTEGER NOT NULL,
|
shipping_id INTEGER NOT NULL,
|
||||||
entityaddress_id INTEGER NOT NULL,
|
entityaddress_id INTEGER NOT NULL,
|
||||||
"number" TEXT NOT NULL,
|
"number" TEXT NOT NULL,
|
||||||
|
|||||||
@@ -22,17 +22,17 @@ export default function addImage(provider) {
|
|||||||
const addArticlePicSql = isSqlite ? SQLITE_ADD_ARTICLEPIC : MSSQL_ADD_ARTICLEPIC;
|
const addArticlePicSql = isSqlite ? SQLITE_ADD_ARTICLEPIC : MSSQL_ADD_ARTICLEPIC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an image to an article by its SKU, processing it into AVIF variants.
|
* Adds an image to an article by its SKU, processing full, thumb, and 40px-edge small-thumb AVIF variants.
|
||||||
*
|
*
|
||||||
* @param {number} googleAuthId - The id of the Google auth user.
|
* @param {number} googleAuthId - The id of the Google auth user.
|
||||||
* @param {string} sku - The article SKU.
|
* @param {string} sku - The article SKU.
|
||||||
* @param {Buffer} image - The source image buffer.
|
* @param {Buffer} image - The source image buffer.
|
||||||
* @param {object} [tx] - Optional transaction to run within.
|
* @param {object} [tx] - Optional transaction to run within.
|
||||||
* @returns {Promise<{picId: number, sort: number, full: {w: number, h: number, size: number}, thumb: {w: number, h: number}, fullHash: string, thumbHash: string}>} The added image info.
|
* @returns {Promise<{picId: number, sort: number, full: {w: number, h: number, size: number}, thumb: {w: number, h: number}, smallThumb: {w: number, h: number}, fullHash: string, thumbHash: string}>} The added image info.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* const result = await store.article.addImage(42, 'SKU-1', imageBuffer);
|
* const result = await store.article.addImage(42, 'SKU-1', imageBuffer);
|
||||||
* // => { picId, sort, full: { w, h, size }, thumb: { w, h }, fullHash, thumbHash }
|
* // => { picId, sort, full: { w, h, size }, thumb: { w, h }, smallThumb: { w, h }, fullHash, thumbHash }
|
||||||
*/
|
*/
|
||||||
return async (googleAuthId, sku, image, tx) => {
|
return async (googleAuthId, sku, image, tx) => {
|
||||||
const runAdd = async (runner) => {
|
const runAdd = async (runner) => {
|
||||||
@@ -71,6 +71,9 @@ export default function addImage(provider) {
|
|||||||
thumbw: processed.thumb.w,
|
thumbw: processed.thumb.w,
|
||||||
thumbh: processed.thumb.h,
|
thumbh: processed.thumb.h,
|
||||||
thumbhash: processed.thumb.hash,
|
thumbhash: processed.thumb.hash,
|
||||||
|
smallthumbw: processed.smallThumb.w,
|
||||||
|
smallthumbh: processed.smallThumb.h,
|
||||||
|
smallthumbbinary: processed.smallThumb.buffer,
|
||||||
source: '',
|
source: '',
|
||||||
fullbinary: processed.full.buffer,
|
fullbinary: processed.full.buffer,
|
||||||
thumbbinary: processed.thumb.buffer,
|
thumbbinary: processed.thumb.buffer,
|
||||||
@@ -107,6 +110,10 @@ export default function addImage(provider) {
|
|||||||
w: processed.thumb.w,
|
w: processed.thumb.w,
|
||||||
h: processed.thumb.h,
|
h: processed.thumb.h,
|
||||||
},
|
},
|
||||||
|
smallThumb: {
|
||||||
|
w: processed.smallThumb.w,
|
||||||
|
h: processed.smallThumb.h,
|
||||||
|
},
|
||||||
fullHash,
|
fullHash,
|
||||||
thumbHash: processed.thumb.hash,
|
thumbHash: processed.thumb.hash,
|
||||||
};
|
};
|
||||||
@@ -121,4 +128,3 @@ export default function addImage(provider) {
|
|||||||
return runAdd(makeRunner(provider));
|
return runAdd(makeRunner(provider));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ export default function addImage(provider) {
|
|||||||
const addBrandPicSql = isSqlite ? SQLITE_ADD_BRANDPIC : MSSQL_ADD_BRANDPIC;
|
const addBrandPicSql = isSqlite ? SQLITE_ADD_BRANDPIC : MSSQL_ADD_BRANDPIC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an image to a brand, processing it into AVIF full and thumb variants.
|
* Adds an image to a brand, processing full, thumb, and 40px-edge small-thumb AVIF variants.
|
||||||
*
|
*
|
||||||
* @param {number} googleAuthId - The id of the Google auth user.
|
* @param {number} googleAuthId - The id of the Google auth user.
|
||||||
* @param {number} brandId - The id of the brand.
|
* @param {number} brandId - The id of the brand.
|
||||||
* @param {Buffer} image - The source image buffer.
|
* @param {Buffer} image - The source image buffer.
|
||||||
* @param {object} [tx] - Optional transaction to run within.
|
* @param {object} [tx] - Optional transaction to run within.
|
||||||
* @returns {Promise<{id: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string, pics: Array<object>}>}
|
* @returns {Promise<{id: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string, smallThumbW: number, smallThumbH: number, pics: Array<object>}>}
|
||||||
*/
|
*/
|
||||||
return async (googleAuthId, brandId, image, tx) => {
|
return async (googleAuthId, brandId, image, tx) => {
|
||||||
const runAdd = async (runner) => {
|
const runAdd = async (runner) => {
|
||||||
@@ -69,6 +69,9 @@ export default function addImage(provider) {
|
|||||||
thumbw: processed.thumb.w,
|
thumbw: processed.thumb.w,
|
||||||
thumbh: processed.thumb.h,
|
thumbh: processed.thumb.h,
|
||||||
thumbhash: processed.thumb.hash,
|
thumbhash: processed.thumb.hash,
|
||||||
|
smallthumbw: processed.smallThumb.w,
|
||||||
|
smallthumbh: processed.smallThumb.h,
|
||||||
|
smallthumbbinary: processed.smallThumb.buffer,
|
||||||
source: '',
|
source: '',
|
||||||
fullbinary: processed.full.buffer,
|
fullbinary: processed.full.buffer,
|
||||||
thumbbinary: processed.thumb.buffer,
|
thumbbinary: processed.thumb.buffer,
|
||||||
@@ -82,15 +85,14 @@ export default function addImage(provider) {
|
|||||||
picId,
|
picId,
|
||||||
sort,
|
sort,
|
||||||
});
|
});
|
||||||
const brandPicId = brandPicResult.rows[0]?.id ?? brandPicResult.insertId;
|
|
||||||
|
|
||||||
const picObj = {
|
const picObj = {
|
||||||
id: brandPicId,
|
|
||||||
sort,
|
|
||||||
fullHash,
|
fullHash,
|
||||||
thumbW: processed.thumb.w,
|
thumbW: processed.thumb.w,
|
||||||
thumbH: processed.thumb.h,
|
thumbH: processed.thumb.h,
|
||||||
thumbHash: processed.thumb.hash,
|
thumbHash: processed.thumb.hash,
|
||||||
|
smallThumbW: processed.smallThumb.w,
|
||||||
|
smallThumbH: processed.smallThumb.h,
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -99,6 +101,8 @@ export default function addImage(provider) {
|
|||||||
thumbW: processed.thumb.w,
|
thumbW: processed.thumb.w,
|
||||||
thumbH: processed.thumb.h,
|
thumbH: processed.thumb.h,
|
||||||
thumbHash: processed.thumb.hash,
|
thumbHash: processed.thumb.hash,
|
||||||
|
smallThumbW: processed.smallThumb.w,
|
||||||
|
smallThumbH: processed.smallThumb.h,
|
||||||
pics: [picObj],
|
pics: [picObj],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
78
src/store/brand/create.js
Normal file
78
src/store/brand/create.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import {
|
||||||
|
CREATE as MSSQL_CREATE,
|
||||||
|
GET_BY_COMPANY_AND_NAME as MSSQL_GET_BY_COMPANY_AND_NAME,
|
||||||
|
} from '../../providers/mssql/queries/brand.js';
|
||||||
|
import {
|
||||||
|
CREATE as SQLITE_CREATE,
|
||||||
|
GET_BY_COMPANY_AND_NAME as SQLITE_GET_BY_COMPANY_AND_NAME,
|
||||||
|
} from '../../providers/sqlite3/queries/brand.js';
|
||||||
|
import { isUniqueConstraintError } from '../../providers/provider.js';
|
||||||
|
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||||
|
import makeRunner from '../runner.js';
|
||||||
|
|
||||||
|
export default function create(provider) {
|
||||||
|
const access = resolveSelectedCompanyAccess(provider);
|
||||||
|
const isSqlite = provider?.dialect === 'sqlite3';
|
||||||
|
const createSql = isSqlite ? SQLITE_CREATE : MSSQL_CREATE;
|
||||||
|
const getSql = isSqlite
|
||||||
|
? SQLITE_GET_BY_COMPANY_AND_NAME
|
||||||
|
: MSSQL_GET_BY_COMPANY_AND_NAME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a brand for the user's selected company.
|
||||||
|
*
|
||||||
|
* @param {number} googleAuthId - The id of the Google auth user.
|
||||||
|
* @param {object} input - The brand input.
|
||||||
|
* @param {string} input.name - The brand name.
|
||||||
|
* @param {string} [input.gsprpinfo] - Optional GSPRP info.
|
||||||
|
* @param {object} [tx] - Optional transaction to run within.
|
||||||
|
* @returns {Promise<{id: number, name: string, gsprpinfo: string|null, pics: Array<{fullHash: string, thumbW: number, thumbH: number, thumbHash: string}>}>} The created brand.
|
||||||
|
* @throws {Error} If the brand is invalid or already exists.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const brand = await store.brand.create(42, { name: 'Coca-Cola', gsprpinfo: 'x' });
|
||||||
|
* // => { id, name, gsprpinfo, pics: [] }
|
||||||
|
*/
|
||||||
|
return async (googleAuthId, input = {}, tx) => {
|
||||||
|
const name = input.name?.trim();
|
||||||
|
if (!name) {
|
||||||
|
throw new Error('Invalid brand');
|
||||||
|
}
|
||||||
|
const gsprpinfo = input.gsprpinfo ?? null;
|
||||||
|
|
||||||
|
const runner = makeRunner(provider, tx);
|
||||||
|
const { companyId } = await access(googleAuthId, tx);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const created = await runner.query(createSql, {
|
||||||
|
companyId,
|
||||||
|
name,
|
||||||
|
gsprpinfo,
|
||||||
|
});
|
||||||
|
|
||||||
|
const id = created.rows[0]?.id ?? created.insertId;
|
||||||
|
if (id == null) {
|
||||||
|
const fetched = await runner.query(getSql, { companyId, name });
|
||||||
|
const row = fetched.rows[0];
|
||||||
|
return {
|
||||||
|
id: row.id,
|
||||||
|
name,
|
||||||
|
gsprpinfo,
|
||||||
|
pics: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
gsprpinfo,
|
||||||
|
pics: [],
|
||||||
|
};
|
||||||
|
} catch (err) {
|
||||||
|
if (isUniqueConstraintError(err)) {
|
||||||
|
throw new Error('Brand already exists');
|
||||||
|
}
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,42 +1,102 @@
|
|||||||
import { LIST_BY_COMPANY as MSSQL_LIST_BY_COMPANY } from '../../providers/mssql/queries/brand.js';
|
import {
|
||||||
import { LIST_BY_COMPANY as SQLITE_LIST_BY_COMPANY } from '../../providers/sqlite3/queries/brand.js';
|
COUNT_BY_COMPANY as MSSQL_COUNT,
|
||||||
|
LIST_BY_COMPANY as MSSQL_LIST_BY_COMPANY,
|
||||||
|
LIST_BY_COMPANY_PAGED as MSSQL_LIST_PAGED,
|
||||||
|
LIST_BY_COMPANY_PAGED_WITH_SMALL_THUMBS as MSSQL_LIST_PAGED_WITH_SMALL_THUMBS,
|
||||||
|
} from '../../providers/mssql/queries/brand.js';
|
||||||
|
import {
|
||||||
|
COUNT_BY_COMPANY as SQLITE_COUNT,
|
||||||
|
LIST_BY_COMPANY as SQLITE_LIST_BY_COMPANY,
|
||||||
|
LIST_BY_COMPANY_PAGED as SQLITE_LIST_PAGED,
|
||||||
|
LIST_BY_COMPANY_PAGED_WITH_SMALL_THUMBS as SQLITE_LIST_PAGED_WITH_SMALL_THUMBS,
|
||||||
|
} from '../../providers/sqlite3/queries/brand.js';
|
||||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||||
import makeRunner from '../runner.js';
|
import makeRunner from '../runner.js';
|
||||||
|
|
||||||
function parsePics(raw) {
|
function parsePics(raw) {
|
||||||
if (!raw) return [];
|
if (!raw) return [];
|
||||||
const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;
|
const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;
|
||||||
return Array.isArray(parsed) ? parsed : [];
|
if (!Array.isArray(parsed)) return [];
|
||||||
|
return parsed.map((pic) => {
|
||||||
|
const { smallThumbBinaryHex, ...result } = pic;
|
||||||
|
if (smallThumbBinaryHex === undefined) return result;
|
||||||
|
return {
|
||||||
|
...result,
|
||||||
|
smallThumbBinary: smallThumbBinaryHex === null
|
||||||
|
? null
|
||||||
|
: Buffer.from(smallThumbBinaryHex, 'hex').toString('base64'),
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function list(provider) {
|
export default function list(provider) {
|
||||||
const access = resolveSelectedCompanyAccess(provider);
|
const access = resolveSelectedCompanyAccess(provider);
|
||||||
const sql =
|
const isSqlite = provider?.dialect === 'sqlite3';
|
||||||
provider?.dialect === 'sqlite3'
|
const sql = isSqlite ? SQLITE_LIST_BY_COMPANY : MSSQL_LIST_BY_COMPANY;
|
||||||
? SQLITE_LIST_BY_COMPANY
|
const sqlCount = isSqlite ? SQLITE_COUNT : MSSQL_COUNT;
|
||||||
: MSSQL_LIST_BY_COMPANY;
|
const sqlPaged = isSqlite ? SQLITE_LIST_PAGED : MSSQL_LIST_PAGED;
|
||||||
|
const sqlPagedWithSmallThumbs = isSqlite
|
||||||
|
? SQLITE_LIST_PAGED_WITH_SMALL_THUMBS
|
||||||
|
: MSSQL_LIST_PAGED_WITH_SMALL_THUMBS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists the brands of the user's selected company.
|
* Lists the brands of the user's selected company, sorted by name.
|
||||||
*
|
*
|
||||||
* @param {number} googleAuthId - The id of the Google auth user.
|
* @param {number} googleAuthId - The id of the Google auth user.
|
||||||
|
* @param {object} [opts] - Optional pagination options.
|
||||||
|
* @param {number} [opts.offset=0] - Number of brands to skip.
|
||||||
|
* @param {number} [opts.limit=10] - Number of brands to return (max 100).
|
||||||
|
* @param {boolean} [opts.includeSmallThumbs=false] - Include 40px-edge small thumbnail dimensions and base64 AVIF data.
|
||||||
* @param {object} [tx] - Optional transaction to run within.
|
* @param {object} [tx] - Optional transaction to run within.
|
||||||
* @returns {Promise<Array<{id: number, name: string, gsprpinfo: string|null, pics: Array<{id: number, sort: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string}>}>>} The brands.
|
* @returns {Promise<{brands: Array<{id: number, name: string, gsprpinfo: string|null, pics: Array<{fullHash: string, thumbW: number, thumbH: number, thumbHash: string, smallThumbW?: number|null, smallThumbH?: number|null, smallThumbBinary?: string|null}>}>, total: number, offset: number, limit: number}>} The brands plus the total unpaged count. Small-thumbnail fields are present only when `includeSmallThumbs` is true; the binary is base64-encoded AVIF data.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* const brands = await store.brand.list(42);
|
* const result = await store.brand.list(42, { offset: 0, limit: 10 });
|
||||||
* // => [{ id, name, gsprpinfo, pics: [{ sort, fullHash, thumbW, thumbH, thumbHash }] }]
|
* // => { brands: [{ id, name, gsprpinfo, pics: [...] }], total: 25, offset: 0, limit: 10 }
|
||||||
*/
|
*/
|
||||||
return async (googleAuthId, tx) => {
|
return async (googleAuthId, opts, tx) => {
|
||||||
const { companyId } = await access(googleAuthId, tx);
|
let offset = 0;
|
||||||
|
let limit = 10;
|
||||||
|
let includeSmallThumbs = false;
|
||||||
|
let resolvedTx = tx;
|
||||||
|
|
||||||
const result = await makeRunner(provider, tx).query(sql, { companyId });
|
if (opts != null && typeof opts === 'object' && !opts._isTx) {
|
||||||
|
const parsedOffset = Number(opts.offset ?? 0);
|
||||||
|
const parsedLimit = Number(opts.limit ?? 10);
|
||||||
|
if (!Number.isInteger(parsedOffset) || parsedOffset < 0) {
|
||||||
|
throw new Error('Invalid offset');
|
||||||
|
}
|
||||||
|
if (!Number.isInteger(parsedLimit) || parsedLimit < 1 || parsedLimit > 100) {
|
||||||
|
throw new Error('Invalid limit');
|
||||||
|
}
|
||||||
|
offset = parsedOffset;
|
||||||
|
limit = parsedLimit;
|
||||||
|
includeSmallThumbs = opts.includeSmallThumbs === true;
|
||||||
|
} else if (opts != null) {
|
||||||
|
resolvedTx = opts;
|
||||||
|
}
|
||||||
|
|
||||||
return result.rows.map((row) => ({
|
const runner = makeRunner(provider, resolvedTx);
|
||||||
|
const { companyId } = await access(googleAuthId, runner);
|
||||||
|
|
||||||
|
const [countResult, listResult] = await Promise.all([
|
||||||
|
runner.query(sqlCount, { companyId }),
|
||||||
|
runner.query(
|
||||||
|
includeSmallThumbs ? sqlPagedWithSmallThumbs : sqlPaged,
|
||||||
|
{ companyId, offset, limit },
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
brands: listResult.rows.map((row) => ({
|
||||||
id: row.id,
|
id: row.id,
|
||||||
name: row.name,
|
name: row.name,
|
||||||
gsprpinfo: row.gsprpinfo,
|
gsprpinfo: row.gsprpinfo,
|
||||||
pics: parsePics(row.picsJson),
|
pics: parsePics(row.picsJson),
|
||||||
}));
|
})),
|
||||||
|
total: Number(countResult.rows[0]?.total ?? 0),
|
||||||
|
offset,
|
||||||
|
limit,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
90
src/store/brand/update.js
Normal file
90
src/store/brand/update.js
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import {
|
||||||
|
GET_BY_ID_AND_COMPANY as MSSQL_GET,
|
||||||
|
UPDATE_BY_ID as MSSQL_UPDATE,
|
||||||
|
} from '../../providers/mssql/queries/brand.js';
|
||||||
|
import {
|
||||||
|
GET_BY_ID_AND_COMPANY as SQLITE_GET,
|
||||||
|
UPDATE_BY_ID as SQLITE_UPDATE,
|
||||||
|
} from '../../providers/sqlite3/queries/brand.js';
|
||||||
|
import { isUniqueConstraintError } from '../../providers/provider.js';
|
||||||
|
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||||
|
import makeRunner from '../runner.js';
|
||||||
|
|
||||||
|
export default function update(provider) {
|
||||||
|
const access = resolveSelectedCompanyAccess(provider);
|
||||||
|
const isSqlite = provider?.dialect === 'sqlite3';
|
||||||
|
const getSql = isSqlite ? SQLITE_GET : MSSQL_GET;
|
||||||
|
const updateSql = isSqlite ? SQLITE_UPDATE : MSSQL_UPDATE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renames/updates a brand for the user's selected company by id.
|
||||||
|
* Touching `article.updated_at` for all articles linked via `brand_id`
|
||||||
|
* when the name actually changes, so list caches invalidate.
|
||||||
|
*
|
||||||
|
* @param {number} googleAuthId - The id of the Google auth user.
|
||||||
|
* @param {number} id - The id of the brand to update.
|
||||||
|
* @param {object} input - The update input.
|
||||||
|
* @param {string} [input.name] - The new brand name.
|
||||||
|
* @param {string} [input.gsprpinfo] - The new GSPRP info.
|
||||||
|
* @param {object} [tx] - Optional transaction to run within.
|
||||||
|
* @returns {Promise<{id: number, name: string, gsprpinfo: string|null, touchedArticleCount: number}>} The updated brand plus the number of linked articles whose `updated_at` was bumped.
|
||||||
|
* @throws {Error} If the brand is not found, invalid, or the name is already taken.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const brand = await store.brand.update(42, 3, { name: 'Coca-Cola GmbH' });
|
||||||
|
* // => { id: 3, name, gsprpinfo, touchedArticleCount: 2 }
|
||||||
|
*/
|
||||||
|
return async (googleAuthId, id, input = {}, tx) => {
|
||||||
|
const numericId = Number(id);
|
||||||
|
if (!Number.isInteger(numericId) || numericId <= 0) {
|
||||||
|
throw new Error('Brand not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const runner = makeRunner(provider, tx);
|
||||||
|
const { companyId } = await access(googleAuthId, tx);
|
||||||
|
|
||||||
|
const existing = await runner.query(getSql, { id: numericId, companyId });
|
||||||
|
const current = existing.rows[0];
|
||||||
|
if (!current) {
|
||||||
|
throw new Error('Brand not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = input.name !== undefined ? input.name?.trim() : current.name;
|
||||||
|
if (!name) {
|
||||||
|
throw new Error('Invalid brand');
|
||||||
|
}
|
||||||
|
const gsprpinfo = input.gsprpinfo !== undefined ? input.gsprpinfo : current.gsprpinfo;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await runner.query(updateSql, {
|
||||||
|
id: numericId,
|
||||||
|
companyId,
|
||||||
|
name,
|
||||||
|
gsprpinfo,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
if (isUniqueConstraintError(err)) {
|
||||||
|
throw new Error('Brand already exists');
|
||||||
|
}
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
let touchedArticleCount = 0;
|
||||||
|
if (name !== current.name) {
|
||||||
|
// Brand name is denormalized into article list views — bump
|
||||||
|
// updated_at so caches/incremental syncs pick up the rename.
|
||||||
|
const touchSql = isSqlite
|
||||||
|
? "UPDATE article SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE brand_id = @brandId AND company_id = @companyId"
|
||||||
|
: 'UPDATE article SET updated_at = SYSUTCDATETIME() WHERE brand_id = @brandId AND company_id = @companyId';
|
||||||
|
const touched = await runner.query(touchSql, { brandId: numericId, companyId });
|
||||||
|
touchedArticleCount = touched.rowsAffected ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: numericId,
|
||||||
|
name,
|
||||||
|
gsprpinfo,
|
||||||
|
touchedArticleCount,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -34,7 +34,7 @@ export default function upsert(provider) {
|
|||||||
* @param {string} input.name - The brand name.
|
* @param {string} input.name - The brand name.
|
||||||
* @param {string} [input.gsprpinfo] - Optional GSPRP info.
|
* @param {string} [input.gsprpinfo] - Optional GSPRP info.
|
||||||
* @param {object} [tx] - Optional transaction to run within.
|
* @param {object} [tx] - Optional transaction to run within.
|
||||||
* @returns {Promise<{id: number, name: string, gsprpinfo: string|null, pics: Array<{id: number, sort: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string}>}>} The upserted brand.
|
* @returns {Promise<{id: number, name: string, gsprpinfo: string|null, pics: Array<{fullHash: string, thumbW: number, thumbH: number, thumbHash: string}>}>} The upserted brand.
|
||||||
* @throws {Error} If the brand is invalid.
|
* @throws {Error} If the brand is invalid.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ export default function addImage(provider) {
|
|||||||
const addCategoryPicSql = isSqlite ? SQLITE_ADD_CATEGORYPIC : MSSQL_ADD_CATEGORYPIC;
|
const addCategoryPicSql = isSqlite ? SQLITE_ADD_CATEGORYPIC : MSSQL_ADD_CATEGORYPIC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an image to a category, processing it into AVIF full and thumb variants.
|
* Adds an image to a category, processing full, thumb, and 40px-edge small-thumb AVIF variants.
|
||||||
*
|
*
|
||||||
* @param {number} googleAuthId - The id of the Google auth user.
|
* @param {number} googleAuthId - The id of the Google auth user.
|
||||||
* @param {number} categoryId - The id of the category.
|
* @param {number} categoryId - The id of the category.
|
||||||
* @param {Buffer} image - The source image buffer.
|
* @param {Buffer} image - The source image buffer.
|
||||||
* @param {object} [tx] - Optional transaction to run within.
|
* @param {object} [tx] - Optional transaction to run within.
|
||||||
* @returns {Promise<{id: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string}>} The added image info.
|
* @returns {Promise<{id: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string, smallThumbW: number, smallThumbH: number}>} The added image info.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* const result = await store.category.addImage(42, 5, imageBuffer);
|
* const result = await store.category.addImage(42, 5, imageBuffer);
|
||||||
@@ -71,6 +71,9 @@ export default function addImage(provider) {
|
|||||||
thumbw: processed.thumb.w,
|
thumbw: processed.thumb.w,
|
||||||
thumbh: processed.thumb.h,
|
thumbh: processed.thumb.h,
|
||||||
thumbhash: processed.thumb.hash,
|
thumbhash: processed.thumb.hash,
|
||||||
|
smallthumbw: processed.smallThumb.w,
|
||||||
|
smallthumbh: processed.smallThumb.h,
|
||||||
|
smallthumbbinary: processed.smallThumb.buffer,
|
||||||
source: '',
|
source: '',
|
||||||
fullbinary: processed.full.buffer,
|
fullbinary: processed.full.buffer,
|
||||||
thumbbinary: processed.thumb.buffer,
|
thumbbinary: processed.thumb.buffer,
|
||||||
@@ -98,6 +101,8 @@ export default function addImage(provider) {
|
|||||||
thumbW: processed.thumb.w,
|
thumbW: processed.thumb.w,
|
||||||
thumbH: processed.thumb.h,
|
thumbH: processed.thumb.h,
|
||||||
thumbHash: processed.thumb.hash,
|
thumbHash: processed.thumb.hash,
|
||||||
|
smallThumbW: processed.smallThumb.w,
|
||||||
|
smallThumbH: processed.smallThumb.h,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { rgbaToThumbHash } from 'thumbhash';
|
|||||||
|
|
||||||
const FULL_MAX = 1000;
|
const FULL_MAX = 1000;
|
||||||
const THUMB_MAX = 200;
|
const THUMB_MAX = 200;
|
||||||
|
const SMALL_THUMB_MAX = 40;
|
||||||
|
|
||||||
export default async function processAvifImage(inputBuffer) {
|
export default async function processAvifImage(inputBuffer) {
|
||||||
const input = Buffer.isBuffer(inputBuffer)
|
const input = Buffer.isBuffer(inputBuffer)
|
||||||
@@ -26,8 +27,10 @@ export default async function processAvifImage(inputBuffer) {
|
|||||||
|
|
||||||
const thumbPipeline = sharp(input)
|
const thumbPipeline = sharp(input)
|
||||||
.resize(THUMB_MAX, THUMB_MAX, { fit: 'inside', withoutEnlargement: true });
|
.resize(THUMB_MAX, THUMB_MAX, { fit: 'inside', withoutEnlargement: true });
|
||||||
|
const smallThumbPipeline = sharp(input)
|
||||||
|
.resize(SMALL_THUMB_MAX, SMALL_THUMB_MAX, { fit: 'inside', withoutEnlargement: true });
|
||||||
|
|
||||||
const [full, thumb, thumbRgba] = await Promise.all([
|
const [full, thumb, thumbRgba, smallThumb] = await Promise.all([
|
||||||
useOriginalFull
|
useOriginalFull
|
||||||
? Promise.resolve({
|
? Promise.resolve({
|
||||||
info: { width: w, height: h },
|
info: { width: w, height: h },
|
||||||
@@ -44,6 +47,9 @@ export default async function processAvifImage(inputBuffer) {
|
|||||||
.ensureAlpha()
|
.ensureAlpha()
|
||||||
.raw()
|
.raw()
|
||||||
.toBuffer({ resolveWithObject: true }),
|
.toBuffer({ resolveWithObject: true }),
|
||||||
|
smallThumbPipeline
|
||||||
|
.avif({ effort: 2 })
|
||||||
|
.toBuffer({ resolveWithObject: true }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const thumbHashBytes = rgbaToThumbHash(
|
const thumbHashBytes = rgbaToThumbHash(
|
||||||
@@ -66,5 +72,10 @@ export default async function processAvifImage(inputBuffer) {
|
|||||||
buffer: thumb.data,
|
buffer: thumb.data,
|
||||||
hash: Buffer.from(thumbHashBytes).toString('base64'),
|
hash: Buffer.from(thumbHashBytes).toString('base64'),
|
||||||
},
|
},
|
||||||
|
smallThumb: {
|
||||||
|
w: smallThumb.info.width,
|
||||||
|
h: smallThumb.info.height,
|
||||||
|
buffer: smallThumb.data,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user