diff --git a/.env.template b/.env.template index 92e99255a..b20ce862b 100644 --- a/.env.template +++ b/.env.template @@ -58,4 +58,6 @@ SENTRY_ENVIRONMENT=local CAMPAIGN_CREATION_WEBHOOK=https://webhook.site/11111111-1111-1111-1111-11111111111 -STATUS_CHANGE_WEBHOOK=https://webhook.site/11111111-1111-1111-1111-11111111111 \ No newline at end of file +STATUS_CHANGE_WEBHOOK=https://webhook.site/11111111-1111-1111-1111-11111111111 + +AI_REVIEWER_PROFILE_ID=11111 \ No newline at end of file diff --git a/deployment/after-install.sh b/deployment/after-install.sh index 879cf0082..e2e3f5a07 100644 --- a/deployment/after-install.sh +++ b/deployment/after-install.sh @@ -97,6 +97,7 @@ services: TESTER_LEADER_CPV2_EMAIL: '${TESTER_LEADER_CPV2_EMAIL}' TASK_MEDIA_BUCKET: '${TASK_MEDIA_BUCKET}' OPTIMIZED_TASK_MEDIA_BUCKET: '${OPTIMIZED_TASK_MEDIA_BUCKET}' + AI_REVIEWER_PROFILE_ID: '${AI_REVIEWER_PROFILE_ID}' volumes: - /var/docker/keys:/app/keys logging: diff --git a/src/config.ts b/src/config.ts index bfdec4397..ef6ffe440 100644 --- a/src/config.ts +++ b/src/config.ts @@ -41,6 +41,7 @@ const config: { name: string; email: string; }; + aiReviewer: number; } = { port: process.env.PORT || "3000", apiRoot: false, @@ -77,6 +78,7 @@ const config: { name: process.env.TESTER_LEADER_CPV2_NAME || "Unknown", email: process.env.TESTER_LEADER_CPV2_EMAIL || "Unknown", }, + aiReviewer: Number(process.env.AI_REVIEWER_PROFILE_ID) || 0, }; if (process.env.SSL_CHAIN && process.env.SSL_PRIVATE) { diff --git a/src/reference/openapi.yml b/src/reference/openapi.yml index e5dc569a7..82380cbac 100644 --- a/src/reference/openapi.yml +++ b/src/reference/openapi.yml @@ -2985,11 +2985,86 @@ paths: size: 0 start: 0 total: 0 + reviewer-types: + value: + items: + - created: string + duplication: father + id: 1 + internalId: string + isFavourite: true + severity: + id: 0 + name: string + status: + id: 0 + name: string + tags: + - id: 0 + name: string + tester: + id: 0 + title: string + type: + id: 0 + name: string + updated: string + - created: string + duplication: father + id: 2 + internalId: string + isFavourite: true + reviewerType: ai + severity: + id: 0 + name: string + status: + id: 0 + name: string + tags: + - id: 0 + name: string + tester: + id: 0 + title: string + type: + id: 0 + name: string + updated: string + - created: string + duplication: father + id: 3 + internalId: string + isFavourite: true + reviewerType: human + severity: + id: 0 + name: string + status: + id: 0 + name: string + tags: + - id: 0 + name: string + tester: + id: 0 + title: string + type: + id: 0 + name: string + updated: string + limit: 0 + size: 0 + start: 0 + total: 3 schema: allOf: - - properties: + - type: object + properties: items: + type: array items: + type: object properties: created: type: string @@ -3005,68 +3080,70 @@ paths: type: string isFavourite: type: boolean + reviewerType: + type: string + enum: + - ai + - human severity: + type: object + required: + - id + - name properties: id: type: integer name: type: string + status: + type: object required: - id - name - type: object - status: properties: id: type: integer name: type: string - required: - - id - - name - type: object tags: + type: array items: $ref: '#/components/schemas/BugTag' - type: array tester: + type: object + required: + - id properties: id: type: integer - required: - - id - type: object title: type: string type: + type: object + required: + - id + - name properties: id: type: integer name: type: string - required: - - id - - name - type: object updated: type: string required: + - created + - duplication - id - - title - internalId - - status - - type + - isFavourite - severity + - status - tester - - duplication - - isFavourite - - created + - title + - type - updated - type: object - type: array required: - items - type: object - $ref: '#/components/schemas/PaginationData' description: OK '403': @@ -6671,13 +6748,7 @@ paths: summary: Get Human Resources for a campaign tags: [] parameters: - - schema: - type: string - name: campaign - in: path - required: true - $ref: '#/components/parameters/campaign' - description: Updates tokens_usage in campaign and updates the link between cp_id and agreementId put: summary: Your PUT endpoint tags: [] @@ -12841,6 +12912,7 @@ paths: - id: 0 name: Name rate: 0 + description: '' '403': $ref: '#/components/responses/Authentication' '404': @@ -13173,12 +13245,6 @@ paths: schema: type: object properties: {} - '': - content: - application/json: - schema: - type: object - properties: {} security: - JWT: [] requestBody: diff --git a/src/routes/campaigns/campaignId/bugs/_get/index.spec.ts b/src/routes/campaigns/campaignId/bugs/_get/index.spec.ts index bda0d7367..f80a9869c 100644 --- a/src/routes/campaigns/campaignId/bugs/_get/index.spec.ts +++ b/src/routes/campaigns/campaignId/bugs/_get/index.spec.ts @@ -5,6 +5,15 @@ import request from "supertest"; const yesterday = new Date(new Date().getTime() - 86400000).toISOString(); const tomorrow = new Date(new Date().getTime() + 86400000).toISOString(); +// mock config to set aiReviewer to 100 +jest.mock("@src/config", () => ({ + __esModule: true, + default: { + ...jest.requireActual("@src/config").default, + aiReviewer: 100, + }, +})); + beforeAll(async () => { await tryber.tables.WpAppqEvdProfile.do().insert({ id: 1, @@ -70,7 +79,7 @@ beforeAll(async () => { status_id: 1, wp_user_id: 1, profile_id: 1, - reviewer: 1, + reviewer: 100, last_editor_id: 1, severity_id: 1, bug_replicability_id: 1, @@ -227,4 +236,16 @@ describe("GET /campaigns/campaignId/bugs", () => { expect(response.body.items[1]).toHaveProperty("tester", { id: 1 }); expect(response.body.items[2]).toHaveProperty("tester", { id: 1 }); }); + // Should return a bug list with reviewerType foreach bug + it("Should return a bug list with reviewerType foreach bug", async () => { + const response = await request(app) + .get("/campaigns/1/bugs") + .set("Authorization", "Bearer admin"); + expect(response.body).toHaveProperty("items"); + + expect(response.body.items).toHaveLength(3); + expect(response.body.items[0]).toHaveProperty("reviewerType", "ai"); + expect(response.body.items[1]).toHaveProperty("reviewerType", "human"); + expect(response.body.items[2]).toHaveProperty("reviewerType", "human"); + }); }); diff --git a/src/routes/campaigns/campaignId/bugs/_get/index.ts b/src/routes/campaigns/campaignId/bugs/_get/index.ts index c8e0926f1..10b8e62cc 100644 --- a/src/routes/campaigns/campaignId/bugs/_get/index.ts +++ b/src/routes/campaigns/campaignId/bugs/_get/index.ts @@ -3,12 +3,16 @@ import OpenapiError from "@src/features/OpenapiError"; import { tryber } from "@src/features/database"; import CampaignRoute from "@src/features/routes/CampaignRoute"; +import config from "@src/config"; interface Tag { id: number; name: string; } +type ReviewerType = + StoplightOperations["get-campaigns-cid-bugs"]["responses"]["200"]["content"]["application/json"]["items"][number]["reviewerType"]; + export default class BugsRoute extends CampaignRoute<{ response: StoplightOperations["get-campaigns-cid-bugs"]["responses"]["200"]["content"]["application/json"]; parameters: StoplightOperations["get-campaigns-cid-bugs"]["parameters"]["path"]; @@ -133,6 +137,7 @@ export default class BugsRoute extends CampaignRoute<{ "is_duplicated", "duplicated_of_id", "is_favorite", + "reviewer", tryber.raw("CAST(created AS CHAR) as created"), tryber.raw("CAST(updated AS CHAR) as updated"), tryber.ref("message").as("title"), @@ -197,6 +202,7 @@ export default class BugsRoute extends CampaignRoute<{ id: bug.bug_type_id, name: bug.type, }, + reviewerType: bug.reviewer === config.aiReviewer ? "ai" : "human", })); } @@ -277,6 +283,7 @@ export default class BugsRoute extends CampaignRoute<{ .toISOString() .slice(0, 19) .replace("T", " "), + reviewerType: bug.reviewerType as ReviewerType, }; }); } diff --git a/src/routes/media/_post/index.ts b/src/routes/media/_post/index.ts index 215fc882b..bf63ea416 100644 --- a/src/routes/media/_post/index.ts +++ b/src/routes/media/_post/index.ts @@ -2,7 +2,6 @@ import debugMessage from "@src/features/debugMessage"; import upload from "@src/features/upload"; import { Context } from "openapi-backend"; import path from "path"; -import fs from "fs"; import busboyMapper from "@src/features/busboyMapper"; /** OPENAPI-ROUTE: post-media */ diff --git a/src/schema.ts b/src/schema.ts index 05530f136..b2b29ff9a 100644 --- a/src/schema.ts +++ b/src/schema.ts @@ -809,6 +809,7 @@ export interface components { }; Agreement: { expirationDate: string; + /** @default false */ isTokenBased?: boolean; note?: string; startDate: string; @@ -888,6 +889,7 @@ export interface components { applied?: boolean; /** @description If bugform is deactivated is a boolean else contains URLs to bugforms for each languages */ bugform_link?: boolean | components["schemas"]["TranslatablePage"]; + /** @default 0 */ csm_effort?: number; customerCanViewReviewing?: boolean; customer_title?: string; @@ -910,7 +912,9 @@ export interface components { public?: boolean; status?: boolean; titleRule?: boolean; + /** @default 0 */ tokens?: number; + /** @default 0 */ ux_effort?: number; visibility?: { freeSpots?: number; @@ -1867,6 +1871,8 @@ export interface operations { id: number; internalId: string; isFavourite: boolean; + /** @enum {string} */ + reviewerType?: "ai" | "human"; severity: { id: number; name: string; @@ -2984,15 +2990,20 @@ export interface operations { }; } & { autoApply?: number; + /** @default 0 */ autoApprove?: number; bugLanguage?: components["schemas"]["BugLang"]; hasBugForm?: number; hasBugParade?: number; /** @enum {string} */ pageVersion?: "v1" | "v2"; + /** @default 0 */ skipPagesAndTasks?: number; } & { - /** @enum {undefined} */ + /** + * @default 0 + * @enum {undefined} + */ notify_everyone?: 0 | 1; /** @example 1 */ ux_notify?: number; @@ -3013,6 +3024,7 @@ export interface operations { content: { "application/json": { autoApply: number; + /** @default 0 */ autoApprove: number; browsers?: { id: number; @@ -3035,6 +3047,7 @@ export interface operations { name: string; }[]; deviceRequirements?: string; + /** @default false */ hasPlan?: boolean; /** Format: date-time */ endDate: string; @@ -3121,6 +3134,7 @@ export interface operations { content: { "application/json": components["schemas"]["DossierCreationData"] & { autoApply?: number; + /** @default 0 */ autoApprove?: number; bugLanguage?: components["schemas"]["BugLang"] | boolean; hasBugParade?: number; @@ -5443,11 +5457,6 @@ export interface operations { "application/json": { [key: string]: unknown }; }; }; - "": { - content: { - "application/json": { [key: string]: unknown }; - }; - }; }; requestBody: { content: {