Add article.listSearchIndex for client-side search preload

Returns all company articles with id, sku, name, and eans as a flat
array. Walks the category tree to find reachable articles. Single
query using recursive CTE + FOR JSON for eans.
This commit is contained in:
seb
2026-08-03 22:31:36 +02:00
parent eaf4df4f5a
commit 84bb561031
4 changed files with 70 additions and 1 deletions

View File

@@ -20,6 +20,7 @@ import articleOrderImages from './store/article/orderImages.js';
import articleAddImage from './store/article/addImage.js';
import articleCreateUnderParent from './store/article/createUnderParent.js';
import articleGetBySku from './store/article/getBySku.js';
import articleListSearchIndex from './store/article/listSearchIndex.js';
import articleUpdateBySku from './store/article/updateBySku.js';
import articleSetPricesBySku from './store/article/setPricesBySku.js';
import articleSetEansBySku from './store/article/setEansBySku.js';
@@ -95,6 +96,7 @@ export default class LibDashStore {
this.article = {
createUnderParent: articleCreateUnderParent(pool),
getBySku: articleGetBySku(pool),
listSearchIndex: articleListSearchIndex(pool),
updateBySku: articleUpdateBySku(pool),
setPricesBySku: articleSetPricesBySku(pool),
setEansBySku: articleSetEansBySku(pool),

View File

@@ -160,6 +160,46 @@ FROM brand
WHERE id = @brandId AND company_id = @companyId
`;
/**
* Company-wide article search index.
* Returns one row per article with id, sku, name, and all eans as a JSON array.
* Used by the client for local search / autocomplete.
*/
export const SEARCH_ARTICLES = `
;WITH category_tree AS (
SELECT id
FROM category
WHERE id = @rootCategoryId
UNION ALL
SELECT c.id
FROM category c
INNER JOIN category_tree ct ON c.parent_id = ct.id
)
SELECT
a.id,
a.sku,
at.name,
(
SELECT ae.ean
FROM articleean ae
WHERE ae.article_id = a.id
ORDER BY ae.ean
FOR JSON PATH
) AS eansJson
FROM article a
LEFT JOIN articletext at
ON at.article_id = a.id AND at.language_id = @languageId
WHERE EXISTS (
SELECT 1
FROM categoryarticle ca
INNER JOIN category_tree ct ON ct.id = ca.category_id
WHERE ca.article_id = a.id
)
ORDER BY a.id
`;
/**
* Single-query replacement for resolveArticleBySku + queryBySku.
* Resolves SKU → article + company + auth, then loads full article detail

View File

@@ -0,0 +1,23 @@
import { SEARCH_ARTICLES } from '../../sql/article.js';
import resolveCompanyAccess from '../companyuser/resolveCompanyAccess.js';
export default function listSearchIndex(pool) {
const access = resolveCompanyAccess(pool);
return async (googleAuthId, companyId) => {
const { rootCategoryId, languageId } = await access(googleAuthId, companyId);
const result = await pool
.request()
.input('rootCategoryId', rootCategoryId)
.input('languageId', languageId)
.query(SEARCH_ARTICLES);
return result.recordset.map((row) => ({
id: row.id,
sku: row.sku,
name: row.name,
eans: row.eansJson ? JSON.parse(row.eansJson).map((r) => r.ean) : [],
}));
};
}