From 98f6e550bc0258a92d389edb4fd278c02a7a6353 Mon Sep 17 00:00:00 2001 From: emiliocc5 Date: Tue, 26 Sep 2023 19:53:57 -0300 Subject: [PATCH 1/9] Add Brand Status entity --- src/intelligentSuite/brands/entities/Brand.ts | 5 ++++ .../brands/entities/BrandStatus.ts | 24 ++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/intelligentSuite/brands/entities/Brand.ts b/src/intelligentSuite/brands/entities/Brand.ts index 1ecc25e..8001c9c 100644 --- a/src/intelligentSuite/brands/entities/Brand.ts +++ b/src/intelligentSuite/brands/entities/Brand.ts @@ -4,6 +4,7 @@ import {BaseEntity} from "../../../common/entities/BaseEntity"; import {BusinessAccount} from "../../businessAccounts/entities/BusinessAccount"; import {Sector} from "../../common/entities/Sector"; import {CreateBrandInput, UpdateBrandInput} from "../input/BrandInput"; +import BrandStatus from "./BrandStatus"; @ObjectType() @Entity() @@ -32,6 +33,10 @@ export default class Brand extends BaseEntity { @Field(() => BusinessAccount) businessAccount!: BusinessAccount; + @ManyToOne(() => BrandStatus) + @Field(() => BrandStatus) + brandStatus!: BrandStatus; + static create(businessAccount: BusinessAccount, input: CreateBrandInput) { const brand = new Brand(); brand.setId(); diff --git a/src/intelligentSuite/brands/entities/BrandStatus.ts b/src/intelligentSuite/brands/entities/BrandStatus.ts index 2b7fd58..07bb346 100644 --- a/src/intelligentSuite/brands/entities/BrandStatus.ts +++ b/src/intelligentSuite/brands/entities/BrandStatus.ts @@ -1,6 +1,28 @@ -export enum BrandStatus { +import {BaseEntity, Column, Entity, OneToMany} from "typeorm"; +import {Field, ObjectType} from "type-graphql"; +import Brand from "./Brand"; + +export enum ValidBrandStatus { IN_PROGRESS = "IN_PROGRESS", DATA_READY = "DATA_READY", MODEL_TRAINING = "MODEL_TRAINING", READY = "READY", } +@ObjectType() +@Entity() +export default class BrandStatus extends BaseEntity { + + @Column() + @Field() + status! : ValidBrandStatus + + @OneToMany(() => Brand, (brand) => brand.brandStatus, {eager: true}) + @Field(() => [Brand]) + brand!: Brand; + + @Column() + @Field() + createdDate! : Date + + +} \ No newline at end of file From 6fa88ef951eec9eecc2699924902c634b362e2a5 Mon Sep 17 00:00:00 2001 From: emiliocc5 Date: Tue, 26 Sep 2023 21:07:43 -0300 Subject: [PATCH 2/9] WIP brand status service --- src/intelligentSuite/brands/entities/Brand.ts | 4 +++ .../brands/entities/BrandStatus.ts | 15 +++++--- .../brands/input/BrandInput.ts | 8 +++++ .../brands/repository/BrandStatusQuerySet.ts | 4 +++ .../repository/BrandStatusRepository.ts | 20 +++++++++++ .../brands/service/BrandStatusService.ts | 34 +++++++++++++++++++ 6 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 src/intelligentSuite/brands/repository/BrandStatusQuerySet.ts create mode 100644 src/intelligentSuite/brands/repository/BrandStatusRepository.ts create mode 100644 src/intelligentSuite/brands/service/BrandStatusService.ts diff --git a/src/intelligentSuite/brands/entities/Brand.ts b/src/intelligentSuite/brands/entities/Brand.ts index 8001c9c..1348e1f 100644 --- a/src/intelligentSuite/brands/entities/Brand.ts +++ b/src/intelligentSuite/brands/entities/Brand.ts @@ -52,6 +52,10 @@ export default class Brand extends BaseEntity { this.sector = input.sector || this.sector; this.logoUrl = input.logoUrl || this.logoUrl; } + + updateBrandStatus(input: BrandStatus){ + this.brandStatus = input || this.brandStatus + } } export type BrandInfo = { diff --git a/src/intelligentSuite/brands/entities/BrandStatus.ts b/src/intelligentSuite/brands/entities/BrandStatus.ts index 07bb346..0ab840c 100644 --- a/src/intelligentSuite/brands/entities/BrandStatus.ts +++ b/src/intelligentSuite/brands/entities/BrandStatus.ts @@ -1,6 +1,8 @@ -import {BaseEntity, Column, Entity, OneToMany} from "typeorm"; +import {Column, Entity, OneToMany} from "typeorm"; import {Field, ObjectType} from "type-graphql"; import Brand from "./Brand"; +import {BaseEntity} from "../../../common/entities/BaseEntity"; +import {BrandStatusInput} from "../input/BrandInput"; export enum ValidBrandStatus { IN_PROGRESS = "IN_PROGRESS", @@ -20,9 +22,12 @@ export default class BrandStatus extends BaseEntity { @Field(() => [Brand]) brand!: Brand; - @Column() - @Field() - createdDate! : Date - + static create(brand: Brand, input: BrandStatusInput) { + const brandStatus = new BrandStatus() + brandStatus.setId(); + brandStatus.status = input.status + brandStatus.brand = brand + return brandStatus + } } \ No newline at end of file diff --git a/src/intelligentSuite/brands/input/BrandInput.ts b/src/intelligentSuite/brands/input/BrandInput.ts index 086a1d0..3b616e2 100644 --- a/src/intelligentSuite/brands/input/BrandInput.ts +++ b/src/intelligentSuite/brands/input/BrandInput.ts @@ -1,6 +1,7 @@ import {Field, InputType, Int} from "type-graphql"; import {AdAccountType, SocialAccountType} from "../../common/entities/Assets"; import {Sector} from "../../common/entities/Sector"; +import {ValidBrandStatus} from "../entities/BrandStatus"; @InputType() export class CreateBrandInput { @@ -30,6 +31,13 @@ export class BrandAssetsInput { @Field(() => [SocialAccountInput], {nullable: true}) socialAccount?: SocialAccountInput[]; } + +@InputType() +export class BrandStatusInput { + @Field(() => ValidBrandStatus) + status!: ValidBrandStatus; +} + @InputType() export class SocialAccountInput { @Field(() => Int) diff --git a/src/intelligentSuite/brands/repository/BrandStatusQuerySet.ts b/src/intelligentSuite/brands/repository/BrandStatusQuerySet.ts new file mode 100644 index 0000000..67ad7e2 --- /dev/null +++ b/src/intelligentSuite/brands/repository/BrandStatusQuerySet.ts @@ -0,0 +1,4 @@ +import {BaseEntity} from "../../../common/entities/BaseEntity"; +import {QuerySet} from "../../../common/repositories/QuerySet"; + +export class BrandStatusQuerySet extends QuerySet {} diff --git a/src/intelligentSuite/brands/repository/BrandStatusRepository.ts b/src/intelligentSuite/brands/repository/BrandStatusRepository.ts new file mode 100644 index 0000000..3dd9837 --- /dev/null +++ b/src/intelligentSuite/brands/repository/BrandStatusRepository.ts @@ -0,0 +1,20 @@ +import {Service} from "typedi"; +import {Repository} from "typeorm"; +import {InjectRepository} from "typeorm-typedi-extensions"; +import {BaseRepository} from "../../../common/repositories/BaseRepository"; +import Brand from "../entities/Brand"; +import {BrandQuerySet} from "./BrandQuerySet"; +import BrandStatus from "../entities/BrandStatus"; +import {BrandStatusQuerySet} from "./BrandStatusQuerySet"; + +@Service() +export class BrandStatusRepository extends BaseRepository { + constructor(@InjectRepository(BrandStatus) private repository: Repository) { + super(repository); + } + + getQuerySet(): BrandStatusQuerySet { + const queryBuilder = this.repository.createQueryBuilder("Brand"); + return new BrandQuerySet(queryBuilder, "Brand"); + } +} diff --git a/src/intelligentSuite/brands/service/BrandStatusService.ts b/src/intelligentSuite/brands/service/BrandStatusService.ts new file mode 100644 index 0000000..8bdb53a --- /dev/null +++ b/src/intelligentSuite/brands/service/BrandStatusService.ts @@ -0,0 +1,34 @@ +import {Service} from "typedi"; +import {BaseService} from "../../common/service/BaseService"; +import {User} from "../../users/entities/User"; +import {BrandStatusInput} from "../input/BrandInput"; +import {BrandRepository} from "../repository/BrandRepository"; +import {BrandStatusRepository} from "../repository/BrandStatusRepository"; +import BrandStatus from "../entities/BrandStatus"; + +@Service() +export class BrandStatusService extends BaseService { + constructor(private readonly brandRepository: BrandRepository, private readonly brandStatusRepository: BrandStatusRepository) { + super(); + } + + async updateBrandStatus(user: User, brandId: string, input: BrandStatusInput) { + this.logger.verbose(this.updateBrandStatus.name, `Updating brand status for brand`, {brand: brandId}); + this.validateUserAdmin(user, this.updateBrandStatus.name); + + const brand = user.getBrand(brandId); + + if (brand.brandStatus.status == input.status) { + this.logger.info(this.updateBrandStatus.name, "the brand is actually in the selected status") + return brand + } + + const newBrandStatus = BrandStatus.create(brand, input) + await this.brandStatusRepository.save(newBrandStatus) + + brand.brandStatus = newBrandStatus + await this.brandRepository.save(brand); + this.logger.debug(this.updateBrandStatus.name, `Updated brand status successfully`); + return brand; + } +} From 48db2be4aa9d5875fd9c53561863350f4b30bbcd Mon Sep 17 00:00:00 2001 From: emiliocc5 Date: Wed, 27 Sep 2023 20:08:47 -0300 Subject: [PATCH 3/9] Add status in creation brand input --- src/intelligentSuite/brands/entities/Brand.ts | 9 +++++---- src/intelligentSuite/brands/entities/BrandStatus.ts | 2 +- src/intelligentSuite/brands/input/BrandInput.ts | 4 +++- src/intelligentSuite/brands/service/BrandService.ts | 2 +- .../brands/service/BrandStatusService.ts | 4 ++-- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/intelligentSuite/brands/entities/Brand.ts b/src/intelligentSuite/brands/entities/Brand.ts index 1348e1f..36ca66b 100644 --- a/src/intelligentSuite/brands/entities/Brand.ts +++ b/src/intelligentSuite/brands/entities/Brand.ts @@ -33,9 +33,9 @@ export default class Brand extends BaseEntity { @Field(() => BusinessAccount) businessAccount!: BusinessAccount; - @ManyToOne(() => BrandStatus) - @Field(() => BrandStatus) - brandStatus!: BrandStatus; + @ManyToOne(() => BrandStatus, {nullable: true, eager: true}) + @Field(() => BrandStatus, {nullable: true}) + status!: BrandStatus; static create(businessAccount: BusinessAccount, input: CreateBrandInput) { const brand = new Brand(); @@ -44,6 +44,7 @@ export default class Brand extends BaseEntity { brand.sector = input.sector; brand.logoUrl = input.logoUrl || brand.logoUrl; brand.businessAccount = businessAccount; + brand.status = input.status || brand.status return brand; } @@ -54,7 +55,7 @@ export default class Brand extends BaseEntity { } updateBrandStatus(input: BrandStatus){ - this.brandStatus = input || this.brandStatus + this.status = input || this.status } } diff --git a/src/intelligentSuite/brands/entities/BrandStatus.ts b/src/intelligentSuite/brands/entities/BrandStatus.ts index 0ab840c..b66b410 100644 --- a/src/intelligentSuite/brands/entities/BrandStatus.ts +++ b/src/intelligentSuite/brands/entities/BrandStatus.ts @@ -18,7 +18,7 @@ export default class BrandStatus extends BaseEntity { @Field() status! : ValidBrandStatus - @OneToMany(() => Brand, (brand) => brand.brandStatus, {eager: true}) + @OneToMany(() => Brand, (brand) => brand.status, {eager: true}) @Field(() => [Brand]) brand!: Brand; diff --git a/src/intelligentSuite/brands/input/BrandInput.ts b/src/intelligentSuite/brands/input/BrandInput.ts index 3b616e2..ed7a59e 100644 --- a/src/intelligentSuite/brands/input/BrandInput.ts +++ b/src/intelligentSuite/brands/input/BrandInput.ts @@ -1,7 +1,7 @@ import {Field, InputType, Int} from "type-graphql"; import {AdAccountType, SocialAccountType} from "../../common/entities/Assets"; import {Sector} from "../../common/entities/Sector"; -import {ValidBrandStatus} from "../entities/BrandStatus"; +import BrandStatus, {ValidBrandStatus} from "../entities/BrandStatus"; @InputType() export class CreateBrandInput { @@ -11,6 +11,8 @@ export class CreateBrandInput { logoUrl?: string; @Field(() => [Sector]) sector!: Sector[]; + @Field(() => BrandStatus) + status!: BrandStatus; } @InputType() diff --git a/src/intelligentSuite/brands/service/BrandService.ts b/src/intelligentSuite/brands/service/BrandService.ts index cd744c1..44241c8 100644 --- a/src/intelligentSuite/brands/service/BrandService.ts +++ b/src/intelligentSuite/brands/service/BrandService.ts @@ -29,7 +29,7 @@ export class BrandService extends BaseService { } async updateBrand(user: User, brandId: string, input: UpdateBrandInput) { - this.validateUserAdmin(user, this.createBrand.name); + this.validateUserAdmin(user, this.updateBrand.name); const brand = user.getBrand(brandId); brand.update(input); diff --git a/src/intelligentSuite/brands/service/BrandStatusService.ts b/src/intelligentSuite/brands/service/BrandStatusService.ts index 8bdb53a..526b633 100644 --- a/src/intelligentSuite/brands/service/BrandStatusService.ts +++ b/src/intelligentSuite/brands/service/BrandStatusService.ts @@ -18,7 +18,7 @@ export class BrandStatusService extends BaseService { const brand = user.getBrand(brandId); - if (brand.brandStatus.status == input.status) { + if (brand.status.status == input.status) { this.logger.info(this.updateBrandStatus.name, "the brand is actually in the selected status") return brand } @@ -26,7 +26,7 @@ export class BrandStatusService extends BaseService { const newBrandStatus = BrandStatus.create(brand, input) await this.brandStatusRepository.save(newBrandStatus) - brand.brandStatus = newBrandStatus + brand.updateBrandStatus(newBrandStatus) await this.brandRepository.save(brand); this.logger.debug(this.updateBrandStatus.name, `Updated brand status successfully`); return brand; From 5fe9c4a59580a4306924475a413528061f0411e3 Mon Sep 17 00:00:00 2001 From: emiliocc5 Date: Wed, 27 Sep 2023 20:45:19 -0300 Subject: [PATCH 4/9] add update status method in resolver --- src/intelligentSuite/brands/entities/Brand.ts | 10 +++------- .../brands/repository/BrandStatusRepository.ts | 4 ++-- .../brands/resolvers/BrandResolver.ts | 13 ++++++++++++- .../brands/service/BrandStatusService.ts | 6 +++--- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/intelligentSuite/brands/entities/Brand.ts b/src/intelligentSuite/brands/entities/Brand.ts index 36ca66b..38d3956 100644 --- a/src/intelligentSuite/brands/entities/Brand.ts +++ b/src/intelligentSuite/brands/entities/Brand.ts @@ -33,9 +33,9 @@ export default class Brand extends BaseEntity { @Field(() => BusinessAccount) businessAccount!: BusinessAccount; - @ManyToOne(() => BrandStatus, {nullable: true, eager: true}) - @Field(() => BrandStatus, {nullable: true}) - status!: BrandStatus; + @ManyToOne(() => BrandStatus) + @Field(() => BrandStatus) + status!: BrandStatus; //Si lo hago opcional te puede pasar que termines un brand sin cambiarle de estado nunca static create(businessAccount: BusinessAccount, input: CreateBrandInput) { const brand = new Brand(); @@ -53,10 +53,6 @@ export default class Brand extends BaseEntity { this.sector = input.sector || this.sector; this.logoUrl = input.logoUrl || this.logoUrl; } - - updateBrandStatus(input: BrandStatus){ - this.status = input || this.status - } } export type BrandInfo = { diff --git a/src/intelligentSuite/brands/repository/BrandStatusRepository.ts b/src/intelligentSuite/brands/repository/BrandStatusRepository.ts index 3dd9837..322b042 100644 --- a/src/intelligentSuite/brands/repository/BrandStatusRepository.ts +++ b/src/intelligentSuite/brands/repository/BrandStatusRepository.ts @@ -14,7 +14,7 @@ export class BrandStatusRepository extends BaseRepository { } getQuerySet(): BrandStatusQuerySet { - const queryBuilder = this.repository.createQueryBuilder("Brand"); - return new BrandQuerySet(queryBuilder, "Brand"); + const queryBuilder = this.repository.createQueryBuilder("BrandStatus"); + return new BrandQuerySet(queryBuilder, "BrandStatus"); } } diff --git a/src/intelligentSuite/brands/resolvers/BrandResolver.ts b/src/intelligentSuite/brands/resolvers/BrandResolver.ts index 6cf9b94..d159d01 100644 --- a/src/intelligentSuite/brands/resolvers/BrandResolver.ts +++ b/src/intelligentSuite/brands/resolvers/BrandResolver.ts @@ -6,9 +6,10 @@ import {UploadDataResponse} from "../../fileHandler/entities/UploadDataResponse" import {User} from "../../users/entities/User"; import Brand from "../entities/Brand"; import {BrandAssetsResponse} from "../entities/BrandAssetsResponse"; -import {BrandAssetsInput, CreateBrandInput, UpdateBrandInput} from "../input/BrandInput"; +import {BrandAssetsInput, BrandStatusInput, CreateBrandInput, UpdateBrandInput} from "../input/BrandInput"; import {BrandAccountsService} from "../service/BrandAccountsService"; import {BrandService} from "../service/BrandService"; +import {BrandStatusService} from "../service/BrandStatusService"; @Service() @Resolver() @@ -16,6 +17,7 @@ export class BrandResolver { constructor( private readonly brandService: BrandService, private readonly brandAccountsService: BrandAccountsService, + private readonly brandStatusService: BrandStatusService, ) {} @Mutation((_returns) => Brand, { @@ -43,6 +45,15 @@ export class BrandResolver { return await this.brandAccountsService.updateBrandAssets(user, brandId, input); } + @Mutation((_returns) => Brand, {description: "Updates status of a brand"}) + async updateBrandStatus( + @CurrentUser() user: User, + @Arg("brandId") brandId: string, + @Arg("input") input: BrandStatusInput, + ) { + return await this.brandStatusService.updateBrandStatus(user, brandId, input); + } + @Mutation((_returns) => UploadDataResponse, {description: "Uploads brand logo"}) async requestLogoUploadData(@CurrentUser() user: User, @Arg("input") input: UploadRequestInput) { return await this.brandService.getLogoUploadData(user, input); diff --git a/src/intelligentSuite/brands/service/BrandStatusService.ts b/src/intelligentSuite/brands/service/BrandStatusService.ts index 526b633..ac52892 100644 --- a/src/intelligentSuite/brands/service/BrandStatusService.ts +++ b/src/intelligentSuite/brands/service/BrandStatusService.ts @@ -13,20 +13,20 @@ export class BrandStatusService extends BaseService { } async updateBrandStatus(user: User, brandId: string, input: BrandStatusInput) { - this.logger.verbose(this.updateBrandStatus.name, `Updating brand status for brand`, {brand: brandId}); + this.logger.verbose(this.updateBrandStatus.name, `Updating status for brand`, {brand: brandId}); this.validateUserAdmin(user, this.updateBrandStatus.name); const brand = user.getBrand(brandId); if (brand.status.status == input.status) { - this.logger.info(this.updateBrandStatus.name, "the brand is actually in the selected status") + this.logger.info(this.updateBrandStatus.name, "the brand is actually in the selected status, nothing to update") return brand } const newBrandStatus = BrandStatus.create(brand, input) await this.brandStatusRepository.save(newBrandStatus) - brand.updateBrandStatus(newBrandStatus) + brand.status = newBrandStatus await this.brandRepository.save(brand); this.logger.debug(this.updateBrandStatus.name, `Updated brand status successfully`); return brand; From 410b90ca41fbc70dfd5a35018edd866735015c28 Mon Sep 17 00:00:00 2001 From: emiliocc5 Date: Wed, 27 Sep 2023 21:13:40 -0300 Subject: [PATCH 5/9] WIP db schema creation --- init-project/db-user-schema-create.sql | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/init-project/db-user-schema-create.sql b/init-project/db-user-schema-create.sql index b2e2068..897dfa4 100644 --- a/init-project/db-user-schema-create.sql +++ b/init-project/db-user-schema-create.sql @@ -1,8 +1,8 @@ -CREATE DATABASE test_schema +CREATE DATABASE IF NOT EXISTS test_memorable_db CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; -use test_schema; +use test_memorable_db; @@ -24,6 +24,18 @@ CREATE TABLE `business_account` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +-- +-- Table structure for table `brand_status` +-- + +DROP TABLE IF EXISTS `brand_status`; +CREATE TABLE `brand_status` ( + `id` varchar(255) NOT NULL, + `createdAt` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + `updatedAt` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), + + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; DROP TABLE IF EXISTS `brand`; CREATE TABLE `brand` ( From 477900f0d19c5bbfa1486d614ff33bb2c774f2f2 Mon Sep 17 00:00:00 2001 From: emiliocc5 Date: Sun, 1 Oct 2023 18:06:13 -0300 Subject: [PATCH 6/9] Change brand status to optional --- docker-compose.yml | 2 +- init-project/db-user-schema-create.sql | 27 ++++++++++--------- init-project/init-db-dump.sql | 19 ++++++++++--- schema.gql | 24 +++++++++++++++++ src/graphql/graphqlSchema.ts | 4 +-- src/intelligentSuite/brands/entities/Brand.ts | 3 +-- .../brands/entities/BrandStatus.ts | 14 +++++----- .../brands/input/BrandInput.ts | 4 +-- .../brands/service/BrandStatusService.ts | 2 +- 9 files changed, 68 insertions(+), 31 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index deee72e..40f1384 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,7 +4,7 @@ services: image: mysql environment: MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: test_db + MYSQL_DATABASE: test_memorable_db ports: - "3307:3306" command: ["mysqld", "--character-set-server=latin1", "--collation-server=latin1_swedish_ci"] diff --git a/init-project/db-user-schema-create.sql b/init-project/db-user-schema-create.sql index 897dfa4..3c14421 100644 --- a/init-project/db-user-schema-create.sql +++ b/init-project/db-user-schema-create.sql @@ -4,13 +4,15 @@ CREATE DATABASE IF NOT EXISTS test_memorable_db use test_memorable_db; - +DROP TABLE IF EXISTS `invitation`; +DROP TABLE IF EXISTS `brand`; +DROP TABLE IF EXISTS `user`; +DROP TABLE IF EXISTS `business_account`; +DROP TABLE IF EXISTS `brand_status`; -- -- Table structure for table `business_account` -- - -DROP TABLE IF EXISTS `business_account`; CREATE TABLE `business_account` ( `id` varchar(255) NOT NULL, `createdAt` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), @@ -27,17 +29,17 @@ CREATE TABLE `business_account` ( -- -- Table structure for table `brand_status` -- - -DROP TABLE IF EXISTS `brand_status`; CREATE TABLE `brand_status` ( `id` varchar(255) NOT NULL, + `status` varchar(255) NOT NULL, `createdAt` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `updatedAt` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), - PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -DROP TABLE IF EXISTS `brand`; +-- +-- Table structure for table `brand` +-- CREATE TABLE `brand` ( `id` varchar(255) NOT NULL, `createdAt` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), @@ -48,15 +50,18 @@ CREATE TABLE `brand` ( `sector` text, `adAccounts` text, `socialAccounts` text, + `brandStatusId` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), KEY `FK_ce8346e2deaf4543dd3f83304a3` (`businessAccountId`), - CONSTRAINT `FK_ce8346e2deaf4543dd3f83304a3` FOREIGN KEY (`businessAccountId`) REFERENCES `business_account` (`id`) + CONSTRAINT `FK_ce8346e2deaf4543dd3f83304a3` FOREIGN KEY (`businessAccountId`) REFERENCES `business_account` (`id`), + KEY `FK_Brand_brandStatus` (`brandStatusId`), + CONSTRAINT `FK_Brand_brandStatus` FOREIGN KEY (`brandStatusId`) REFERENCES `brand_status` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + + -- -- Table structure for table `user` -- - -DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` varchar(255) NOT NULL, `createdAt` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), @@ -81,8 +86,6 @@ CREATE TABLE `user` ( -- -- Table structure for table `invitation` -- - -DROP TABLE IF EXISTS `invitation`; CREATE TABLE `invitation` ( `id` varchar(255) NOT NULL, `createdAt` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), diff --git a/init-project/init-db-dump.sql b/init-project/init-db-dump.sql index afd34b6..9b06557 100644 --- a/init-project/init-db-dump.sql +++ b/init-project/init-db-dump.sql @@ -1,6 +1,6 @@ -- MySQL dump 10.13 Distrib 8.0.32, for Win64 (x86_64) -- --- Host: 127.0.0.1 Database: test_schema +-- Host: 127.0.0.1 Database: test_memorable_db -- ------------------------------------------------------ -- Server version 8.0.31 @@ -15,16 +15,29 @@ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Dumping data for table `brand_status` +-- +use test_memorable_db; +LOCK TABLES `brand_status` WRITE; +/*!40000 ALTER TABLE `brand_status` DISABLE KEYS */; +INSERT INTO `brand_status` VALUES ('01H4618V8XGS613BS5BSPZP183','IN_PROGRESS','2023-10-01 16:46:00.580809','2023-10-01 16:46:00.580809'); +/*!40000 ALTER TABLE `brand_status` ENABLE KEYS */; +UNLOCK TABLES; + + -- -- Dumping data for table `brand` -- -use test_schema; +use test_memorable_db; LOCK TABLES `brand` WRITE; /*!40000 ALTER TABLE `brand` DISABLE KEYS */; -INSERT INTO `brand` VALUES ('01H4618V8XGS613BS5BSPZP180','2023-06-30 11:33:32.580809','2023-06-30 11:33:32.580809','Pharma Tecnologies','logoUrl','01H4616SGMFZ1GX71ZG5DCZMFD','PharmaceuticalsAndBiotechnology',NULL,NULL); +INSERT INTO `brand` VALUES ('01H4618V8XGS613BS5BSPZP180','2023-06-30 11:33:32.580809','2023-06-30 11:33:32.580809','Pharma Tecnologies','logoUrl','01H4616SGMFZ1GX71ZG5DCZMFD','PharmaceuticalsAndBiotechnology',NULL,NULL,'01H4618V8XGS613BS5BSPZP183'); /*!40000 ALTER TABLE `brand` ENABLE KEYS */; UNLOCK TABLES; + -- -- Dumping data for table `business_account` -- diff --git a/schema.gql b/schema.gql index cd60536..e5046a0 100644 --- a/schema.gql +++ b/schema.gql @@ -70,6 +70,7 @@ type Brand { adAccounts: [String!] socialAccounts: [String!] businessAccount: BusinessAccount! + status: BrandStatus! } enum Sector { @@ -123,6 +124,14 @@ enum Sector { CorporateTrainingAndDevelopment } +type BrandStatus { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + status: String! + brand: [Brand!]! +} + type Mutation { """Creates a business Account for the provided business admin""" createBrand(input: CreateBrandInput!): Brand! @@ -133,6 +142,9 @@ type Mutation { """Updates assets of a brand""" updateBrandAssets(input: BrandAssetsInput!, brandId: String!): Brand! + """Updates status of a brand""" + updateBrandStatus(input: BrandStatusInput!, brandId: String!): Brand! + """Uploads brand logo""" requestLogoUploadData(input: UploadRequestInput!): UploadDataResponse! @@ -215,6 +227,18 @@ enum SocialAccountType { TiktokAccount } +input BrandStatusInput { + status: ValidBrandStatus! +} + +"""Brand Status""" +enum ValidBrandStatus { + IN_PROGRESS + DATA_READY + MODEL_TRAINING + READY +} + type UploadDataResponse { id: String! originalUrl: String! diff --git a/src/graphql/graphqlSchema.ts b/src/graphql/graphqlSchema.ts index fc676a4..8e0d73c 100644 --- a/src/graphql/graphqlSchema.ts +++ b/src/graphql/graphqlSchema.ts @@ -5,7 +5,6 @@ import {buildSchema, registerEnumType} from "type-graphql"; import {Container} from "typedi"; import {ErrorCode, ErrorMsg} from "../common/errors/ErrorCode"; import {SortType} from "../common/queries/Sort"; -import {BrandStatus} from "../intelligentSuite/brands/entities/BrandStatus"; import {BrandResolver} from "../intelligentSuite/brands/resolvers/BrandResolver"; import {BusinessAccountResolver} from "../intelligentSuite/businessAccounts/resolvers/BusinessAccountResolver"; import {AdAccountType, SocialAccountType} from "../intelligentSuite/common/entities/Assets"; @@ -22,12 +21,13 @@ import {InvitationType} from "../intelligentSuite/invitations/entities/Invitatio import {InvitationResolver} from "../intelligentSuite/invitations/resolvers/InvitationResolver"; import {UserResolver} from "../intelligentSuite/users/resolvers/UserResolver"; import {subscriptionConnection} from "../pubsub/SubscriptionConnection"; +import {ValidBrandStatus} from "../intelligentSuite/brands/entities/BrandStatus"; const resolvers = [UserResolver, BusinessAccountResolver, BrandResolver, InvitationResolver] as const; export const graphqlSchema = async (emitSchema = false, usePubSub = true) => { registerEnumType(OrderingDirection, {name: "OrderingDirection", description: "Ordering direction"}); - registerEnumType(BrandStatus, {name: "BrandStatus", description: "Brand Status"}); + registerEnumType(ValidBrandStatus, {name: "ValidBrandStatus", description: "Brand Status"}); registerEnumType(LabeledMetricValue, {name: "LabeledMetricValue", description: "Labeled Metric Value"}); registerEnumType(ErrorCode, {name: "ErrorCode", description: "Api error codes"}); registerEnumType(FileType, {name: "FileType"}); diff --git a/src/intelligentSuite/brands/entities/Brand.ts b/src/intelligentSuite/brands/entities/Brand.ts index 38d3956..054e8d6 100644 --- a/src/intelligentSuite/brands/entities/Brand.ts +++ b/src/intelligentSuite/brands/entities/Brand.ts @@ -35,7 +35,7 @@ export default class Brand extends BaseEntity { @ManyToOne(() => BrandStatus) @Field(() => BrandStatus) - status!: BrandStatus; //Si lo hago opcional te puede pasar que termines un brand sin cambiarle de estado nunca + status?: BrandStatus; static create(businessAccount: BusinessAccount, input: CreateBrandInput) { const brand = new Brand(); @@ -44,7 +44,6 @@ export default class Brand extends BaseEntity { brand.sector = input.sector; brand.logoUrl = input.logoUrl || brand.logoUrl; brand.businessAccount = businessAccount; - brand.status = input.status || brand.status return brand; } diff --git a/src/intelligentSuite/brands/entities/BrandStatus.ts b/src/intelligentSuite/brands/entities/BrandStatus.ts index b66b410..dc60d9a 100644 --- a/src/intelligentSuite/brands/entities/BrandStatus.ts +++ b/src/intelligentSuite/brands/entities/BrandStatus.ts @@ -4,19 +4,13 @@ import Brand from "./Brand"; import {BaseEntity} from "../../../common/entities/BaseEntity"; import {BrandStatusInput} from "../input/BrandInput"; -export enum ValidBrandStatus { - IN_PROGRESS = "IN_PROGRESS", - DATA_READY = "DATA_READY", - MODEL_TRAINING = "MODEL_TRAINING", - READY = "READY", -} @ObjectType() @Entity() export default class BrandStatus extends BaseEntity { @Column() @Field() - status! : ValidBrandStatus + status!: ValidBrandStatus @OneToMany(() => Brand, (brand) => brand.status, {eager: true}) @Field(() => [Brand]) @@ -30,4 +24,10 @@ export default class BrandStatus extends BaseEntity { return brandStatus } +} +export enum ValidBrandStatus { + IN_PROGRESS = "IN_PROGRESS", + DATA_READY = "DATA_READY", + MODEL_TRAINING = "MODEL_TRAINING", + READY = "READY", } \ No newline at end of file diff --git a/src/intelligentSuite/brands/input/BrandInput.ts b/src/intelligentSuite/brands/input/BrandInput.ts index ed7a59e..3b616e2 100644 --- a/src/intelligentSuite/brands/input/BrandInput.ts +++ b/src/intelligentSuite/brands/input/BrandInput.ts @@ -1,7 +1,7 @@ import {Field, InputType, Int} from "type-graphql"; import {AdAccountType, SocialAccountType} from "../../common/entities/Assets"; import {Sector} from "../../common/entities/Sector"; -import BrandStatus, {ValidBrandStatus} from "../entities/BrandStatus"; +import {ValidBrandStatus} from "../entities/BrandStatus"; @InputType() export class CreateBrandInput { @@ -11,8 +11,6 @@ export class CreateBrandInput { logoUrl?: string; @Field(() => [Sector]) sector!: Sector[]; - @Field(() => BrandStatus) - status!: BrandStatus; } @InputType() diff --git a/src/intelligentSuite/brands/service/BrandStatusService.ts b/src/intelligentSuite/brands/service/BrandStatusService.ts index ac52892..7faba49 100644 --- a/src/intelligentSuite/brands/service/BrandStatusService.ts +++ b/src/intelligentSuite/brands/service/BrandStatusService.ts @@ -18,7 +18,7 @@ export class BrandStatusService extends BaseService { const brand = user.getBrand(brandId); - if (brand.status.status == input.status) { + if (brand.status?.status == input.status) { this.logger.info(this.updateBrandStatus.name, "the brand is actually in the selected status, nothing to update") return brand } From 9e768e65c2dbcd34a03ddbc139e12f2f91cdb410 Mon Sep 17 00:00:00 2001 From: emiliocc5 Date: Tue, 3 Oct 2023 18:58:22 -0300 Subject: [PATCH 7/9] Change relation to OneToOne, add custom query set & add thunder client test cases --- schema.gql | 13 +--- src/common/errors/ErrorCode.ts | 1 + src/graphql/graphqlSchema.ts | 2 - src/intelligentSuite/brands/entities/Brand.ts | 7 ++- .../brands/entities/BrandStatus.ts | 28 +++++---- .../brands/input/BrandInput.ts | 4 +- .../brands/repository/BrandQuerySet.ts | 10 ++- .../brands/repository/BrandRepository.ts | 4 ++ .../brands/resolvers/BrandResolver.ts | 2 +- .../brands/service/BrandService.ts | 27 +++++++- .../brands/service/BrandStatusService.ts | 31 ++++------ .../collections/tc_col_memorable-test.json | 61 ++++++++++++++++++- .../environments/tc_env_local-dev.json | 5 +- 13 files changed, 140 insertions(+), 55 deletions(-) diff --git a/schema.gql b/schema.gql index e5046a0..7630c9b 100644 --- a/schema.gql +++ b/schema.gql @@ -70,7 +70,7 @@ type Brand { adAccounts: [String!] socialAccounts: [String!] businessAccount: BusinessAccount! - status: BrandStatus! + brandStatus: BrandStatus! } enum Sector { @@ -129,7 +129,6 @@ type BrandStatus { createdAt: DateTime! updatedAt: DateTime! status: String! - brand: [Brand!]! } type Mutation { @@ -228,15 +227,7 @@ enum SocialAccountType { } input BrandStatusInput { - status: ValidBrandStatus! -} - -"""Brand Status""" -enum ValidBrandStatus { - IN_PROGRESS - DATA_READY - MODEL_TRAINING - READY + status: String! } type UploadDataResponse { diff --git a/src/common/errors/ErrorCode.ts b/src/common/errors/ErrorCode.ts index 65f316d..2f3e8b0 100644 --- a/src/common/errors/ErrorCode.ts +++ b/src/common/errors/ErrorCode.ts @@ -41,4 +41,5 @@ export enum ErrorMsg { PASSWORD_LENGTH_ERROR = "PASSWORD_LENGTH_ERROR", PASSWORD_TOO_WEAK = "PASSWORD_TOO_WEAK", FIELD_STRING_INVALID = "FIELD_STRING_INVALID", + INVALID_BRAND_STATUS = "INVALID_BRAND_STATUS" } diff --git a/src/graphql/graphqlSchema.ts b/src/graphql/graphqlSchema.ts index 8e0d73c..25f2270 100644 --- a/src/graphql/graphqlSchema.ts +++ b/src/graphql/graphqlSchema.ts @@ -21,13 +21,11 @@ import {InvitationType} from "../intelligentSuite/invitations/entities/Invitatio import {InvitationResolver} from "../intelligentSuite/invitations/resolvers/InvitationResolver"; import {UserResolver} from "../intelligentSuite/users/resolvers/UserResolver"; import {subscriptionConnection} from "../pubsub/SubscriptionConnection"; -import {ValidBrandStatus} from "../intelligentSuite/brands/entities/BrandStatus"; const resolvers = [UserResolver, BusinessAccountResolver, BrandResolver, InvitationResolver] as const; export const graphqlSchema = async (emitSchema = false, usePubSub = true) => { registerEnumType(OrderingDirection, {name: "OrderingDirection", description: "Ordering direction"}); - registerEnumType(ValidBrandStatus, {name: "ValidBrandStatus", description: "Brand Status"}); registerEnumType(LabeledMetricValue, {name: "LabeledMetricValue", description: "Labeled Metric Value"}); registerEnumType(ErrorCode, {name: "ErrorCode", description: "Api error codes"}); registerEnumType(FileType, {name: "FileType"}); diff --git a/src/intelligentSuite/brands/entities/Brand.ts b/src/intelligentSuite/brands/entities/Brand.ts index 054e8d6..2716602 100644 --- a/src/intelligentSuite/brands/entities/Brand.ts +++ b/src/intelligentSuite/brands/entities/Brand.ts @@ -1,5 +1,5 @@ import {Field, ObjectType} from "type-graphql"; -import {Column, Entity, ManyToOne} from "typeorm"; +import {Column, Entity, JoinColumn, ManyToOne, OneToMany, OneToOne} from "typeorm"; import {BaseEntity} from "../../../common/entities/BaseEntity"; import {BusinessAccount} from "../../businessAccounts/entities/BusinessAccount"; import {Sector} from "../../common/entities/Sector"; @@ -33,9 +33,10 @@ export default class Brand extends BaseEntity { @Field(() => BusinessAccount) businessAccount!: BusinessAccount; - @ManyToOne(() => BrandStatus) + @OneToOne(() => BrandStatus, (brandStatus: BrandStatus) => brandStatus.id) + @JoinColumn() @Field(() => BrandStatus) - status?: BrandStatus; + brandStatus?: BrandStatus; static create(businessAccount: BusinessAccount, input: CreateBrandInput) { const brand = new Brand(); diff --git a/src/intelligentSuite/brands/entities/BrandStatus.ts b/src/intelligentSuite/brands/entities/BrandStatus.ts index dc60d9a..b6e2eb3 100644 --- a/src/intelligentSuite/brands/entities/BrandStatus.ts +++ b/src/intelligentSuite/brands/entities/BrandStatus.ts @@ -1,8 +1,17 @@ -import {Column, Entity, OneToMany} from "typeorm"; +import {Column, Entity, ManyToOne, OneToMany, OneToOne} from "typeorm"; import {Field, ObjectType} from "type-graphql"; import Brand from "./Brand"; import {BaseEntity} from "../../../common/entities/BaseEntity"; import {BrandStatusInput} from "../input/BrandInput"; +import {BadRequestError} from "../../../common/errors/BadRequestError"; +import {ErrorMsg} from "../../../common/errors/ErrorCode"; + +export enum ValidBrandStatus { + IN_PROGRESS = "IN_PROGRESS", + DATA_READY = "DATA_READY", + MODEL_TRAINING = "MODEL_TRAINING", + READY = "READY", +} @ObjectType() @Entity() @@ -10,24 +19,17 @@ export default class BrandStatus extends BaseEntity { @Column() @Field() - status!: ValidBrandStatus - - @OneToMany(() => Brand, (brand) => brand.status, {eager: true}) - @Field(() => [Brand]) - brand!: Brand; + status!: string static create(brand: Brand, input: BrandStatusInput) { const brandStatus = new BrandStatus() brandStatus.setId(); brandStatus.status = input.status - brandStatus.brand = brand return brandStatus } -} -export enum ValidBrandStatus { - IN_PROGRESS = "IN_PROGRESS", - DATA_READY = "DATA_READY", - MODEL_TRAINING = "MODEL_TRAINING", - READY = "READY", + + isSameStatus(status: string){ + return this.status == status + } } \ No newline at end of file diff --git a/src/intelligentSuite/brands/input/BrandInput.ts b/src/intelligentSuite/brands/input/BrandInput.ts index 3b616e2..26c396e 100644 --- a/src/intelligentSuite/brands/input/BrandInput.ts +++ b/src/intelligentSuite/brands/input/BrandInput.ts @@ -34,8 +34,8 @@ export class BrandAssetsInput { @InputType() export class BrandStatusInput { - @Field(() => ValidBrandStatus) - status!: ValidBrandStatus; + @Field(() => String) + status!: string; } @InputType() diff --git a/src/intelligentSuite/brands/repository/BrandQuerySet.ts b/src/intelligentSuite/brands/repository/BrandQuerySet.ts index acbe426..b3874e7 100644 --- a/src/intelligentSuite/brands/repository/BrandQuerySet.ts +++ b/src/intelligentSuite/brands/repository/BrandQuerySet.ts @@ -1,4 +1,12 @@ import {BaseEntity} from "../../../common/entities/BaseEntity"; import {QuerySet} from "../../../common/repositories/QuerySet"; +import {UserQuerySet} from "../../users/repositories/UserQuerySet"; +import {BrandStatusQuerySet} from "./BrandStatusQuerySet"; -export class BrandQuerySet extends QuerySet {} +export class BrandQuerySet extends QuerySet { + + withBrandStatus(): this { + this.queryBuilder = this.leftJoinRelation(BrandStatusQuerySet, "brandStatus", "brandStatus", true).getQueryBuilder(); + return this; + } +} diff --git a/src/intelligentSuite/brands/repository/BrandRepository.ts b/src/intelligentSuite/brands/repository/BrandRepository.ts index 13895db..ef00341 100644 --- a/src/intelligentSuite/brands/repository/BrandRepository.ts +++ b/src/intelligentSuite/brands/repository/BrandRepository.ts @@ -25,6 +25,10 @@ export class BrandRepository extends BaseRepository { super(repository); } + async getByIDWithStatus(brandId: string){ + return this.getQuerySet().filterById(brandId).withBrandStatus().getOne() + } + getQuerySet(): BrandQuerySet { const queryBuilder = this.repository.createQueryBuilder("Brand"); return new BrandQuerySet(queryBuilder, "Brand"); diff --git a/src/intelligentSuite/brands/resolvers/BrandResolver.ts b/src/intelligentSuite/brands/resolvers/BrandResolver.ts index d159d01..0d54e6c 100644 --- a/src/intelligentSuite/brands/resolvers/BrandResolver.ts +++ b/src/intelligentSuite/brands/resolvers/BrandResolver.ts @@ -51,7 +51,7 @@ export class BrandResolver { @Arg("brandId") brandId: string, @Arg("input") input: BrandStatusInput, ) { - return await this.brandStatusService.updateBrandStatus(user, brandId, input); + return await this.brandService.updateBrandStatus(user, brandId, input); } @Mutation((_returns) => UploadDataResponse, {description: "Uploads brand logo"}) diff --git a/src/intelligentSuite/brands/service/BrandService.ts b/src/intelligentSuite/brands/service/BrandService.ts index 44241c8..2c7135e 100644 --- a/src/intelligentSuite/brands/service/BrandService.ts +++ b/src/intelligentSuite/brands/service/BrandService.ts @@ -5,14 +5,18 @@ import {UploadDataResponse} from "../../fileHandler/entities/UploadDataResponse" import {FileHandlerService} from "../../fileHandler/service/FileHandlerService"; import {User} from "../../users/entities/User"; import Brand from "../entities/Brand"; -import {CreateBrandInput, UpdateBrandInput} from "../input/BrandInput"; +import {BrandStatusInput, CreateBrandInput, UpdateBrandInput} from "../input/BrandInput"; import {BrandRepository} from "../repository/BrandRepository"; +import {BrandStatusService} from "./BrandStatusService"; +import {BadRequestError} from "../../../common/errors/BadRequestError"; +import {ErrorMsg} from "../../../common/errors/ErrorCode"; @Service() export class BrandService extends BaseService { constructor( private readonly brandRepository: BrandRepository, private readonly fileHandlerService: FileHandlerService, + private readonly brandStatusService: BrandStatusService, ) { super(); } @@ -50,4 +54,25 @@ export class BrandService extends BaseService { this.logger.debug(this.getLogoUploadData.name, `Got logo upload data successfully`); return result; } + + async updateBrandStatus(user: User, brandId: string, input: BrandStatusInput) { + this.brandStatusService.isValidBrandStatus(input.status); + this.logger.info(this.updateBrandStatus.name, `Updating status for brand`, {brand: brandId}); + this.validateUserAdmin(user, this.updateBrandStatus.name); + + const brand = await this.brandRepository.getByIDWithStatus(brandId); + if (!brand){ + throw new BadRequestError(ErrorMsg.BRAND_NOT_FOUND) + } + + if (brand.brandStatus?.isSameStatus(input.status)) { + this.logger.info(this.updateBrandStatus.name, "the brand is actually in the selected status, nothing to update") + return brand + } + + brand.brandStatus = await this.brandStatusService.createBrandStatus(brand, input) + await this.brandRepository.save(brand); + this.logger.info(this.updateBrandStatus.name, `Updated brand status successfully`); + return brand; + } } diff --git a/src/intelligentSuite/brands/service/BrandStatusService.ts b/src/intelligentSuite/brands/service/BrandStatusService.ts index 7faba49..48dbbe0 100644 --- a/src/intelligentSuite/brands/service/BrandStatusService.ts +++ b/src/intelligentSuite/brands/service/BrandStatusService.ts @@ -4,31 +4,26 @@ import {User} from "../../users/entities/User"; import {BrandStatusInput} from "../input/BrandInput"; import {BrandRepository} from "../repository/BrandRepository"; import {BrandStatusRepository} from "../repository/BrandStatusRepository"; -import BrandStatus from "../entities/BrandStatus"; +import BrandStatus, {ValidBrandStatus} from "../entities/BrandStatus"; +import {BadRequestError} from "../../../common/errors/BadRequestError"; +import {ErrorMsg} from "../../../common/errors/ErrorCode"; +import Brand from "../entities/Brand"; @Service() export class BrandStatusService extends BaseService { - constructor(private readonly brandRepository: BrandRepository, private readonly brandStatusRepository: BrandStatusRepository) { + constructor(private readonly brandStatusRepository: BrandStatusRepository) { super(); } - async updateBrandStatus(user: User, brandId: string, input: BrandStatusInput) { - this.logger.verbose(this.updateBrandStatus.name, `Updating status for brand`, {brand: brandId}); - this.validateUserAdmin(user, this.updateBrandStatus.name); - - const brand = user.getBrand(brandId); - - if (brand.status?.status == input.status) { - this.logger.info(this.updateBrandStatus.name, "the brand is actually in the selected status, nothing to update") - return brand - } - + async createBrandStatus(brand: Brand, input: BrandStatusInput) { + this.logger.info(this.createBrandStatus.name, "Creating new status for brand", {brand: brand.id}) const newBrandStatus = BrandStatus.create(brand, input) - await this.brandStatusRepository.save(newBrandStatus) + return await this.brandStatusRepository.save(newBrandStatus) + } - brand.status = newBrandStatus - await this.brandRepository.save(brand); - this.logger.debug(this.updateBrandStatus.name, `Updated brand status successfully`); - return brand; + isValidBrandStatus(status: string) { + if (!Object.values(ValidBrandStatus).includes(status as ValidBrandStatus)) { + throw new BadRequestError(ErrorMsg.INVALID_BRAND_STATUS) + } } } diff --git a/thunder-client/collections/tc_col_memorable-test.json b/thunder-client/collections/tc_col_memorable-test.json index 4dcdac0..1bef055 100644 --- a/thunder-client/collections/tc_col_memorable-test.json +++ b/thunder-client/collections/tc_col_memorable-test.json @@ -1,6 +1,7 @@ { "_id": "bdfbad21-e244-4370-bf29-ebc7989769c1", - "colName": "memorable-test", + "client": "Thunder Client", + "collectionName": "memorable-test", "created": "2023-07-03T09:31:31.740Z", "sortNum": 10000, "folders": [], @@ -85,7 +86,7 @@ "raw": "", "form": [], "graphql": { - "query": "query {\n getLoggedInUser{\n id,\n name,\n email,\n isAdmin,\n businessAccount {\n id,\n businessName,\n businessLogoUrl,\n businessPhone,\n website,\n address,\n brands {\n id,\n name,\n logoUrl,\n sector,\n status,\n adAccounts,\n socialAccounts,\n }\n }\n }\n}", + "query": "query {\n getLoggedInUser{\n id,\n name,\n email,\n isAdmin,\n businessAccount {\n id,\n businessName,\n businessLogoUrl,\n businessPhone,\n website,\n address,\n brands {\n id,\n name,\n logoUrl,\n sector,\n adAccounts,\n socialAccounts,\n }\n }\n }\n}", "variables": "{}" } }, @@ -146,6 +147,62 @@ } }, "tests": [] + }, + { + "_id": "9f4d0c59-dcd6-48d1-9e60-0cd6c4a66156", + "colId": "bdfbad21-e244-4370-bf29-ebc7989769c1", + "containerId": "", + "name": "update Brand Status", + "url": "{{baseUrl}}", + "method": "POST", + "sortNum": 60000, + "created": "2023-07-03T09:42:36.064Z", + "modified": "2023-07-03T09:44:08.438Z", + "headers": [ + { + "name": "authorization", + "value": "Bearer {{token}}" + } + ], + "params": [], + "body": { + "type": "graphql", + "raw": "", + "form": [], + "graphql": { + "query": "mutation updateBrandStatus($brandId: String!, $input: BrandStatusInput!){\n updateBrandStatus(brandId: $brandId, input: $input){\n id,\n }\n}", + "variables": "{\n \"input\": {\n \"status\": \"DATA_READY\"\n \n },\n \"brandId\": \"01H2Q81MZ45Y2FVD2KB0SDTMXR\"\n}" + } + }, + "tests": [] + }, + { + "_id": "9f4d0c59-dcd6-48d1-9e60-0cd6c4a66156", + "colId": "bdfbad21-e244-4370-bf29-ebc7989769c1", + "containerId": "", + "name": "update Brand Status with invalid status", + "url": "{{baseUrl}}", + "method": "POST", + "sortNum": 70000, + "created": "2023-07-03T09:42:36.064Z", + "modified": "2023-07-03T09:44:08.438Z", + "headers": [ + { + "name": "authorization", + "value": "Bearer {{token}}" + } + ], + "params": [], + "body": { + "type": "graphql", + "raw": "", + "form": [], + "graphql": { + "query": "mutation updateBrandStatus($brandId: String!, $input: BrandStatusInput!){\n updateBrandStatus(brandId: $brandId, input: $input){\n id,\n }\n}", + "variables": "{\n \"input\": {\n \"status\": \"NOT_VALID_STATUS\"\n \n },\n \"brandId\": \"01H2Q81MZ45Y2FVD2KB0SDTMXR\"\n}" + } + }, + "tests": [] } ] } \ No newline at end of file diff --git a/thunder-client/environments/tc_env_local-dev.json b/thunder-client/environments/tc_env_local-dev.json index 1b32f97..d65bd68 100644 --- a/thunder-client/environments/tc_env_local-dev.json +++ b/thunder-client/environments/tc_env_local-dev.json @@ -1,6 +1,9 @@ { "_id": "7a21206d-6833-492d-bf04-8be56301ec57", - "name": "Local Dev", + "client": "Thunder Client", + "environmentName": "Local Dev", + "version": "1.0", + "variables": [], "default": true, "sortNum": 10000, "created": "2023-07-03T09:39:57.955Z", From b2e99a4b8ec5f19182abbabea2d0ef5ff28a3d04 Mon Sep 17 00:00:00 2001 From: emiliocc5 Date: Tue, 3 Oct 2023 19:49:59 -0300 Subject: [PATCH 8/9] Add foreign key reference in brand status table --- init-project/db-user-schema-create.sql | 5 +++++ init-project/init-db-dump.sql | 2 +- schema.gql | 1 + src/intelligentSuite/brands/entities/BrandStatus.ts | 7 ++++++- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/init-project/db-user-schema-create.sql b/init-project/db-user-schema-create.sql index 3c14421..66f1a39 100644 --- a/init-project/db-user-schema-create.sql +++ b/init-project/db-user-schema-create.sql @@ -34,6 +34,7 @@ CREATE TABLE `brand_status` ( `status` varchar(255) NOT NULL, `createdAt` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `updatedAt` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), + `brandId` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; @@ -58,6 +59,10 @@ CREATE TABLE `brand` ( CONSTRAINT `FK_Brand_brandStatus` FOREIGN KEY (`brandStatusId`) REFERENCES `brand_status` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +-- +-- Brand Status modification to add foreign key +-- +ALTER TABLE `brand_status` ADD FOREIGN KEY `FK_BrandStatus_Brand` (`brandId`) REFERENCES `brand`(`id`); -- -- Table structure for table `user` diff --git a/init-project/init-db-dump.sql b/init-project/init-db-dump.sql index 9b06557..73b90c9 100644 --- a/init-project/init-db-dump.sql +++ b/init-project/init-db-dump.sql @@ -22,7 +22,7 @@ use test_memorable_db; LOCK TABLES `brand_status` WRITE; /*!40000 ALTER TABLE `brand_status` DISABLE KEYS */; -INSERT INTO `brand_status` VALUES ('01H4618V8XGS613BS5BSPZP183','IN_PROGRESS','2023-10-01 16:46:00.580809','2023-10-01 16:46:00.580809'); +INSERT INTO `brand_status` VALUES ('01H4618V8XGS613BS5BSPZP183','IN_PROGRESS','2023-10-01 16:46:00.580809','2023-10-01 16:46:00.580809','01H4618V8XGS613BS5BSPZP180'); /*!40000 ALTER TABLE `brand_status` ENABLE KEYS */; UNLOCK TABLES; diff --git a/schema.gql b/schema.gql index 7630c9b..f6cdc67 100644 --- a/schema.gql +++ b/schema.gql @@ -129,6 +129,7 @@ type BrandStatus { createdAt: DateTime! updatedAt: DateTime! status: String! + brand: Brand! } type Mutation { diff --git a/src/intelligentSuite/brands/entities/BrandStatus.ts b/src/intelligentSuite/brands/entities/BrandStatus.ts index b6e2eb3..dfa347b 100644 --- a/src/intelligentSuite/brands/entities/BrandStatus.ts +++ b/src/intelligentSuite/brands/entities/BrandStatus.ts @@ -1,4 +1,4 @@ -import {Column, Entity, ManyToOne, OneToMany, OneToOne} from "typeorm"; +import {Column, Entity, JoinColumn, ManyToOne, OneToMany, OneToOne} from "typeorm"; import {Field, ObjectType} from "type-graphql"; import Brand from "./Brand"; import {BaseEntity} from "../../../common/entities/BaseEntity"; @@ -21,10 +21,15 @@ export default class BrandStatus extends BaseEntity { @Field() status!: string + @OneToOne(() => Brand, (brand: Brand) => brand.id) + @Field(() => Brand) + brand!: Brand; + static create(brand: Brand, input: BrandStatusInput) { const brandStatus = new BrandStatus() brandStatus.setId(); brandStatus.status = input.status + brandStatus.brand = brand return brandStatus } From a78ee5c2ebdf71fa115f45d783a144eaeb2f299f Mon Sep 17 00:00:00 2001 From: emiliocc5 Date: Tue, 3 Oct 2023 20:04:57 -0300 Subject: [PATCH 9/9] Add sentence to drop foreign key index table --- init-project/db-user-schema-create.sql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/init-project/db-user-schema-create.sql b/init-project/db-user-schema-create.sql index 66f1a39..39ed888 100644 --- a/init-project/db-user-schema-create.sql +++ b/init-project/db-user-schema-create.sql @@ -4,7 +4,11 @@ CREATE DATABASE IF NOT EXISTS test_memorable_db use test_memorable_db; + DROP TABLE IF EXISTS `invitation`; + +ALTER TABLE `brand_status` DROP FOREIGN KEY `brand_status_ibfk_1`; + DROP TABLE IF EXISTS `brand`; DROP TABLE IF EXISTS `user`; DROP TABLE IF EXISTS `business_account`;