From b12a9af68dba6b5efaa3e0f45b709c13fdfe2186 Mon Sep 17 00:00:00 2001 From: hxtree Date: Thu, 5 Oct 2023 12:58:42 +0000 Subject: [PATCH] feat: add affiliation endpoints Signed-off-by: hxtree --- .../character-sheet/src/data/affiliations.ts | 4 ++ .../models/affiliation-embeddable.schema.ts | 18 ++++++ .../src/models/character-sheet.schema.ts | 8 +++ .../affilation/affiliation.controller.ts | 30 +++++++++ .../affilation/affiliation.e2e-spec.ts | 62 +++++++++++++++++++ .../modules/affilation/affiliation.module.ts | 10 +++ .../modules/affilation/affiliation.service.ts | 33 ++++++++++ .../affilation/query-affiliation.dto.ts | 9 +++ 8 files changed, 174 insertions(+) create mode 100644 services/character-sheet/src/models/affiliation-embeddable.schema.ts create mode 100644 services/character-sheet/src/modules/affilation/affiliation.controller.ts create mode 100644 services/character-sheet/src/modules/affilation/affiliation.e2e-spec.ts create mode 100644 services/character-sheet/src/modules/affilation/affiliation.module.ts create mode 100644 services/character-sheet/src/modules/affilation/affiliation.service.ts create mode 100644 services/character-sheet/src/modules/affilation/query-affiliation.dto.ts diff --git a/services/character-sheet/src/data/affiliations.ts b/services/character-sheet/src/data/affiliations.ts index 515d4e103..716ea86a1 100644 --- a/services/character-sheet/src/data/affiliations.ts +++ b/services/character-sheet/src/data/affiliations.ts @@ -236,3 +236,7 @@ export namespace Affiliation { ], }; } + +export const AffiliationIds = Object.keys(Affiliation); + +export type AffiliationId = keyof typeof Affiliation; diff --git a/services/character-sheet/src/models/affiliation-embeddable.schema.ts b/services/character-sheet/src/models/affiliation-embeddable.schema.ts new file mode 100644 index 000000000..5d15b0daa --- /dev/null +++ b/services/character-sheet/src/models/affiliation-embeddable.schema.ts @@ -0,0 +1,18 @@ +import { Prop, Schema } from '@nestjs/mongoose'; +import { + IsInt, Min, Max, IsEnum, +} from '@cats-cradle/validation-schemas'; +import { AffiliationId, AffiliationIds } from '../data/affiliations'; + +@Schema({ _id: false }) +export class AffiliationEmbeddable { + @IsEnum(AffiliationIds) + @Prop() + public affiliationId!: AffiliationId; + + @IsInt() + @Min(0) + @Max(255) + @Prop() + public amount!: number; +} diff --git a/services/character-sheet/src/models/character-sheet.schema.ts b/services/character-sheet/src/models/character-sheet.schema.ts index 36b4ab994..480b98d37 100644 --- a/services/character-sheet/src/models/character-sheet.schema.ts +++ b/services/character-sheet/src/models/character-sheet.schema.ts @@ -17,6 +17,7 @@ import { } from '@cats-cradle/validation-schemas'; import { v4 as uuidv4 } from 'uuid'; import { DisciplineEmbeddable } from './discipline-embeddable.schema'; +import { AffiliationEmbeddable } from './affiliation-embeddable.schema'; import { StatsEmbeddable } from './stats-embeddable.schema'; import { EquipmentEmbeddable } from './equipment-embeddable.schema'; import { GaugeEmbeddable } from './gauge-embeddable.schema'; @@ -106,6 +107,13 @@ export class CharacterSheet { @ArrayMaxSize(12) @Prop() public equipment: EquipmentEmbeddable[]; + + @ValidateNested({ each: true }) + @Type(() => AffiliationEmbeddable) + @IsArray() + @ArrayUnique() + @Prop() + public affiliation: AffiliationEmbeddable[]; } export type TCharacterSheetDocument = CharacterSheet & Document; diff --git a/services/character-sheet/src/modules/affilation/affiliation.controller.ts b/services/character-sheet/src/modules/affilation/affiliation.controller.ts new file mode 100644 index 000000000..1a20f741f --- /dev/null +++ b/services/character-sheet/src/modules/affilation/affiliation.controller.ts @@ -0,0 +1,30 @@ +import { + Controller, Get, Param, VERSION_NEUTRAL, +} from '@nestjs/common'; +import { AffiliationService } from './affiliation.service'; +import { QueryAffiliationDto } from './query-affiliation.dto'; +import { CharacterSheetRepository } from '../../models/character-sheet.repository'; + +@Controller({ path: '/affiliations', version: [VERSION_NEUTRAL, '1'] }) +export class AffiliationController { + constructor( + private _affiliationService: AffiliationService, + private _characterSheetRepository: CharacterSheetRepository, + ) {} + + @Get('/:id') + async find(@Param() param: QueryAffiliationDto): Promise { + const result = await this._characterSheetRepository.findOne({ + id: param.characterSheetId, + }); + + if (!result) { + return []; + } + + return result.affiliation ?? []; + } + + // :id/:id + // POST :id/:id +2 -2 +} diff --git a/services/character-sheet/src/modules/affilation/affiliation.e2e-spec.ts b/services/character-sheet/src/modules/affilation/affiliation.e2e-spec.ts new file mode 100644 index 000000000..0d1ab7dac --- /dev/null +++ b/services/character-sheet/src/modules/affilation/affiliation.e2e-spec.ts @@ -0,0 +1,62 @@ +import supertest from 'supertest'; +import { Test, TestingModule } from '@nestjs/testing'; +import { INestApplication } from '@nestjs/common'; +import { FakerFactory } from '@cats-cradle/faker-factory'; +import { + closeInMongodConnection, + rootMongooseTestModule, + MongooseModule, +} from '@cats-cradle/nestjs-modules'; +import { AffiliationController } from './affiliation.controller'; +import { AffiliationService } from './affiliation.service'; +import { CharacterSheetRepository } from '../../models/character-sheet.repository'; +import { CharacterSheet, CharacterSheetSchema } from '../../models/character-sheet.schema'; + +describe('/affiliations', () => { + let app: INestApplication; + let affiliationService: AffiliationService; + let characterSheetRepository: CharacterSheetRepository; + + beforeEach(async () => { + const moduleRef: TestingModule = await Test.createTestingModule({ + imports: [ + rootMongooseTestModule(), + MongooseModule.forFeature([ + { name: 'CharacterSheet', schema: CharacterSheetSchema }, + ]), + ], + providers: [CharacterSheetRepository, AffiliationService], + controllers: [AffiliationController], + }).compile(); + + app = moduleRef.createNestApplication(); + affiliationService = moduleRef.get(AffiliationService); + characterSheetRepository = moduleRef.get( + CharacterSheetRepository, + ); + await app.init(); + }); + + afterEach(async () => { + await characterSheetRepository.deleteAll(); + }); + + afterAll(async () => { + await closeInMongodConnection(); + await app.close(); + }); + + it('/GET /affiliations/:id', async () => { + const characterSheet = await FakerFactory.create( + CharacterSheet, + { archetypeId: 'MEEKU_ONI' }, + ); + await characterSheetRepository.create(characterSheet); + + const response = await supertest(app.getHttpServer()) + .get(`/affiliations/${characterSheet._id}`) + .expect(200); + + expect(response.body).toEqual(characterSheet.affiliation); + }); +}); diff --git a/services/character-sheet/src/modules/affilation/affiliation.module.ts b/services/character-sheet/src/modules/affilation/affiliation.module.ts new file mode 100644 index 000000000..1e6bbe403 --- /dev/null +++ b/services/character-sheet/src/modules/affilation/affiliation.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { AffiliationService } from './affiliation.service'; +import { AffiliationController } from './affiliation.controller'; +import { CharacterSheetRepository } from '../../models/character-sheet.repository'; + +@Module({ + controllers: [AffiliationController], + providers: [AffiliationService, CharacterSheetRepository], +}) +export class AffiliationModule {} diff --git a/services/character-sheet/src/modules/affilation/affiliation.service.ts b/services/character-sheet/src/modules/affilation/affiliation.service.ts new file mode 100644 index 000000000..d6fd7b2e9 --- /dev/null +++ b/services/character-sheet/src/modules/affilation/affiliation.service.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@nestjs/common'; + +export enum Reputation { + HONORED = 'HONORED', + FRIENDLY = 'FRIENDLY', + NEUTRAL = 'NEUTRAL', + HATED = 'HATED', +} + +@Injectable() +export class AffiliationService { + toString(amount: number | undefined): Reputation { + if (amount === undefined) { + return Reputation.NEUTRAL; + } + if (amount > 90) { + return Reputation.HONORED; + } + if (amount > 50) { + return Reputation.FRIENDLY; + } + + if (amount < 0) { + return Reputation.HATED; + } + + return Reputation.NEUTRAL; + } + + async find(instanceId: string, characterId: string): Promise { + // get from mongo + } +} diff --git a/services/character-sheet/src/modules/affilation/query-affiliation.dto.ts b/services/character-sheet/src/modules/affilation/query-affiliation.dto.ts new file mode 100644 index 000000000..dc94dd191 --- /dev/null +++ b/services/character-sheet/src/modules/affilation/query-affiliation.dto.ts @@ -0,0 +1,9 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { v4 } from 'uuid'; + +export class QueryAffiliationDto { + @ApiProperty({ + default: v4(), + }) + characterSheetId: string; +}