This commit is contained in:
seb
2026-08-01 02:15:21 +02:00
parent 59c874144b
commit 69a24192d3
8 changed files with 206 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
import { DELETE_BY_ARTICLE_AND_HASH } from '../../sql/pic.js';
import resolveArticleBySku from './resolveArticleBySku.js';
export default function deleteImage(pool) {
const resolve = resolveArticleBySku(pool);
return async (googleAuthId, sku, fullHash) => {
const { articleId } = await resolve(googleAuthId, sku);
const result = await pool
.request()
.input('articleId', articleId)
.input('fullHash', fullHash)
.query(DELETE_BY_ARTICLE_AND_HASH);
if (!result.rowsAffected[0]) {
throw new Error('Image not found');
}
};
}

View File

@@ -0,0 +1,70 @@
import {
LIST_HASHES_BY_ARTICLE,
SET_TEMP_SORTS,
UPDATE_SORT_BY_HASH,
} from '../../sql/articlepic.js';
import resolveArticleBySku from './resolveArticleBySku.js';
import request from '../request.js';
export default function orderImages(pool) {
const resolve = resolveArticleBySku(pool);
return async (googleAuthId, sku, { fullHashes }) => {
if (!Array.isArray(fullHashes)) {
throw new Error('Invalid image order');
}
const { articleId } = await resolve(googleAuthId, sku);
const current = await pool
.request()
.input('articleId', articleId)
.query(LIST_HASHES_BY_ARTICLE);
const existing = new Set(current.recordset.map((r) => r.fullHash));
if (fullHashes.length !== existing.size) {
throw new Error('Invalid image order');
}
const seen = new Set();
for (const fullHash of fullHashes) {
if (!existing.has(fullHash) || seen.has(fullHash)) {
throw new Error('Invalid image order');
}
seen.add(fullHash);
}
const tx = pool.transaction();
await tx.begin();
try {
await request(pool, tx)
.input('articleId', articleId)
.query(SET_TEMP_SORTS);
for (let sort = 0; sort < fullHashes.length; sort++) {
const update = await request(pool, tx)
.input('articleId', articleId)
.input('fullHash', fullHashes[sort])
.input('sort', sort)
.query(UPDATE_SORT_BY_HASH);
if (!update.rowsAffected[0]) {
throw new Error('Invalid image order');
}
}
await tx.commit();
return { fullHashes };
} catch (err) {
try {
await tx.rollback();
} catch {
// ignore
}
throw err;
}
};
}

View File

@@ -0,0 +1,25 @@
import { GET_CATEGORY_ID_BY_SKU } from '../../sql/article.js';
import resolveCategoryAccess from '../category/resolveCategoryAccess.js';
export default function resolveArticleBySku(pool) {
const access = resolveCategoryAccess(pool);
return async (googleAuthId, sku) => {
const lookup = await pool
.request()
.input('sku', sku)
.query(GET_CATEGORY_ID_BY_SKU);
const row = lookup.recordset[0];
if (!row?.categoryId || !row?.articleId) {
throw new Error('Article not found');
}
await access(googleAuthId, row.categoryId);
return {
articleId: row.articleId,
categoryId: row.categoryId,
};
};
}