all
This commit is contained in:
1 parent
90125aede9
commit
2d6c29a1f3
404 files changed
+126983
-85
No files matched your search
@@ -0,0 +1,6 @@
|
||||
src/prisma/contract.json linguist-generated
|
||||
src/prisma/contract.d.ts linguist-generated
|
||||
src/prisma/ops.json linguist-generated
|
||||
src/prisma/migration.json linguist-generated
|
||||
migrations/snapshots/**/contract.json linguist-generated
|
||||
migrations/snapshots/**/contract.d.ts linguist-generated
|
||||
@@ -0,0 +1,3 @@
|
||||
node_modules/
|
||||
dist/
|
||||
.env
|
||||
@@ -0,0 +1,363 @@
|
||||
#!/usr/bin/env -S node
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const contract_json_1 = __importDefault(require("../../snapshots/a6d994c8ca49497bbabf294eb5fe9e8feb2cdafb62dfaf7c9a5b2c2e9135a15f/contract.json"));
|
||||
const migration_1 = require("@prisma/orm-postgres/migration");
|
||||
class M extends migration_1.Migration {
|
||||
endContractJson = contract_json_1.default;
|
||||
get operations() {
|
||||
return [
|
||||
this.createSchema({ schema: 'public' }),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'cart_products',
|
||||
columns: [
|
||||
(0, migration_1.col)('cartId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('historyId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('quantity', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
],
|
||||
constraints: [(0, migration_1.primaryKey)(['cartId', 'historyId'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'category',
|
||||
columns: [
|
||||
(0, migration_1.col)('createdAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
default: (0, migration_1.fn)('now()'),
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
(0, migration_1.col)('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('name', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
],
|
||||
constraints: [(0, migration_1.primaryKey)(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'inventory',
|
||||
columns: [
|
||||
(0, migration_1.col)('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('name', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
],
|
||||
constraints: [(0, migration_1.primaryKey)(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'payment',
|
||||
columns: [
|
||||
(0, migration_1.col)('cartId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('createdAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
default: (0, migration_1.fn)('now()'),
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
(0, migration_1.col)('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('orderId', 'int4', { codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('paid', 'bool', {
|
||||
notNull: true,
|
||||
default: (0, migration_1.lit)(false),
|
||||
codecRef: { codecId: 'pg/bool@1' },
|
||||
}),
|
||||
(0, migration_1.col)('paidAt', 'timestamptz', { codecRef: { codecId: 'pg/timestamptz-string@1' } }),
|
||||
(0, migration_1.col)('paymentMethod', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
(0, migration_1.col)('status', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
(0, migration_1.col)('terminalId', 'int4', { codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('userId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
],
|
||||
constraints: [(0, migration_1.primaryKey)(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'product',
|
||||
columns: [
|
||||
(0, migration_1.col)('createdAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
default: (0, migration_1.fn)('now()'),
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
(0, migration_1.col)('description', 'text', { codecRef: { codecId: 'pg/text@1' } }),
|
||||
(0, migration_1.col)('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('name', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
(0, migration_1.col)('sku', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
(0, migration_1.col)('supplierId', 'int4', { codecRef: { codecId: 'pg/int4@1' } }),
|
||||
],
|
||||
constraints: [(0, migration_1.primaryKey)(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'product_category',
|
||||
columns: [
|
||||
(0, migration_1.col)('categoryId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('productId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
],
|
||||
constraints: [(0, migration_1.primaryKey)(['productId', 'categoryId'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'product_history',
|
||||
columns: [
|
||||
(0, migration_1.col)('costUnit', 'numeric', { notNull: true, codecRef: { codecId: 'pg/numeric@1' } }),
|
||||
(0, migration_1.col)('createdAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
default: (0, migration_1.fn)('now()'),
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
(0, migration_1.col)('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('productId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('soldAt', 'timestamptz', { codecRef: { codecId: 'pg/timestamptz-string@1' } }),
|
||||
(0, migration_1.col)('status', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
(0, migration_1.col)('unitPrice', 'numeric', { notNull: true, codecRef: { codecId: 'pg/numeric@1' } }),
|
||||
],
|
||||
constraints: [(0, migration_1.primaryKey)(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'shop_cart',
|
||||
columns: [
|
||||
(0, migration_1.col)('createdAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
default: (0, migration_1.fn)('now()'),
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
(0, migration_1.col)('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('totalPrice', 'numeric', { notNull: true, codecRef: { codecId: 'pg/numeric@1' } }),
|
||||
(0, migration_1.col)('userId', 'int4', { codecRef: { codecId: 'pg/int4@1' } }),
|
||||
],
|
||||
constraints: [(0, migration_1.primaryKey)(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'supplier',
|
||||
columns: [
|
||||
(0, migration_1.col)('createdAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
default: (0, migration_1.fn)('now()'),
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
(0, migration_1.col)('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('lastSupply', 'timestamptz', { codecRef: { codecId: 'pg/timestamptz-string@1' } }),
|
||||
(0, migration_1.col)('name', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
],
|
||||
constraints: [(0, migration_1.primaryKey)(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'user',
|
||||
columns: [
|
||||
(0, migration_1.col)('createdAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
default: (0, migration_1.fn)('now()'),
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
(0, migration_1.col)('email', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
(0, migration_1.col)('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('name', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
(0, migration_1.col)('password', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
(0, migration_1.col)('role', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
(0, migration_1.col)('updatedAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
],
|
||||
constraints: [(0, migration_1.primaryKey)(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'warehouse',
|
||||
columns: [
|
||||
(0, migration_1.col)('inventoryId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('productId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
(0, migration_1.col)('stock', 'int4', {
|
||||
notNull: true,
|
||||
default: (0, migration_1.lit)(0),
|
||||
codecRef: { codecId: 'pg/int4@1' },
|
||||
}),
|
||||
],
|
||||
constraints: [(0, migration_1.primaryKey)(['inventoryId', 'productId'])],
|
||||
}),
|
||||
this.addUnique({
|
||||
schema: 'public',
|
||||
table: 'product',
|
||||
constraint: 'product_sku_key',
|
||||
columns: ['sku'],
|
||||
}),
|
||||
this.addUnique({
|
||||
schema: 'public',
|
||||
table: 'user',
|
||||
constraint: 'user_email_key',
|
||||
columns: ['email'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'cart_products',
|
||||
index: 'cart_products_cartId_idx_79939295',
|
||||
columns: ['cartId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'cart_products',
|
||||
index: 'cart_products_historyId_idx_dfaba3ef',
|
||||
columns: ['historyId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'payment',
|
||||
index: 'payment_cartId_idx_79939295',
|
||||
columns: ['cartId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'payment',
|
||||
index: 'payment_userId_idx_a489d58a',
|
||||
columns: ['userId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'product',
|
||||
index: 'product_supplierId_idx_c4d9a8b9',
|
||||
columns: ['supplierId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'product_category',
|
||||
index: 'product_category_categoryId_idx_15c304f2',
|
||||
columns: ['categoryId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'product_category',
|
||||
index: 'product_category_productId_idx_5858600a',
|
||||
columns: ['productId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'product_history',
|
||||
index: 'product_history_productId_idx_5858600a',
|
||||
columns: ['productId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'shop_cart',
|
||||
index: 'shop_cart_userId_idx_a489d58a',
|
||||
columns: ['userId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'warehouse',
|
||||
index: 'warehouse_inventoryId_idx_367f33d0',
|
||||
columns: ['inventoryId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'warehouse',
|
||||
index: 'warehouse_productId_idx_5858600a',
|
||||
columns: ['productId'],
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'cart_products',
|
||||
foreignKey: {
|
||||
name: 'cart_products_cartId_fkey',
|
||||
columns: ['cartId'],
|
||||
references: { schema: 'public', table: 'shop_cart', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'cart_products',
|
||||
foreignKey: {
|
||||
name: 'cart_products_historyId_fkey',
|
||||
columns: ['historyId'],
|
||||
references: { schema: 'public', table: 'product_history', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'payment',
|
||||
foreignKey: {
|
||||
name: 'payment_cartId_fkey',
|
||||
columns: ['cartId'],
|
||||
references: { schema: 'public', table: 'shop_cart', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'payment',
|
||||
foreignKey: {
|
||||
name: 'payment_userId_fkey',
|
||||
columns: ['userId'],
|
||||
references: { schema: 'public', table: 'user', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'product',
|
||||
foreignKey: {
|
||||
name: 'product_supplierId_fkey',
|
||||
columns: ['supplierId'],
|
||||
references: { schema: 'public', table: 'supplier', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'product_category',
|
||||
foreignKey: {
|
||||
name: 'product_category_productId_fkey',
|
||||
columns: ['productId'],
|
||||
references: { schema: 'public', table: 'product', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'product_category',
|
||||
foreignKey: {
|
||||
name: 'product_category_categoryId_fkey',
|
||||
columns: ['categoryId'],
|
||||
references: { schema: 'public', table: 'category', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'product_history',
|
||||
foreignKey: {
|
||||
name: 'product_history_productId_fkey',
|
||||
columns: ['productId'],
|
||||
references: { schema: 'public', table: 'product', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'shop_cart',
|
||||
foreignKey: {
|
||||
name: 'shop_cart_userId_fkey',
|
||||
columns: ['userId'],
|
||||
references: { schema: 'public', table: 'user', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'warehouse',
|
||||
foreignKey: {
|
||||
name: 'warehouse_inventoryId_fkey',
|
||||
columns: ['inventoryId'],
|
||||
references: { schema: 'public', table: 'inventory', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'warehouse',
|
||||
foreignKey: {
|
||||
name: 'warehouse_productId_fkey',
|
||||
columns: ['productId'],
|
||||
references: { schema: 'public', table: 'product', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
exports.default = M;
|
||||
migration_1.MigrationCLI.run(import.meta.url, M);
|
||||
//# sourceMappingURL=migration.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"migration.js","sourceRoot":"","sources":["migration.ts"],"names":[],"mappings":";;;;;;AAEA,mJAA+I;AAC/I,8DAAmG;AAEnG,MAAqB,CAAE,SAAQ,qBAAqB;IAChC,eAAe,GAAG,uBAAW,CAAC;IAEhD,IAAa,UAAU;QACrB,OAAO;YACL,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;YACvC,IAAI,CAAC,WAAW,CAAC;gBACf,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE;oBACP,IAAA,eAAG,EAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBAC5E,IAAA,eAAG,EAAC,WAAW,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBAC/E,IAAA,eAAG,EAAC,UAAU,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;iBAC/E;gBACD,WAAW,EAAE,CAAC,IAAA,sBAAU,EAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;aACnD,CAAC;YACF,IAAI,CAAC,WAAW,CAAC;gBACf,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,UAAU;gBACjB,OAAO,EAAE;oBACP,IAAA,eAAG,EAAC,WAAW,EAAE,aAAa,EAAE;wBAC9B,OAAO,EAAE,IAAI;wBACb,OAAO,EAAE,IAAA,cAAE,EAAC,OAAO,CAAC;wBACpB,QAAQ,EAAE,EAAE,OAAO,EAAE,yBAAyB,EAAE;qBACjD,CAAC;oBACF,IAAA,eAAG,EAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBAC1E,IAAA,eAAG,EAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;iBAC3E;gBACD,WAAW,EAAE,CAAC,IAAA,sBAAU,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC;aAClC,CAAC;YACF,IAAI,CAAC,WAAW,CAAC;gBACf,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,WAAW;gBAClB,OAAO,EAAE;oBACP,IAAA,eAAG,EAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBAC1E,IAAA,eAAG,EAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;iBAC3E;gBACD,WAAW,EAAE,CAAC,IAAA,sBAAU,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC;aAClC,CAAC;YACF,IAAI,CAAC,WAAW,CAAC;gBACf,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,SAAS;gBAChB,OAAO,EAAE;oBACP,IAAA,eAAG,EAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBAC5E,IAAA,eAAG,EAAC,WAAW,EAAE,aAAa,EAAE;wBAC9B,OAAO,EAAE,IAAI;wBACb,OAAO,EAAE,IAAA,cAAE,EAAC,OAAO,CAAC;wBACpB,QAAQ,EAAE,EAAE,OAAO,EAAE,yBAAyB,EAAE;qBACjD,CAAC;oBACF,IAAA,eAAG,EAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBAC1E,IAAA,eAAG,EAAC,SAAS,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBAC9D,IAAA,eAAG,EAAC,MAAM,EAAE,MAAM,EAAE;wBAClB,OAAO,EAAE,IAAI;wBACb,OAAO,EAAE,IAAA,eAAG,EAAC,KAAK,CAAC;wBACnB,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE;qBACnC,CAAC;oBACF,IAAA,eAAG,EAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,yBAAyB,EAAE,EAAE,CAAC;oBAClF,IAAA,eAAG,EAAC,eAAe,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBACnF,IAAA,eAAG,EAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBAC5E,IAAA,eAAG,EAAC,YAAY,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBACjE,IAAA,eAAG,EAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;iBAC7E;gBACD,WAAW,EAAE,CAAC,IAAA,sBAAU,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC;aAClC,CAAC;YACF,IAAI,CAAC,WAAW,CAAC;gBACf,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,SAAS;gBAChB,OAAO,EAAE;oBACP,IAAA,eAAG,EAAC,WAAW,EAAE,aAAa,EAAE;wBAC9B,OAAO,EAAE,IAAI;wBACb,OAAO,EAAE,IAAA,cAAE,EAAC,OAAO,CAAC;wBACpB,QAAQ,EAAE,EAAE,OAAO,EAAE,yBAAyB,EAAE;qBACjD,CAAC;oBACF,IAAA,eAAG,EAAC,aAAa,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBAClE,IAAA,eAAG,EAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBAC1E,IAAA,eAAG,EAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBAC1E,IAAA,eAAG,EAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBACzE,IAAA,eAAG,EAAC,YAAY,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;iBAClE;gBACD,WAAW,EAAE,CAAC,IAAA,sBAAU,EAAC,CAAC,IAAI,CAAC,CAAC,CAAC;aAClC,CAAC;YACF,IAAI,CAAC,WAAW,CAAC;gBACf,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,kBAAkB;gBACzB,OAAO,EAAE;oBACP,IAAA,eAAG,EAAC,YAAY,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBAChF,IAAA,eAAG,EAAC,WAAW,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;iBAChF;gBACD,WAAW,EAAE,CAAC,IAAA,sBAAU,EAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;aACvD,CAAC;YACF,IAAI,CAAC,WAAW,CAAC;gBACf,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,iBAAiB;gBACxB,OAAO,EAAE;oBACP,IAAA,eAAG,EAAC,UAAU,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,CAAC;oBACpF,IAAA,eAAG,EAAC,WAAW,EAAE,aAAa,EAAE;wBAC9B,OAAO,EAAE,IAAI;wBACb,OAAO,EAAE,IAAA,cAAE,EAAC,OAAO,CAAC;wBACpB,QAAQ,EAAE,EAAE,OAAO,EAAE,yBAAyB,EAAE;qBACjD,CAAC;oBACF,IAAA,eAAG,EAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBAC1E,IAAA,eAAG,EAAC,WAAW,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;oBAC/E,IAAA,eAAG,EAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,yBAAyB,EAAE,EAAE,CAAC;oBAClF,IAAA,eAAG,EAAC,QAAQ,EAAE,MAAM,EAAE,Line truncated
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"from": null,
|
||||
"to": "a6d994c8ca49497bbabf294eb5fe9e8feb2cdafb62dfaf7c9a5b2c2e9135a15f",
|
||||
"providedInvariants": [],
|
||||
"createdAt": "2026-09-28T19:10:54.766Z",
|
||||
"migrationHash": "e54c1d31bafdfcf8fbbf8ac2f901f904562be301481a310ae7e89b870eb58457"
|
||||
}
|
||||
+360
@@ -0,0 +1,360 @@
|
||||
#!/usr/bin/env -S node
|
||||
import type { Contract as End } from '../../snapshots/a6d994c8ca49497bbabf294eb5fe9e8feb2cdafb62dfaf7c9a5b2c2e9135a15f/contract';
|
||||
import endContract from '../../snapshots/a6d994c8ca49497bbabf294eb5fe9e8feb2cdafb62dfaf7c9a5b2c2e9135a15f/contract.json' with { type: 'json' };
|
||||
import { Migration, MigrationCLI, col, fn, lit, primaryKey } from '@prisma/orm-postgres/migration';
|
||||
|
||||
export default class M extends Migration<never, End> {
|
||||
override readonly endContractJson = endContract;
|
||||
|
||||
override get operations() {
|
||||
return [
|
||||
this.createSchema({ schema: 'public' }),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'cart_products',
|
||||
columns: [
|
||||
col('cartId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('historyId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('quantity', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
],
|
||||
constraints: [primaryKey(['cartId', 'historyId'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'category',
|
||||
columns: [
|
||||
col('createdAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
default: fn('now()'),
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
col('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('name', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
],
|
||||
constraints: [primaryKey(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'inventory',
|
||||
columns: [
|
||||
col('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('name', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
],
|
||||
constraints: [primaryKey(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'payment',
|
||||
columns: [
|
||||
col('cartId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('createdAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
default: fn('now()'),
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
col('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('orderId', 'int4', { codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('paid', 'bool', {
|
||||
notNull: true,
|
||||
default: lit(false),
|
||||
codecRef: { codecId: 'pg/bool@1' },
|
||||
}),
|
||||
col('paidAt', 'timestamptz', { codecRef: { codecId: 'pg/timestamptz-string@1' } }),
|
||||
col('paymentMethod', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
col('status', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
col('terminalId', 'int4', { codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('userId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
],
|
||||
constraints: [primaryKey(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'product',
|
||||
columns: [
|
||||
col('createdAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
default: fn('now()'),
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
col('description', 'text', { codecRef: { codecId: 'pg/text@1' } }),
|
||||
col('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('name', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
col('sku', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
col('supplierId', 'int4', { codecRef: { codecId: 'pg/int4@1' } }),
|
||||
],
|
||||
constraints: [primaryKey(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'product_category',
|
||||
columns: [
|
||||
col('categoryId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('productId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
],
|
||||
constraints: [primaryKey(['productId', 'categoryId'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'product_history',
|
||||
columns: [
|
||||
col('costUnit', 'numeric', { notNull: true, codecRef: { codecId: 'pg/numeric@1' } }),
|
||||
col('createdAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
default: fn('now()'),
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
col('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('productId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('soldAt', 'timestamptz', { codecRef: { codecId: 'pg/timestamptz-string@1' } }),
|
||||
col('status', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
col('unitPrice', 'numeric', { notNull: true, codecRef: { codecId: 'pg/numeric@1' } }),
|
||||
],
|
||||
constraints: [primaryKey(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'shop_cart',
|
||||
columns: [
|
||||
col('createdAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
default: fn('now()'),
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
col('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('totalPrice', 'numeric', { notNull: true, codecRef: { codecId: 'pg/numeric@1' } }),
|
||||
col('userId', 'int4', { codecRef: { codecId: 'pg/int4@1' } }),
|
||||
],
|
||||
constraints: [primaryKey(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'supplier',
|
||||
columns: [
|
||||
col('createdAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
default: fn('now()'),
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
col('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('lastSupply', 'timestamptz', { codecRef: { codecId: 'pg/timestamptz-string@1' } }),
|
||||
col('name', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
],
|
||||
constraints: [primaryKey(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'user',
|
||||
columns: [
|
||||
col('createdAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
default: fn('now()'),
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
col('email', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
col('id', 'SERIAL', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('name', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
col('password', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
col('role', 'text', { notNull: true, codecRef: { codecId: 'pg/text@1' } }),
|
||||
col('updatedAt', 'timestamptz', {
|
||||
notNull: true,
|
||||
codecRef: { codecId: 'pg/timestamptz-string@1' },
|
||||
}),
|
||||
],
|
||||
constraints: [primaryKey(['id'])],
|
||||
}),
|
||||
this.createTable({
|
||||
schema: 'public',
|
||||
table: 'warehouse',
|
||||
columns: [
|
||||
col('inventoryId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('productId', 'int4', { notNull: true, codecRef: { codecId: 'pg/int4@1' } }),
|
||||
col('stock', 'int4', {
|
||||
notNull: true,
|
||||
default: lit(0),
|
||||
codecRef: { codecId: 'pg/int4@1' },
|
||||
}),
|
||||
],
|
||||
constraints: [primaryKey(['inventoryId', 'productId'])],
|
||||
}),
|
||||
this.addUnique({
|
||||
schema: 'public',
|
||||
table: 'product',
|
||||
constraint: 'product_sku_key',
|
||||
columns: ['sku'],
|
||||
}),
|
||||
this.addUnique({
|
||||
schema: 'public',
|
||||
table: 'user',
|
||||
constraint: 'user_email_key',
|
||||
columns: ['email'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'cart_products',
|
||||
index: 'cart_products_cartId_idx_79939295',
|
||||
columns: ['cartId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'cart_products',
|
||||
index: 'cart_products_historyId_idx_dfaba3ef',
|
||||
columns: ['historyId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'payment',
|
||||
index: 'payment_cartId_idx_79939295',
|
||||
columns: ['cartId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'payment',
|
||||
index: 'payment_userId_idx_a489d58a',
|
||||
columns: ['userId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'product',
|
||||
index: 'product_supplierId_idx_c4d9a8b9',
|
||||
columns: ['supplierId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'product_category',
|
||||
index: 'product_category_categoryId_idx_15c304f2',
|
||||
columns: ['categoryId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'product_category',
|
||||
index: 'product_category_productId_idx_5858600a',
|
||||
columns: ['productId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'product_history',
|
||||
index: 'product_history_productId_idx_5858600a',
|
||||
columns: ['productId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'shop_cart',
|
||||
index: 'shop_cart_userId_idx_a489d58a',
|
||||
columns: ['userId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'warehouse',
|
||||
index: 'warehouse_inventoryId_idx_367f33d0',
|
||||
columns: ['inventoryId'],
|
||||
}),
|
||||
this.createIndex({
|
||||
schema: 'public',
|
||||
table: 'warehouse',
|
||||
index: 'warehouse_productId_idx_5858600a',
|
||||
columns: ['productId'],
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'cart_products',
|
||||
foreignKey: {
|
||||
name: 'cart_products_cartId_fkey',
|
||||
columns: ['cartId'],
|
||||
references: { schema: 'public', table: 'shop_cart', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'cart_products',
|
||||
foreignKey: {
|
||||
name: 'cart_products_historyId_fkey',
|
||||
columns: ['historyId'],
|
||||
references: { schema: 'public', table: 'product_history', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'payment',
|
||||
foreignKey: {
|
||||
name: 'payment_cartId_fkey',
|
||||
columns: ['cartId'],
|
||||
references: { schema: 'public', table: 'shop_cart', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'payment',
|
||||
foreignKey: {
|
||||
name: 'payment_userId_fkey',
|
||||
columns: ['userId'],
|
||||
references: { schema: 'public', table: 'user', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'product',
|
||||
foreignKey: {
|
||||
name: 'product_supplierId_fkey',
|
||||
columns: ['supplierId'],
|
||||
references: { schema: 'public', table: 'supplier', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'product_category',
|
||||
foreignKey: {
|
||||
name: 'product_category_productId_fkey',
|
||||
columns: ['productId'],
|
||||
references: { schema: 'public', table: 'product', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'product_category',
|
||||
foreignKey: {
|
||||
name: 'product_category_categoryId_fkey',
|
||||
columns: ['categoryId'],
|
||||
references: { schema: 'public', table: 'category', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'product_history',
|
||||
foreignKey: {
|
||||
name: 'product_history_productId_fkey',
|
||||
columns: ['productId'],
|
||||
references: { schema: 'public', table: 'product', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'shop_cart',
|
||||
foreignKey: {
|
||||
name: 'shop_cart_userId_fkey',
|
||||
columns: ['userId'],
|
||||
references: { schema: 'public', table: 'user', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'warehouse',
|
||||
foreignKey: {
|
||||
name: 'warehouse_inventoryId_fkey',
|
||||
columns: ['inventoryId'],
|
||||
references: { schema: 'public', table: 'inventory', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
this.addForeignKey({
|
||||
schema: 'public',
|
||||
table: 'warehouse',
|
||||
foreignKey: {
|
||||
name: 'warehouse_productId_fkey',
|
||||
columns: ['productId'],
|
||||
references: { schema: 'public', table: 'product', columns: ['id'] },
|
||||
},
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
MigrationCLI.run(import.meta.url, M);
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"hash": "b5e61e3bbb48a37870fbaa4f995b31a2f79884401b2346370519c5b9bf61e6d9",
|
||||
"invariants": []
|
||||
}
|
||||
Generated
Vendored
+2056
File diff suppressed because it is too large.
Load diff
+1
@@ -0,0 +1 @@
|
||||
{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{"postgres":{"distinctOn":true,"jsonAgg":true,"lateral":true,"limit":true,"orderBy":true,"returning":true},"sql":{"checkConstraint":true,"defaultInInsert":true,"enums":true,"insertOnConflictSkip":true,"insertOnConflictWithoutTarget":true,"lateral":true,"returning":true,"scalarList":true}},"domain":{"namespaces":{"public":{"models":{"CartProduct":{"fields":{"cartId":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"historyId":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"quantity":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}}},"relations":{"cart":{"cardinality":"N:1","nullable":false,"on":{"localFields":["cartId"],"targetFields":["id"]},"to":{"model":"ShopCart","namespace":"public"}},"history":{"cardinality":"N:1","nullable":false,"on":{"localFields":["historyId"],"targetFields":["id"]},"to":{"model":"ProductHistory","namespace":"public"}}},"storage":{"fields":{"cartId":{"column":"cartId"},"historyId":{"column":"historyId"},"quantity":{"column":"quantity"}},"namespaceId":"public","table":"cart_products"}},"Category":{"fields":{"createdAt":{"nullable":false,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}}},"relations":{"products":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["categoryId"]},"to":{"model":"ProductCategory","namespace":"public"}}},"storage":{"fields":{"createdAt":{"column":"createdAt"},"id":{"column":"id"},"name":{"column":"name"}},"namespaceId":"public","table":"category"}},"Inventory":{"fields":{"id":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}}},"relations":{"warehouses":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["inventoryId"]},"to":{"model":"Warehouse","namespace":"public"}}},"storage":{"fields":{"id":{"column":"id"},"name":{"column":"name"}},"namespaceId":"public","table":"inventory"}},"Payment":{"fields":{"cartId":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"createdAt":{"nullable":false,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"orderId":{"nullable":true,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"paid":{"nullable":false,"type":{"codecId":"pg/bool@1","kind":"scalar"}},"paidAt":{"nullable":true,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"paymentMethod":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}},"status":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}},"terminalId":{"nullable":true,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"userId":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}}},"relations":{"cart":{"cardinality":"N:1","nullable":false,"on":{"localFields":["cartId"],"targetFields":["id"]},"to":{"model":"ShopCart","namespace":"public"}},"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"public"}}},"storage":{"fields":{"cartId":{"column":"cartId"},"createdAt":{"column":"createdAt"},"id":{"column":"id"},"orderId":{"column":"orderId"},"paid":{"column":"paid"},"paidAt":{"column":"paidAt"},"paymentMethod":{"column":"paymentMethod"},"status":{"column":"status"},"terminalId":{"column":"terminalId"},"userId":{"column":"userId"}},"namespaceId":"public","table":"payment"}},"Product":{"fields":{"createdAt":{"nullable":false,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"description":{"nullable":true,"type":{"codecId":"pg/text@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}},"sku":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}},"supplierId":{"nullable":true,"type":{"codecId":"pg/int4@1","kind":"scalar"}}},"relations":{"categories":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["productId"]},"to":{"model":"ProductCategory","namespace":"public"}},"history":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["productId"]},"to":{"model":"ProductHistory","namespace":"public"}},"supplier":{"cardinality":"N:1","nullable":true,"on":{"localFields":["supplierId"],"targetFields":["id"]},"to":{"model":"Supplier","namespace":"public"}},"warehouses":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["productId"]},"to":{"model":"Warehouse","namespace":"public"}}},"storage":{"fields":{"createdAt":{"column":"createdAt"},"description":{"column":"description"},"id":{"column":"id"},"name":{"column":"name"Line truncated
|
||||
Generated
Vendored
+3592
File diff suppressed because it is too large.
Load diff
+1
@@ -0,0 +1 @@
|
||||
{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{"postgres":{"distinctOn":true,"jsonAgg":true,"lateral":true,"limit":true,"orderBy":true,"returning":true},"sql":{"checkConstraint":true,"defaultInInsert":true,"enums":true,"insertOnConflictSkip":true,"insertOnConflictWithoutTarget":true,"lateral":true,"returning":true,"scalarList":true}},"domain":{"namespaces":{"public":{"models":{"CartProduct":{"fields":{"cartId":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"historyId":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"quantity":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}}},"relations":{"cart":{"cardinality":"N:1","nullable":false,"on":{"localFields":["cartId"],"targetFields":["id"]},"to":{"model":"ShopCart","namespace":"public"}},"history":{"cardinality":"N:1","nullable":false,"on":{"localFields":["historyId"],"targetFields":["id"]},"to":{"model":"ProductHistory","namespace":"public"}}},"storage":{"fields":{"cartId":{"column":"cartId"},"historyId":{"column":"historyId"},"quantity":{"column":"quantity"}},"namespaceId":"public","table":"cart_products"}},"CashMovement":{"fields":{"amount":{"nullable":false,"type":{"codecId":"pg/numeric@1","kind":"scalar"}},"createdAt":{"nullable":false,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"reason":{"nullable":true,"type":{"codecId":"pg/text@1","kind":"scalar"}},"sessionId":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"type":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}},"userId":{"nullable":true,"type":{"codecId":"pg/int4@1","kind":"scalar"}}},"relations":{"session":{"cardinality":"N:1","nullable":false,"on":{"localFields":["sessionId"],"targetFields":["id"]},"to":{"model":"CashRegisterSession","namespace":"public"}},"user":{"cardinality":"N:1","nullable":true,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"public"}}},"storage":{"fields":{"amount":{"column":"amount"},"createdAt":{"column":"createdAt"},"id":{"column":"id"},"reason":{"column":"reason"},"sessionId":{"column":"sessionId"},"type":{"column":"type"},"userId":{"column":"userId"}},"namespaceId":"public","table":"cash_movement"}},"CashRegisterSession":{"fields":{"closedAt":{"nullable":true,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"closedById":{"nullable":true,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"closingCash":{"nullable":true,"type":{"codecId":"pg/numeric@1","kind":"scalar"}},"expectedCash":{"nullable":true,"type":{"codecId":"pg/numeric@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"inventoryId":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"openedAt":{"nullable":false,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"openedById":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"openingCash":{"nullable":false,"type":{"codecId":"pg/numeric@1","kind":"scalar"}},"status":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}}},"relations":{"closedBy":{"cardinality":"N:1","nullable":true,"on":{"localFields":["closedById"],"targetFields":["id"]},"to":{"model":"User","namespace":"public"}},"inventory":{"cardinality":"N:1","nullable":false,"on":{"localFields":["inventoryId"],"targetFields":["id"]},"to":{"model":"Inventory","namespace":"public"}},"movements":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["sessionId"]},"to":{"model":"CashMovement","namespace":"public"}},"openedBy":{"cardinality":"N:1","nullable":false,"on":{"localFields":["openedById"],"targetFields":["id"]},"to":{"model":"User","namespace":"public"}}},"storage":{"fields":{"closedAt":{"column":"closedAt"},"closedById":{"column":"closedById"},"closingCash":{"column":"closingCash"},"expectedCash":{"column":"expectedCash"},"id":{"column":"id"},"inventoryId":{"column":"inventoryId"},"openedAt":{"column":"openedAt"},"openedById":{"column":"openedById"},"openingCash":{"column":"openingCash"},"status":{"column":"status"}},"namespaceId":"public","table":"cash_register_session"}},"Category":{"fields":{"createdAt":{"nullable":false,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}}},"relations":{"products":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["categoryId"]},"to":{"model":"ProductCategory","namespace":"public"}}},"storage":{"fields":{"createdAt":{"column":"createdAt"},"id":{"column":"id"},"name":{"column":"name"}},"namespaceId":"public","table":"category"}},"Customer":{"fields":{"createdAt":{"nullable":false,"type":{"codecId":"pg/timestamptz-string@Line truncated
|
||||
Generated
Vendored
+3348
File diff suppressed because it is too large.
Load diff
+1
@@ -0,0 +1 @@
|
||||
{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{"postgres":{"distinctOn":true,"jsonAgg":true,"lateral":true,"limit":true,"orderBy":true,"returning":true},"sql":{"checkConstraint":true,"defaultInInsert":true,"enums":true,"insertOnConflictSkip":true,"insertOnConflictWithoutTarget":true,"lateral":true,"returning":true,"scalarList":true}},"domain":{"namespaces":{"public":{"models":{"CartProduct":{"fields":{"cartId":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"historyId":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"quantity":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}}},"relations":{"cart":{"cardinality":"N:1","nullable":false,"on":{"localFields":["cartId"],"targetFields":["id"]},"to":{"model":"ShopCart","namespace":"public"}},"history":{"cardinality":"N:1","nullable":false,"on":{"localFields":["historyId"],"targetFields":["id"]},"to":{"model":"ProductHistory","namespace":"public"}}},"storage":{"fields":{"cartId":{"column":"cartId"},"historyId":{"column":"historyId"},"quantity":{"column":"quantity"}},"namespaceId":"public","table":"cart_products"}},"CashMovement":{"fields":{"amount":{"nullable":false,"type":{"codecId":"pg/numeric@1","kind":"scalar"}},"createdAt":{"nullable":false,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"reason":{"nullable":true,"type":{"codecId":"pg/text@1","kind":"scalar"}},"sessionId":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"type":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}},"userId":{"nullable":true,"type":{"codecId":"pg/int4@1","kind":"scalar"}}},"relations":{"session":{"cardinality":"N:1","nullable":false,"on":{"localFields":["sessionId"],"targetFields":["id"]},"to":{"model":"CashRegisterSession","namespace":"public"}},"user":{"cardinality":"N:1","nullable":true,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"public"}}},"storage":{"fields":{"amount":{"column":"amount"},"createdAt":{"column":"createdAt"},"id":{"column":"id"},"reason":{"column":"reason"},"sessionId":{"column":"sessionId"},"type":{"column":"type"},"userId":{"column":"userId"}},"namespaceId":"public","table":"cash_movement"}},"CashRegisterSession":{"fields":{"closedAt":{"nullable":true,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"closedById":{"nullable":true,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"closingCash":{"nullable":true,"type":{"codecId":"pg/numeric@1","kind":"scalar"}},"expectedCash":{"nullable":true,"type":{"codecId":"pg/numeric@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"inventoryId":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"openedAt":{"nullable":false,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"openedById":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"openingCash":{"nullable":false,"type":{"codecId":"pg/numeric@1","kind":"scalar"}},"status":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}}},"relations":{"closedBy":{"cardinality":"N:1","nullable":true,"on":{"localFields":["closedById"],"targetFields":["id"]},"to":{"model":"User","namespace":"public"}},"inventory":{"cardinality":"N:1","nullable":false,"on":{"localFields":["inventoryId"],"targetFields":["id"]},"to":{"model":"Inventory","namespace":"public"}},"movements":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["sessionId"]},"to":{"model":"CashMovement","namespace":"public"}},"openedBy":{"cardinality":"N:1","nullable":false,"on":{"localFields":["openedById"],"targetFields":["id"]},"to":{"model":"User","namespace":"public"}}},"storage":{"fields":{"closedAt":{"column":"closedAt"},"closedById":{"column":"closedById"},"closingCash":{"column":"closingCash"},"expectedCash":{"column":"expectedCash"},"id":{"column":"id"},"inventoryId":{"column":"inventoryId"},"openedAt":{"column":"openedAt"},"openedById":{"column":"openedById"},"openingCash":{"column":"openingCash"},"status":{"column":"status"}},"namespaceId":"public","table":"cash_register_session"}},"Category":{"fields":{"createdAt":{"nullable":false,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}}},"relations":{"products":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["categoryId"]},"to":{"model":"ProductCategory","namespace":"public"}}},"storage":{"fields":{"createdAt":{"column":"createdAt"},"id":{"column":"id"},"name":{"column":"name"}},"namespaceId":"public","table":"category"}},"Customer":{"fields":{"createdAt":{"nullable":false,"type":{"codecId":"pg/timestamptz-string@Line truncated
|
||||
Generated
Vendored
+3090
File diff suppressed because it is too large.
Load diff
+1
@@ -0,0 +1 @@
|
||||
{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{"postgres":{"distinctOn":true,"jsonAgg":true,"lateral":true,"limit":true,"orderBy":true,"returning":true},"sql":{"checkConstraint":true,"defaultInInsert":true,"enums":true,"insertOnConflictSkip":true,"insertOnConflictWithoutTarget":true,"lateral":true,"returning":true,"scalarList":true}},"domain":{"namespaces":{"public":{"models":{"CartProduct":{"fields":{"cartId":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"historyId":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"quantity":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}}},"relations":{"cart":{"cardinality":"N:1","nullable":false,"on":{"localFields":["cartId"],"targetFields":["id"]},"to":{"model":"ShopCart","namespace":"public"}},"history":{"cardinality":"N:1","nullable":false,"on":{"localFields":["historyId"],"targetFields":["id"]},"to":{"model":"ProductHistory","namespace":"public"}}},"storage":{"fields":{"cartId":{"column":"cartId"},"historyId":{"column":"historyId"},"quantity":{"column":"quantity"}},"namespaceId":"public","table":"cart_products"}},"CashRegisterSession":{"fields":{"closedAt":{"nullable":true,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"closedById":{"nullable":true,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"closingCash":{"nullable":true,"type":{"codecId":"pg/numeric@1","kind":"scalar"}},"expectedCash":{"nullable":true,"type":{"codecId":"pg/numeric@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"inventoryId":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"openedAt":{"nullable":false,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"openedById":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"openingCash":{"nullable":false,"type":{"codecId":"pg/numeric@1","kind":"scalar"}},"status":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}}},"relations":{"closedBy":{"cardinality":"N:1","nullable":true,"on":{"localFields":["closedById"],"targetFields":["id"]},"to":{"model":"User","namespace":"public"}},"inventory":{"cardinality":"N:1","nullable":false,"on":{"localFields":["inventoryId"],"targetFields":["id"]},"to":{"model":"Inventory","namespace":"public"}},"openedBy":{"cardinality":"N:1","nullable":false,"on":{"localFields":["openedById"],"targetFields":["id"]},"to":{"model":"User","namespace":"public"}}},"storage":{"fields":{"closedAt":{"column":"closedAt"},"closedById":{"column":"closedById"},"closingCash":{"column":"closingCash"},"expectedCash":{"column":"expectedCash"},"id":{"column":"id"},"inventoryId":{"column":"inventoryId"},"openedAt":{"column":"openedAt"},"openedById":{"column":"openedById"},"openingCash":{"column":"openingCash"},"status":{"column":"status"}},"namespaceId":"public","table":"cash_register_session"}},"Category":{"fields":{"createdAt":{"nullable":false,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}}},"relations":{"products":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["categoryId"]},"to":{"model":"ProductCategory","namespace":"public"}}},"storage":{"fields":{"createdAt":{"column":"createdAt"},"id":{"column":"id"},"name":{"column":"name"}},"namespaceId":"public","table":"category"}},"Customer":{"fields":{"createdAt":{"nullable":false,"type":{"codecId":"pg/timestamptz-string@1","kind":"scalar"}},"email":{"nullable":true,"type":{"codecId":"pg/text@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}},"phone":{"nullable":true,"type":{"codecId":"pg/text@1","kind":"scalar"}},"taxId":{"nullable":true,"type":{"codecId":"pg/text@1","kind":"scalar"}}},"relations":{"carts":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["customerId"]},"to":{"model":"ShopCart","namespace":"public"}}},"storage":{"fields":{"createdAt":{"column":"createdAt"},"email":{"column":"email"},"id":{"column":"id"},"name":{"column":"name"},"phone":{"column":"phone"},"taxId":{"column":"taxId"}},"namespaceId":"public","table":"customer"}},"Inventory":{"fields":{"address":{"nullable":true,"type":{"codecId":"pg/text@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"pg/int4@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"pg/text@1","kind":"scalar"}}},"relations":{"movements":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["inventoryId"]},"to":{"model":"InventoryMovement","namespace":"public"}},"sessions":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["inventoryId"]},"to":{"model":"CashRegisterSession","namespacLine truncated
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "@pdv/api",
|
||||
"type": "module",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -7,12 +8,16 @@
|
||||
"start": "nest start",
|
||||
"start:dev": "nest start --watch",
|
||||
"start:prod": "node dist/main.js",
|
||||
"lint": "eslint \"{src,test}/**/*.ts\" --fix"
|
||||
"lint": "eslint \"{src,test}/**/*.ts\" --fix",
|
||||
"contract:emit": "prisma contract emit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nestjs/common": "^12.0.3",
|
||||
"@nestjs/core": "^12.0.3",
|
||||
"@nestjs/platform-express": "^12.0.3",
|
||||
"@prisma/client": "^7.10.0",
|
||||
"@prisma/orm-postgres": "^8.0.0-rc.13",
|
||||
"dotenv": "^17.4.2",
|
||||
"next": "^16.3.5",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rxjs": "^7.8.2"
|
||||
@@ -22,6 +27,7 @@
|
||||
"@nestjs/cli": "^12.0.3",
|
||||
"@nestjs/schematics": "^12.0.0",
|
||||
"@nestjs/testing": "^12.0.3",
|
||||
"@prisma/cli-engine": "^0.6.1",
|
||||
"@types/express": "^5.0.6",
|
||||
"@types/node": "^20.19.43",
|
||||
"eslint": "^9.39.5",
|
||||
@@ -29,6 +35,7 @@
|
||||
"eslint-plugin-prettier": "^5.5.6",
|
||||
"globals": "^14.0.0",
|
||||
"prettier": "^3.9.8",
|
||||
"prisma": "^8.0.0-rc.17",
|
||||
"typescript": "^6.0.3",
|
||||
"typescript-eslint": "^8.70.0"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
# Welcome to Prisma ORM!
|
||||
|
||||
Prisma ORM lets you query your database in simple, easy-to-read TypeScript. Define what your data looks like, and Prisma ORM gives you a fully typed client — with autocomplete for every table, column, and relation.
|
||||
|
||||
This project is set up for PostgreSQL. Prisma ORM also supports other databases.
|
||||
|
||||
## Requirements
|
||||
|
||||
- **PostgreSQL 15 or newer.** Older servers are not supported. Run `SELECT version()` against your server to verify.
|
||||
- The CLI never connects to your database without explicit consent. Pass `--probe-db` to `npx prisma orm init` if you want `init` to verify the server version itself.
|
||||
|
||||
## Your data contract
|
||||
|
||||
Your data contract is the heart of your application. It lives at [`src/prisma/contract.prisma`](src/prisma/contract.prisma) and describes your models:
|
||||
|
||||
```prisma
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
email String @unique
|
||||
username String?
|
||||
name String?
|
||||
}
|
||||
```
|
||||
|
||||
Every model you define in your contract can be queried from your app. Your editor will autocomplete the query methods and show you what type each model field is:
|
||||
|
||||
```typescript
|
||||
import { db } from './src/prisma/db';
|
||||
|
||||
const user = await db.orm.public.User
|
||||
.where({ email: '[email protected]' })
|
||||
.first();
|
||||
|
||||
// Your editor will show the type of user as
|
||||
// { id: number; email: string; username: string | null; name: string | null; createdAt: Date; posts: Post[] } | null
|
||||
```
|
||||
|
||||
Your contract has two companion files in the same directory:
|
||||
|
||||
- **`contract.json`** — this tells your application what models exist, just like `package-lock.json` tells your package manager what dependencies your project has
|
||||
- **`contract.d.ts`** — this powers autocomplete and type checking in your editor
|
||||
|
||||
Commit both files to git. When you change your contract, run `npx prisma contract emit` to update them.
|
||||
|
||||
If you use a framework like Next.js or Vite, the Prisma ORM plugin will do this for you automatically.
|
||||
|
||||
## Configuration
|
||||
|
||||
[`prisma.config.ts`](prisma.config.ts) tells the CLI where your contract lives and how to connect to your database. It loads environment variables from `.env` automatically:
|
||||
|
||||
```typescript
|
||||
import 'dotenv/config';
|
||||
import { definePrismaConfig } from '@prisma/cli-engine';
|
||||
import { defineConfig as ormConfig } from '@prisma/orm-postgres/config';
|
||||
|
||||
export default definePrismaConfig({
|
||||
orm: ormConfig({
|
||||
contract: './src/prisma/contract.prisma',
|
||||
db: {
|
||||
connection: process.env['DATABASE_URL']!,
|
||||
},
|
||||
}),
|
||||
});
|
||||
```
|
||||
|
||||
Notice the `DATABASE_URL` above? It's defined in your [`.env`](./.env) file:
|
||||
|
||||
```env
|
||||
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
|
||||
```
|
||||
|
||||
You can customize how your environment variables are loaded by changing or removing the `import 'dotenv/config'` line.
|
||||
|
||||
## Quick reference
|
||||
|
||||
### Commands
|
||||
|
||||
```bash
|
||||
npx prisma contract emit # Update contract.json and contract.d.ts
|
||||
npx prisma db init # Create tables in the database
|
||||
npx prisma migration status # Show migration status
|
||||
```
|
||||
|
||||
### Files
|
||||
|
||||
| File | Purpose |
|
||||
|---|---|
|
||||
| [`src/prisma/contract.prisma`](src/prisma/contract.prisma) | Your data contract — define your models here |
|
||||
| [`prisma.config.ts`](prisma.config.ts) | CLI configuration |
|
||||
| [`src/prisma/db.ts`](src/prisma/db.ts) | Database client — `import { db } from './src/prisma/db'` |
|
||||
| `src/prisma/contract.json` | Compiled contract (generated) |
|
||||
| `src/prisma/contract.d.ts` | Contract types (generated) |
|
||||
|
||||
### Workflow
|
||||
|
||||
1. Edit [`src/prisma/contract.prisma`](src/prisma/contract.prisma) to add or change models.
|
||||
2. Run `npx prisma contract emit` to regenerate the contract.
|
||||
3. Query your models — your IDE will autocomplete everything.
|
||||
|
||||
## Monorepo notes (pnpm workspaces)
|
||||
|
||||
If this project lives inside a pnpm workspace, a few things are worth knowing:
|
||||
|
||||
- **Catalogs.** When the workspace's `pnpm-workspace.yaml` defines a `catalogs` entry for `prisma` or `@prisma/orm-postgres`, pnpm uses the catalog version everywhere — `init` does too. If you wanted the published `latest` instead, update or remove the catalog entry, then re-run `pnpm install`.
|
||||
- **`pnpm dlx`.** `pnpm dlx prisma@latest orm init …` works in any directory. Inside a workspace, pnpm still resolves dependencies through the workspace's catalog/overrides rather than the registry; expect the installed Prisma ORM packages to reflect the workspace's catalog rather than `latest`.
|
||||
- **`pnpm` → `npm` fallback.** If `pnpm` ever fails to install Prisma ORM with a `workspace:*` or `catalog:` resolution error (a leak in a published artefact), `init` falls back to `npm install` and surfaces a warning. Once the offending package republishes a clean version you can switch back with `pnpm install`.
|
||||
@@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
require("dotenv/config");
|
||||
const cli_engine_1 = require("@prisma/cli-engine");
|
||||
const config_1 = require("@prisma/orm-postgres/config");
|
||||
exports.default = (0, cli_engine_1.definePrismaConfig)({
|
||||
orm: (0, config_1.defineConfig)({
|
||||
contract: "./src/prisma/contract.prisma",
|
||||
db: {
|
||||
connection: process.env['DATABASE_URL'],
|
||||
},
|
||||
}),
|
||||
});
|
||||
//# sourceMappingURL=prisma.config.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"prisma.config.js","sourceRoot":"","sources":["prisma.config.ts"],"names":[],"mappings":";;AAAA,yBAAuB;AACvB,mDAAwD;AACxD,wDAAwE;AAExE,kBAAe,IAAA,+BAAkB,EAAC;IAChC,GAAG,EAAE,IAAA,qBAAS,EAAC;QACb,QAAQ,EAAE,8BAA8B;QACxC,EAAE,EAAE;YACF,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,CAAE;SACzC;KACF,CAAC;CACH,CAAC,CAAC"}
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'dotenv/config';
|
||||
import { definePrismaConfig } from '@prisma/cli-engine';
|
||||
import { defineConfig as ormConfig } from '@prisma/orm-postgres/config';
|
||||
|
||||
export default definePrismaConfig({
|
||||
orm: ormConfig({
|
||||
contract: "./src/prisma/contract.prisma",
|
||||
db: {
|
||||
connection: process.env['DATABASE_URL']!,
|
||||
},
|
||||
}),
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Controller, Get } from "@nestjs/common";
|
||||
import { AppService } from "./app.service";
|
||||
import { AppService } from "./app.service.js";
|
||||
|
||||
@Controller()
|
||||
export class AppController {
|
||||
|
||||
@@ -1,9 +1,46 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { AppController } from "./app.controller";
|
||||
import { AppService } from "./app.service";
|
||||
import { AppController } from "./app.controller.js";
|
||||
import { AppService } from "./app.service.js";
|
||||
import { AuthModule } from "./modules/auth/auth.module.js";
|
||||
import { DatabaseModule } from "./database/database.module.js";
|
||||
import { CartProductModule } from "./modules/cart-product/cart-product.module.js";
|
||||
import { CashMovementModule } from "./modules/cash-movement/cash-movement.module.js";
|
||||
import { CashRegisterSessionModule } from "./modules/cash-register-session/cash-register-session.module.js";
|
||||
import { CategoryModule } from "./modules/category/category.module.js";
|
||||
import { CustomerModule } from "./modules/customer/customer.module.js";
|
||||
import { InventoryModule } from "./modules/inventory/inventory.module.js";
|
||||
import { InventoryMovementModule } from "./modules/inventory-movement/inventory-movement.module.js";
|
||||
import { OperatingDayModule } from "./modules/operating-day/operating-day.module.js";
|
||||
import { PaymentModule } from "./modules/payment/payment.module.js";
|
||||
import { ProductModule } from "./modules/product/product.module.js";
|
||||
import { ProductCategoryModule } from "./modules/product-category/product-category.module.js";
|
||||
import { ProductHistoryModule } from "./modules/product-history/product-history.module.js";
|
||||
import { ShopCartModule } from "./modules/shop-cart/shop-cart.module.js";
|
||||
import { SupplierModule } from "./modules/supplier/supplier.module.js";
|
||||
import { UserModule } from "./modules/user/user.module.js";
|
||||
import { WarehouseModule } from "./modules/warehouse/warehouse.module.js";
|
||||
|
||||
@Module({
|
||||
imports: [],
|
||||
imports: [
|
||||
DatabaseModule,
|
||||
SupplierModule,
|
||||
ProductModule,
|
||||
CategoryModule,
|
||||
ProductCategoryModule,
|
||||
InventoryModule,
|
||||
WarehouseModule,
|
||||
InventoryMovementModule,
|
||||
ProductHistoryModule,
|
||||
ShopCartModule,
|
||||
CartProductModule,
|
||||
UserModule,
|
||||
PaymentModule,
|
||||
CustomerModule,
|
||||
CashRegisterSessionModule,
|
||||
CashMovementModule,
|
||||
OperatingDayModule,
|
||||
AuthModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
})
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return -- `model` is the deliberate untyped boundary to Prisma's ORM; the public contract stays fully typed via T/CreateInput/UpdateInput/WhereKey above. */
|
||||
import { Inject } from "@nestjs/common";
|
||||
import { DB } from "../database/database.tokens.js";
|
||||
import type { Database } from "../prisma/db.js";
|
||||
import type { IRepository } from "./repository.interface.js";
|
||||
|
||||
/**
|
||||
* Generic CRUD repository over a `db.orm.public.<Model>` collection.
|
||||
* Subclasses only declare which columns to select and which model to target.
|
||||
*/
|
||||
export abstract class BaseRepository<
|
||||
T,
|
||||
CreateInput,
|
||||
UpdateInput,
|
||||
WhereKey extends object,
|
||||
> implements IRepository<T, CreateInput, UpdateInput, WhereKey> {
|
||||
constructor(@Inject(DB) protected readonly db: Database) {}
|
||||
|
||||
/** The `db.orm.public.<Model>` collection this repository targets. */
|
||||
protected abstract readonly model: any;
|
||||
|
||||
/** Columns fetched by `findAll()`. */
|
||||
protected abstract readonly columns: readonly string[];
|
||||
|
||||
findAll(): Promise<T[]> {
|
||||
return this.model
|
||||
.select(...this.columns)
|
||||
.all()
|
||||
.toArray();
|
||||
}
|
||||
|
||||
findById(where: WhereKey): Promise<T | null> {
|
||||
return this.model.where(where).first();
|
||||
}
|
||||
|
||||
create(data: CreateInput): Promise<T> {
|
||||
return this.model.create(data);
|
||||
}
|
||||
|
||||
async update(where: WhereKey, data: UpdateInput): Promise<T> {
|
||||
await this.model.where(where).update(data);
|
||||
return this.findById(where) as Promise<T>;
|
||||
}
|
||||
|
||||
async delete(where: WhereKey): Promise<void> {
|
||||
await this.model.where(where).delete();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { NotFoundException } from "@nestjs/common";
|
||||
import type { IRepository } from "./repository.interface.js";
|
||||
import type { IService } from "./service.interface.js";
|
||||
|
||||
/**
|
||||
* Generic business layer: delegates to an `IRepository`, translating a
|
||||
* missing row into a `NotFoundException`. Subclasses may override
|
||||
* `notFoundMessage` for a more specific error message.
|
||||
*/
|
||||
export abstract class BaseService<
|
||||
T,
|
||||
CreateInput,
|
||||
UpdateInput,
|
||||
WhereKey,
|
||||
> implements IService<T, CreateInput, UpdateInput, WhereKey> {
|
||||
constructor(
|
||||
protected readonly repository: IRepository<
|
||||
T,
|
||||
CreateInput,
|
||||
UpdateInput,
|
||||
WhereKey
|
||||
>,
|
||||
) {}
|
||||
|
||||
findAll(): Promise<T[]> {
|
||||
return this.repository.findAll();
|
||||
}
|
||||
|
||||
async findById(where: WhereKey): Promise<T> {
|
||||
const entity = await this.repository.findById(where);
|
||||
if (!entity) {
|
||||
throw new NotFoundException(this.notFoundMessage(where));
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
create(data: CreateInput): Promise<T> {
|
||||
return this.repository.create(data);
|
||||
}
|
||||
|
||||
async update(where: WhereKey, data: UpdateInput): Promise<T> {
|
||||
await this.findById(where);
|
||||
return this.repository.update(where, data);
|
||||
}
|
||||
|
||||
async delete(where: WhereKey): Promise<void> {
|
||||
await this.findById(where);
|
||||
await this.repository.delete(where);
|
||||
}
|
||||
|
||||
protected notFoundMessage(where: WhereKey): string {
|
||||
return `Resource not found: ${JSON.stringify(where)}`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import {
|
||||
randomBytes,
|
||||
scrypt as scryptCallback,
|
||||
timingSafeEqual,
|
||||
} from "node:crypto";
|
||||
import { promisify } from "node:util";
|
||||
|
||||
const scrypt = promisify(scryptCallback);
|
||||
const KEY_LENGTH = 64;
|
||||
|
||||
export async function hashPassword(password: string): Promise<string> {
|
||||
const salt = randomBytes(16).toString("hex");
|
||||
const derivedKey = (await scrypt(password, salt, KEY_LENGTH)) as Buffer;
|
||||
return `${salt}:${derivedKey.toString("hex")}`;
|
||||
}
|
||||
|
||||
export async function verifyPassword(
|
||||
password: string,
|
||||
storedHash: string,
|
||||
): Promise<boolean> {
|
||||
const [salt, key] = storedHash.split(":");
|
||||
if (!salt || !key) {
|
||||
return false;
|
||||
}
|
||||
const keyBuffer = Buffer.from(key, "hex");
|
||||
const derivedKey = (await scrypt(password, salt, KEY_LENGTH)) as Buffer;
|
||||
if (derivedKey.length !== keyBuffer.length) {
|
||||
return false;
|
||||
}
|
||||
return timingSafeEqual(derivedKey, keyBuffer);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export interface IRepository<T, CreateInput, UpdateInput, WhereKey> {
|
||||
findAll(): Promise<T[]>;
|
||||
findById(where: WhereKey): Promise<T | null>;
|
||||
create(data: CreateInput): Promise<T>;
|
||||
update(where: WhereKey, data: UpdateInput): Promise<T>;
|
||||
delete(where: WhereKey): Promise<void>;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export interface IService<T, CreateInput, UpdateInput, WhereKey> {
|
||||
findAll(): Promise<T[]>;
|
||||
findById(where: WhereKey): Promise<T>;
|
||||
create(data: CreateInput): Promise<T>;
|
||||
update(where: WhereKey, data: UpdateInput): Promise<T>;
|
||||
delete(where: WhereKey): Promise<void>;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Global, Module } from "@nestjs/common";
|
||||
import { db } from "../prisma/db.js";
|
||||
import { DB } from "./database.tokens.js";
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
providers: [{ provide: DB, useValue: db }],
|
||||
exports: [DB],
|
||||
})
|
||||
export class DatabaseModule {}
|
||||
@@ -0,0 +1 @@
|
||||
export const DB = Symbol("DB");
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface LoginInput {
|
||||
id: number;
|
||||
password: string;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export interface CreateCartProductInput {
|
||||
cartId: number;
|
||||
historyId: number;
|
||||
quantity: number;
|
||||
}
|
||||
|
||||
export interface UpdateCartProductInput {
|
||||
quantity: number;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export type CashMovementType = "in" | "out";
|
||||
|
||||
export interface CreateCashMovementInput {
|
||||
sessionId: number;
|
||||
type: CashMovementType;
|
||||
amount: string;
|
||||
reason?: string | null;
|
||||
userId?: number | null;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export interface CreateCashRegisterSessionInput {
|
||||
inventoryId: number;
|
||||
openedById: number;
|
||||
openingCash: string;
|
||||
}
|
||||
|
||||
export interface UpdateCashRegisterSessionInput {
|
||||
closedById?: number | null;
|
||||
closingCash?: string | null;
|
||||
expectedCash?: string | null;
|
||||
status?: string;
|
||||
closedAt?: string | null;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export interface CreateCategoryInput {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface UpdateCategoryInput {
|
||||
name?: string;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export interface CreateCustomerInput {
|
||||
name: string;
|
||||
phone?: string | null;
|
||||
email?: string | null;
|
||||
taxId?: string | null;
|
||||
}
|
||||
|
||||
export interface UpdateCustomerInput {
|
||||
name?: string;
|
||||
phone?: string | null;
|
||||
email?: string | null;
|
||||
taxId?: string | null;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export type InventoryMovementType = "in" | "out";
|
||||
|
||||
export interface CreateInventoryMovementInput {
|
||||
productId: number;
|
||||
inventoryId: number;
|
||||
type: InventoryMovementType;
|
||||
quantity: number;
|
||||
reason?: string | null;
|
||||
userId?: number | null;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export interface CreateInventoryInput {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface UpdateInventoryInput {
|
||||
name?: string;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export interface CreateOperatingDayInput {
|
||||
openedById: number;
|
||||
}
|
||||
|
||||
export interface UpdateOperatingDayInput {
|
||||
closedById?: number;
|
||||
status?: string;
|
||||
closedAt?: string | null;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
export interface CreatePaymentInput {
|
||||
cartId: number;
|
||||
userId: number;
|
||||
amount: string;
|
||||
orderId?: number | null;
|
||||
terminalId?: number | null;
|
||||
status: string;
|
||||
paid?: boolean;
|
||||
paymentMethod: string;
|
||||
paidAt?: string | null;
|
||||
}
|
||||
|
||||
export interface UpdatePaymentInput {
|
||||
amount?: string;
|
||||
orderId?: number | null;
|
||||
terminalId?: number | null;
|
||||
status?: string;
|
||||
paid?: boolean;
|
||||
paymentMethod?: string;
|
||||
paidAt?: string | null;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export interface CreateProductCategoryInput {
|
||||
productId: number;
|
||||
categoryId: number;
|
||||
}
|
||||
|
||||
// No mutable fields on this junction table — nothing to PATCH.
|
||||
export type UpdateProductCategoryInput = Record<string, never>;
|
||||
@@ -0,0 +1,14 @@
|
||||
export interface CreateProductHistoryInput {
|
||||
productId: number;
|
||||
unitPrice: string;
|
||||
costUnit: string;
|
||||
status: string;
|
||||
soldAt?: string | null;
|
||||
}
|
||||
|
||||
export interface UpdateProductHistoryInput {
|
||||
unitPrice?: string;
|
||||
costUnit?: string;
|
||||
status?: string;
|
||||
soldAt?: string | null;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
export interface CreateProductInput {
|
||||
name: string;
|
||||
description?: string | null;
|
||||
sku: string;
|
||||
barcode?: string | null;
|
||||
minStock?: number;
|
||||
imageUrl?: string | null;
|
||||
supplierId?: number | null;
|
||||
}
|
||||
|
||||
export interface UpdateProductInput {
|
||||
name?: string;
|
||||
description?: string | null;
|
||||
sku?: string;
|
||||
barcode?: string | null;
|
||||
minStock?: number;
|
||||
imageUrl?: string | null;
|
||||
supplierId?: number | null;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
export interface CreateShopCartInput {
|
||||
totalPrice: string;
|
||||
discount?: string;
|
||||
status?: string;
|
||||
userId?: number | null;
|
||||
customerId?: number | null;
|
||||
}
|
||||
|
||||
export interface UpdateShopCartInput {
|
||||
totalPrice?: string;
|
||||
discount?: string;
|
||||
status?: string;
|
||||
userId?: number | null;
|
||||
customerId?: number | null;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export interface CreateSupplierInput {
|
||||
name: string;
|
||||
lastSupply?: string | null;
|
||||
}
|
||||
|
||||
export interface UpdateSupplierInput {
|
||||
name?: string;
|
||||
lastSupply?: string | null;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export interface CreateUserInput {
|
||||
name: string;
|
||||
email: string;
|
||||
role: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface UpdateUserInput {
|
||||
name?: string;
|
||||
email?: string;
|
||||
role?: string;
|
||||
password?: string;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export interface CreateWarehouseInput {
|
||||
inventoryId: number;
|
||||
productId: number;
|
||||
stock?: number;
|
||||
}
|
||||
|
||||
export interface UpdateWarehouseInput {
|
||||
stock: number;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export interface CartProduct {
|
||||
cartId: number;
|
||||
historyId: number;
|
||||
quantity: number;
|
||||
}
|
||||
|
||||
export interface CartProductKey {
|
||||
cartId: number;
|
||||
historyId: number;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export interface CashMovement {
|
||||
id: number;
|
||||
sessionId: number;
|
||||
type: string;
|
||||
amount: string;
|
||||
reason: string | null;
|
||||
userId: number | null;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface CashMovementKey {
|
||||
id: number;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
export interface CashRegisterSession {
|
||||
id: number;
|
||||
inventoryId: number;
|
||||
openedById: number;
|
||||
closedById: number | null;
|
||||
openingCash: string;
|
||||
closingCash: string | null;
|
||||
expectedCash: string | null;
|
||||
status: string;
|
||||
openedAt: string;
|
||||
closedAt: string | null;
|
||||
}
|
||||
|
||||
export interface CashRegisterSessionKey {
|
||||
id: number;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export interface Category {
|
||||
id: number;
|
||||
name: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface CategoryKey {
|
||||
id: number;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
export interface Customer {
|
||||
id: number;
|
||||
name: string;
|
||||
phone: string | null;
|
||||
email: string | null;
|
||||
taxId: string | null;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface CustomerKey {
|
||||
id: number;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
export interface InventoryMovement {
|
||||
id: number;
|
||||
productId: number;
|
||||
inventoryId: number;
|
||||
type: string;
|
||||
quantity: number;
|
||||
reason: string | null;
|
||||
userId: number | null;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface InventoryMovementKey {
|
||||
id: number;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export interface Inventory {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface InventoryKey {
|
||||
id: number;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export interface OperatingDay {
|
||||
id: number;
|
||||
date: string;
|
||||
status: string;
|
||||
openedById: number;
|
||||
closedById: number | null;
|
||||
openedAt: string;
|
||||
closedAt: string | null;
|
||||
}
|
||||
|
||||
export interface OperatingDayKey {
|
||||
id: number;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
export interface Payment {
|
||||
id: number;
|
||||
cartId: number;
|
||||
userId: number;
|
||||
amount: string;
|
||||
orderId: number | null;
|
||||
terminalId: number | null;
|
||||
status: string;
|
||||
paid: boolean;
|
||||
paymentMethod: string;
|
||||
paidAt: string | null;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface PaymentKey {
|
||||
id: number;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export interface ProductCategory {
|
||||
productId: number;
|
||||
categoryId: number;
|
||||
}
|
||||
|
||||
export interface ProductCategoryKey {
|
||||
productId: number;
|
||||
categoryId: number;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export interface ProductHistory {
|
||||
id: number;
|
||||
productId: number;
|
||||
unitPrice: string;
|
||||
costUnit: string;
|
||||
status: string;
|
||||
createdAt: string;
|
||||
soldAt: string | null;
|
||||
}
|
||||
|
||||
export interface ProductHistoryKey {
|
||||
id: number;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
export interface Product {
|
||||
id: number;
|
||||
name: string;
|
||||
description: string | null;
|
||||
sku: string;
|
||||
barcode: string | null;
|
||||
minStock: number;
|
||||
imageUrl: string | null;
|
||||
createdAt: string;
|
||||
supplierId: number | null;
|
||||
}
|
||||
|
||||
export interface ProductKey {
|
||||
id: number;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export interface ShopCart {
|
||||
id: number;
|
||||
totalPrice: string;
|
||||
discount: string;
|
||||
status: string;
|
||||
createdAt: string;
|
||||
userId: number | null;
|
||||
customerId: number | null;
|
||||
}
|
||||
|
||||
export interface ShopCartKey {
|
||||
id: number;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export interface Supplier {
|
||||
id: number;
|
||||
name: string;
|
||||
lastSupply: string | null;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface SupplierKey {
|
||||
id: number;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
export interface User {
|
||||
id: number;
|
||||
name: string;
|
||||
email: string;
|
||||
role: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface UserKey {
|
||||
id: number;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export interface Warehouse {
|
||||
inventoryId: number;
|
||||
productId: number;
|
||||
stock: number;
|
||||
}
|
||||
|
||||
export interface WarehouseKey {
|
||||
inventoryId: number;
|
||||
productId: number;
|
||||
}
|
||||
Whitespace-only changes.
+14
-2
@@ -1,9 +1,21 @@
|
||||
import "dotenv/config";
|
||||
import "reflect-metadata";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { NestFactory } from "@nestjs/core";
|
||||
import type { NestExpressApplication } from "@nestjs/platform-express";
|
||||
import next from "next";
|
||||
import { AppModule } from "./app.module";
|
||||
import nextFactory from "next";
|
||||
import { AppModule } from "./app.module.js";
|
||||
|
||||
// El paquete `next` reexporta su función por defecto a través de varios
|
||||
// niveles (`next/index.d.ts` -> `next/types.d.ts` -> `next/dist/server/next.d.ts`),
|
||||
// lo que hace que TypeScript con `nodenext` infiera el namespace del módulo en
|
||||
// lugar del `default` real. En runtime sí es una función invocable (ver
|
||||
// `next/dist/server/next.js`), así que se re-tipa explícitamente aquí.
|
||||
const next =
|
||||
nextFactory as unknown as typeof import("next/dist/server/next.js").default;
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
async function bootstrap() {
|
||||
const dev = process.env.NODE_ENV !== "production";
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Body, Controller, Inject, Post } from "@nestjs/common";
|
||||
import type { LoginInput } from "../../dtos/auth.dto.js";
|
||||
import {
|
||||
AUTH_SERVICE,
|
||||
type IAuthService,
|
||||
} from "./interfaces/auth-service.interface.js";
|
||||
|
||||
@Controller("auth")
|
||||
export class AuthController {
|
||||
constructor(
|
||||
@Inject(AUTH_SERVICE) private readonly authService: IAuthService,
|
||||
) {}
|
||||
|
||||
@Post("login")
|
||||
login(@Body() body: LoginInput) {
|
||||
return this.authService.login(body);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { UserModule } from "../user/user.module.js";
|
||||
import { AuthController } from "./auth.controller.js";
|
||||
import { AuthService } from "./auth.service.js";
|
||||
import { AUTH_SERVICE } from "./interfaces/auth-service.interface.js";
|
||||
|
||||
@Module({
|
||||
imports: [UserModule],
|
||||
controllers: [AuthController],
|
||||
providers: [{ provide: AUTH_SERVICE, useClass: AuthService }],
|
||||
})
|
||||
export class AuthModule {}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Inject, Injectable, UnauthorizedException } from "@nestjs/common";
|
||||
import type { LoginInput } from "../../dtos/auth.dto.js";
|
||||
import type { User } from "../../entities/user.entity.js";
|
||||
import {
|
||||
USER_SERVICE,
|
||||
type IUserService,
|
||||
} from "../user/interfaces/user-service.interface.js";
|
||||
import type { IAuthService } from "./interfaces/auth-service.interface.js";
|
||||
|
||||
@Injectable()
|
||||
export class AuthService implements IAuthService {
|
||||
constructor(
|
||||
@Inject(USER_SERVICE) private readonly userService: IUserService,
|
||||
) {}
|
||||
|
||||
async login({ id, password }: LoginInput): Promise<User> {
|
||||
const user = await this.userService.verifyCredentials({ id, password });
|
||||
if (!user) {
|
||||
throw new UnauthorizedException("Credenciales inválidas");
|
||||
}
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { LoginInput } from "../../../dtos/auth.dto.js";
|
||||
import type { User } from "../../../entities/user.entity.js";
|
||||
|
||||
export const AUTH_SERVICE = Symbol("AUTH_SERVICE");
|
||||
|
||||
export interface IAuthService {
|
||||
login(input: LoginInput): Promise<User>;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Inject,
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
Patch,
|
||||
Post,
|
||||
} from "@nestjs/common";
|
||||
import type {
|
||||
CreateCartProductInput,
|
||||
UpdateCartProductInput,
|
||||
} from "../../dtos/cart-product.dto.js";
|
||||
import { CART_PRODUCT_SERVICE } from "./interfaces/cart-product-service.interface.js";
|
||||
import type { ICartProductService } from "./interfaces/cart-product-service.interface.js";
|
||||
|
||||
@Controller("cart-products")
|
||||
export class CartProductController {
|
||||
constructor(
|
||||
@Inject(CART_PRODUCT_SERVICE)
|
||||
private readonly cartProductService: ICartProductService,
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
return this.cartProductService.findAll();
|
||||
}
|
||||
|
||||
@Get(":cartId/:historyId")
|
||||
findOne(
|
||||
@Param("cartId", ParseIntPipe) cartId: number,
|
||||
@Param("historyId", ParseIntPipe) historyId: number,
|
||||
) {
|
||||
return this.cartProductService.findById({ cartId, historyId });
|
||||
}
|
||||
|
||||
@Post()
|
||||
create(@Body() body: CreateCartProductInput) {
|
||||
return this.cartProductService.create(body);
|
||||
}
|
||||
|
||||
@Patch(":cartId/:historyId")
|
||||
update(
|
||||
@Param("cartId", ParseIntPipe) cartId: number,
|
||||
@Param("historyId", ParseIntPipe) historyId: number,
|
||||
@Body() body: UpdateCartProductInput,
|
||||
) {
|
||||
return this.cartProductService.update({ cartId, historyId }, body);
|
||||
}
|
||||
|
||||
@Delete(":cartId/:historyId")
|
||||
remove(
|
||||
@Param("cartId", ParseIntPipe) cartId: number,
|
||||
@Param("historyId", ParseIntPipe) historyId: number,
|
||||
) {
|
||||
return this.cartProductService.delete({ cartId, historyId });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { CART_PRODUCT_REPOSITORY } from "./interfaces/cart-product-repository.interface.js";
|
||||
import { CART_PRODUCT_SERVICE } from "./interfaces/cart-product-service.interface.js";
|
||||
import { CartProductController } from "./cart-product.controller.js";
|
||||
import { CartProductRepository } from "./cart-product.repository.js";
|
||||
import { CartProductService } from "./cart-product.service.js";
|
||||
|
||||
@Module({
|
||||
controllers: [CartProductController],
|
||||
providers: [
|
||||
{ provide: CART_PRODUCT_REPOSITORY, useClass: CartProductRepository },
|
||||
{ provide: CART_PRODUCT_SERVICE, useClass: CartProductService },
|
||||
],
|
||||
exports: [CART_PRODUCT_SERVICE],
|
||||
})
|
||||
export class CartProductModule {}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { BaseRepository } from "../../common/base.repository.js";
|
||||
import type {
|
||||
CreateCartProductInput,
|
||||
UpdateCartProductInput,
|
||||
} from "../../dtos/cart-product.dto.js";
|
||||
import type {
|
||||
CartProduct,
|
||||
CartProductKey,
|
||||
} from "../../entities/cart-product.entity.js";
|
||||
import type { ICartProductRepository } from "./interfaces/cart-product-repository.interface.js";
|
||||
|
||||
@Injectable()
|
||||
export class CartProductRepository
|
||||
extends BaseRepository<
|
||||
CartProduct,
|
||||
CreateCartProductInput,
|
||||
UpdateCartProductInput,
|
||||
CartProductKey
|
||||
>
|
||||
implements ICartProductRepository
|
||||
{
|
||||
protected readonly columns = ["cartId", "historyId", "quantity"] as const;
|
||||
|
||||
protected get model() {
|
||||
return this.db.orm.public.CartProduct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Inject, Injectable } from "@nestjs/common";
|
||||
import { BaseService } from "../../common/base.service.js";
|
||||
import type {
|
||||
CreateCartProductInput,
|
||||
UpdateCartProductInput,
|
||||
} from "../../dtos/cart-product.dto.js";
|
||||
import type {
|
||||
CartProduct,
|
||||
CartProductKey,
|
||||
} from "../../entities/cart-product.entity.js";
|
||||
import {
|
||||
CART_PRODUCT_REPOSITORY,
|
||||
type ICartProductRepository,
|
||||
} from "./interfaces/cart-product-repository.interface.js";
|
||||
import type { ICartProductService } from "./interfaces/cart-product-service.interface.js";
|
||||
|
||||
@Injectable()
|
||||
export class CartProductService
|
||||
extends BaseService<
|
||||
CartProduct,
|
||||
CreateCartProductInput,
|
||||
UpdateCartProductInput,
|
||||
CartProductKey
|
||||
>
|
||||
implements ICartProductService
|
||||
{
|
||||
constructor(
|
||||
@Inject(CART_PRODUCT_REPOSITORY) repository: ICartProductRepository,
|
||||
) {
|
||||
super(repository);
|
||||
}
|
||||
|
||||
protected override notFoundMessage(where: CartProductKey): string {
|
||||
return `CartProduct (${where.cartId}, ${where.historyId}) not found`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { IRepository } from "../../../common/repository.interface.js";
|
||||
import type {
|
||||
CartProduct,
|
||||
CartProductKey,
|
||||
} from "../../../entities/cart-product.entity.js";
|
||||
import type {
|
||||
CreateCartProductInput,
|
||||
UpdateCartProductInput,
|
||||
} from "../../../dtos/cart-product.dto.js";
|
||||
|
||||
export const CART_PRODUCT_REPOSITORY = Symbol("CART_PRODUCT_REPOSITORY");
|
||||
|
||||
export type ICartProductRepository = IRepository<
|
||||
CartProduct,
|
||||
CreateCartProductInput,
|
||||
UpdateCartProductInput,
|
||||
CartProductKey
|
||||
>;
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { IService } from "../../../common/service.interface.js";
|
||||
import type {
|
||||
CartProduct,
|
||||
CartProductKey,
|
||||
} from "../../../entities/cart-product.entity.js";
|
||||
import type {
|
||||
CreateCartProductInput,
|
||||
UpdateCartProductInput,
|
||||
} from "../../../dtos/cart-product.dto.js";
|
||||
|
||||
export const CART_PRODUCT_SERVICE = Symbol("CART_PRODUCT_SERVICE");
|
||||
|
||||
export type ICartProductService = IService<
|
||||
CartProduct,
|
||||
CreateCartProductInput,
|
||||
UpdateCartProductInput,
|
||||
CartProductKey
|
||||
>;
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Body, Controller, Get, Inject, Param, ParseIntPipe, Post } from "@nestjs/common";
|
||||
import type { CreateCashMovementInput } from "../../dtos/cash-movement.dto.js";
|
||||
import { CASH_MOVEMENT_SERVICE } from "./interfaces/cash-movement-service.interface.js";
|
||||
import type { ICashMovementService } from "./interfaces/cash-movement-service.interface.js";
|
||||
|
||||
@Controller("cash-movements")
|
||||
export class CashMovementController {
|
||||
constructor(
|
||||
@Inject(CASH_MOVEMENT_SERVICE) private readonly cashMovementService: ICashMovementService,
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
return this.cashMovementService.findAll();
|
||||
}
|
||||
|
||||
@Get(":id")
|
||||
findOne(@Param("id", ParseIntPipe) id: number) {
|
||||
return this.cashMovementService.findById({ id });
|
||||
}
|
||||
|
||||
@Post()
|
||||
create(@Body() body: CreateCashMovementInput) {
|
||||
return this.cashMovementService.create(body);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { CASH_MOVEMENT_REPOSITORY } from "./interfaces/cash-movement-repository.interface.js";
|
||||
import { CASH_MOVEMENT_SERVICE } from "./interfaces/cash-movement-service.interface.js";
|
||||
import { CashMovementController } from "./cash-movement.controller.js";
|
||||
import { CashMovementRepository } from "./cash-movement.repository.js";
|
||||
import { CashMovementService } from "./cash-movement.service.js";
|
||||
|
||||
@Module({
|
||||
controllers: [CashMovementController],
|
||||
providers: [
|
||||
{ provide: CASH_MOVEMENT_REPOSITORY, useClass: CashMovementRepository },
|
||||
{ provide: CASH_MOVEMENT_SERVICE, useClass: CashMovementService },
|
||||
],
|
||||
exports: [CASH_MOVEMENT_SERVICE],
|
||||
})
|
||||
export class CashMovementModule {}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Inject, Injectable } from "@nestjs/common";
|
||||
import { DB } from "../../database/database.tokens.js";
|
||||
import type { Database } from "../../prisma/db.js";
|
||||
import type { CashMovement, CashMovementKey } from "../../entities/cash-movement.entity.js";
|
||||
import type { CreateCashMovementInput } from "../../dtos/cash-movement.dto.js";
|
||||
import type { ICashMovementRepository } from "./interfaces/cash-movement-repository.interface.js";
|
||||
|
||||
const COLUMNS = ["id", "sessionId", "type", "amount", "reason", "userId", "createdAt"] as const;
|
||||
|
||||
@Injectable()
|
||||
export class CashMovementRepository implements ICashMovementRepository {
|
||||
constructor(@Inject(DB) private readonly db: Database) {}
|
||||
|
||||
private get model() {
|
||||
return this.db.orm.public.CashMovement;
|
||||
}
|
||||
|
||||
findAll(): Promise<CashMovement[]> {
|
||||
return this.model.select(...COLUMNS).all().toArray();
|
||||
}
|
||||
|
||||
findById(where: CashMovementKey): Promise<CashMovement | null> {
|
||||
return this.model.select(...COLUMNS).where(where).first();
|
||||
}
|
||||
|
||||
create(data: CreateCashMovementInput): Promise<CashMovement> {
|
||||
return this.model.select(...COLUMNS).create(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { Inject, Injectable, NotFoundException } from "@nestjs/common";
|
||||
import type { CashMovement, CashMovementKey } from "../../entities/cash-movement.entity.js";
|
||||
import type { CreateCashMovementInput } from "../../dtos/cash-movement.dto.js";
|
||||
import {
|
||||
CASH_MOVEMENT_REPOSITORY,
|
||||
type ICashMovementRepository,
|
||||
} from "./interfaces/cash-movement-repository.interface.js";
|
||||
import type { ICashMovementService } from "./interfaces/cash-movement-service.interface.js";
|
||||
|
||||
@Injectable()
|
||||
export class CashMovementService implements ICashMovementService {
|
||||
constructor(
|
||||
@Inject(CASH_MOVEMENT_REPOSITORY) private readonly repository: ICashMovementRepository,
|
||||
) {}
|
||||
|
||||
findAll(): Promise<CashMovement[]> {
|
||||
return this.repository.findAll();
|
||||
}
|
||||
|
||||
async findById(where: CashMovementKey): Promise<CashMovement> {
|
||||
const movement = await this.repository.findById(where);
|
||||
if (!movement) {
|
||||
throw new NotFoundException(`CashMovement ${where.id} not found`);
|
||||
}
|
||||
return movement;
|
||||
}
|
||||
|
||||
create(data: CreateCashMovementInput): Promise<CashMovement> {
|
||||
return this.repository.create(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import type { CashMovement, CashMovementKey } from "../../../entities/cash-movement.entity.js";
|
||||
import type { CreateCashMovementInput } from "../../../dtos/cash-movement.dto.js";
|
||||
|
||||
export const CASH_MOVEMENT_REPOSITORY = Symbol("CASH_MOVEMENT_REPOSITORY");
|
||||
|
||||
export interface ICashMovementRepository {
|
||||
findAll(): Promise<CashMovement[]>;
|
||||
findById(where: CashMovementKey): Promise<CashMovement | null>;
|
||||
create(data: CreateCashMovementInput): Promise<CashMovement>;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import type { CashMovement, CashMovementKey } from "../../../entities/cash-movement.entity.js";
|
||||
import type { CreateCashMovementInput } from "../../../dtos/cash-movement.dto.js";
|
||||
|
||||
export const CASH_MOVEMENT_SERVICE = Symbol("CASH_MOVEMENT_SERVICE");
|
||||
|
||||
export interface ICashMovementService {
|
||||
findAll(): Promise<CashMovement[]>;
|
||||
findById(where: CashMovementKey): Promise<CashMovement>;
|
||||
create(data: CreateCashMovementInput): Promise<CashMovement>;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { Body, Controller, Delete, Get, Inject, Param, ParseIntPipe, Patch, Post } from "@nestjs/common";
|
||||
import type {
|
||||
CreateCashRegisterSessionInput,
|
||||
UpdateCashRegisterSessionInput,
|
||||
} from "../../dtos/cash-register-session.dto.js";
|
||||
import { CASH_REGISTER_SESSION_SERVICE } from "./interfaces/cash-register-session-service.interface.js";
|
||||
import type { ICashRegisterSessionService } from "./interfaces/cash-register-session-service.interface.js";
|
||||
|
||||
@Controller("cash-register-sessions")
|
||||
export class CashRegisterSessionController {
|
||||
constructor(
|
||||
@Inject(CASH_REGISTER_SESSION_SERVICE)
|
||||
private readonly sessionService: ICashRegisterSessionService,
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
return this.sessionService.findAll();
|
||||
}
|
||||
|
||||
@Get(":id")
|
||||
findOne(@Param("id", ParseIntPipe) id: number) {
|
||||
return this.sessionService.findById({ id });
|
||||
}
|
||||
|
||||
@Post()
|
||||
create(@Body() body: CreateCashRegisterSessionInput) {
|
||||
return this.sessionService.create(body);
|
||||
}
|
||||
|
||||
@Patch(":id")
|
||||
update(@Param("id", ParseIntPipe) id: number, @Body() body: UpdateCashRegisterSessionInput) {
|
||||
return this.sessionService.update({ id }, body);
|
||||
}
|
||||
|
||||
@Delete(":id")
|
||||
remove(@Param("id", ParseIntPipe) id: number) {
|
||||
return this.sessionService.delete({ id });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { CASH_REGISTER_SESSION_REPOSITORY } from "./interfaces/cash-register-session-repository.interface.js";
|
||||
import { CASH_REGISTER_SESSION_SERVICE } from "./interfaces/cash-register-session-service.interface.js";
|
||||
import { CashRegisterSessionController } from "./cash-register-session.controller.js";
|
||||
import { CashRegisterSessionRepository } from "./cash-register-session.repository.js";
|
||||
import { CashRegisterSessionService } from "./cash-register-session.service.js";
|
||||
|
||||
@Module({
|
||||
controllers: [CashRegisterSessionController],
|
||||
providers: [
|
||||
{ provide: CASH_REGISTER_SESSION_REPOSITORY, useClass: CashRegisterSessionRepository },
|
||||
{ provide: CASH_REGISTER_SESSION_SERVICE, useClass: CashRegisterSessionService },
|
||||
],
|
||||
exports: [CASH_REGISTER_SESSION_SERVICE],
|
||||
})
|
||||
export class CashRegisterSessionModule {}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { BaseRepository } from "../../common/base.repository.js";
|
||||
import type {
|
||||
CreateCashRegisterSessionInput,
|
||||
UpdateCashRegisterSessionInput,
|
||||
} from "../../dtos/cash-register-session.dto.js";
|
||||
import type {
|
||||
CashRegisterSession,
|
||||
CashRegisterSessionKey,
|
||||
} from "../../entities/cash-register-session.entity.js";
|
||||
import type { ICashRegisterSessionRepository } from "./interfaces/cash-register-session-repository.interface.js";
|
||||
|
||||
@Injectable()
|
||||
export class CashRegisterSessionRepository
|
||||
extends BaseRepository<
|
||||
CashRegisterSession,
|
||||
CreateCashRegisterSessionInput,
|
||||
UpdateCashRegisterSessionInput,
|
||||
CashRegisterSessionKey
|
||||
>
|
||||
implements ICashRegisterSessionRepository
|
||||
{
|
||||
protected readonly columns = [
|
||||
"id",
|
||||
"inventoryId",
|
||||
"openedById",
|
||||
"closedById",
|
||||
"openingCash",
|
||||
"closingCash",
|
||||
"expectedCash",
|
||||
"status",
|
||||
"openedAt",
|
||||
"closedAt",
|
||||
] as const;
|
||||
|
||||
protected get model() {
|
||||
return this.db.orm.public.CashRegisterSession;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import { BadRequestException, Inject, Injectable } from "@nestjs/common";
|
||||
import { BaseService } from "../../common/base.service.js";
|
||||
import type {
|
||||
CreateCashRegisterSessionInput,
|
||||
UpdateCashRegisterSessionInput,
|
||||
} from "../../dtos/cash-register-session.dto.js";
|
||||
import type {
|
||||
CashRegisterSession,
|
||||
CashRegisterSessionKey,
|
||||
} from "../../entities/cash-register-session.entity.js";
|
||||
import {
|
||||
CASH_REGISTER_SESSION_REPOSITORY,
|
||||
type ICashRegisterSessionRepository,
|
||||
} from "./interfaces/cash-register-session-repository.interface.js";
|
||||
import type { ICashRegisterSessionService } from "./interfaces/cash-register-session-service.interface.js";
|
||||
|
||||
@Injectable()
|
||||
export class CashRegisterSessionService
|
||||
extends BaseService<
|
||||
CashRegisterSession,
|
||||
CreateCashRegisterSessionInput,
|
||||
UpdateCashRegisterSessionInput,
|
||||
CashRegisterSessionKey
|
||||
>
|
||||
implements ICashRegisterSessionService
|
||||
{
|
||||
constructor(
|
||||
@Inject(CASH_REGISTER_SESSION_REPOSITORY)
|
||||
private readonly sessionRepository: ICashRegisterSessionRepository,
|
||||
) {
|
||||
super(sessionRepository);
|
||||
}
|
||||
|
||||
override async create(data: CreateCashRegisterSessionInput): Promise<CashRegisterSession> {
|
||||
const all = await this.sessionRepository.findAll();
|
||||
const alreadyOpen = all.some((s) => s.inventoryId === data.inventoryId && s.status === "open");
|
||||
if (alreadyOpen) {
|
||||
throw new BadRequestException("Ya hay una caja abierta en este almacén");
|
||||
}
|
||||
return this.sessionRepository.create(data);
|
||||
}
|
||||
|
||||
override async update(
|
||||
where: CashRegisterSessionKey,
|
||||
data: UpdateCashRegisterSessionInput,
|
||||
): Promise<CashRegisterSession> {
|
||||
const current = await this.findById(where);
|
||||
if (data.status === "closed" && current.status === "closed") {
|
||||
throw new BadRequestException("Esta caja ya está cerrada");
|
||||
}
|
||||
const payload =
|
||||
data.status === "closed" && !data.closedAt
|
||||
? { ...data, closedAt: new Date().toISOString() }
|
||||
: data;
|
||||
return this.sessionRepository.update(where, payload);
|
||||
}
|
||||
|
||||
protected override notFoundMessage(where: CashRegisterSessionKey): string {
|
||||
return `CashRegisterSession ${where.id} not found`;
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import type { IRepository } from "../../../common/repository.interface.js";
|
||||
import type {
|
||||
CashRegisterSession,
|
||||
CashRegisterSessionKey,
|
||||
} from "../../../entities/cash-register-session.entity.js";
|
||||
import type {
|
||||
CreateCashRegisterSessionInput,
|
||||
UpdateCashRegisterSessionInput,
|
||||
} from "../../../dtos/cash-register-session.dto.js";
|
||||
|
||||
export const CASH_REGISTER_SESSION_REPOSITORY = Symbol("CASH_REGISTER_SESSION_REPOSITORY");
|
||||
|
||||
export type ICashRegisterSessionRepository = IRepository<
|
||||
CashRegisterSession,
|
||||
CreateCashRegisterSessionInput,
|
||||
UpdateCashRegisterSessionInput,
|
||||
CashRegisterSessionKey
|
||||
>;
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import type { IService } from "../../../common/service.interface.js";
|
||||
import type {
|
||||
CashRegisterSession,
|
||||
CashRegisterSessionKey,
|
||||
} from "../../../entities/cash-register-session.entity.js";
|
||||
import type {
|
||||
CreateCashRegisterSessionInput,
|
||||
UpdateCashRegisterSessionInput,
|
||||
} from "../../../dtos/cash-register-session.dto.js";
|
||||
|
||||
export const CASH_REGISTER_SESSION_SERVICE = Symbol("CASH_REGISTER_SESSION_SERVICE");
|
||||
|
||||
export type ICashRegisterSessionService = IService<
|
||||
CashRegisterSession,
|
||||
CreateCashRegisterSessionInput,
|
||||
UpdateCashRegisterSessionInput,
|
||||
CashRegisterSessionKey
|
||||
>;
|
||||
@@ -0,0 +1,53 @@
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Inject,
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
Patch,
|
||||
Post,
|
||||
} from "@nestjs/common";
|
||||
import type {
|
||||
CreateCategoryInput,
|
||||
UpdateCategoryInput,
|
||||
} from "../../dtos/category.dto.js";
|
||||
import { CATEGORY_SERVICE } from "./interfaces/category-service.interface.js";
|
||||
import type { ICategoryService } from "./interfaces/category-service.interface.js";
|
||||
|
||||
@Controller("categories")
|
||||
export class CategoryController {
|
||||
constructor(
|
||||
@Inject(CATEGORY_SERVICE)
|
||||
private readonly categoryService: ICategoryService,
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
return this.categoryService.findAll();
|
||||
}
|
||||
|
||||
@Get(":id")
|
||||
findOne(@Param("id", ParseIntPipe) id: number) {
|
||||
return this.categoryService.findById({ id });
|
||||
}
|
||||
|
||||
@Post()
|
||||
create(@Body() body: CreateCategoryInput) {
|
||||
return this.categoryService.create(body);
|
||||
}
|
||||
|
||||
@Patch(":id")
|
||||
update(
|
||||
@Param("id", ParseIntPipe) id: number,
|
||||
@Body() body: UpdateCategoryInput,
|
||||
) {
|
||||
return this.categoryService.update({ id }, body);
|
||||
}
|
||||
|
||||
@Delete(":id")
|
||||
remove(@Param("id", ParseIntPipe) id: number) {
|
||||
return this.categoryService.delete({ id });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { CATEGORY_REPOSITORY } from "./interfaces/category-repository.interface.js";
|
||||
import { CATEGORY_SERVICE } from "./interfaces/category-service.interface.js";
|
||||
import { CategoryController } from "./category.controller.js";
|
||||
import { CategoryRepository } from "./category.repository.js";
|
||||
import { CategoryService } from "./category.service.js";
|
||||
|
||||
@Module({
|
||||
controllers: [CategoryController],
|
||||
providers: [
|
||||
{ provide: CATEGORY_REPOSITORY, useClass: CategoryRepository },
|
||||
{ provide: CATEGORY_SERVICE, useClass: CategoryService },
|
||||
],
|
||||
exports: [CATEGORY_SERVICE],
|
||||
})
|
||||
export class CategoryModule {}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { BaseRepository } from "../../common/base.repository.js";
|
||||
import type {
|
||||
CreateCategoryInput,
|
||||
UpdateCategoryInput,
|
||||
} from "../../dtos/category.dto.js";
|
||||
import type { Category, CategoryKey } from "../../entities/category.entity.js";
|
||||
import type { ICategoryRepository } from "./interfaces/category-repository.interface.js";
|
||||
|
||||
@Injectable()
|
||||
export class CategoryRepository
|
||||
extends BaseRepository<
|
||||
Category,
|
||||
CreateCategoryInput,
|
||||
UpdateCategoryInput,
|
||||
CategoryKey
|
||||
>
|
||||
implements ICategoryRepository
|
||||
{
|
||||
protected readonly columns = ["id", "name", "createdAt"] as const;
|
||||
|
||||
protected get model() {
|
||||
return this.db.orm.public.Category;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { Inject, Injectable } from "@nestjs/common";
|
||||
import { BaseService } from "../../common/base.service.js";
|
||||
import type {
|
||||
CreateCategoryInput,
|
||||
UpdateCategoryInput,
|
||||
} from "../../dtos/category.dto.js";
|
||||
import type { Category, CategoryKey } from "../../entities/category.entity.js";
|
||||
import {
|
||||
CATEGORY_REPOSITORY,
|
||||
type ICategoryRepository,
|
||||
} from "./interfaces/category-repository.interface.js";
|
||||
import type { ICategoryService } from "./interfaces/category-service.interface.js";
|
||||
|
||||
@Injectable()
|
||||
export class CategoryService
|
||||
extends BaseService<
|
||||
Category,
|
||||
CreateCategoryInput,
|
||||
UpdateCategoryInput,
|
||||
CategoryKey
|
||||
>
|
||||
implements ICategoryService
|
||||
{
|
||||
constructor(@Inject(CATEGORY_REPOSITORY) repository: ICategoryRepository) {
|
||||
super(repository);
|
||||
}
|
||||
|
||||
protected override notFoundMessage(where: CategoryKey): string {
|
||||
return `Category ${where.id} not found`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { IRepository } from "../../../common/repository.interface.js";
|
||||
import type {
|
||||
Category,
|
||||
CategoryKey,
|
||||
} from "../../../entities/category.entity.js";
|
||||
import type {
|
||||
CreateCategoryInput,
|
||||
UpdateCategoryInput,
|
||||
} from "../../../dtos/category.dto.js";
|
||||
|
||||
export const CATEGORY_REPOSITORY = Symbol("CATEGORY_REPOSITORY");
|
||||
|
||||
export type ICategoryRepository = IRepository<
|
||||
Category,
|
||||
CreateCategoryInput,
|
||||
UpdateCategoryInput,
|
||||
CategoryKey
|
||||
>;
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { IService } from "../../../common/service.interface.js";
|
||||
import type {
|
||||
Category,
|
||||
CategoryKey,
|
||||
} from "../../../entities/category.entity.js";
|
||||
import type {
|
||||
CreateCategoryInput,
|
||||
UpdateCategoryInput,
|
||||
} from "../../../dtos/category.dto.js";
|
||||
|
||||
export const CATEGORY_SERVICE = Symbol("CATEGORY_SERVICE");
|
||||
|
||||
export type ICategoryService = IService<
|
||||
Category,
|
||||
CreateCategoryInput,
|
||||
UpdateCategoryInput,
|
||||
CategoryKey
|
||||
>;
|
||||
@@ -0,0 +1,34 @@
|
||||
import { Body, Controller, Delete, Get, Inject, Param, ParseIntPipe, Patch, Post } from "@nestjs/common";
|
||||
import type { CreateCustomerInput, UpdateCustomerInput } from "../../dtos/customer.dto.js";
|
||||
import { CUSTOMER_SERVICE } from "./interfaces/customer-service.interface.js";
|
||||
import type { ICustomerService } from "./interfaces/customer-service.interface.js";
|
||||
|
||||
@Controller("customers")
|
||||
export class CustomerController {
|
||||
constructor(@Inject(CUSTOMER_SERVICE) private readonly customerService: ICustomerService) {}
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
return this.customerService.findAll();
|
||||
}
|
||||
|
||||
@Get(":id")
|
||||
findOne(@Param("id", ParseIntPipe) id: number) {
|
||||
return this.customerService.findById({ id });
|
||||
}
|
||||
|
||||
@Post()
|
||||
create(@Body() body: CreateCustomerInput) {
|
||||
return this.customerService.create(body);
|
||||
}
|
||||
|
||||
@Patch(":id")
|
||||
update(@Param("id", ParseIntPipe) id: number, @Body() body: UpdateCustomerInput) {
|
||||
return this.customerService.update({ id }, body);
|
||||
}
|
||||
|
||||
@Delete(":id")
|
||||
remove(@Param("id", ParseIntPipe) id: number) {
|
||||
return this.customerService.delete({ id });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { CUSTOMER_REPOSITORY } from "./interfaces/customer-repository.interface.js";
|
||||
import { CUSTOMER_SERVICE } from "./interfaces/customer-service.interface.js";
|
||||
import { CustomerController } from "./customer.controller.js";
|
||||
import { CustomerRepository } from "./customer.repository.js";
|
||||
import { CustomerService } from "./customer.service.js";
|
||||
|
||||
@Module({
|
||||
controllers: [CustomerController],
|
||||
providers: [
|
||||
{ provide: CUSTOMER_REPOSITORY, useClass: CustomerRepository },
|
||||
{ provide: CUSTOMER_SERVICE, useClass: CustomerService },
|
||||
],
|
||||
exports: [CUSTOMER_SERVICE],
|
||||
})
|
||||
export class CustomerModule {}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { BaseRepository } from "../../common/base.repository.js";
|
||||
import type { CreateCustomerInput, UpdateCustomerInput } from "../../dtos/customer.dto.js";
|
||||
import type { Customer, CustomerKey } from "../../entities/customer.entity.js";
|
||||
import type { ICustomerRepository } from "./interfaces/customer-repository.interface.js";
|
||||
|
||||
@Injectable()
|
||||
export class CustomerRepository
|
||||
extends BaseRepository<Customer, CreateCustomerInput, UpdateCustomerInput, CustomerKey>
|
||||
implements ICustomerRepository
|
||||
{
|
||||
protected readonly columns = ["id", "name", "phone", "email", "taxId", "createdAt"] as const;
|
||||
|
||||
protected get model() {
|
||||
return this.db.orm.public.Customer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Inject, Injectable } from "@nestjs/common";
|
||||
import { BaseService } from "../../common/base.service.js";
|
||||
import type { CreateCustomerInput, UpdateCustomerInput } from "../../dtos/customer.dto.js";
|
||||
import type { Customer, CustomerKey } from "../../entities/customer.entity.js";
|
||||
import {
|
||||
CUSTOMER_REPOSITORY,
|
||||
type ICustomerRepository,
|
||||
} from "./interfaces/customer-repository.interface.js";
|
||||
import type { ICustomerService } from "./interfaces/customer-service.interface.js";
|
||||
|
||||
@Injectable()
|
||||
export class CustomerService
|
||||
extends BaseService<Customer, CreateCustomerInput, UpdateCustomerInput, CustomerKey>
|
||||
implements ICustomerService
|
||||
{
|
||||
constructor(@Inject(CUSTOMER_REPOSITORY) repository: ICustomerRepository) {
|
||||
super(repository);
|
||||
}
|
||||
|
||||
protected override notFoundMessage(where: CustomerKey): string {
|
||||
return `Customer ${where.id} not found`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import type { IRepository } from "../../../common/repository.interface.js";
|
||||
import type { Customer, CustomerKey } from "../../../entities/customer.entity.js";
|
||||
import type { CreateCustomerInput, UpdateCustomerInput } from "../../../dtos/customer.dto.js";
|
||||
|
||||
export const CUSTOMER_REPOSITORY = Symbol("CUSTOMER_REPOSITORY");
|
||||
|
||||
export type ICustomerRepository = IRepository<
|
||||
Customer,
|
||||
CreateCustomerInput,
|
||||
UpdateCustomerInput,
|
||||
CustomerKey
|
||||
>;
|
||||
@@ -0,0 +1,12 @@
|
||||
import type { IService } from "../../../common/service.interface.js";
|
||||
import type { Customer, CustomerKey } from "../../../entities/customer.entity.js";
|
||||
import type { CreateCustomerInput, UpdateCustomerInput } from "../../../dtos/customer.dto.js";
|
||||
|
||||
export const CUSTOMER_SERVICE = Symbol("CUSTOMER_SERVICE");
|
||||
|
||||
export type ICustomerService = IService<
|
||||
Customer,
|
||||
CreateCustomerInput,
|
||||
UpdateCustomerInput,
|
||||
CustomerKey
|
||||
>;
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import type {
|
||||
InventoryMovement,
|
||||
InventoryMovementKey,
|
||||
} from "../../../entities/inventory-movement.entity.js";
|
||||
import type { CreateInventoryMovementInput } from "../../../dtos/inventory-movement.dto.js";
|
||||
|
||||
export const INVENTORY_MOVEMENT_REPOSITORY = Symbol(
|
||||
"INVENTORY_MOVEMENT_REPOSITORY",
|
||||
);
|
||||
|
||||
export interface IInventoryMovementRepository {
|
||||
findAll(): Promise<InventoryMovement[]>;
|
||||
findById(where: InventoryMovementKey): Promise<InventoryMovement | null>;
|
||||
create(data: CreateInventoryMovementInput): Promise<InventoryMovement>;
|
||||
}
|
||||
Loaded 100 of 404 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user