@merkaly/api 0.2.5-4 → 0.2.5-6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. package/.bin/deploy.sh +9 -0
  2. package/.bin/package.sh +12 -0
  3. package/.docker/Dockerfile +21 -0
  4. package/.dockerignore +12 -0
  5. package/.github/dependabot.yml +17 -0
  6. package/.github/semantic.yml +5 -0
  7. package/.github/workflows/pull_request.yml +35 -0
  8. package/.prettierrc +5 -0
  9. package/app.ts +11 -0
  10. package/authCertificate.pem +19 -0
  11. package/nest-cli.json +8 -0
  12. package/package.json +66 -78
  13. package/src/abstracts/abstarct.repository.ts +62 -0
  14. package/src/abstracts/abstract.controller.ts +18 -0
  15. package/src/abstracts/abstract.entity.ts +22 -0
  16. package/src/abstracts/abstract.router.ts +7 -0
  17. package/src/abstracts/abstract.validator.ts +61 -0
  18. package/src/app.config.ts +59 -0
  19. package/src/app.console.ts +24 -0
  20. package/src/app.guard.ts +39 -0
  21. package/src/app.module.ts +54 -0
  22. package/src/app.strategy.ts +21 -0
  23. package/src/commands/seed.command.ts +263 -0
  24. package/src/decorators/public.decorator.ts +5 -0
  25. package/src/decorators/user.decorator.ts +30 -0
  26. package/src/exceptions/missing-identity.exception.ts +11 -0
  27. package/src/interceptors/mongoose.interceptor.ts +63 -0
  28. package/src/main.ts +27 -0
  29. package/src/middlewares/router.middleware.ts +14 -0
  30. package/src/modules/asset/asset.module.ts +19 -0
  31. package/src/modules/asset/files/file.controller.ts +22 -0
  32. package/src/modules/asset/files/file.entity.ts +24 -0
  33. package/src/modules/asset/files/file.module.ts +21 -0
  34. package/src/modules/asset/files/file.repository.ts +44 -0
  35. package/src/modules/asset/files/file.schema.ts +8 -0
  36. package/src/modules/asset/files/file.service.ts +4 -0
  37. package/src/modules/auth/auth.controller.ts +57 -0
  38. package/src/modules/auth/auth.module.ts +20 -0
  39. package/src/modules/auth/organizations/organization.controller.ts +20 -0
  40. package/src/modules/auth/organizations/organization.entity.ts +22 -0
  41. package/src/modules/auth/organizations/organization.module.ts +21 -0
  42. package/src/modules/auth/organizations/organization.repository.ts +16 -0
  43. package/src/modules/auth/organizations/organization.schema.ts +8 -0
  44. package/src/modules/auth/users/user.controller.ts +23 -0
  45. package/src/modules/auth/users/user.entity.ts +25 -0
  46. package/src/modules/auth/users/user.module.ts +20 -0
  47. package/src/modules/auth/users/user.repository.ts +79 -0
  48. package/src/modules/auth/users/user.schema.ts +8 -0
  49. package/src/modules/auth/users/user.validator.ts +32 -0
  50. package/src/modules/command.module.ts +15 -0
  51. package/src/modules/global.module.ts +46 -0
  52. package/src/modules/inventory/brands/brand.controller.ts +44 -0
  53. package/src/modules/inventory/brands/brand.entity.ts +20 -0
  54. package/src/modules/inventory/brands/brand.module.ts +20 -0
  55. package/src/modules/inventory/brands/brand.repository.ts +40 -0
  56. package/src/modules/inventory/brands/brand.schema.ts +8 -0
  57. package/src/modules/inventory/brands/brand.validator.ts +31 -0
  58. package/src/modules/inventory/categories/category.controller.ts +42 -0
  59. package/src/modules/inventory/categories/category.entity.ts +15 -0
  60. package/src/modules/inventory/categories/category.module.ts +19 -0
  61. package/src/modules/inventory/categories/category.repository.ts +34 -0
  62. package/src/modules/inventory/categories/category.schema.ts +8 -0
  63. package/src/modules/inventory/categories/category.validator.ts +20 -0
  64. package/src/modules/inventory/complements/complement.controller.ts +41 -0
  65. package/src/modules/inventory/complements/complement.entity.ts +15 -0
  66. package/src/modules/inventory/complements/complement.module.ts +19 -0
  67. package/src/modules/inventory/complements/complement.repository.ts +37 -0
  68. package/src/modules/inventory/complements/complement.schema.ts +8 -0
  69. package/src/modules/inventory/complements/complement.validator.ts +28 -0
  70. package/src/modules/inventory/inventory.module.ts +23 -0
  71. package/src/modules/inventory/products/documents/attribute.document.ts +14 -0
  72. package/src/modules/inventory/products/documents/dimension.document.ts +16 -0
  73. package/src/modules/inventory/products/product.controller.ts +62 -0
  74. package/src/modules/inventory/products/product.entity.ts +46 -0
  75. package/src/modules/inventory/products/product.module.ts +19 -0
  76. package/src/modules/inventory/products/product.repository.ts +64 -0
  77. package/src/modules/inventory/products/product.schema.ts +19 -0
  78. package/src/modules/inventory/products/product.validator.ts +132 -0
  79. package/src/modules/inventory/products/validators/attributes.validator.ts +15 -0
  80. package/src/modules/inventory/products/validators/dimension.validator.ts +19 -0
  81. package/src/modules/sale/customers/customer.controller.ts +41 -0
  82. package/src/modules/sale/customers/customer.entity.ts +19 -0
  83. package/src/modules/sale/customers/customer.module.ts +18 -0
  84. package/src/modules/sale/customers/customer.repository.ts +30 -0
  85. package/src/modules/sale/customers/customer.schema.ts +8 -0
  86. package/src/modules/sale/customers/customer.validator.ts +43 -0
  87. package/src/modules/sale/orders/documents/address.document.ts +22 -0
  88. package/src/modules/sale/orders/documents/status.document.ts +17 -0
  89. package/src/modules/sale/orders/entities/item.entity.ts +24 -0
  90. package/src/modules/sale/orders/enums/order.status.ts +6 -0
  91. package/src/modules/sale/orders/order.controller.ts +65 -0
  92. package/src/modules/sale/orders/order.entity.ts +46 -0
  93. package/src/modules/sale/orders/order.module.ts +22 -0
  94. package/src/modules/sale/orders/order.repository.ts +122 -0
  95. package/src/modules/sale/orders/order.schema.ts +36 -0
  96. package/src/modules/sale/orders/order.validator.ts +44 -0
  97. package/src/modules/sale/orders/validators/address.validator.ts +50 -0
  98. package/src/modules/sale/orders/validators/billing.validator.ts +11 -0
  99. package/src/modules/sale/orders/validators/item.validator.ts +14 -0
  100. package/src/modules/sale/orders/validators/payment.validator.ts +44 -0
  101. package/src/modules/sale/orders/validators/shipping.validator.ts +14 -0
  102. package/src/modules/sale/payments/entities/status.entity.ts +17 -0
  103. package/src/modules/sale/payments/enums/billing.type.ts +6 -0
  104. package/src/modules/sale/payments/enums/payment.status.ts +7 -0
  105. package/src/modules/sale/payments/enums/shipping.type.ts +4 -0
  106. package/src/modules/sale/payments/payment.controller.ts +45 -0
  107. package/src/modules/sale/payments/payment.entity.ts +25 -0
  108. package/src/modules/sale/payments/payment.module.ts +20 -0
  109. package/src/modules/sale/payments/payment.repository.ts +57 -0
  110. package/src/modules/sale/payments/payment.schema.ts +14 -0
  111. package/src/modules/sale/payments/payment.validator.ts +32 -0
  112. package/src/modules/sale/sale.module.ts +20 -0
  113. package/src/services/auth0.service.ts +49 -0
  114. package/src/services/mongo.service.ts +52 -0
  115. package/test/auth/auth.spec.ts +20 -0
  116. package/test/main.ts +12 -0
  117. package/tsconfig.build.json +4 -0
  118. package/tsconfig.json +21 -0
  119. package/tsconfig.package.json +22 -0
  120. package/.output/abstract/abstract.entity.d.ts +0 -9
  121. package/.output/abstract/abstract.exception.d.ts +0 -11
  122. package/.output/abstract/abstract.exception.js +0 -53
  123. package/.output/abstract/abstract.fixture.d.ts +0 -4
  124. package/.output/abstract/abstract.fixture.js +0 -11
  125. package/.output/abstract/abstract.validator.d.ts +0 -20
  126. package/.output/abstract/abstract.validator.js +0 -105
  127. package/.output/exceptions/missing-identity.exception.d.ts +0 -5
  128. package/.output/exceptions/missing-identity.exception.js +0 -30
  129. package/.output/exceptions/store-not-implemented.exception.d.ts +0 -5
  130. package/.output/exceptions/store-not-implemented.exception.js +0 -31
  131. package/.output/exceptions/store-not-recognized.exception.d.ts +0 -5
  132. package/.output/exceptions/store-not-recognized.exception.js +0 -30
  133. package/.output/modules/asset/files/file.entity.d.ts +0 -10
  134. package/.output/modules/auth/auth.types.d.ts +0 -3
  135. package/.output/modules/auth/auth.types.js +0 -7
  136. package/.output/modules/auth/users/user.validator.d.ts +0 -10
  137. package/.output/modules/auth/users/user.validator.js +0 -50
  138. package/.output/modules/config/organization/organization.entity.d.ts +0 -21
  139. package/.output/modules/config/organization/organization.types.d.ts +0 -23
  140. package/.output/modules/config/organization/organization.types.js +0 -107
  141. package/.output/modules/config/organization/organization.validator.d.ts +0 -18
  142. package/.output/modules/config/organization/organization.validator.js +0 -88
  143. package/.output/modules/insight/validators/order.validator.d.ts +0 -4
  144. package/.output/modules/insight/validators/order.validator.js +0 -27
  145. package/.output/modules/inventory/brands/brand.entity.d.ts +0 -9
  146. package/.output/modules/inventory/brands/brand.exception.d.ts +0 -5
  147. package/.output/modules/inventory/brands/brand.exception.js +0 -40
  148. package/.output/modules/inventory/brands/brand.validator.d.ts +0 -11
  149. package/.output/modules/inventory/brands/brand.validator.js +0 -75
  150. package/.output/modules/inventory/categories/category.entity.d.ts +0 -12
  151. package/.output/modules/inventory/categories/category.exception.d.ts +0 -5
  152. package/.output/modules/inventory/categories/category.exception.js +0 -40
  153. package/.output/modules/inventory/categories/category.fixture.d.ts +0 -5
  154. package/.output/modules/inventory/categories/category.fixture.js +0 -38
  155. package/.output/modules/inventory/categories/category.validator.d.ts +0 -13
  156. package/.output/modules/inventory/categories/category.validator.js +0 -88
  157. package/.output/modules/inventory/products/entities/code.entity.d.ts +0 -5
  158. package/.output/modules/inventory/products/entities/dimension.entity.d.ts +0 -6
  159. package/.output/modules/inventory/products/entities/seo.entity.d.ts +0 -5
  160. package/.output/modules/inventory/products/entities/variant.entity.d.ts +0 -10
  161. package/.output/modules/inventory/products/product.entity.d.ts +0 -26
  162. package/.output/modules/inventory/products/product.exception.d.ts +0 -5
  163. package/.output/modules/inventory/products/product.exception.js +0 -40
  164. package/.output/modules/inventory/products/product.fixture.d.ts +0 -5
  165. package/.output/modules/inventory/products/product.fixture.js +0 -39
  166. package/.output/modules/inventory/products/product.validator.d.ts +0 -38
  167. package/.output/modules/inventory/products/product.validator.js +0 -235
  168. package/.output/modules/inventory/products/schemas/variant.schema.d.ts +0 -27
  169. package/.output/modules/inventory/products/schemas/variant.schema.js +0 -6
  170. package/.output/modules/inventory/products/validators/code.validator.d.ts +0 -5
  171. package/.output/modules/inventory/products/validators/code.validator.js +0 -37
  172. package/.output/modules/inventory/products/validators/dimension.validator.d.ts +0 -6
  173. package/.output/modules/inventory/products/validators/dimension.validator.js +0 -43
  174. package/.output/modules/inventory/products/validators/seo.validator.d.ts +0 -5
  175. package/.output/modules/inventory/products/validators/seo.validator.js +0 -34
  176. package/.output/modules/inventory/products/validators/variant.validator.d.ts +0 -9
  177. package/.output/modules/inventory/products/validators/variant.validator.js +0 -39
  178. package/.output/modules/inventory/properties/property.entity.d.ts +0 -8
  179. package/.output/modules/inventory/properties/property.exception.d.ts +0 -5
  180. package/.output/modules/inventory/properties/property.exception.js +0 -40
  181. package/.output/modules/inventory/properties/property.types.d.ts +0 -6
  182. package/.output/modules/inventory/properties/property.types.js +0 -10
  183. package/.output/modules/inventory/properties/property.validator.d.ts +0 -12
  184. package/.output/modules/inventory/properties/property.validator.js +0 -79
  185. package/.output/modules/layout/pages/page.entity.d.ts +0 -8
  186. package/.output/modules/layout/pages/page.fixture.d.ts +0 -5
  187. package/.output/modules/layout/pages/page.fixture.js +0 -36
  188. package/.output/modules/layout/pages/page.types.d.ts +0 -20
  189. package/.output/modules/layout/pages/page.types.js +0 -2
  190. package/.output/modules/layout/pages/page.validator.d.ts +0 -8
  191. package/.output/modules/layout/pages/page.validator.js +0 -61
  192. package/.output/modules/sale/customers/customer.entity.d.ts +0 -12
  193. package/.output/modules/sale/customers/customer.exception.d.ts +0 -5
  194. package/.output/modules/sale/customers/customer.exception.js +0 -40
  195. package/.output/modules/sale/customers/customer.validator.d.ts +0 -18
  196. package/.output/modules/sale/customers/customer.validator.js +0 -107
  197. package/.output/modules/sale/orders/billing/billing.entity.d.ts +0 -10
  198. package/.output/modules/sale/orders/billing/billing.types.d.ts +0 -9
  199. package/.output/modules/sale/orders/billing/billing.types.js +0 -14
  200. package/.output/modules/sale/orders/billing/billing.validator.d.ts +0 -9
  201. package/.output/modules/sale/orders/billing/billing.validator.js +0 -42
  202. package/.output/modules/sale/orders/billing/entities/address.entity.d.ts +0 -10
  203. package/.output/modules/sale/orders/billing/entities/customer.entity.d.ts +0 -5
  204. package/.output/modules/sale/orders/billing/entities/status.entity.d.ts +0 -6
  205. package/.output/modules/sale/orders/billing/validators/address.validator.d.ts +0 -10
  206. package/.output/modules/sale/orders/billing/validators/address.validator.js +0 -56
  207. package/.output/modules/sale/orders/billing/validators/customer.validator.d.ts +0 -5
  208. package/.output/modules/sale/orders/billing/validators/customer.validator.js +0 -36
  209. package/.output/modules/sale/orders/customer/customer.entity.d.ts +0 -5
  210. package/.output/modules/sale/orders/customer/customer.validator.d.ts +0 -5
  211. package/.output/modules/sale/orders/customer/customer.validator.js +0 -36
  212. package/.output/modules/sale/orders/item/item.entity.d.ts +0 -9
  213. package/.output/modules/sale/orders/item/item.schema.d.ts +0 -27
  214. package/.output/modules/sale/orders/item/item.schema.js +0 -9
  215. package/.output/modules/sale/orders/item/item.validator.d.ts +0 -4
  216. package/.output/modules/sale/orders/item/item.validator.js +0 -29
  217. package/.output/modules/sale/orders/order.entity.d.ts +0 -21
  218. package/.output/modules/sale/orders/order.exception.d.ts +0 -13
  219. package/.output/modules/sale/orders/order.exception.js +0 -46
  220. package/.output/modules/sale/orders/order.validator.d.ts +0 -28
  221. package/.output/modules/sale/orders/order.validator.js +0 -140
  222. package/.output/modules/sale/orders/shipping/entities/address.entity.d.ts +0 -10
  223. package/.output/modules/sale/orders/shipping/entities/customer.entity.d.ts +0 -5
  224. package/.output/modules/sale/orders/shipping/entities/status.entity.d.ts +0 -6
  225. package/.output/modules/sale/orders/shipping/shipping.entity.d.ts +0 -11
  226. package/.output/modules/sale/orders/shipping/shipping.types.d.ts +0 -11
  227. package/.output/modules/sale/orders/shipping/shipping.types.js +0 -16
  228. package/.output/modules/sale/orders/shipping/shipping.validator.d.ts +0 -10
  229. package/.output/modules/sale/orders/shipping/shipping.validator.js +0 -48
  230. package/.output/modules/sale/orders/shipping/validators/address.validator.d.ts +0 -10
  231. package/.output/modules/sale/orders/shipping/validators/address.validator.js +0 -56
  232. package/.output/modules/sale/orders/shipping/validators/customer.validator.d.ts +0 -5
  233. package/.output/modules/sale/orders/shipping/validators/customer.validator.js +0 -36
  234. package/.output/modules/sale/orders/status/status.entity.d.ts +0 -6
  235. package/.output/modules/sale/orders/status/status.validator.d.ts +0 -8
  236. package/.output/modules/sale/orders/status/status.validator.js +0 -12
  237. package/.output/services/logger.service.d.ts +0 -11
  238. package/.output/services/logger.service.js +0 -50
  239. package/.output/types.d.ts +0 -18
  240. package/.output/types.js +0 -2
  241. package/LICENSE +0 -674
@@ -0,0 +1,19 @@
1
+ import { Module, ModuleMetadata } from '@nestjs/common';
2
+ import { CategoryController } from './category.controller';
3
+ import { CategoryRepository } from './category.repository';
4
+
5
+ export const metadata: ModuleMetadata = {
6
+ controllers: [CategoryController],
7
+ exports: [CategoryRepository],
8
+ imports: [],
9
+ providers: [CategoryRepository],
10
+ };
11
+
12
+ @Module(metadata)
13
+ export class CategoryModule {
14
+ public static readonly path = '/categories';
15
+
16
+ public static readonly module = CategoryModule;
17
+
18
+ public static readonly children = metadata.imports;
19
+ }
@@ -0,0 +1,34 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { InjectModel } from '@nestjs/mongoose';
3
+ import { Model } from 'mongoose';
4
+ import { AbstractRepository } from '../../../abstracts/abstarct.repository';
5
+ import { CategoryEntity } from './category.entity';
6
+ import { CategorySchema } from './category.schema';
7
+ import { CreateCategoryValidator, UpdateCategoryValidator } from './category.validator';
8
+
9
+ @Injectable()
10
+ export class CategoryRepository extends AbstractRepository<CategoryEntity> {
11
+ @InjectModel(CategorySchema.name)
12
+ protected readonly $model: Model<CategoryEntity>;
13
+
14
+ public async create(validator: CreateCategoryValidator) {
15
+ const category = new this.$model();
16
+
17
+ category.name = validator.name;
18
+ category.description = validator.description;
19
+
20
+ await category.save();
21
+
22
+ return category;
23
+ }
24
+
25
+ public async update(id: string, validator: UpdateCategoryValidator) {
26
+ const category = await this.read(id);
27
+
28
+ category.name = validator.name || category.name;
29
+ category.description = validator.description || category.description;
30
+
31
+ await category.save();
32
+ return category;
33
+ }
34
+ }
@@ -0,0 +1,8 @@
1
+ import { SchemaFactory } from '@nestjs/mongoose';
2
+ import { CategoryEntity } from './category.entity';
3
+
4
+ export namespace CategorySchema {
5
+ export const name = 'inventory_categories';
6
+
7
+ export const schema = SchemaFactory.createForClass(CategoryEntity);
8
+ }
@@ -0,0 +1,20 @@
1
+ import { IsOptional, IsString } from 'class-validator';
2
+
3
+ export class CreateCategoryValidator {
4
+ @IsString()
5
+ public name: string;
6
+
7
+ @IsString()
8
+ @IsOptional()
9
+ public description?: string;
10
+ }
11
+
12
+ export class UpdateCategoryValidator {
13
+ @IsString()
14
+ @IsOptional()
15
+ public name: string;
16
+
17
+ @IsString()
18
+ @IsOptional()
19
+ public description?: string;
20
+ }
@@ -0,0 +1,41 @@
1
+ import { Body, Controller, Delete, Get, Inject, Param, Patch, Post, Query } from '@nestjs/common';
2
+ import { ApiTags } from '@nestjs/swagger';
3
+ import { AbstractController } from '../../../abstracts/abstract.controller';
4
+ import { IdMongoValidator, ReadValidator } from '../../../abstracts/abstract.validator';
5
+ import { Public } from '../../../decorators/public.decorator';
6
+ import { ComplementRepository } from './complement.repository';
7
+ import { CreateComplementValidator, UpdateComplementValidator } from './complement.validator';
8
+
9
+ @Controller('/')
10
+ @ApiTags('inventory')
11
+ export class ComplementController extends AbstractController {
12
+ @Inject()
13
+ protected readonly $repository: ComplementRepository;
14
+
15
+ @Public()
16
+ @Get('/')
17
+ public find() {
18
+ return this.$repository.find();
19
+ }
20
+
21
+ @Public()
22
+ @Get('/:id')
23
+ public read(@Param() { id }: IdMongoValidator, @Query() validator?: ReadValidator) {
24
+ return this.$repository.read(id, validator);
25
+ }
26
+
27
+ @Post('/')
28
+ public create(@Body() validator: CreateComplementValidator) {
29
+ return this.$repository.create(validator);
30
+ }
31
+
32
+ @Patch('/:id')
33
+ public update(@Param() { id }: IdMongoValidator, @Body() validator: UpdateComplementValidator) {
34
+ return this.$repository.update(id, validator);
35
+ }
36
+
37
+ @Delete('/:id')
38
+ public delete(@Param() { id }: IdMongoValidator) {
39
+ return this.$repository.delete(id);
40
+ }
41
+ }
@@ -0,0 +1,15 @@
1
+ import { Prop, Schema as Collection } from '@nestjs/mongoose';
2
+ import { Schema } from 'mongoose';
3
+ import { $collection, AbstractEntity } from '../../../abstracts/abstract.entity';
4
+
5
+ @Collection($collection)
6
+ export class ComplementEntity extends AbstractEntity {
7
+ @Prop({ required: true, type: Schema.Types.String, unique: true })
8
+ public name: string;
9
+
10
+ @Prop({ type: Schema.Types.String })
11
+ public description: string;
12
+
13
+ @Prop({ default: () => 0, type: Schema.Types.Number })
14
+ public price: number;
15
+ }
@@ -0,0 +1,19 @@
1
+ import { Module, ModuleMetadata } from '@nestjs/common';
2
+ import { ComplementController } from './complement.controller';
3
+ import { ComplementRepository } from './complement.repository';
4
+
5
+ export const metadata: ModuleMetadata = {
6
+ controllers: [ComplementController],
7
+ exports: [ComplementRepository],
8
+ imports: [],
9
+ providers: [ComplementRepository],
10
+ };
11
+
12
+ @Module(metadata)
13
+ export class ComplementModule {
14
+ public static readonly path = '/complements';
15
+
16
+ public static readonly module = ComplementModule;
17
+
18
+ public static readonly children = metadata.imports;
19
+ }
@@ -0,0 +1,37 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { InjectModel } from '@nestjs/mongoose';
3
+ import { Model } from 'mongoose';
4
+ import { AbstractRepository } from '../../../abstracts/abstarct.repository';
5
+ import { ComplementEntity } from './complement.entity';
6
+ import { ComplementSchema } from './complement.schema';
7
+ import { CreateComplementValidator, UpdateComplementValidator } from './complement.validator';
8
+
9
+ @Injectable()
10
+ export class ComplementRepository extends AbstractRepository<ComplementEntity> {
11
+ @InjectModel(ComplementSchema.name)
12
+ protected readonly $model: Model<ComplementEntity>;
13
+
14
+ public async create(validator: CreateComplementValidator) {
15
+ const complement = new this.$model();
16
+
17
+ complement.name = validator.name;
18
+ complement.description = validator.description;
19
+ complement.price = validator.price;
20
+
21
+ await complement.save();
22
+
23
+ return complement;
24
+ }
25
+
26
+ public async update(id: string, validator: UpdateComplementValidator) {
27
+ const complement = await this.read(id);
28
+
29
+ complement.name = validator.name || complement.name;
30
+ complement.description = validator.description || complement.description;
31
+ complement.price = validator.price || complement.price;
32
+
33
+ complement.save();
34
+
35
+ return complement;
36
+ }
37
+ }
@@ -0,0 +1,8 @@
1
+ import { SchemaFactory } from '@nestjs/mongoose';
2
+ import { ComplementEntity } from './complement.entity';
3
+
4
+ export namespace ComplementSchema {
5
+ export const name = 'inventory_complements';
6
+
7
+ export const schema = SchemaFactory.createForClass(ComplementEntity);
8
+ }
@@ -0,0 +1,28 @@
1
+ import { IsNumber, IsOptional, IsPositive, IsString } from 'class-validator';
2
+
3
+ export class CreateComplementValidator {
4
+ @IsString()
5
+ public name: string;
6
+
7
+ @IsString()
8
+ public description: string;
9
+
10
+ @IsNumber()
11
+ @IsPositive()
12
+ public price: number;
13
+ }
14
+
15
+ export class UpdateComplementValidator {
16
+ @IsOptional()
17
+ @IsString()
18
+ public name: string;
19
+
20
+ @IsOptional()
21
+ @IsString()
22
+ public description: string;
23
+
24
+ @IsOptional()
25
+ @IsNumber()
26
+ @IsPositive()
27
+ public price: number;
28
+ }
@@ -0,0 +1,23 @@
1
+ import { Module, ModuleMetadata } from '@nestjs/common';
2
+ import { BrandModule } from './brands/brand.module';
3
+ import { CategoryModule } from './categories/category.module';
4
+ import { ComplementModule } from './complements/complement.module';
5
+ import { ProductModule } from './products/product.module';
6
+
7
+ const modules = [ProductModule, CategoryModule, ComplementModule, BrandModule];
8
+
9
+ export const metadata: ModuleMetadata = {
10
+ controllers: [],
11
+ exports: modules,
12
+ imports: modules,
13
+ providers: [],
14
+ };
15
+
16
+ @Module(metadata)
17
+ export class InventoryModule {
18
+ public static readonly path = '/inventory';
19
+
20
+ public static readonly module = InventoryModule;
21
+
22
+ public static readonly children = metadata.imports;
23
+ }
@@ -0,0 +1,14 @@
1
+ import { Prop } from '@nestjs/mongoose';
2
+ import { Schema } from 'mongoose';
3
+
4
+ export class ProductAttributesDocument {
5
+ // Cantidad de unidades que se venden en ese producto
6
+ @Prop({ default: () => 1, type: Schema.Types.Number })
7
+ public units = 1;
8
+
9
+ @Prop({ default: () => null, type: Schema.Types.Number })
10
+ public stock: null | number = null;
11
+
12
+ @Prop({ default: () => undefined, required: true, type: Schema.Types.String, unique: true })
13
+ public sku: string;
14
+ }
@@ -0,0 +1,16 @@
1
+ import { Prop } from '@nestjs/mongoose';
2
+ import { Schema } from 'mongoose';
3
+
4
+ export class ProductDimensionDocument {
5
+ @Prop({ type: Schema.Types.Number })
6
+ public weight: number;
7
+
8
+ @Prop({ type: Schema.Types.Number })
9
+ public height: number;
10
+
11
+ @Prop({ type: Schema.Types.Number })
12
+ public width: number;
13
+
14
+ @Prop({ type: Schema.Types.Number })
15
+ public depth: number;
16
+ }
@@ -0,0 +1,62 @@
1
+ import { Body, Controller, Delete, Get, Inject, Param, Patch, Post, Query } from '@nestjs/common';
2
+ import { ApiTags } from '@nestjs/swagger';
3
+ import { AbstractController } from '../../../abstracts/abstract.controller';
4
+ import { FindValidator, IdMongoValidator, ReadValidator } from '../../../abstracts/abstract.validator';
5
+ import { Public } from '../../../decorators/public.decorator';
6
+ import { ProductEntity } from './product.entity';
7
+ import { ProductRepository } from './product.repository';
8
+ import { CreateProductValidator, UpdateProductValidator } from './product.validator';
9
+
10
+ @Controller('/')
11
+ @ApiTags('inventory')
12
+ export class ProductController extends AbstractController {
13
+ @Inject()
14
+ protected readonly $repository: ProductRepository;
15
+
16
+ @Public()
17
+ @Get('/')
18
+ public find(@Query() validator: FindValidator<ProductEntity>) {
19
+ return this.$repository.find(validator);
20
+ }
21
+
22
+ @Public()
23
+ @Post('/')
24
+ public create(@Body() validator: CreateProductValidator) {
25
+ return this.$repository.create(validator);
26
+ }
27
+
28
+ @Public()
29
+ @Get('/:id')
30
+ public read(@Param() { id }: IdMongoValidator, @Query() validator?: ReadValidator) {
31
+ return this.$repository.read(id, validator);
32
+ }
33
+
34
+ @Patch('/:id')
35
+ public update(@Param() { id }: IdMongoValidator, @Body() validator: UpdateProductValidator) {
36
+ return this.$repository.update(id, validator);
37
+ }
38
+
39
+ @Delete('/:id')
40
+ public delete(@Param() { id }: IdMongoValidator) {
41
+ return this.$repository.delete(id);
42
+ }
43
+
44
+ @Public()
45
+ @Get('/:id/related')
46
+ public async findRelated(@Param() { id }: IdMongoValidator, @Query() validator: FindValidator<ProductEntity> = {}) {
47
+ const product = await this.read({ id }, {});
48
+
49
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
50
+ // @ts-ignore
51
+ validator.filters._id = { $ne: id };
52
+ validator.filters.category = product.category;
53
+ validator.filters.$text = {
54
+ $caseSensitive: false,
55
+ $search: product.name,
56
+ };
57
+
58
+ const { items } = await this.$repository.find(validator);
59
+
60
+ return items;
61
+ }
62
+ }
@@ -0,0 +1,46 @@
1
+ import { Prop, Schema as Collection } from '@nestjs/mongoose';
2
+ import { Schema } from 'mongoose';
3
+ import { $collection, AbstractEntity, MaybeEntity } from '../../../abstracts/abstract.entity';
4
+ import { FileEntity } from '../../asset/files/file.entity';
5
+ import { FileSchema } from '../../asset/files/file.schema';
6
+ import { BrandEntity } from '../brands/brand.entity';
7
+ import { BrandSchema } from '../brands/brand.schema';
8
+ import { CategoryEntity } from '../categories/category.entity';
9
+ import { CategorySchema } from '../categories/category.schema';
10
+ import { ProductAttributesDocument } from './documents/attribute.document';
11
+ import { ProductDimensionDocument } from './documents/dimension.document';
12
+
13
+ @Collection($collection)
14
+ export class ProductEntity extends AbstractEntity {
15
+ @Prop({ required: true, type: Schema.Types.String, unique: true })
16
+ public name: string;
17
+
18
+ @Prop({ default: () => String(), type: Schema.Types.String })
19
+ public description: string;
20
+
21
+ @Prop({ default: true, type: Schema.Types.Boolean })
22
+ public active = true;
23
+
24
+ @Prop({ required: true, type: Schema.Types.Number })
25
+ public price: number;
26
+
27
+ @Prop({ default: [], type: Schema.Types.Array })
28
+ public hashtags: string[] = [];
29
+
30
+ @Prop({ ref: BrandSchema.name, type: Schema.Types.ObjectId })
31
+ public brand?: MaybeEntity<BrandEntity>;
32
+
33
+ @Prop({ ref: CategorySchema.name, type: Schema.Types.ObjectId })
34
+ public category?: MaybeEntity<CategoryEntity>;
35
+
36
+ @Prop({ default: [], ref: FileSchema.name, type: [{ type: Schema.Types.String }] })
37
+ public pictures: FileEntity[] = [];
38
+
39
+ @Prop({ default: () => new ProductAttributesDocument(), type: Schema.Types.Mixed })
40
+ public attributes = new ProductAttributesDocument();
41
+
42
+ @Prop({ default: () => new ProductDimensionDocument(), type: Schema.Types.Mixed })
43
+ public dimension = new ProductDimensionDocument();
44
+
45
+ public readonly image: string;
46
+ }
@@ -0,0 +1,19 @@
1
+ import { Module, ModuleMetadata } from '@nestjs/common';
2
+ import { ProductController } from './product.controller';
3
+ import { ProductRepository } from './product.repository';
4
+
5
+ export const metadata: ModuleMetadata = {
6
+ controllers: [ProductController],
7
+ exports: [ProductRepository],
8
+ imports: [],
9
+ providers: [ProductRepository],
10
+ };
11
+
12
+ @Module(metadata)
13
+ export class ProductModule {
14
+ public static readonly path = '/products';
15
+
16
+ public static readonly module = ProductModule;
17
+
18
+ public static readonly children = metadata.imports;
19
+ }
@@ -0,0 +1,64 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { InjectModel } from '@nestjs/mongoose';
3
+ import { Model } from 'mongoose';
4
+ import { AbstractRepository } from '../../../abstracts/abstarct.repository';
5
+ import { ProductEntity } from './product.entity';
6
+ import { ProductSchema } from './product.schema';
7
+ import { CreateProductValidator, UpdateProductValidator } from './product.validator';
8
+
9
+ @Injectable()
10
+ export class ProductRepository extends AbstractRepository<ProductEntity> {
11
+ @InjectModel(ProductSchema.name)
12
+ protected readonly $model: Model<ProductEntity>;
13
+
14
+ public async create(validator: CreateProductValidator) {
15
+ const product = new this.$model();
16
+
17
+ product.active = validator.active;
18
+
19
+ product.name = validator.name;
20
+ product.description = validator.description;
21
+ product.price = validator.price;
22
+ product.hashtags = validator.hashtags;
23
+
24
+ product.pictures = validator.pictures as any;
25
+ product.category = validator.category as any;
26
+ product.brand = validator.brand as any;
27
+
28
+ product.dimension = {
29
+ depth: validator.dimension?.depth,
30
+ height: validator.dimension?.height,
31
+ weight: validator.dimension?.weight,
32
+ width: validator.dimension?.width,
33
+ };
34
+
35
+ product.attributes = {
36
+ stock: validator.attributes.stock,
37
+ sku: validator.attributes.sku,
38
+ units: validator.attributes.units,
39
+ };
40
+
41
+ await product.save();
42
+
43
+ return product;
44
+ }
45
+
46
+ public async update(id: string, validator: UpdateProductValidator) {
47
+ const product = await this.read(id);
48
+
49
+ validator.active && (product.active = validator.active);
50
+
51
+ validator.name && (product.name = validator.name);
52
+ validator.description && (product.description = validator.description);
53
+ validator.price && (product.price = validator.price);
54
+ validator.hashtags?.length && (product.hashtags = validator.hashtags);
55
+
56
+ validator.category && (product.category = validator.category as any);
57
+ validator.brand && (product.brand = validator.brand as any);
58
+ validator.pictures?.length && (product.pictures = validator.pictures as any);
59
+
60
+ await product.save();
61
+
62
+ return product;
63
+ }
64
+ }
@@ -0,0 +1,19 @@
1
+ import { SchemaFactory } from '@nestjs/mongoose';
2
+ import { ProductEntity } from './product.entity';
3
+
4
+ export namespace ProductSchema {
5
+ export const name = 'inventory_products';
6
+
7
+ export const schema = SchemaFactory.createForClass(ProductEntity);
8
+
9
+ schema.index({
10
+ description: 'text',
11
+ name: 'text',
12
+ });
13
+
14
+ schema.virtual('image').get(function () {
15
+ const [first] = this.pictures;
16
+
17
+ return first?.url;
18
+ });
19
+ }
@@ -0,0 +1,132 @@
1
+ import { Type } from 'class-transformer';
2
+ import {
3
+ IsArray,
4
+ IsBoolean,
5
+ IsMongoId,
6
+ IsNotEmpty,
7
+ IsNumber,
8
+ IsOptional,
9
+ IsPositive,
10
+ IsString,
11
+ ValidateNested,
12
+ } from 'class-validator';
13
+ import { AbstractValidator } from '../../../abstracts/abstract.validator';
14
+ import { ProductEntity } from './product.entity';
15
+ import { AttributesValidator } from './validators/attributes.validator';
16
+ import { DimensionValidator } from './validators/dimension.validator';
17
+
18
+ export class CreateProductValidator extends AbstractValidator {
19
+ @IsBoolean()
20
+ @IsOptional()
21
+ public active? = true;
22
+
23
+ @IsString({ each: true })
24
+ @IsNotEmpty({ each: true })
25
+ @IsOptional()
26
+ public hashtags?: string[] = [];
27
+
28
+ @IsString()
29
+ @IsNotEmpty()
30
+ public name: string;
31
+
32
+ @IsString()
33
+ @IsOptional()
34
+ public description: string;
35
+
36
+ @IsNumber()
37
+ @IsPositive()
38
+ public price: number;
39
+
40
+ @IsMongoId({ each: true })
41
+ @IsArray()
42
+ @IsOptional()
43
+ public pictures?: string[] = [];
44
+
45
+ @IsOptional()
46
+ @IsMongoId()
47
+ public category?: string;
48
+
49
+ @IsOptional()
50
+ @IsMongoId()
51
+ public brand?: string;
52
+
53
+ @Type(() => DimensionValidator)
54
+ @ValidateNested()
55
+ @IsOptional()
56
+ public dimension? = new DimensionValidator();
57
+
58
+ @Type(() => AttributesValidator)
59
+ @ValidateNested()
60
+ @IsOptional()
61
+ public attributes? = new AttributesValidator();
62
+ }
63
+
64
+ export class UpdateProductValidator {
65
+ @IsBoolean()
66
+ @IsOptional()
67
+ public active?: boolean;
68
+
69
+ @IsString({ each: true })
70
+ @IsNotEmpty({ each: true })
71
+ @IsOptional()
72
+ public hashtags?: string[] = [];
73
+
74
+ @IsOptional()
75
+ @IsString()
76
+ @IsNotEmpty()
77
+ public name?: string;
78
+
79
+ @IsOptional()
80
+ @IsString()
81
+ @IsOptional()
82
+ public description?: string;
83
+
84
+ @IsOptional()
85
+ @IsNumber()
86
+ public price?: number;
87
+
88
+ @IsOptional()
89
+ @IsMongoId()
90
+ public category?: string;
91
+
92
+ @IsOptional()
93
+ @IsMongoId()
94
+ public brand?: string;
95
+
96
+ @IsMongoId({ each: true })
97
+ @IsArray()
98
+ @IsOptional()
99
+ public pictures?: string[] = [];
100
+
101
+ @Type(() => DimensionValidator)
102
+ @ValidateNested()
103
+ @IsOptional()
104
+ public dimension?: DimensionValidator;
105
+
106
+ @Type(() => AttributesValidator)
107
+ @ValidateNested()
108
+ @IsOptional()
109
+ public attributes?: AttributesValidator = new AttributesValidator();
110
+
111
+ public constructor(entity: ProductEntity) {
112
+ this.active = entity.active;
113
+
114
+ this.name = entity.name;
115
+ this.description = entity.description;
116
+ this.price = entity.price;
117
+ this.hashtags = entity.hashtags;
118
+
119
+ this.category = entity.category?._id;
120
+ this.brand = entity.brand?._id;
121
+ this.pictures = entity.pictures.map((file) => file._id);
122
+
123
+ this.attributes.sku = entity.attributes.sku;
124
+ this.attributes.stock = entity.attributes.stock;
125
+ this.attributes.units = entity.attributes.units;
126
+
127
+ this.dimension.depth = entity.dimension.depth;
128
+ this.dimension.height = entity.dimension.height;
129
+ this.dimension.weight = entity.dimension.weight;
130
+ this.dimension.width = entity.dimension.width;
131
+ }
132
+ }
@@ -0,0 +1,15 @@
1
+ import { IsNumber, IsOptional, IsPositive, IsString } from 'class-validator';
2
+
3
+ export class AttributesValidator {
4
+ @IsPositive()
5
+ public units = 1;
6
+
7
+ @IsNumber()
8
+ @IsOptional()
9
+ public stock: number | null = null;
10
+
11
+ @IsString()
12
+ @IsOptional()
13
+ @IsOptional()
14
+ public sku: string;
15
+ }
@@ -0,0 +1,19 @@
1
+ import { IsOptional, IsPositive } from 'class-validator';
2
+
3
+ export class DimensionValidator {
4
+ @IsPositive()
5
+ @IsOptional()
6
+ public weight: number;
7
+
8
+ @IsPositive()
9
+ @IsOptional()
10
+ public height: number;
11
+
12
+ @IsPositive()
13
+ @IsOptional()
14
+ public width: number;
15
+
16
+ @IsPositive()
17
+ @IsOptional()
18
+ public depth: number;
19
+ }