6.4 KiB
libdashstore
MSSQL schema + domain API for Dash. One class, methods mirror the file path under src/store/.
import sql from 'mssql';
import LibDashStore from 'libdashstore';
const pool = await sql.connect({ /* … */ });
const client = await new LibDashStore(pool); // runs initialize() (ensure schema, no purge)
SQL lives in src/sql/<table>.js. Schema DDL: src/schema.js / import 'libdashstore/schema'.
ID fields in the JS API use camelCase …Id (DB columns stay snake_case). googleAuthId is always google_auth.id (the logged-in user), not companyuser.id.
Schema
Kein Migrations-Code: Wir gehen von einer frischen DB aus (npm run reset-db). Schema nur in src/schema.js; Anpassungen an einer laufenden DB manuell per sqlcmd, nicht im Repo.
| Method | Description |
|---|---|
initialize() |
Runs all SCHEMA_SCRIPTS (IF NOT EXISTS). Does not purge. |
purge() |
Drops all known tables + number procedure. |
company
| Method | Signature | Returns |
|---|---|---|
create |
({ iso639, name, taxrate, reducedtaxrate, googleAuthId }) |
{ id, rootCategoryId, languageId, taxrateId, reducedtaxrateId, taxfreerateId } |
update |
(id, { iso639, name, taxrate, reducedtaxrate }) |
{ id, rootCategoryId, languageId, taxrateId, reducedtaxrateId, taxfreerateId } |
delete |
(companyId) |
void |
list |
(googleAuthId) |
{ id, name, rootCategoryId, languageId, taxrate, reducedtaxrate, taxfreerate }[] |
create (transaction)
For POST /api/company:
- Fails if
nameis taken (Company name not available) - Ensures language by
iso639(get or create) - Ensures tax rows for
taxrate,reducedtaxrate, and0→taxfreerateId - Creates root category (
parentId = null) - Inserts company with all FKs set
- Links creator as
companyuser(googleAuthId→company_id)
company.poscustomergroup_id (optional) points at the customergroup used for POS pricing in getTreeForCompany articles.
list
Returns only companies where googleAuthId has a companyuser row.
update (transaction)
For PATCH /api/company/:id:
- Fails if company missing / name taken by another company
- Ensures lang + tax rates
- Updates
name,default_language_id,taxrate,reducedtaxrate
(taxfreerateId/ root category unchanged)
google_auth
| Method | Signature | Returns |
|---|---|---|
add |
(email) |
id |
getByEmail |
(email) |
{ id, email, createdAt, selectedCompanyId } | undefined |
listAllowedEmails |
() |
{ id, email, createdAt, selectedCompanyId }[] |
removeAllowedEmail |
(email) |
void |
setSelectedCompany |
(googleAuthId, companyId) |
void |
Backend mapping:
- Login:
getByEmail(email) - CLI user manager:
listAllowedEmails()/removeAllowedEmail(email)/add(email) PUT /api/auth/selected-company:setSelectedCompany(googleAuthId, companyId)
companyuser
| Method | Signature | Returns |
|---|---|---|
add |
(companyId, googleAuthId) |
id |
getByEmail |
(email) |
id[] |
delete |
(id) |
void |
lang
| Method | Signature | Returns |
|---|---|---|
create |
(iso639) |
id |
getByIso639 |
(iso639) |
{ id, iso639 } | undefined |
ensure |
(iso639, tx?) |
id |
list |
() |
{ id, iso639 }[] |
delete |
(id) |
void |
tax
| Method | Signature | Returns |
|---|---|---|
create |
(rate) |
id |
getByRate |
(rate) |
{ id, rate } | undefined |
ensure |
(rate, tx?) |
id |
list |
() |
{ id, rate }[] |
category
| Method | Signature | Returns |
|---|---|---|
createUnderParent |
({ googleAuthId, parentId, name }) |
{ id, parentId, sort, name } |
delete |
({ googleAuthId, id }) |
void — blocked by FK if categoryarticle or child categories remain |
getTreeForCompany |
(googleAuthId, companyId) |
{ languageId, tree, articles } |
getCategoryArticles |
(googleAuthId, categoryId) |
{ id, sku, name, slug, net, taxRate, optionsCount, articleListCount, childCount, thumbW, thumbH, thumbHash }[] |
createUnderParent (transaction)
parentIdexists, elseParent not found- Walk ancestors to root; find
companywithroot_category_id= root companyuserfor(googleAuthId, companyId), elseNot authorized- Insert
category(next siblingsort) +categorytext(name, slugifiedslug, company default language)
getTreeForCompany throws Not authorized if googleAuthId is not a companyuser of companyId, and Company not found if the company is missing, has no root_category_id, or no default_language_id.
article
| Method | Signature | Returns |
|---|---|---|
createUnderParent |
({ googleAuthId, parentId, name }) |
{ id, parentId, name, sku } |
parentId is the category id. Creates article + articletext (company default language) + categoryarticle in one transaction. Allocates sku via getnextnumberwithprefixandpadding (type sku; creates numbers row with empty prefix if missing). Default unit pc is ensured if missing (unitamount 1, weight 0).
Auth via resolveCategoryAccess(googleAuthId, parentId) — Parent not found / Not authorized.
Backend route cheatsheet
| Route | Store call |
|---|---|
POST /api/company |
company.create({ iso639, name, taxrate, reducedtaxrate, googleAuthId }) |
GET /api/company |
company.list(googleAuthId) |
PATCH /api/company/:id |
company.update(id, { iso639, name, taxrate, reducedtaxrate }) |
DELETE /api/company/:id |
company.delete(id) |
PUT /api/auth/selected-company |
google_auth.setSelectedCompany(googleAuthId, companyId) |
GET /api/category/tree?companyId= |
category.getTreeForCompany(googleAuthId, companyId) |
POST /api/category |
category.createUnderParent({ googleAuthId, parentId, name }) |
DELETE /api/category/:id |
category.delete({ googleAuthId, id }) |
POST /api/article |
article.createUnderParent({ googleAuthId, parentId, name }) |
Scripts
npm run purge-db # drop all tables + procedure (wipe data)
npm run reset-db # purge + init-schema (empty DB, fresh schema)
npm run init-schema # ensure schema only (does NOT delete data)
npm run test:api # interactive API tester
npm run schema-graph # regenerate schema-graph.svg
Env: MSSQL_SERVER, MSSQL_DATABASE, MSSQL_USER, MSSQL_PASSWORD.