diff --git a/dictation_server/src/api/odms/openapi.json b/dictation_server/src/api/odms/openapi.json index da51092..7ecacde 100644 --- a/dictation_server/src/api/odms/openapi.json +++ b/dictation_server/src/api/odms/openapi.json @@ -901,6 +901,120 @@ "security": [{ "bearer": [] }] } }, + "/accounts/worktypes/{id}/option-items": { + "get": { + "operationId": "getOptionItems", + "summary": "", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "description": "Worktypeの内部ID", + "schema": { "type": "number" } + } + ], + "responses": { + "200": { + "description": "成功時のレスポンス", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetOptionItemsResponse" + } + } + } + }, + "400": { + "description": "WorktypeIDが不在", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" } + } + } + }, + "401": { + "description": "認証エラー", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" } + } + } + }, + "500": { + "description": "想定外のサーバーエラー", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" } + } + } + } + }, + "tags": ["accounts"], + "security": [{ "bearer": [] }] + }, + "post": { + "operationId": "updateOptionItems", + "summary": "", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "description": "Worktypeの内部ID", + "schema": { "type": "number" } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateOptionItemsRequest" + } + } + } + }, + "responses": { + "200": { + "description": "成功時のレスポンス", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateOptionItemsResponse" + } + } + } + }, + "400": { + "description": "WorktypeIDが不在", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" } + } + } + }, + "401": { + "description": "認証エラー", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" } + } + } + }, + "500": { + "description": "想定外のサーバーエラー", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" } + } + } + } + }, + "tags": ["accounts"], + "security": [{ "bearer": [] }] + } + }, "/accounts/partners": { "get": { "operationId": "getPartners", @@ -2901,6 +3015,44 @@ "required": ["worktypeId"] }, "UpdateWorktypeResponse": { "type": "object", "properties": {} }, + "WorktypeOptionItem": { + "type": "object", + "properties": { + "itemLabel": { "type": "string", "maxLength": 16 }, + "defaultValueType": { + "type": "string", + "maxLength": 20, + "description": "Default / Blank / LastInput" + }, + "initialValue": { "type": "string", "maxLength": 20 } + }, + "required": ["itemLabel", "defaultValueType", "initialValue"] + }, + "GetOptionItemsResponse": { + "type": "object", + "properties": { + "optionItems": { + "maxItems": 10, + "minItems": 10, + "type": "array", + "items": { "$ref": "#/components/schemas/WorktypeOptionItem" } + } + }, + "required": ["optionItems"] + }, + "UpdateOptionItemsRequest": { + "type": "object", + "properties": { + "optionItems": { + "maxItems": 10, + "minItems": 10, + "type": "array", + "items": { "$ref": "#/components/schemas/WorktypeOptionItem" } + } + }, + "required": ["optionItems"] + }, + "UpdateOptionItemsResponse": { "type": "object", "properties": {} }, "Partner": { "type": "object", "properties": { diff --git a/dictation_server/src/features/accounts/accounts.controller.ts b/dictation_server/src/features/accounts/accounts.controller.ts index 93abc48..84c091b 100644 --- a/dictation_server/src/features/accounts/accounts.controller.ts +++ b/dictation_server/src/features/accounts/accounts.controller.ts @@ -51,8 +51,18 @@ import { UpdateWorktypeRequestParam, UpdateWorktypeResponse, UpdateWorktypesRequest, + GetOptionItemsRequestParam, + GetOptionItemsResponse, + UpdateOptionItemsResponse, + UpdateOptionItemsRequestParam, + UpdateOptionItemsRequest, } from './types/types'; -import { USER_ROLES, ADMIN_ROLES, TIERS } from '../../constants'; +import { + USER_ROLES, + ADMIN_ROLES, + TIERS, + OPTION_ITEM_VALUE_TYPE, +} from '../../constants'; import { AuthGuard } from '../../common/guards/auth/authguards'; import { RoleGuard } from '../../common/guards/role/roleguards'; import { retrieveAuthorizationToken } from '../../common/http/helper'; @@ -770,6 +780,144 @@ export class AccountsController { return {}; } + @Get('/worktypes/:id/option-items') + @ApiResponse({ + status: HttpStatus.OK, + type: GetOptionItemsResponse, + description: '成功時のレスポンス', + }) + @ApiResponse({ + status: HttpStatus.BAD_REQUEST, + description: 'WorktypeIDが不在', + type: ErrorResponse, + }) + @ApiResponse({ + status: HttpStatus.UNAUTHORIZED, + description: '認証エラー', + type: ErrorResponse, + }) + @ApiResponse({ + status: HttpStatus.INTERNAL_SERVER_ERROR, + description: '想定外のサーバーエラー', + type: ErrorResponse, + }) + @ApiOperation({ operationId: 'getOptionItems' }) + @ApiBearerAuth() + @UseGuards(AuthGuard) + @UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] })) + async getOptionItems( + @Req() req: Request, + @Param() param: GetOptionItemsRequestParam, + ): Promise { + const { id } = param; + const token = retrieveAuthorizationToken(req); + const { userId } = jwt.decode(token, { json: true }) as AccessToken; + + const context = makeContext(userId); + + console.log('id', id); + console.log(context.trackingId); + + return { + optionItems: [ + { + itemLabel: '', + defaultValueType: OPTION_ITEM_VALUE_TYPE.DEFAULT, + initialValue: '', + }, + { + itemLabel: '', + defaultValueType: OPTION_ITEM_VALUE_TYPE.DEFAULT, + initialValue: '', + }, + { + itemLabel: '', + defaultValueType: OPTION_ITEM_VALUE_TYPE.DEFAULT, + initialValue: '', + }, + { + itemLabel: '', + defaultValueType: OPTION_ITEM_VALUE_TYPE.DEFAULT, + initialValue: '', + }, + { + itemLabel: '', + defaultValueType: OPTION_ITEM_VALUE_TYPE.DEFAULT, + initialValue: '', + }, + { + itemLabel: '', + defaultValueType: OPTION_ITEM_VALUE_TYPE.DEFAULT, + initialValue: '', + }, + { + itemLabel: '', + defaultValueType: OPTION_ITEM_VALUE_TYPE.DEFAULT, + initialValue: '', + }, + { + itemLabel: '', + defaultValueType: OPTION_ITEM_VALUE_TYPE.DEFAULT, + initialValue: '', + }, + { + itemLabel: '', + defaultValueType: OPTION_ITEM_VALUE_TYPE.DEFAULT, + initialValue: '', + }, + { + itemLabel: '', + defaultValueType: OPTION_ITEM_VALUE_TYPE.DEFAULT, + initialValue: '', + }, + ], + }; + } + + @Post('/worktypes/:id/option-items') + @ApiResponse({ + status: HttpStatus.OK, + type: UpdateOptionItemsResponse, + description: '成功時のレスポンス', + }) + @ApiResponse({ + status: HttpStatus.BAD_REQUEST, + description: 'WorktypeIDが不在', + type: ErrorResponse, + }) + @ApiResponse({ + status: HttpStatus.UNAUTHORIZED, + description: '認証エラー', + type: ErrorResponse, + }) + @ApiResponse({ + status: HttpStatus.INTERNAL_SERVER_ERROR, + description: '想定外のサーバーエラー', + type: ErrorResponse, + }) + @ApiOperation({ operationId: 'updateOptionItems' }) + @ApiBearerAuth() + @UseGuards(AuthGuard) + @UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] })) + async updateOptionItems( + @Req() req: Request, + @Param() param: UpdateOptionItemsRequestParam, + @Body() body: UpdateOptionItemsRequest, + ): Promise { + const { optionItems } = body; + const { id } = param; + const token = retrieveAuthorizationToken(req); + const { userId } = jwt.decode(token, { json: true }) as AccessToken; + + const context = makeContext(userId); + + console.log('id', id); + console.log('optionItems', optionItems); + console.log(context.trackingId); + + return {}; + } + @Get('/partners') @ApiResponse({ status: HttpStatus.OK, diff --git a/dictation_server/src/features/accounts/types/types.ts b/dictation_server/src/features/accounts/types/types.ts index 9679586..d63013c 100644 --- a/dictation_server/src/features/accounts/types/types.ts +++ b/dictation_server/src/features/accounts/types/types.ts @@ -9,11 +9,15 @@ import { ArrayMinSize, MinLength, IsArray, + IsIn, + ArrayMaxSize, + ValidateNested, } from 'class-validator'; import { IsAdminPasswordvalid } from '../../../common/validators/admin.validator'; import { IsUnique } from '../../../common/validators/IsUnique.validator'; import { Type } from 'class-transformer'; import { IsWorktypeId } from '../../../common/validators/worktype.validator'; +import { OPTION_ITEM_VALUE_TYPE } from '../../../constants'; export class CreateAccountRequest { @ApiProperty() @@ -376,6 +380,62 @@ export class UpdateWorktypesRequest { export class UpdateWorktypeResponse {} +export class WorktypeOptionItem { + @ApiProperty({ maxLength: 16 }) + @MaxLength(16) + itemLabel: string; + @ApiProperty({ + maxLength: 20, + description: `${Object.values(OPTION_ITEM_VALUE_TYPE).join(' / ')}`, + }) + @MaxLength(20) + @IsIn(Object.values(OPTION_ITEM_VALUE_TYPE)) + defaultValueType: string; + @ApiProperty({ maxLength: 20 }) + @MaxLength(20) + initialValue: string; +} +export class GetOptionItemsResponse { + @ApiProperty({ + maxItems: 10, + minItems: 10, + type: [WorktypeOptionItem], + }) + optionItems: WorktypeOptionItem[]; +} + +export class GetOptionItemsRequestParam { + @ApiProperty({ description: 'Worktypeの内部ID' }) + @Type(() => Number) + @IsInt() + @Min(0) + id: number; +} + +export class UpdateOptionItemsRequest { + @ApiProperty({ + maxItems: 10, + minItems: 10, + type: [WorktypeOptionItem], + }) + @IsArray() + @ValidateNested({ each: true }) + @Type(() => WorktypeOptionItem) + @ArrayMinSize(10) + @ArrayMaxSize(10) + optionItems: WorktypeOptionItem[]; +} + +export class UpdateOptionItemsResponse {} + +export class UpdateOptionItemsRequestParam { + @ApiProperty({ description: 'Worktypeの内部ID' }) + @Type(() => Number) + @IsInt() + @Min(0) + id: number; +} + export class UpdateWorktypeRequestParam { @ApiProperty({ description: 'Worktypeの内部ID' }) @Type(() => Number)