Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
337 changes: 207 additions & 130 deletions src/routes/users/me/bugs/_get/index.ts
Original file line number Diff line number Diff line change
@@ -1,145 +1,222 @@
/** OPENAPI-ROUTE: get-users-me-bugs */

import * as db from "@src/features/db";
import { Context } from "openapi-backend";

export default async (
c: Context,
req: OpenapiRequest,
res: OpenapiResponse
) => {
try {
const sqlCountFields = `SELECT count(b.id) as total`;
const sqlSelectFields = `SELECT
b.id as id, s.id as severityID, s.name as severity,
st.id as statusID, st.name as status,
c.title as campaignTITLE, c.id as campaign, b.message as title`;

let fromSql = `
FROM wp_appq_evd_bug b
JOIN wp_appq_evd_campaign c ON (c.id = b.campaign_id)
JOIN wp_appq_evd_severity s ON (s.id = b.severity_id)
JOIN wp_appq_evd_bug_status st ON (st.id = b.status_id)
WHERE b.profile_id = ?`;

let limits = "";
const data = [req.user.testerId.toString()];
const accepted = {
title: ["b.message"],
campaign: ["c.id", "c.title"],
status: ["st.name", "st.id"],
severity: ["s.id", "s.name"],
id: ["b.id"],
/** OPENAPI-CLASS: get-users-me-bugs */

import { tryber } from "@src/features/database";
import UserRoute from "@src/features/routes/UserRoute";

export default class Route extends UserRoute<{
response: StoplightOperations["get-users-me-bugs"]["responses"]["200"]["content"]["application/json"];
query: StoplightOperations["get-users-me-bugs"]["parameters"]["query"];
}> {
private start: number = 0;
private limit: number | undefined;

private orderBy: NonNullable<Route["query"]>["orderBy"];
private order: NonNullable<Route["query"]>["order"] = "DESC";

private filterBy:
| {
campaign?: string;
title?: string;
status?: string;
severity?: string;
id?: string;
}
| false = false;

constructor(configuration: RouteClassConfiguration) {
super({ ...configuration, element: "bugs" });
this.setId(0);
const query = this.getQuery();
if (query.start) this.start = Number(query.start as unknown as string);
if (query.limit) this.limit = Number(query.limit as unknown as string);

if (query.orderBy) this.orderBy = query.orderBy;
if (query.order) this.order = query.order;

this.filterBy = this.getFilterBy();
}
private getFilterBy() {
const query = this.getQuery();
if (!query.filterBy) return false;

return {
...(query.filterBy?.campaign
? { campaign: query.filterBy.campaign as string }
: {}),
...(query.filterBy?.title
? { title: query.filterBy.title as string }
: {}),
...(query.filterBy?.status
? { status: query.filterBy.status as string }
: {}),
...(query.filterBy?.severity
? { status: query.filterBy.severity as string }
: {}),
...(query.filterBy?.id ? { status: query.filterBy.id as string } : {}),
};
}

protected async prepare() {
const query = this.getBugsQuery();

if (req.query.filterBy) {
for (const [key, value] of Object.entries(req.query.filterBy)) {
if (Object.keys(accepted).includes(key)) {
fromSql += " AND (";
const orQuery = accepted[key as keyof typeof accepted].map((el) => {
data.push(el, value);
return "?? = ? ";
});
fromSql += orQuery.join(" OR ");
fromSql += ") ";
}
this.applyFilterBy(query);
this.applyOrderBy(query);
this.applyLimit(query);

const rows = await query;
if (!rows.length) {
this.setError(404, Error("Error on finding bugs") as OpenapiError);
return;
}

this.setSuccess(200, {
results: rows.map((bug) => {
return {
id: bug.id,
severity: {
id: bug.severityID,
name: bug.severity,
},
status: {
id: bug.statusID,
name: bug.status,
},
campaign: {
id: bug.campaign,
name: bug.campaignTITLE,
},
title: bug.title,
};
}),
size: rows.length,
start: this.start,
limit: this.limit,
total: this.limit ? await this.getCount() : undefined,
});
}

private applyFilterBy(query: any) {
if (this.filterBy) {
if (this.filterBy?.campaign) {
query
.where("wp_appq_evd_campaign.id", this.filterBy.campaign)
.orWhere("wp_appq_evd_campaign.title", this.filterBy.campaign);
}
if (this.filterBy?.title) {
query.where("wp_appq_evd_bug.title", this.filterBy.title);
}
if (this.filterBy?.status) {
query
.where("wp_appq_evd_bug_status.name", this.filterBy.status)
.orWhere("wp_appq_evd_bug_status.id", this.filterBy.status);
}
if (this.filterBy?.severity) {
query
.where("wp_appq_evd_severity.name", this.filterBy.severity)
.orWhere("wp_appq_evd_severity.id", this.filterBy.severity);
}
}
}

if (req.query.orderBy) {
let orderBy = "b.id";
if (req.query.orderBy == "id") orderBy = "b.id";
if (req.query.orderBy == "campaign") orderBy = "c.id";
if (req.query.orderBy == "status") orderBy = "st.id";
if (req.query.orderBy == "title") orderBy = "b.message";
fromSql += ` ORDER BY ?? ${req.query.order || "DESC"}`;
data.push(orderBy);
private applyOrderBy(query: any) {
if (this.orderBy) {
switch (this.orderBy) {
case "campaign":
query.orderBy("wp_appq_evd_campaign.id", this.order);
break;
case "status":
query.orderBy("wp_appq_evd_bug_status.id", this.order);
break;
case "title":
query.orderBy("wp_appq_evd_bug.message", this.order);
break;
default:
query.orderBy("wp_appq_evd_bug.id", this.order);
}
}
}

const limitData: number[] = [];
if (req.query.limit && typeof req.query.limit === "string") {
limits += " LIMIT ? ";
limitData.push(parseInt(req.query.limit));
if (req.query.start && typeof req.query.start === "string") {
limits += " OFFSET ? ";
limitData.push(parseInt(req.query.start));
private applyLimit(query: any) {
if (this.limit) {
query.limit(this.limit);
if (this.start) {
query.offset(this.start);
}
}
}

const getBugsSql = sqlSelectFields + fromSql + limits;
let getBugsQuery = db.format(getBugsSql, data);
getBugsQuery = db.format(getBugsQuery, limitData);
private getBugsQuery() {
const query = tryber.tables.WpAppqEvdBug.do()
.select(
tryber.ref("id").withSchema("wp_appq_evd_bug"),
tryber
.ref("severity_id")
.withSchema("wp_appq_evd_bug")
.as("severityID"),
tryber.ref("status_id").withSchema("wp_appq_evd_bug").as("statusID"),
tryber.ref("message").withSchema("wp_appq_evd_bug").as("title"),
tryber.ref("campaign_id").withSchema("wp_appq_evd_bug").as("campaign")
)
.join(
"wp_appq_evd_bug_status",
"wp_appq_evd_bug.status_id",
"wp_appq_evd_bug_status.id"
)
.select(
tryber.ref("name").withSchema("wp_appq_evd_bug_status").as("status")
)
.join(
"wp_appq_evd_severity",
"wp_appq_evd_bug.severity_id",
"wp_appq_evd_severity.id"
)
.select(
tryber.ref("name").withSchema("wp_appq_evd_severity").as("severity")
)
.join(
"wp_appq_evd_campaign",
"wp_appq_evd_bug.campaign_id",
"wp_appq_evd_campaign.id"
)
.select(
tryber
.ref("title")
.withSchema("wp_appq_evd_campaign")
.as("campaignTITLE")
)
.where("wp_appq_evd_bug.profile_id", this.getTesterId());

const rows = await db.query(getBugsQuery);
if (!rows.length) {
throw Error("Error on finding bugs");
}
return query;
}

let bugList = rows.map(mapQueryToObject);
let start = 0;
if (req.query.start && typeof req.query.start === "string") {
start = parseInt(req.query.start);
}
private async getCount() {
const query = tryber.tables.WpAppqEvdBug.do()
.count({
total: tryber.ref("id").withSchema("wp_appq_evd_bug"),
})
.join(
"wp_appq_evd_bug_status",
"wp_appq_evd_bug.status_id",
"wp_appq_evd_bug_status.id"
)
.join(
"wp_appq_evd_severity",
"wp_appq_evd_bug.severity_id",
"wp_appq_evd_severity.id"
)
.join(
"wp_appq_evd_campaign",
"wp_appq_evd_bug.campaign_id",
"wp_appq_evd_campaign.id"
)
.where("wp_appq_evd_bug.profile_id", this.getTesterId());

const results: {
results: typeof bugList;
size: number;
total?: number;
start: number;
limit?: number;
} = {
results: bugList,
size: rows.length,
start: start,
};
if (req.query.limit && typeof req.query.limit === "string") {
results.limit = parseInt(req.query.limit);
const getBugsCountSql = sqlCountFields + fromSql;
const getBugsCountQuery = db.format(getBugsCountSql, data);

const countRows = await db.query(getBugsCountQuery);
if (!countRows.length) {
throw Error("Error on finding bugs total");
}
results.total = countRows[0].total;
this.applyFilterBy(query);

const countRows = await query;
if (!countRows.length) {
throw Error("Error on finding bugs total");
}
res.status_code = 200;
return results;
} catch (error) {
if (process.env && process.env.DEBUG) console.log(error);
res.status_code = 404;
return {
element: "bugs",
id: 0,
message: (error as OpenapiError).message,
};
return Number(countRows[0].total);
}
};

const mapQueryToObject = (bug: {
id: string;
severityID: string;
severity: string;
statusID: string;
status: string;
campaignTITLE: string;
campaign: string;
title: string;
}) => {
return {
id: bug.id,
severity: {
id: bug.severityID,
name: bug.severity,
},
status: {
id: bug.statusID,
name: bug.status,
},
campaign: {
id: bug.campaign,
name: bug.campaignTITLE,
},
title: bug.title,
};
};
}