Skip to content

Commit

Permalink
Merge pull request #46 from bcgov/dev
Browse files Browse the repository at this point in the history
Release to prod
  • Loading branch information
timwekkenbc authored Nov 12, 2024
2 parents 15a8136 + bdcf37c commit 4c6ad13
Show file tree
Hide file tree
Showing 28 changed files with 466 additions and 78 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-and-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,4 @@ jobs:

- name: Run Helm
run: |
helm upgrade --install brms-frontend ./helm --set image.tag=${{ needs.build_image.outputs.image_tag }}
helm upgrade --install brm-app ./helm --set image.tag=${{ needs.build_image.outputs.image_tag }}
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

# BRMS Simulator Frontend (POC)
# BRM (Business Rules Management) App

This is a tool for testing/simulating rules for SDPR's Business Rules Engine. It is a [Next.js](https://nextjs.org/) project that makes use of the [GoRules JDM Editor](https://github.com/gorules/jdm-editor). This project is currently just in the experimental POC phase.
This app is a tool for authoring and testing/simulating rules for SDPR's Business Rules Engine. It is a [Next.js](https://nextjs.org/) project that makes use of a custom fork of the [GoRules JDM Editor](https://github.com/gorules/jdm-editor) (located at https://github.com/bcgov/jdm-editor). You can read more about working with our custom JDM Editor fork [here](https://knowledge.social.gov.bc.ca/successor/bre/jdm-editor).

## Requirements

This project current depends on the API provided by the [brms-api](https://github.com/bcgov/brms-api) project. You'll have to set an environment variable of `NEXT_PUBLIC_SERVER_URL` pointing to the URL of that when it is up and running (like `http://localhost:3000`).
This project current depends on the API provided by the [brm-backend](https://github.com/bcgov/brm-backend) project. You'll have to set an environment variable of `NEXT_PUBLIC_SERVER_URL` pointing to the URL of that when it is up and running (like `http://localhost:3000`).

## Getting it running

Expand Down
5 changes: 3 additions & 2 deletions app/admin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Table, Input, Button, Flex, Tooltip } from "antd";
import { ColumnsType, TablePaginationConfig } from "antd/es/table";
import { FilterValue } from "antd/es/table/interface";
import { HomeOutlined } from "@ant-design/icons";
import { logError } from "@/app/utils/logger";
import { RuleInfo, RuleInfoBasic } from "../types/ruleInfo";
import { getAllRuleData, postRuleData, updateRuleData, deleteRuleData } from "../utils/api";

Expand Down Expand Up @@ -76,7 +77,7 @@ export default function Admin() {
try {
await updateRuleData(rule._id, rule);
} catch (error) {
console.error(`Error reseting draft for rule ${rule._id}: ${error}`);
logError(`Error reseting draft for rule ${rule._id}: ${error}`);
} finally {
setIsLoading(false);
}
Expand Down Expand Up @@ -127,7 +128,7 @@ export default function Admin() {
}
}
} catch (error) {
console.error(`Error performing action ${action} on rule ${rule._id}: ${error}`);
logError(`Error performing action ${action} on rule ${rule._id}: ${error}`);
}
})
);
Expand Down
22 changes: 22 additions & 0 deletions app/api/logError/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
interface ErrorRequest {
error: string;
errorInfo?: string;
}

export async function POST(req: Request): Promise<Response> {
try {
const { error, errorInfo }: ErrorRequest = await req.json();
console.error({ error, errorInfo });
// Respond back to the client that error has been logged
return new Response(JSON.stringify({ status: "Error logged successfully" }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
} catch (err) {
console.error("Error processing log request:", { err });
return new Response(JSON.stringify({ message: "Internal Server Error" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
}
4 changes: 2 additions & 2 deletions app/components/ErrorBoundary/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";
import { Alert } from "antd";
import React from "react";
import { logError } from "@/app/utils/logger";

interface ErrorBoundaryState {
hasError: boolean;
Expand All @@ -19,8 +20,7 @@ class ErrorBoundary extends React.Component<{ children: React.ReactNode }, Error
}

componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
// Log to any new error reporting service here
console.error("Uncaught error:", error, errorInfo);
// logError(error.message, errorInfo);
}

render() {
Expand Down
3 changes: 2 additions & 1 deletion app/components/InputOutputTable/InputOutputTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { MinusCircleOutlined } from "@ant-design/icons";
import { RuleMap } from "@/app/types/rulemap";
import styles from "./InputOutputTable.module.css";
import { dollarFormat } from "@/app/utils/utils";
import { logError } from "@/app/utils/logger";
import FieldStyler from "../InputStyler/subcomponents/FieldStyler";

const COLUMNS = [
Expand Down Expand Up @@ -55,7 +56,7 @@ export default function InputOutputTable({
if (typeof setRawData === "function") {
setRawData(updatedData);
} else {
console.error("setRawData is not a function or is undefined");
logError("setRawData is not a function or is undefined");
}
};

Expand Down
3 changes: 2 additions & 1 deletion app/components/InputStyler/InputStyler.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Scenario } from "@/app/types/scenario";
import { getFieldValidation } from "@/app/utils/utils";
import { logError } from "@/app/utils/logger";
import {
DefaultInput,
ObjectArrayInput,
Expand Down Expand Up @@ -84,7 +85,7 @@ export default function InputStyler(
if (typeof setRawData === "function") {
setRawData(updatedData);
} else {
console.error("setRawData is not a function or is undefined");
logError("setRawData is not a function or is undefined");
}
};

Expand Down
3 changes: 2 additions & 1 deletion app/components/RuleManager/RuleManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Scenario } from "@/app/types/scenario";
import useLeaveScreenPopup from "@/app/hooks/useLeaveScreenPopup";
import { DEFAULT_RULE_CONTENT } from "@/app/constants/defaultRuleContent";
import { RULE_VERSION } from "@/app/constants/ruleVersion";
import { logError } from "@/app/utils/logger";
import SavePublish from "../SavePublish";
import ScenariosManager from "../ScenariosManager";
import styles from "./RuleManager.module.css";
Expand Down Expand Up @@ -116,7 +117,7 @@ export default function RuleManager({
setResultsOfSimulation(data?.result);
} catch (e: any) {
message.error("Error during simulation run: " + e, 10);
console.error("Error during simulation run:", e);
logError("Error during simulation run:", e);
}
} else {
// Reset the result if there is no contextToSimulate (used to reset the trace)
Expand Down
9 changes: 5 additions & 4 deletions app/components/RuleViewerEditor/RuleViewerEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { SchemaSelectProps, PanelType } from "@/app/types/jdm-editor";
import { Scenario, Variable } from "@/app/types/scenario";
import { downloadFileBlob } from "@/app/utils/utils";
import { getScenariosByFilename } from "@/app/utils/api";
import { logError } from "@/app/utils/logger";
import LinkRuleComponent from "./subcomponents/LinkRuleComponent";
import SimulatorPanel from "./subcomponents/SimulatorPanel";
import RuleInputOutputFieldsComponent from "./subcomponents/RuleInputOutputFieldsComponent";
Expand Down Expand Up @@ -97,8 +98,8 @@ export default function RuleViewerEditor({
...scenarioObject,
};
return downloadJSON(updatedJSON, jsonFilename);
} catch (error) {
console.error("Error fetching JSON:", error);
} catch (error: any) {
logError("Error fetching JSON:", error);
throw error;
}
};
Expand All @@ -108,8 +109,8 @@ export default function RuleViewerEditor({
event.preventDefault();
try {
await handleScenarioInsertion();
} catch (error) {
console.error("Error intercepting JSON download:", error);
} catch (error: any) {
logError("Error intercepting JSON download:", error);
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { GraphNodeProps } from "@gorules/jdm-editor";
import { SchemaSelectProps } from "@/app/types/jdm-editor";
import { KlammBREField } from "@/app/types/klamm";
import { getBREFields, getBREFieldFromName } from "@/app/utils/api";
import { logError } from "@/app/utils/logger";
import styles from "./RuleInputOutputFieldsComponent.module.css";

declare type InputOutputField = {
Expand Down Expand Up @@ -60,8 +61,8 @@ export default function RuleInputOutputFieldsComponent({
setInputOutputOptions(newInputOutputOptions);
}
setIsLoading(false);
} catch (error) {
console.error("Error:", error);
} catch (error: any) {
logError("Error getting fields from Klamm:", error);
}
};
// Before searching, first set the options to empty and isLoading to true while we wait
Expand Down Expand Up @@ -229,8 +230,8 @@ export default function RuleInputOutputFieldsComponent({
});

message.success("Fields refreshed successfully from Klamm");
} catch (error) {
console.error("Error refreshing fields from Klamm:", error);
} catch (error: any) {
logError("Error refreshing fields from Klamm:", error);
message.error("Failed to refresh fields from Klamm");
} finally {
setIsLoading(false);
Expand Down
5 changes: 3 additions & 2 deletions app/components/SavePublish/SavePublish.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { DecisionGraphType } from "@gorules/jdm-editor";
import { RuleInfo } from "@/app/types/ruleInfo";
import { updateRuleData } from "@/app/utils/api";
import { sendRuleForReview } from "@/app/utils/githubApi";
import { logError } from "@/app/utils/logger";
import NewReviewForm from "./NewReviewForm";
import SavePublishWarnings from "./SavePublishWarnings";
import styles from "./SavePublish.module.css";
Expand Down Expand Up @@ -55,8 +56,8 @@ export default function SavePublish({ ruleInfo, ruleContent, setHasSaved }: Save
setCurrReviewBranch(newReviewBranch);
}
message.success("Review updated/created");
} catch (e) {
console.error("Unable to update/create review");
} catch (e: any) {
logError("Unable to update/create review", e);
message.error("Unable to update/create review");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Flex, Button, message, InputNumber, Collapse, Spin } from "antd";
import { Scenario } from "@/app/types/scenario";
import { getCSVTests } from "@/app/utils/api";
import { RuleMap } from "@/app/types/rulemap";
import { logError } from "@/app/utils/logger";
import ScenarioFormatter from "../ScenarioFormatter";
import styles from "./IsolationTester.module.css";
import { DecisionGraphType } from "@gorules/jdm-editor";
Expand Down Expand Up @@ -35,9 +36,9 @@ export default function IsolationTester({
setLoading(true);
const csvContent = await getCSVTests(jsonFile, ruleContent, simulationContext, testScenarioCount);
message.success(`Scenario Tests: ${csvContent}`);
} catch (error) {
} catch (error: any) {
message.error("Error downloading scenarios.");
console.error("Error:", error);
logError("Error:", error);
} finally {
setLoading(false);
}
Expand Down
11 changes: 6 additions & 5 deletions app/components/ScenariosManager/ScenarioCSV/ScenarioCSV.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { useState } from "react";
import { Button, Flex, Upload, message } from "antd";
import { UploadOutlined } from "@ant-design/icons";
import { DecisionGraphType } from "@gorules/jdm-editor";
import styles from "./ScenarioCSV.module.css";
import { logError } from "@/app/utils/logger";
import { uploadCSVAndProcess, getCSVForRuleRun } from "@/app/utils/api";
import styles from "./ScenarioCSV.module.css";

interface ScenarioCSVProps {
jsonFile: string;
Expand All @@ -22,19 +23,19 @@ export default function ScenarioCSV({ jsonFile, ruleContent }: ScenarioCSVProps)
try {
const csvContent = await uploadCSVAndProcess(file, jsonFile, ruleContent);
message.success(`Scenarios Test: ${csvContent}`);
} catch (error) {
} catch (error: any) {
message.error("Error processing scenarios.");
console.error("Error:", error);
logError("Error:", error);
}
};

const handleDownloadScenarios = async () => {
try {
const csvContent = await getCSVForRuleRun(jsonFile, ruleContent);
message.success(`Scenario Testing Template: ${csvContent}`);
} catch (error) {
} catch (error: any) {
message.error("Error downloading scenarios.");
console.error("Error:", error);
logError("Error:", error);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { createScenario, updateScenario } from "@/app/utils/api";
import { RuleMap } from "@/app/types/rulemap";
import ScenarioFormatter from "../ScenarioFormatter";
import { getScenariosByFilename } from "@/app/utils/api";
import { logError } from "@/app/utils/logger";
import styles from "./ScenarioGenerator.module.css";

interface ScenarioGeneratorProps {
Expand Down Expand Up @@ -81,8 +82,8 @@ export default function ScenarioGenerator({
}
updateScenarios();
setActiveTabKey?.(scenariosManagerTabs.ScenariosTab);
} catch (error) {
console.error("Error creating scenario:", error);
} catch (error: any) {
logError("Error creating scenario:", error);
}
};

Expand Down
5 changes: 3 additions & 2 deletions app/hooks/getRuleDataForVersion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { RULE_VERSION } from "../constants/ruleVersion";
import { getFileAsJsonIfAlreadyExists } from "../utils/githubApi";
import { getRuleDraft, getDocument, getRuleDataById } from "../utils/api";
import { DEFAULT_RULE_CONTENT } from "../constants/defaultRuleContent";
import { logError } from "@/app/utils/logger";

export default async function getRuleDataForVersion(ruleId: string, version?: string) {
// Get rule data
Expand Down Expand Up @@ -42,8 +43,8 @@ export default async function getRuleDataForVersion(ruleId: string, version?: st
default:
ruleContent = await getDocument(ruleInfo.filepath);
}
} catch (error) {
console.error("Error fetching rule content:", error);
} catch (error: any) {
logError("Error fetching rule content:", error);
}

return { ruleInfo, ruleContent };
Expand Down
3 changes: 2 additions & 1 deletion app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from "@ant-design/icons";
import { RuleInfo } from "./types/ruleInfo";
import { getAllRuleData } from "./utils/api";
import { logError } from "./utils/logger";
import styles from "./styles/home.module.css";

interface TableParams {
Expand Down Expand Up @@ -59,7 +60,7 @@ export default function Home() {
},
});
} catch (error) {
console.error(`Error loading rules: ${error}`);
logError(`Error loading rules: ${error}`);
} finally {
setLoading(false);
}
Expand Down
5 changes: 3 additions & 2 deletions app/rule/new/NewRule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import RuleHeader from "@/app/components/RuleHeader";
import RuleManager from "../../components/RuleManager";
import { RULE_VERSION } from "@/app/constants/ruleVersion";
import { postRuleData } from "@/app/utils/api";
import { logError } from "@/app/utils/logger";

export default function NewRule() {
const [openNewRuleModal, setOpenNewRuleModal] = useState(false);
Expand All @@ -27,8 +28,8 @@ export default function NewRule() {
message.success("New draft created");
setRuleInfo(updatedRuleInfo);
window.location.href = `/rule/${updatedRuleInfo._id}?version=draft`;
} catch (e) {
console.error("Error updating rule", e);
} catch (e: any) {
logError("Error updating rule", e);
message.error("Unable to create new draft");
}
};
Expand Down
Loading

0 comments on commit 4c6ad13

Please sign in to comment.