Compare commits

...

2 Commits

Author SHA1 Message Date
seb
da2cdd5b23 u 2026-10-18 14:20:35 +02:00
seb
bf4109d8ec u 2026-10-18 14:07:01 +02:00
5 changed files with 367 additions and 869 deletions

View File

@@ -11,6 +11,7 @@ import { CREATE as SQLITE_CREATE_PIC } from '../../providers/sqlite3/queries/pic
import processAvifImage from '../../util/processAvifImage.js';
import newFullHash from '../../util/newFullHash.js';
import resolveArticleBySku from './resolveArticleBySku.js';
import { recordImageAddHistory } from '../articlehistory/record.js';
import makeRunner from '../runner.js';
export default function addImage(provider) {
@@ -39,7 +40,7 @@ export default function addImage(provider) {
const fullHash = newFullHash(processed.full.buffer);
const runAdd = async (runner) => {
const { articleId } = await resolve(googleAuthId, sku, runner);
const { articleId, companyuserId } = await resolve(googleAuthId, sku, runner);
const sortResult = await runner.query(getSortSql, { articleId });
const sort = sortResult.rows[0].sort;
@@ -96,6 +97,13 @@ export default function addImage(provider) {
picId,
sort,
});
await recordImageAddHistory(runner, {
articleId,
companyuserId,
fullHash,
sort: effectiveSort,
});
}
return {

View File

@@ -1,6 +1,7 @@
import { DELETE_BY_ARTICLE_AND_HASH as MSSQL_QUERY } from '../../providers/mssql/queries/pic.js';
import { DELETE_BY_ARTICLE_AND_HASH as SQLITE_QUERY } from '../../providers/sqlite3/queries/pic.js';
import resolveArticleBySku from './resolveArticleBySku.js';
import { recordImageDeleteHistory } from '../articlehistory/record.js';
import makeRunner from '../runner.js';
export default function deleteImage(provider) {
@@ -21,8 +22,8 @@ export default function deleteImage(provider) {
* await store.article.deleteImage(42, 'SKU-1', 'abc123');
*/
return async (googleAuthId, sku, fullHash, tx) => {
const { articleId } = await resolve(googleAuthId, sku, tx);
const runner = makeRunner(provider, tx);
const runDelete = async (runner) => {
const { articleId, companyuserId } = await resolve(googleAuthId, sku, runner);
const result = await runner.query(sql, { articleId, fullHash });
if (!result.rowsAffected) {
@@ -36,6 +37,21 @@ export default function deleteImage(provider) {
await provider.deletePic(fullHash);
}
}
await recordImageDeleteHistory(runner, {
articleId,
companyuserId,
fullHash,
});
};
if (tx) {
return runDelete(makeRunner(provider, tx));
}
if (typeof provider?.transaction === 'function') {
return provider.transaction(runDelete);
}
return runDelete(makeRunner(provider));
};
}

View File

@@ -1,6 +1,7 @@
import * as mssqlPic from '../../providers/mssql/queries/articlepic.js';
import * as sqlitePic from '../../providers/sqlite3/queries/articlepic.js';
import resolveArticleBySku from './resolveArticleBySku.js';
import { recordImageOrderHistory } from '../articlehistory/record.js';
import makeRunner from '../runner.js';
export default function orderImages(provider) {
@@ -29,7 +30,7 @@ export default function orderImages(provider) {
}
const runOrder = async (runner) => {
const { articleId } = await resolve(googleAuthId, sku, runner);
const { articleId, companyuserId } = await resolve(googleAuthId, sku, runner);
const current = await runner.query(queries.LIST_HASHES_BY_ARTICLE, { articleId });
const existing = new Set(current.rows.map((r) => r.fullHash));
@@ -60,6 +61,16 @@ export default function orderImages(provider) {
}
}
const oldOrder = current.rows.map((r) => r.fullHash);
const isSameOrder = oldOrder.length === fullHashes.length && oldOrder.every((h, i) => h === fullHashes[i]);
if (!isSameOrder) {
await recordImageOrderHistory(runner, {
articleId,
companyuserId,
fullHashes,
});
}
return { fullHashes };
};

File diff suppressed because it is too large Load Diff

View File

@@ -626,6 +626,12 @@ describe('store.article', () => {
() => store.article.deleteImage(gid, art.sku, img2.fullHash),
{ message: 'Image not found' },
);
const history = await store.article.getHistoryBySku(gid, art.sku);
const texts = history.map((h) => h.text);
assert.ok(texts.some((t) => t.includes('Bild hinzugefügt')));
assert.ok(texts.some((t) => t.includes('Bildreihenfolge geändert')));
assert.ok(texts.some((t) => t.includes('Bild gelöscht')));
});
});