Skip to content

Commit

Permalink
feat: Release/lions mane jellyfish (#715)
Browse files Browse the repository at this point in the history
Signed-off-by: OMPRAKASH MISHRA <[email protected]>
Co-authored-by: gregorylavery <[email protected]>
Co-authored-by: Barrett Falk <[email protected]>
Co-authored-by: dmitri-korin-bcps <[email protected]>
Co-authored-by: Scarlett <[email protected]>
Co-authored-by: Mike <[email protected]>
Co-authored-by: Mike Sears <[email protected]>
Co-authored-by: jeznorth <[email protected]>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Scarlett <[email protected]>
Co-authored-by: Ryan Rondeau <[email protected]>
Co-authored-by: jon-funk <[email protected]>
Co-authored-by: Mike Vesprini <[email protected]>
Co-authored-by: Om Mishra <[email protected]>
  • Loading branch information
14 people authored Oct 21, 2024
1 parent 171ad26 commit 4f34914
Show file tree
Hide file tree
Showing 78 changed files with 920 additions and 597 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/.tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
uses: cypress-io/github-action@v5
with:
working-directory: ./frontend
command: npx cypress run --browser electron --config baseUrl=https://${{ env.PREFIX }}-frontend.${{ env.DOMAIN }} --env auth_base_url=${{ vars.KEYCLOAK_URL_DEV }},auth_realm=${{ vars.KEYCLOAK_REALM }},auth_client_id=${{ vars.KEYCLOAK_CLIENT_ID }},keycloak_user=${{ vars.KEYCLOAK_USER }},keycloak_password=${{ secrets.KEYCLOAK_PASSWORD }}
command: npx cypress run --browser electron --config baseUrl=https://${{ env.PREFIX }}-frontend.${{ env.DOMAIN }} --env auth_base_url=${{ vars.KEYCLOAK_URL_DEV }},auth_realm=${{ vars.KEYCLOAK_REALM }},auth_client_id=${{ vars.KEYCLOAK_CLIENT_ID }},keycloak_user=${{ vars.KEYCLOAK_USER }},keycloak_user_02=${{ vars.KEYCLOAK_USER_02 }},keycloak_password=${{ secrets.KEYCLOAK_PASSWORD }}

- name: Upload Artifacts
uses: actions/upload-artifact@v3
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/merge-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,14 @@ jobs:
tag: ${{ needs.vars.outputs.pr }}
params: --set backend.deploymentStrategy=RollingUpdate
--set frontend.deploymentStrategy=RollingUpdate
--set webeoc.deploymentStrategy=RollingUpdate
--set global.autoscaling=true
--set frontend.pdb.enabled=true
--set backend.pdb.enabled=true
--set webeoc.pdb.enabled=true
--set nats.config.cluster.replicas=3
--set nats.config.cluster.enabled=true

promote:
name: Promote Images
needs: [deploy-prod, vars]
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/merge-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ jobs:
with:
environment: test
tag: ${{ needs.vars.outputs.pr }}
params: --set backend.deploymentStrategy=RollingUpdate
--set frontend.deploymentStrategy=RollingUpdate
--set webeoc.deploymentStrategy=RollingUpdate
--set global.autoscaling=true
--set frontend.pdb.enabled=true
--set backend.pdb.enabled=true
--set webeoc.pdb.enabled=true
--set nats.config.cluster.replicas=3
--set nats.config.cluster.enabled=true

promote:
name: Promote Images
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/pr-close.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,12 @@ jobs:
with:
cleanup: helm
packages: backend frontend migrations

cleanup-labeled:
name: Cleanup Labeled Resources
uses: bcgov/quickstart-openshift-helpers/.github/workflows/[email protected]
secrets:
oc_namespace: ${{ secrets.OC_NAMESPACE }}
oc_token: ${{ secrets.OC_TOKEN }}
with:
cleanup: label
1 change: 0 additions & 1 deletion .github/workflows/pr-open.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ jobs:
oc_token: ${{ secrets.OC_TOKEN }}
with:
triggers: ('backend/' 'frontend/' 'webeoc/' 'migrations/')
params: --set global.secrets.persist=false

tests:
name: Tests
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/pr-version-bump.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@ jobs:
if: ${{ github.event.pull_request.merged == true }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
fetch-depth: 0
fetch-tags: true

- name: Fetch all tags
run: git fetch --tags --force

- name: Fetch tags from main
id: get_latest_tag
run: |
git fetch origin main --tags
latest_tag=$(git describe --tags --abbrev=0 origin/main)
git fetch origin main --tags --force
latest_tag=$(git tag --list --sort=-v:refname --merged | head -n 1)
echo "::set-output name=latest_tag::$latest_tag"
echo "Latest tag: $latest_tag"
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/release-branch-creation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ jobs:
if: startsWith(github.ref, 'refs/heads/release/') && !contains(github.ref, '/')
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
fetch-depth: 0
fetch-tags: true

- name: Install npm
run: sudo apt-get install -y npm
Expand All @@ -19,8 +23,8 @@ jobs:
- name: Fetch latest tag
id: latest_tag
run: |
git fetch --tags
latest_tag=$(git tag --sort=-creatordate | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1)
git fetch --tags --force
latest_tag=$(git tag --list --sort=-v:refname --merged | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1)
if [ -z "$latest_tag" ]; then
echo "No previous tags found, starting with v0.1.0"
latest_tag="v0.0.0"
Expand Down
33 changes: 10 additions & 23 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# https://catalog.redhat.com/software/containers/ubi8/nodejs-18-minimal/627d1c38e35da88581633bf1
FROM registry.access.redhat.com/ubi8/nodejs-18-minimal:1-33.1679485315@sha256:74af9dc2b620022c77fcd712b811f64a03c1444ff1e9b9596a242b2edf3cf96f AS builder

# Build
FROM node:22-slim AS build
# Install packages, build and keep only prod packages
USER root
WORKDIR /app
Expand All @@ -10,26 +9,15 @@ RUN npm ci --omit=dev && \
npm run build

# Deployment container
FROM registry.access.redhat.com/ubi8/ubi-micro:8.7-6@sha256:af0a83c2fb7db1b63a5655c85f3f37d32b114443b8969fd8a40d47429cd87016

# Set node to production
ENV NODE_ENV production

# Node packages and dependencies
COPY --from=builder /usr/bin/node /usr/bin/
COPY --from=builder /usr/lib64/libz.so.1 /usr/lib64/
COPY --from=builder /usr/lib64/libbrotlidec.so.1 /usr/lib64/
COPY --from=builder /usr/lib64/libbrotlienc.so.1 /usr/lib64/
COPY --from=builder /usr/lib64/libcrypto.so.1.1 /usr/lib64/
COPY --from=builder /usr/lib64/libssl.so.1.1 /usr/lib64/
COPY --from=builder /usr/lib64/libstdc++.so.6 /usr/lib64/
COPY --from=builder /usr/lib64/libgcc_s.so.1 /usr/lib64/
COPY --from=builder /usr/lib64/libbrotlicommon.so.1 /usr/lib64/
# Deploy using minimal Distroless image
FROM gcr.io/distroless/nodejs22-debian12:nonroot
# Set node to production
ENV NODE_ENV=production

# Copy over app
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY ../templates /app/templates

# Port and health check
Expand All @@ -38,6 +26,5 @@ HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost/:3000

# Non-privileged user
USER app

# Start up command
ENTRYPOINT ["node", "dist/main"]
# max old space the heap size, 120MB with 200MB limit in deployment.
CMD ["--max-old-space-size=120", "/app/dist/main"]
8 changes: 5 additions & 3 deletions backend/src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import "dotenv/config";
import { MiddlewareConsumer, Module } from "@nestjs/common";
import { MiddlewareConsumer, Module, RequestMethod } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { ConfigModule } from "@nestjs/config";
import { AutomapperModule } from "@automapper/nestjs";
Expand Down Expand Up @@ -135,7 +135,9 @@ if (process.env.POSTGRESQL_PASSWORD != null) {
export class AppModule {
// let's add a middleware on all routes
configure(consumer: MiddlewareConsumer) {
consumer.apply(HTTPLoggerMiddleware).forRoutes("*");
consumer.apply(RequestTokenMiddleware).forRoutes("v1/code-table", "v1/case", "v1/configuration");
consumer.apply(HTTPLoggerMiddleware).exclude({ path: "", method: RequestMethod.ALL }).forRoutes("*");
consumer
.apply(RequestTokenMiddleware)
.forRoutes("v1/code-table", "v1/case", "v1/configuration", "v1/complaint/search", "v1/complaint/map/search");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ export interface ComplaintFilterParameters {
status?: string;
girTypeCode?: string;
complaintMethod?: string;
actionTaken?: string;
}
11 changes: 7 additions & 4 deletions backend/src/v1/complaint/complaint.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ComplaintService } from "./complaint.service";
import { Role } from "../../enum/role.enum";
import { Roles } from "../../auth/decorators/roles.decorator";
import { JwtRoleGuard } from "../../auth/jwtrole.guard";
import { Token } from "../../auth/decorators/token.decorator";
import { ApiTags } from "@nestjs/swagger";
import { COMPLAINT_TYPE } from "../../types/models/complaints/complaint-type";
import { WildlifeComplaintDto } from "../../types/models/complaints/wildlife-complaint";
Expand Down Expand Up @@ -45,22 +46,24 @@ export class ComplaintController {
@Param("complaintType") complaintType: COMPLAINT_TYPE,
@Query() model: ComplaintSearchParameters,
@Request() req,
@Token() token,
) {

const hasCEEBRole = hasRole(req, Role.CEEB);

return this.service.mapSearch(complaintType, model, hasCEEBRole);
return this.service.mapSearch(complaintType, model, hasCEEBRole, token);
}

@Get("/search/:complaintType")
@Roles(Role.COS_OFFICER, Role.CEEB)
search(
async search(
@Param("complaintType") complaintType: COMPLAINT_TYPE,
@Query() model: ComplaintSearchParameters,
@Request() req,
@Token() token,
) {
const hasCEEBRole = hasRole(req, Role.CEEB);
return this.service.search(complaintType, model, hasCEEBRole);
const result = await this.service.search(complaintType, model, hasCEEBRole, token);
return result;
}

@Patch("/update-status-by-id/:id")
Expand Down
49 changes: 44 additions & 5 deletions backend/src/v1/complaint/complaint.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { InjectRepository } from "@nestjs/typeorm";
import { Brackets, DataSource, QueryRunner, Repository, SelectQueryBuilder } from "typeorm";
import { InjectMapper } from "@automapper/nestjs";
import { Mapper } from "@automapper/core";
import { get } from "../../external_api/case_management";

import {
applyAllegationComplaintMap,
Expand Down Expand Up @@ -737,6 +738,25 @@ export class ComplaintService {
return Promise.resolve(results);
};

private _getComplaintsByActionTaken = async (token: string, actionTaken: string): Promise<string[]> => {
const { data, errors } = await get(token, {
query: `{getLeadsByActionTaken (actionCode: "${actionTaken}")}`,
});
if (errors) {
this.logger.error("GraphQL errors:", errors);
throw new Error("GraphQL errors occurred");
}
/**
* If no leads in the case manangement database have had the selected action taken, `getLeadsByActionTaken`
* returns an empty array, and WHERE...IN () does not accept an empty set, it throws an error. In our use
* case, if `getLeadsByActionTaken` returns an empty array, we do not want the entire search to error, it
* should simply return an empty result set. To handle this, if `getLeadsByActionTaken` returns an empty
* array, we populate the array with a value that would never match on a complaint_identifier: -1.
*/
const complaintIdentifiers = data.getLeadsByActionTaken.length > 0 ? data.getLeadsByActionTaken : ["-1"];
return complaintIdentifiers;
};

findAllByType = async (
complaintType: COMPLAINT_TYPE,
): Promise<Array<WildlifeComplaintDto> | Array<AllegationComplaintDto>> => {
Expand Down Expand Up @@ -843,6 +863,7 @@ export class ComplaintService {
complaintType: COMPLAINT_TYPE,
model: ComplaintSearchParameters,
hasCEEBRole: boolean,
token?: string,
): Promise<SearchResults> => {
try {
let results: SearchResults = { totalCount: 0, complaints: [] };
Expand Down Expand Up @@ -871,6 +892,15 @@ export class ComplaintService {
builder.andWhere("violation_code.agency_code = :agency", { agency: "EPO" });
}

// -- filter by complaint identifiers returned by case management if actionTaken filter is present
if (hasCEEBRole && filters.actionTaken) {
const complaintIdentifiers = await this._getComplaintsByActionTaken(token, filters.actionTaken);

builder.andWhere("complaint.complaint_identifier IN(:...complaint_identifiers)", {
complaint_identifiers: complaintIdentifiers,
});
}

//-- apply search
if (query) {
builder = this._applySearch(builder, complaintType, query);
Expand Down Expand Up @@ -946,6 +976,7 @@ export class ComplaintService {
complaintType: COMPLAINT_TYPE,
model: ComplaintSearchParameters,
hasCEEBRole: boolean,
token?: string,
): Promise<MapSearchResults> => {
const { orderBy, sortBy, page, pageSize, query, ...filters } = model;

Expand Down Expand Up @@ -985,9 +1016,6 @@ export class ComplaintService {
complaintBuilder.andWhere("ST_X(complaint.location_geometry_point) <> 0");
complaintBuilder.andWhere("ST_Y(complaint.location_geometry_point) <> 0");

//-- run query
const mappedComplaints = await complaintBuilder.getMany();

//-- get unmapable complaints
let unMappedBuilder = this._generateQueryBuilder(complaintType);

Expand All @@ -1008,7 +1036,6 @@ export class ComplaintService {
});
}


//-- added this for consistency with search method
//-- return Waste and Pestivide complaints for CEEB users
if (hasCEEBRole && complaintType === "ERS") {
Expand All @@ -1019,7 +1046,19 @@ export class ComplaintService {
unMappedBuilder.andWhere("ST_X(complaint.location_geometry_point) = 0");
unMappedBuilder.andWhere("ST_Y(complaint.location_geometry_point) = 0");

//-- run query
// -- filter by complaint identifiers returned by case management if actionTaken filter is present
if (hasCEEBRole && filters.actionTaken) {
const complaintIdentifiers = await this._getComplaintsByActionTaken(token, filters.actionTaken);
complaintBuilder.andWhere("complaint.complaint_identifier IN(:...complaint_identifiers)", {
complaint_identifiers: complaintIdentifiers,
});
unMappedBuilder.andWhere("complaint.complaint_identifier IN(:...complaint_identifiers)", {
complaint_identifiers: complaintIdentifiers,
});
}

//-- run queries
const mappedComplaints = await complaintBuilder.getMany();
const unmappedComplaints = await unMappedBuilder.getCount();
results = { ...results, unmappedComplaints };

Expand Down
10 changes: 8 additions & 2 deletions backend/src/v1/staging_complaint/staging_complaint.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,14 @@ export class StagingComplaintService {
// Given two WebEOCComplaint objects, compare them and return true if they're the same. This function
// ignores some attributes (specifically the back_number_of* attributes)
_compareWebEOCComplaints = (complaint1: WebEOCComplaint, complaint2: WebEOCComplaint): boolean => {
// Attributes to ignore
const attributesToIgnore = ["back_number_of_days", "back_number_of_hours", "back_number_of_minutes", "entrydate"];
// Attributes to ignore, if these are changed we don't consider it an edit
const attributesToIgnore = [
"back_number_of_days",
"back_number_of_hours",
"back_number_of_minutes",
"entrydate",
"status",
];

// Omit the attributes to ignore
const complaint1Filtered = omit(complaint1, attributesToIgnore);
Expand Down
7 changes: 5 additions & 2 deletions charts/app/Chart.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@ dependencies:
- name: postgresql
repository: https://charts.bitnami.com/bitnami
version: 15.5.13
digest: sha256:e29db8b50c7ad4e611c43b4590506d2172ac278b08f015fe0240ba123f2166ec
generated: "2024-07-03T12:48:59.269045601Z"
- name: nats
repository: https://nats-io.github.io/k8s/helm/charts/
version: 1.1.12
digest: sha256:daadb6fa80ea04bc755dfeae1b823ce70b60f7bc3326ab9c40b3768bb2d5d9aa
generated: "2024-10-08T14:08:20.367635823-07:00"
1 change: 1 addition & 0 deletions charts/app/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,6 @@ Selector labels
{{- define "selectorLabels" -}}
app.kubernetes.io/name: {{ include "fullname" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app: {{ .Release.Name }}
{{- end }}

5 changes: 1 addition & 4 deletions charts/app/templates/backend/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ spec:
metadata:
annotations:
rollme: {{ randAlphaNum 5 | quote }}
prometheus.io/scrape: 'true'
prometheus.io/port: '3000'
prometheus.io/path: '/api/metrics'
labels:
{{- include "backend.labels" . | nindent 8 }}
spec:
Expand Down Expand Up @@ -125,4 +122,4 @@ spec:
- {{ .Release.Name }}
topologyKey: "kubernetes.io/hostname"

{{- end }}
{{- end }}
Loading

0 comments on commit 4f34914

Please sign in to comment.