Skip to content

Commit

Permalink
feat(orgs): added endpoint to trigger specific jobsite import
Browse files Browse the repository at this point in the history
CLOSES: JOB-799
  • Loading branch information
AndySakov committed Nov 12, 2024
1 parent 606b3d7 commit a3c6051
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/organizations/dto/import-organization-jobsites.input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ApiProperty } from "@nestjs/swagger";
import { IsNotEmpty, IsString, IsUUID } from "class-validator";

export class ImportOrgJobsiteInput {
@ApiProperty()
@IsNotEmpty()
@IsString()
orgId: string;

@ApiProperty()
@IsNotEmpty()
@IsUUID()
jobsiteId: string;
}
43 changes: 43 additions & 0 deletions src/organizations/organizations.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ import { CreateOrgJobsiteInput } from "./dto/create-organization-jobsites.input"
import { randomUUID } from "crypto";
import { Session } from "src/shared/decorators";
import { UserService } from "src/user/user.service";
import { ImportOrgJobsiteInput } from "./dto/import-organization-jobsites.input";
// eslint-disable-next-line @typescript-eslint/no-var-requires
const mime = require("mime");

Expand Down Expand Up @@ -892,6 +893,48 @@ export class OrganizationsController {
return this.organizationsService.updateOrgCommunities(body);
}

@Post("/jobsites/import")
@UseGuards(PBACGuard)
@Permissions(
[CheckWalletPermissions.USER, CheckWalletPermissions.ORG_AFFILIATE],
[CheckWalletPermissions.ADMIN, CheckWalletPermissions.ORG_MANAGER],
)
@ApiOkResponse({
description: "Imports a jobsite for an org",
schema: responseSchemaWrapper({
$ref: getSchemaPath(Organization),
}),
})
@ApiUnprocessableEntityResponse({
description:
"Something went wrong importing the organization jobsites on the destination service",
schema: responseSchemaWrapper({ type: "string" }),
})
async importOrgJobsite(
@Session() { address, permissions }: SessionObject,
@Body() body: ImportOrgJobsiteInput,
): Promise<ResponseWithOptionalData<Jobsite[]>> {
this.logger.log(
`POST /organizations/jobsites/import ${JSON.stringify(
body,
)} from ${address}`,
);

if (permissions.includes(CheckWalletPermissions.ORG_AFFILIATE)) {
const authorized = await this.userService.userAuthorizedForOrg(
address,
body.orgId,
);
if (!authorized) {
throw new ForbiddenException({
success: false,
message: "You are not authorized to access this resource",
});
}
}
return this.organizationsService.importOrganizationJobsiteById(body);
}

@Post("/jobsites/activate")
@UseGuards(PBACGuard)
@Permissions(
Expand Down
63 changes: 63 additions & 0 deletions src/organizations/organizations.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import { AddOrganizationByUrlInput } from "./dto/add-organization-by-url.input";
import { ConfigService } from "@nestjs/config";
import axios from "axios";
import { Auth0Service } from "src/auth0/auth0.service";
import { ImportOrgJobsiteInput } from "./dto/import-organization-jobsites.input";

@Injectable()
export class OrganizationsService {
Expand Down Expand Up @@ -1246,6 +1247,68 @@ export class OrganizationsService {
}
}

async importOrganizationJobsiteById(
dto: ImportOrgJobsiteInput,
): Promise<ResponseWithNoData> {
try {
const jobsite = (
await this.neogma.queryRunner.run(
`
MATCH (:Organization {orgId: $orgId})-[:HAS_JOBSITE]->(jobsite:DetectedJobsite WHERE jobsite.id = $jobsiteId)
RETURN jobsite { .* } as jobsite
`,
dto,
)
).records[0]?.get("jobsite") as Jobsite;
if (jobsite) {
const url = this.configService.get<string>("ETL_DOMAIN");
const authToken = await this.auth0Service.getETLToken();
const response2 = await axios.get(
`${url}/jobposts/jobsite?jobsite=${jobsite.url}`,
{
headers: {
Authorization: authToken ? `Bearer ${authToken}` : undefined,
},
},
);
if ([200, 201, 202].includes(response2.status)) {
return {
success: true,
message: "Organization jobsite queued for import successfully",
};
} else {
this.logger.warn(
`Error queueing organization jobsite ${dto} for import: ${response2.data}`,
);
return {
success: false,
message: "Error importing organization jobsite",
};
}
} else {
return {
success: false,
message: "Organization jobsite not found",
};
}
} catch (err) {
Sentry.withScope(scope => {
scope.setTags({
action: "external-api-call",
source: "organizations.service",
});
Sentry.captureException(err);
});
this.logger.error(
`OrganizationsService::importOrganizationJobsiteById ${err.message}`,
);
return {
success: false,
message: `Error importing organization jobsite`,
};
}
}

async hasProjectRelationship(
orgId: string,
projectId: string,
Expand Down

0 comments on commit a3c6051

Please sign in to comment.