Add entity customer numbers and scope APIs via selected company.

Entity gets an optional unique-per-company number with allocate/peek/isNumberFree helpers. Company-scoped store methods no longer take companyId and resolve google_auth.selected_company instead.
This commit is contained in:
seb
2026-08-07 04:29:35 +02:00
parent 1e89e19863
commit 70e0a9ddc4
78 changed files with 940 additions and 772 deletions

View File

@@ -15,7 +15,7 @@ import {
SUPPLIER_GROUP_NAME,
} from '../../sql/entity.js';
import request from '../request.js';
import resolveCompanyAccess from '../companyuser/resolveCompanyAccess.js';
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
import taxEnsure from '../tax/ensure.js';
function shapeSummary(type, row) {
@@ -179,7 +179,7 @@ async function loadDoc(pool, tx, { type, companyId, id }) {
* `label` → error prefix (`Quote` / `Order` → "Quote not found")
*/
export default function createManifestDocStore(pool, { type, label }) {
const access = resolveCompanyAccess(pool);
const access = resolveSelectedCompanyAccess(pool);
const ensureTax = taxEnsure(pool);
const notFound = `${label} not found`;
const invalid = `Invalid ${label.toLowerCase()}`;
@@ -188,11 +188,10 @@ export default function createManifestDocStore(pool, { type, label }) {
* Lists the quote/order documents of a company.
*
* @param {number} googleAuthId - The Google auth user id.
* @param {number} companyId - The company id.
* @returns {Promise<Array<object>>} The document summaries.
*/
async function list(googleAuthId, companyId) {
await access(googleAuthId, companyId);
async function list(googleAuthId) {
const { companyId } = await access(googleAuthId);
const result = await pool
.request()
@@ -207,16 +206,15 @@ export default function createManifestDocStore(pool, { type, label }) {
* Returns a single quote/order document by its id within a company.
*
* @param {number} googleAuthId - The Google auth user id.
* @param {number} companyId - The company id.
* @param {number} id - The document id.
* @returns {Promise<object|null>} The document with its lines, or null if not found.
*/
async function getById(googleAuthId, companyId, id) {
async function getById(googleAuthId, id) {
if (!Number.isFinite(id)) {
throw new Error(notFound);
}
await access(googleAuthId, companyId);
const { companyId } = await access(googleAuthId);
const doc = await loadDoc(pool, null, { type, companyId, id });
if (!doc) {
@@ -229,11 +227,10 @@ export default function createManifestDocStore(pool, { type, label }) {
* Creates a new quote/order document with its lines.
*
* @param {number} googleAuthId - The Google auth user id.
* @param {number} companyId - The company id.
* @param {object} body - The document payload (`number`, `date`, `entityId`, `lines`).
* @returns {Promise<object>} The created document with its lines.
*/
async function create(googleAuthId, companyId, body = {}) {
async function create(googleAuthId, body = {}) {
const number = body.number?.trim?.() ? body.number.trim() : null;
const date = parseDate(body.date);
if (!number || !date) {
@@ -241,7 +238,7 @@ export default function createManifestDocStore(pool, { type, label }) {
}
const lines = normalizeLines(body.lines ?? []);
const { rootCategoryId } = await access(googleAuthId, companyId);
const { companyId, rootCategoryId } = await access(googleAuthId);
const tx = pool.transaction();
await tx.begin();
@@ -288,12 +285,11 @@ export default function createManifestDocStore(pool, { type, label }) {
* Updates a quote/order document's header and/or lines.
*
* @param {number} googleAuthId - The Google auth user id.
* @param {number} companyId - The company id.
* @param {number} id - The document id.
* @param {object} patch - The fields to update (`number`, `date`, `entityId`, `lines`).
* @returns {Promise<object>} The updated document with its lines.
*/
async function update(googleAuthId, companyId, id, patch = {}) {
async function update(googleAuthId, id, patch = {}) {
if (!Number.isFinite(id)) {
throw new Error(notFound);
}
@@ -312,7 +308,7 @@ export default function createManifestDocStore(pool, { type, label }) {
normalizedLines = normalizeLines(patch.lines);
}
const { rootCategoryId } = await access(googleAuthId, companyId);
const { companyId, rootCategoryId } = await access(googleAuthId);
const tx = pool.transaction();
await tx.begin();
@@ -396,16 +392,15 @@ export default function createManifestDocStore(pool, { type, label }) {
* Deletes a quote/order document by its id within a company.
*
* @param {number} googleAuthId - The Google auth user id.
* @param {number} companyId - The company id.
* @param {number} id - The document id.
* @returns {Promise<void>}
*/
async function del(googleAuthId, companyId, id) {
async function del(googleAuthId, id) {
if (!Number.isFinite(id)) {
throw new Error(notFound);
}
await access(googleAuthId, companyId);
const { companyId } = await access(googleAuthId);
const result = await pool
.request()