This commit is contained in:
seb
2026-09-22 07:25:16 +02:00
parent 4ed6260e91
commit cca131d83a
148 changed files with 5343 additions and 3466 deletions

View File

@@ -1,39 +1,44 @@
import { DELETE_BY_COMPANY_AND_ID } from '../../providers/mssql/queries/brand.js';
import { DELETE_BY_COMPANY_AND_ID as MSSQL_DELETE } from '../../providers/mssql/queries/brand.js';
import { DELETE_BY_COMPANY_AND_ID as SQLITE_DELETE } from '../../providers/sqlite3/queries/brand.js';
import { isForeignKeyConstraintError } from '../../providers/provider.js';
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
import makeRunner from '../runner.js';
export default function del(pool) {
const access = resolveSelectedCompanyAccess(pool);
export default function del(provider) {
const access = resolveSelectedCompanyAccess(provider);
const sql = provider?.dialect === 'sqlite3' ? SQLITE_DELETE : MSSQL_DELETE;
/**
* Deletes a brand for the user's selected company by its id.
*
* @param {number} googleAuthId - The id of the Google auth user.
* @param {number} id - The id of the brand to delete.
* @param {object} [tx] - Optional transaction to run within.
* @returns {Promise<void>}
* @throws {Error} If the brand is not found.
*
* @example
* await store.brand.delete(42, 3);
*/
return async (googleAuthId, id) => {
return async (googleAuthId, id, tx) => {
if (!Number.isFinite(id)) {
throw new Error('Brand not found');
}
const { companyId } = await access(googleAuthId);
const runner = makeRunner(provider, tx);
const { companyId } = await access(googleAuthId, tx);
try {
const result = await pool
.request()
.input('id', id)
.input('companyId', companyId)
.query(DELETE_BY_COMPANY_AND_ID);
const result = await runner.query(sql, {
id,
companyId,
});
if (!result.rowsAffected[0]) {
if (!result.rowsAffected) {
throw new Error('Brand not found');
}
} catch (err) {
if (err.number === 547) {
if (isForeignKeyConstraintError(err)) {
throw new Error('Brand in use');
}
throw err;

View File

@@ -1,27 +1,31 @@
import { LIST_BY_COMPANY } from '../../providers/mssql/queries/brand.js';
import { LIST_BY_COMPANY as MSSQL_LIST_BY_COMPANY } from '../../providers/mssql/queries/brand.js';
import { LIST_BY_COMPANY as SQLITE_LIST_BY_COMPANY } from '../../providers/sqlite3/queries/brand.js';
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
import makeRunner from '../runner.js';
export default function list(pool) {
const access = resolveSelectedCompanyAccess(pool);
export default function list(provider) {
const access = resolveSelectedCompanyAccess(provider);
const sql =
provider?.dialect === 'sqlite3'
? SQLITE_LIST_BY_COMPANY
: MSSQL_LIST_BY_COMPANY;
/**
* Lists the brands of the user's selected company.
*
* @param {number} googleAuthId - The id of the Google auth user.
* @param {object} [tx] - Optional transaction to run within.
* @returns {Promise<Array<{id: number, name: string, gsprpinfo: string|null}>>} The brands.
*
* @example
* const brands = await store.brand.list(42);
* // => [{ id, name, gsprpinfo }]
*/
return async (googleAuthId) => {
const { companyId } = await access(googleAuthId);
return async (googleAuthId, tx) => {
const { companyId } = await access(googleAuthId, tx);
const result = await pool
.request()
.input('companyId', companyId)
.query(LIST_BY_COMPANY);
const result = await makeRunner(provider, tx).query(sql, { companyId });
return result.recordset;
return result.rows;
};
}

View File

@@ -1,12 +1,24 @@
import {
CREATE,
GET_BY_COMPANY_AND_NAME,
UPDATE_BY_ID,
CREATE as MSSQL_CREATE,
GET_BY_COMPANY_AND_NAME as MSSQL_GET_BY_COMPANY_AND_NAME,
UPDATE_BY_ID as MSSQL_UPDATE_BY_ID,
} from '../../providers/mssql/queries/brand.js';
import {
CREATE as SQLITE_CREATE,
GET_BY_COMPANY_AND_NAME as SQLITE_GET_BY_COMPANY_AND_NAME,
UPDATE_BY_ID as SQLITE_UPDATE_BY_ID,
} from '../../providers/sqlite3/queries/brand.js';
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
import makeRunner from '../runner.js';
export default function upsert(pool) {
const access = resolveSelectedCompanyAccess(pool);
export default function upsert(provider) {
const access = resolveSelectedCompanyAccess(provider);
const isSqlite = provider?.dialect === 'sqlite3';
const getSql = isSqlite
? SQLITE_GET_BY_COMPANY_AND_NAME
: MSSQL_GET_BY_COMPANY_AND_NAME;
const updateSql = isSqlite ? SQLITE_UPDATE_BY_ID : MSSQL_UPDATE_BY_ID;
const createSql = isSqlite ? SQLITE_CREATE : MSSQL_CREATE;
/**
* Creates or updates a brand for the user's selected company, keyed by name.
@@ -15,6 +27,7 @@ export default function upsert(pool) {
* @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}>} The upserted brand.
* @throws {Error} If the brand is invalid.
*
@@ -22,42 +35,42 @@ export default function upsert(pool) {
* const brand = await store.brand.upsert(42, { name: 'Coca-Cola', gsprpinfo: 'x' });
* // => { id, name, gsprpinfo }
*/
return async (googleAuthId, input = {}) => {
return async (googleAuthId, input = {}, tx) => {
const name = input.name?.trim();
if (!name) {
throw new Error('Invalid brand');
}
const gsprpinfo = input.gsprpinfo ?? null;
const { companyId } = await access(googleAuthId);
const runner = makeRunner(provider, tx);
const { companyId } = await access(googleAuthId, tx);
const existing = await pool
.request()
.input('companyId', companyId)
.input('name', name)
.query(GET_BY_COMPANY_AND_NAME);
const existing = await runner.query(getSql, {
companyId,
name,
});
if (existing.recordset[0]) {
const { id } = existing.recordset[0];
await pool
.request()
.input('id', id)
.input('companyId', companyId)
.input('name', name)
.input('gsprpinfo', gsprpinfo)
.query(UPDATE_BY_ID);
if (existing.rows[0]) {
const { id } = existing.rows[0];
await runner.query(updateSql, {
id,
companyId,
name,
gsprpinfo,
});
return { id, name, gsprpinfo };
}
const created = await pool
.request()
.input('companyId', companyId)
.input('name', name)
.input('gsprpinfo', gsprpinfo)
.query(CREATE);
const created = await runner.query(createSql, {
companyId,
name,
gsprpinfo,
});
const id = created.rows[0]?.id ?? created.insertId;
return {
id: created.recordset[0].id,
id,
name,
gsprpinfo,
};