feat: Add ProbeOwnerTeam and ProbeOwnerUser APIs

This commit adds the APIs for ProbeOwnerTeam and ProbeOwnerUser, allowing users to manage ownership of probes within the application. The APIs are implemented in the BaseAPI/Index.ts file and include routes for creating, deleting, editing, and reading probe owner teams and users. This enhancement improves the functionality of the application by providing a way to manage probe ownership.
This commit is contained in:
Simon Larsen
2024-07-01 14:02:49 +01:00
parent dec35bbc03
commit 885a6ca36e
5 changed files with 148 additions and 10 deletions

View File

@@ -286,6 +286,16 @@ import WorkflowService, {
import WorkflowVariableService, {
Service as WorkflowVariableServiceType,
} from "CommonServer/Services/WorkflowVariableService";
import ProbeOwnerTeamService, {
Service as ProbeOwnerTeamServiceType,
} from "CommonServer/Services/ProbeOwnerTeamService";
import ProbeOwnerUserService, {
Service as ProbeOwnerUserServiceType,
} from "CommonServer/Services/ProbeOwnerUserService";
import FeatureSet from "CommonServer/Types/FeatureSet";
import Express, { ExpressApplication } from "CommonServer/Utils/Express";
import Log from "Model/AnalyticsModels/Log";
@@ -377,6 +387,8 @@ import UserOnCallLog from "Model/Models/UserOnCallLog";
import Workflow from "Model/Models/Workflow";
import WorkflowLog from "Model/Models/WorkflowLog";
import WorkflowVariable from "Model/Models/WorkflowVariable";
import ProbeOwnerTeam from "Model/Models/ProbeOwnerTeam";
import ProbeOwnerUser from "Model/Models/ProbeOwnerUser";
const BaseAPIFeatureSet: FeatureSet = {
init: async (): Promise<void> => {
@@ -448,6 +460,22 @@ const BaseAPIFeatureSet: FeatureSet = {
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<ProbeOwnerUser, ProbeOwnerUserServiceType>(
ProbeOwnerUser,
ProbeOwnerUserService,
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<ProbeOwnerTeam, ProbeOwnerTeamServiceType>(
ProbeOwnerTeam,
ProbeOwnerTeamService,
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<MonitorSecret, MonitorSecretServiceType>(

View File

@@ -5,7 +5,6 @@ import { EVERY_MINUTE } from "Common/Utils/CronTime";
import ProbeService from "CommonServer/Services/ProbeService";
import logger from "CommonServer/Utils/Logger";
import Probe, { ProbeStatus } from "Model/Models/Probe";
import User from "Model/Models/User";
import MonitorProbe from "Model/Models/MonitorProbe";
import MonitorProbeService from "CommonServer/Services/MonitorProbeService";
@@ -41,7 +40,7 @@ RunCron(
continue;
}
let connectionStatus = ProbeStatus.Connected;
let connectionStatus: ProbeStatus = ProbeStatus.Connected;
if (!probe.lastAlive) {
connectionStatus = ProbeStatus.Disconnected;
@@ -59,8 +58,8 @@ RunCron(
connectionStatus = ProbeStatus.Connected;
}
let shouldNotifyProbeOwner = false;
let shouldUpdateConnectionStatus = false;
let shouldNotifyProbeOwner: boolean = false;
let shouldUpdateConnectionStatus: boolean = false;
if (
probe.connectionStatus &&
@@ -114,7 +113,3 @@ RunCron(
}
},
);
const getProbeOwners = async (probe: Probe): Promise<User> => {};
const updateMonitors = async (probe: Probe): Promise<void> => {};

View File

@@ -0,0 +1,62 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class MigrationName1719838746775 implements MigrationInterface {
public name = 'MigrationName1719838746775'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE TABLE "ProbeOwnerTeam" ("_id" uuid NOT NULL DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP, "version" integer NOT NULL, "projectId" uuid NOT NULL, "teamId" uuid NOT NULL, "probeId" uuid NOT NULL, "createdByUserId" uuid, "deletedByUserId" uuid, "isOwnerNotified" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_b33e4c1d912b244680e0bace977" PRIMARY KEY ("_id"))`);
await queryRunner.query(`CREATE INDEX "IDX_6ffffa98ea1d05063733f36e55" ON "ProbeOwnerTeam" ("projectId") `);
await queryRunner.query(`CREATE INDEX "IDX_90007d943ad04dbef87aefcb6b" ON "ProbeOwnerTeam" ("teamId") `);
await queryRunner.query(`CREATE INDEX "IDX_d9a4b1d48b2eaefefb8f5dceb7" ON "ProbeOwnerTeam" ("probeId") `);
await queryRunner.query(`CREATE INDEX "IDX_b0a43c04a374168e90b5fe63e7" ON "ProbeOwnerTeam" ("isOwnerNotified") `);
await queryRunner.query(`CREATE TABLE "ProbeOwnerUser" ("_id" uuid NOT NULL DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP, "version" integer NOT NULL, "projectId" uuid NOT NULL, "userId" uuid NOT NULL, "probeId" uuid NOT NULL, "createdByUserId" uuid, "deletedByUserId" uuid, "isOwnerNotified" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_6dfa74aadf4e90010fc1e86c76b" PRIMARY KEY ("_id"))`);
await queryRunner.query(`CREATE INDEX "IDX_e94247bb495236a2931d974cf0" ON "ProbeOwnerUser" ("projectId") `);
await queryRunner.query(`CREATE INDEX "IDX_3fbca1f838f73adbba73e81de7" ON "ProbeOwnerUser" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_5d293a0a28ae8b189814761e9b" ON "ProbeOwnerUser" ("probeId") `);
await queryRunner.query(`CREATE INDEX "IDX_da7e9e3e1f350f3f99f0271d85" ON "ProbeOwnerUser" ("isOwnerNotified") `);
await queryRunner.query(`CREATE TABLE "ProbeLabel" ("probeId" uuid NOT NULL, "labelId" uuid NOT NULL, CONSTRAINT "PK_4564a1667bf06e98f36c266e986" PRIMARY KEY ("probeId", "labelId"))`);
await queryRunner.query(`CREATE INDEX "IDX_171fad9149ab82a7e83d12286b" ON "ProbeLabel" ("probeId") `);
await queryRunner.query(`CREATE INDEX "IDX_ab7fd85397d8c70c77c761004d" ON "ProbeLabel" ("labelId") `);
await queryRunner.query(`ALTER TABLE "ProbeOwnerTeam" ADD CONSTRAINT "FK_6ffffa98ea1d05063733f36e557" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerTeam" ADD CONSTRAINT "FK_90007d943ad04dbef87aefcb6b7" FOREIGN KEY ("teamId") REFERENCES "Team"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerTeam" ADD CONSTRAINT "FK_d9a4b1d48b2eaefefb8f5dceb73" FOREIGN KEY ("probeId") REFERENCES "Probe"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerTeam" ADD CONSTRAINT "FK_5f7e1a1dfc8380824e10d83f124" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerTeam" ADD CONSTRAINT "FK_e72250699a438e22153d9c32ea3" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerUser" ADD CONSTRAINT "FK_e94247bb495236a2931d974cf0a" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerUser" ADD CONSTRAINT "FK_3fbca1f838f73adbba73e81de7a" FOREIGN KEY ("userId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerUser" ADD CONSTRAINT "FK_5d293a0a28ae8b189814761e9b7" FOREIGN KEY ("probeId") REFERENCES "Probe"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerUser" ADD CONSTRAINT "FK_011c2a132409253ceb1234695c6" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerUser" ADD CONSTRAINT "FK_248df6f39557f114b03dd815bcf" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "ProbeLabel" ADD CONSTRAINT "FK_171fad9149ab82a7e83d12286b3" FOREIGN KEY ("probeId") REFERENCES "Probe"("_id") ON DELETE CASCADE ON UPDATE CASCADE`);
await queryRunner.query(`ALTER TABLE "ProbeLabel" ADD CONSTRAINT "FK_ab7fd85397d8c70c77c761004d2" FOREIGN KEY ("labelId") REFERENCES "Label"("_id") ON DELETE CASCADE ON UPDATE CASCADE`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "ProbeLabel" DROP CONSTRAINT "FK_ab7fd85397d8c70c77c761004d2"`);
await queryRunner.query(`ALTER TABLE "ProbeLabel" DROP CONSTRAINT "FK_171fad9149ab82a7e83d12286b3"`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerUser" DROP CONSTRAINT "FK_248df6f39557f114b03dd815bcf"`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerUser" DROP CONSTRAINT "FK_011c2a132409253ceb1234695c6"`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerUser" DROP CONSTRAINT "FK_5d293a0a28ae8b189814761e9b7"`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerUser" DROP CONSTRAINT "FK_3fbca1f838f73adbba73e81de7a"`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerUser" DROP CONSTRAINT "FK_e94247bb495236a2931d974cf0a"`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerTeam" DROP CONSTRAINT "FK_e72250699a438e22153d9c32ea3"`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerTeam" DROP CONSTRAINT "FK_5f7e1a1dfc8380824e10d83f124"`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerTeam" DROP CONSTRAINT "FK_d9a4b1d48b2eaefefb8f5dceb73"`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerTeam" DROP CONSTRAINT "FK_90007d943ad04dbef87aefcb6b7"`);
await queryRunner.query(`ALTER TABLE "ProbeOwnerTeam" DROP CONSTRAINT "FK_6ffffa98ea1d05063733f36e557"`);
await queryRunner.query(`DROP INDEX "public"."IDX_ab7fd85397d8c70c77c761004d"`);
await queryRunner.query(`DROP INDEX "public"."IDX_171fad9149ab82a7e83d12286b"`);
await queryRunner.query(`DROP TABLE "ProbeLabel"`);
await queryRunner.query(`DROP INDEX "public"."IDX_da7e9e3e1f350f3f99f0271d85"`);
await queryRunner.query(`DROP INDEX "public"."IDX_5d293a0a28ae8b189814761e9b"`);
await queryRunner.query(`DROP INDEX "public"."IDX_3fbca1f838f73adbba73e81de7"`);
await queryRunner.query(`DROP INDEX "public"."IDX_e94247bb495236a2931d974cf0"`);
await queryRunner.query(`DROP TABLE "ProbeOwnerUser"`);
await queryRunner.query(`DROP INDEX "public"."IDX_b0a43c04a374168e90b5fe63e7"`);
await queryRunner.query(`DROP INDEX "public"."IDX_d9a4b1d48b2eaefefb8f5dceb7"`);
await queryRunner.query(`DROP INDEX "public"."IDX_90007d943ad04dbef87aefcb6b"`);
await queryRunner.query(`DROP INDEX "public"."IDX_6ffffa98ea1d05063733f36e55"`);
await queryRunner.query(`DROP TABLE "ProbeOwnerTeam"`);
}
}

View File

@@ -21,6 +21,7 @@ import { MigrationName1719247426296 } from "./1719247426296-MigrationName";
import { MigrationName1719348009053 } from "./1719348009053-MigrationName";
import { MigrationName1719827175832 } from "./1719827175832-MigrationName";
import { MigrationName1719831213463 } from "./1719831213463-MigrationName";
import { MigrationName1719838746775 } from "./1719838746775-MigrationName";
export default [
InitialMigration,
@@ -46,4 +47,5 @@ export default [
MigrationName1719348009053,
MigrationName1719827175832,
MigrationName1719831213463,
MigrationName1719838746775
];

View File

@@ -7,6 +7,7 @@ import { PlanType } from "Common/Types/Billing/SubscriptionPlan";
import ColumnAccessControl from "Common/Types/Database/AccessControl/ColumnAccessControl";
import TableAccessControl from "Common/Types/Database/AccessControl/TableAccessControl";
import TableBillingAccessControl from "Common/Types/Database/AccessControl/TableBillingAccessControl";
import AccessControlColumn from "Common/Types/Database/AccessControlColumn";
import ColumnLength from "Common/Types/Database/ColumnLength";
import ColumnType from "Common/Types/Database/ColumnType";
import CrudApiEndpoint from "Common/Types/Database/CrudApiEndpoint";
@@ -20,7 +21,8 @@ import IconProp from "Common/Types/Icon/IconProp";
import ObjectID from "Common/Types/ObjectID";
import Permission from "Common/Types/Permission";
import Version from "Common/Types/Version";
import { Column, Entity, JoinColumn, ManyToOne } from "typeorm";
import { Column, Entity, JoinColumn, JoinTable, ManyToMany, ManyToOne } from "typeorm";
import Label from "./Label";
export enum ProbeStatus {
Connected = "connected",
@@ -36,6 +38,7 @@ export enum ProbeStatus {
@IsPermissionsIf(Permission.Public, "projectId", null)
@TenantColumn("projectId")
@CrudApiEndpoint(new Route("/probe"))
@AccessControlColumn("labels")
@SlugifyColumn("name", "slug")
@Entity({
name: "Probe",
@@ -501,4 +504,52 @@ export default class Probe extends BaseModel {
unique: false,
})
public connectionStatus?: ProbeStatus = undefined;
}
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateProjectStatusPage,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadProjectStatusPage,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditProjectStatusPage,
],
})
@TableColumn({
required: false,
type: TableColumnType.EntityArray,
modelType: Label,
title: "Labels",
description:
"Relation to Labels Array where this object is categorized in.",
})
@ManyToMany(
() => {
return Label;
},
{ eager: false },
)
@JoinTable({
name: "ProbeLabel",
inverseJoinColumn: {
name: "labelId",
referencedColumnName: "_id",
},
joinColumn: {
name: "probeId",
referencedColumnName: "_id",
},
})
public labels?: Array<Label> = undefined;
}