Repository: Enterprise-CMCS/macpro-mdct-mcr
Pull request #12155: [CMDCT-4623] MCPAR Program Name Update - July 2025 Change
Author: login: ntsummers1
Labels: name: ready for review
description: Ready for all the reviews!
Created: 2025-05-05T21:55:20Z | Merged: 2025-05-06T19:30:27Z

### Description
<!-- Detailed description of changes and related context -->

Hello! And welcome to the MCPAR Program Name Update. I'm you're host Nick (He/Him/His) and today I'm going to talk about the wonderful world of Program Names. You might be asking yourself "Nick, what has changed? What is happening in MCPAR?" Well you beautiful person you, we're updating the way the program name is set for a report. Gone are the day's where theres one text field and a user can type out what the report will be called. Instead, there has has been a request to add a slight barrier to entry when trying to manually set a report name. They'd like the user to choose from a premade list of report names instead. Of course, if you really need to, a user can still add their own name if they choose. Or they can take one of the premade choices and offer a suggestion on what should be added! Its all excellent stuff. Truly legendary. Much wow.

So whats that look like? Fear not! I've recorded a video of all those above words to be condensed an an easy to view format. Truly the gods have smiled upon us because I can stop typing out this ridiculous, introspective(? Or just wild look into a sleep deprived mind?) meta commentary and actually help you on your quest to make accessible, easy to understand applications that benefit the masses. I.E. Shut up me, heres the video!

https://github.com/user-attachments/assets/fe575632-5067-44e8-8931-8ad268deb07f


### Related ticket(s)
<!-- Link to related ticket(s) or issue(s) -->
<!-- Hint: Type CMDCT-<ticket-number> for autolinking -->
CMDCT-4623

---
### How to test
<!-- Step-by-step instructions on how to test, if necessary -->
Enter the MCPAR and go about creating a report! 
Try to break the validation
Create a report and open it again to change this to make sure you can edit
Select the options, suggest all the things!

---
### Pre-review checklist
<!-- Complete the following steps before opening for review -->
- [x] I have added [thorough](https://shorturl.at/aejkF) tests, if necessary
- [x] I have updated relevant documentation, if necessary
- [x] I have performed a self-review of my code
- [x] I have manually tested this PR in the deployed cloud environment

---
### Pre-merge checklist
<!-- Complete the following steps before merging -->

#### Review
- [x] Design: This work has been reviewed and approved by design, if necessary
- [x] Product: This work has been reviewed and approved by product owner, if necessary



Diff:
diff --git a/logs/launchdarkly-flags.log b/logs/launchdarkly-flags.log
index d15374155..097c05547 100644
--- a/logs/launchdarkly-flags.log
+++ b/logs/launchdarkly-flags.log
@@ -4,8 +4,8 @@
 ./services/ui-src/src/components/app/AppRoutes.tsx:30:useFlags()?.naaarReport;
 ./services/ui-src/src/components/cards/TemplateCard.tsx:33:useFlags()?.naaarReport;
 ./services/ui-src/src/components/forms/AdminDashSelector.tsx:40:useFlags()?.naaarReport;
-./services/ui-src/src/components/modals/AddEditReportModal.tsx:44:useFlags()?.naaarReport;
-./services/ui-src/src/components/pages/Dashboard/DashboardPage.tsx:214:useFlags()?.sortableDashboardTable;
+./services/ui-src/src/components/modals/AddEditReportModal.tsx:49:useFlags()?.naaarReport;
+./services/ui-src/src/components/pages/Dashboard/DashboardPage.tsx:240:useFlags()?.sortableDashboardTable;
 
 # LaunchDarkly flags in tests
 ./services/ui-src/src/components/app/AppRoutes.test.tsx:142:mockLDFlags.set({ naaarReport: true });
diff --git a/services/app-api/utils/testing/setupJest.ts b/services/app-api/utils/testing/setupJest.ts
index 7336f2fd7..9d2c7481a 100644
--- a/services/app-api/utils/testing/setupJest.ts
+++ b/services/app-api/utils/testing/setupJest.ts
@@ -66,6 +66,13 @@ export const mockDynamoDataCompleted: MCPARReportMetadata = {
   ...mockReportKeys,
   reportType: "MCPAR",
   programName: "testProgram",
+  newOrExistingProgram: [
+    {
+      value: "Add new program",
+      key: "newOrExistingProgram-isNewProgram",
+    },
+  ],
+  newProgramName: "testProgram",
   status: "Not started",
   reportingPeriodStartDate: 162515200000,
   reportingPeriodEndDate: 168515200000,
diff --git a/services/app-api/utils/types/reportContext.ts b/services/app-api/utils/types/reportContext.ts
index 7af9843b1..e52d4c98d 100644
--- a/services/app-api/utils/types/reportContext.ts
+++ b/services/app-api/utils/types/reportContext.ts
@@ -1,6 +1,12 @@
 // REPORT PROVIDER/CONTEXT
 
-import { AnyObject, Choice, ErrorVerbiage, ReportJson } from "./index";
+import {
+  AnyObject,
+  Choice,
+  ErrorVerbiage,
+  ReportJson,
+  SelectedOption,
+} from "./index";
 
 export interface ReportKeys {
   reportType: string;
@@ -32,6 +38,10 @@ export interface ReportMetadataShape extends ReportKeys {
   previousRevisions: string[];
   planTypeIncludedInProgram?: Choice[];
   "planTypeIncludedInProgram-otherText"?: string;
+  newOrExistingProgram?: Choice[];
+  existingProgramNameSelection?: SelectedOption;
+  existingProgramNameSuggestion?: string;
+  newProgramName?: string;
 }
 
 export interface ReportShape extends ReportMetadataShape {
diff --git a/services/app-api/utils/types/reports.ts b/services/app-api/utils/types/reports.ts
index 59466ed4a..9f79ce7bc 100644
--- a/services/app-api/utils/types/reports.ts
+++ b/services/app-api/utils/types/reports.ts
@@ -8,6 +8,7 @@ import {
   EntityType,
   ScreenReaderCustomHeaderName,
   TableContentShape,
+  SelectedOption,
 } from "./index";
 
 // REPORT TYPES
@@ -251,6 +252,10 @@ export interface MCPARReportMetadata extends ReportMetadata {
   dueDate: number;
   combinedData: boolean;
   programIsPCCM: Choice[];
+  newOrExistingProgram: Choice[];
+  existingProgramNameSelection?: SelectedOption;
+  existingProgramNameSuggestion?: string;
+  newProgramName?: string;
 }
 
 export interface NAAARReportMetadata extends ReportMetadata {
diff --git a/services/app-api/utils/validation/completionSchemaMap.ts b/services/app-api/utils/validation/completionSchemaMap.ts
index c22023749..8808c6a67 100644
--- a/services/app-api/utils/validation/completionSchemaMap.ts
+++ b/services/app-api/utils/validation/completionSchemaMap.ts
@@ -15,6 +15,7 @@ export const completionSchemaMap: any = {
   date: schema.date(),
   dateOptional: schema.dateOptional(),
   dropdown: schema.dropdown(),
+  dropdownOptional: schema.dropdownOptional(),
   checkbox: schema.checkbox(),
   checkboxOneOptional: schema.checkboxOneOptional(),
   checkboxOptional: schema.checkboxOptional(),
diff --git a/services/app-api/utils/validation/completionSchemas.test.ts b/services/app-api/utils/validation/completionSchemas.test.ts
index 478167c94..6d57d44f6 100644
--- a/services/app-api/utils/validation/completionSchemas.test.ts
+++ b/services/app-api/utils/validation/completionSchemas.test.ts
@@ -6,6 +6,7 @@ import {
   numberNotLessThanOne,
   numberNotLessThanZero,
   validNAValues,
+  dropdownOptional,
 } from "./completionSchemas";
 
 describe("Schemas", () => {
@@ -69,72 +70,74 @@ describe("Schemas", () => {
 
   const badValidNumberTestCases = ["N/A", "number", "foo"];
 
-  const testNumberSchema = (
+  const testSchema = async (
     schemaToUse: MixedSchema,
-    testCases: Array<string>,
+    testCases: Array<any>,
     expectedReturn: boolean
   ) => {
     for (let testCase of testCases) {
-      let test = schemaToUse.isValidSync(testCase);
-      expect(test).toEqual(expectedReturn);
-    }
-  };
-
-  const testValidNumber = (
-    schemaToUse: MixedSchema,
-    testCases: Array<string | number>,
-    expectedReturn: boolean
-  ) => {
-    for (let testCase of testCases) {
-      let test = schemaToUse.isValidSync(testCase);
+      let test = await schemaToUse.isValid(testCase);
       expect(test).toEqual(expectedReturn);
     }
   };
 
   test("Evaluate Number Schema using number scheme", () => {
-    testNumberSchema(number(), goodNumberTestCases, true);
-    testNumberSchema(number(), badNumberTestCases, false);
+    testSchema(number(), goodNumberTestCases, true);
+    testSchema(number(), badNumberTestCases, false);
   });
 
   // testing numberNotLessThanOne scheme
   test("Evaluate Number Schema using numberNotLessThanOne scheme", () => {
-    testNumberSchema(numberNotLessThanOne(), goodPositiveNumberTestCases, true);
-    testNumberSchema(numberNotLessThanOne(), badNumberTestCases, false);
+    testSchema(numberNotLessThanOne(), goodPositiveNumberTestCases, true);
+    testSchema(numberNotLessThanOne(), badNumberTestCases, false);
   });
 
   test("Test zero values using numberNotLessThanOne scheme", () => {
-    testNumberSchema(numberNotLessThanOne(), zeroTest, false);
+    testSchema(numberNotLessThanOne(), zeroTest, false);
   });
 
   test("Test negative values using numberNotLessThanOne scheme", () => {
-    testNumberSchema(numberNotLessThanOne(), negativeNumberTestCases, false);
+    testSchema(numberNotLessThanOne(), negativeNumberTestCases, false);
   });
 
   // testing numberNotLessThanZero scheme
   test("Evaluate Number Schema using numberNotLessThanZero scheme", () => {
-    testNumberSchema(
-      numberNotLessThanZero(),
-      goodPositiveNumberTestCases,
-      true
-    );
-    testNumberSchema(numberNotLessThanZero(), badNumberTestCases, false);
+    testSchema(numberNotLessThanZero(), goodPositiveNumberTestCases, true);
+    testSchema(numberNotLessThanZero(), badNumberTestCases, false);
   });
 
   test("Test zero values using numberNotLessThanZero scheme", () => {
-    testNumberSchema(numberNotLessThanZero(), zeroTest, true);
+    testSchema(numberNotLessThanZero(), zeroTest, true);
   });
 
   test("Test negative values using numberNotLessThanZero scheme", () => {
-    testNumberSchema(numberNotLessThanZero(), negativeNumberTestCases, false);
+    testSchema(numberNotLessThanZero(), negativeNumberTestCases, false);
   });
 
   test("Evaluate Number Schema using ratio scheme", () => {
-    testNumberSchema(ratio(), goodRatioTestCases, true);
-    testNumberSchema(ratio(), badRatioTestCases, false);
+    testSchema(ratio(), goodRatioTestCases, true);
+    testSchema(ratio(), badRatioTestCases, false);
   });
 
   test("Test validNumber schema", () => {
-    testValidNumber(validNumber(), goodValidNumberTestCases, true);
-    testValidNumber(validNumber(), badValidNumberTestCases, false);
+    testSchema(validNumber(), goodValidNumberTestCases, true);
+    testSchema(validNumber(), badValidNumberTestCases, false);
+  });
+
+  test("Test DropdownOptional schema", () => {
+    const goodDropdownTestCases = [
+      undefined,
+      { label: "Select", value: "" },
+      { label: "Select", value: "Actual value" },
+    ];
+    const badDropdownTestCases = [
+      "",
+      { label: "", value: "" },
+      { label: "", value: "Actual value" },
+      1,
+      null,
+    ];
+    testSchema(dropdownOptional(), goodDropdownTestCases, true);
+    testSchema(dropdownOptional(), badDropdownTestCases, false);
   });
 });
diff --git a/services/app-api/utils/validation/completionSchemas.ts b/services/app-api/utils/validation/completionSchemas.ts
index 0e122f80d..8012a1d47 100644
--- a/services/app-api/utils/validation/completionSchemas.ts
+++ b/services/app-api/utils/validation/completionSchemas.ts
@@ -217,6 +217,22 @@ export const dropdown = () =>
   object({ label: textSchema(), value: textSchema() }).required(
     error.REQUIRED_GENERIC
   );
+export const dropdownOptional = () =>
+  mixed().test({
+    message: error.INVALID_GENERIC,
+    test: (val) => {
+      switch (typeof val) {
+        case "object":
+          return object({ label: textSchema(), value: string() })
+            .required()
+            .isValid(val);
+        case "undefined":
+          return true;
+        default:
+          return false;
+      }
+    },
+  });
 
 // CHECKBOX
 export const checkbox = () =>
diff --git a/services/app-api/utils/validation/schemaMap.ts b/services/app-api/utils/validation/schemaMap.ts
index 81d2e089d..fbf06c999 100644
--- a/services/app-api/utils/validation/schemaMap.ts
+++ b/services/app-api/utils/validation/schemaMap.ts
@@ -186,6 +186,11 @@ export const isEndDateAfterStartDate = (
 
 // DROPDOWN
 export const dropdown = () => object({ label: text(), value: text() });
+export const dropdownOptional = () =>
+  object({
+    label: text().notRequired().nullable(),
+    value: text().notRequired().nullable(),
+  });
 
 // CHECKBOX
 export const checkbox = () =>
@@ -251,6 +256,7 @@ export const schemaMap: any = {
   date: date(),
   dateOptional: dateOptional(),
   dropdown: dropdown(),
+  dropdownOptional: dropdownOptional(),
   dynamic: dynamic(),
   dynamicOptional: dynamicOptional(),
   email: email(),
diff --git a/services/app-api/utils/validation/schemas.ts b/services/app-api/utils/validation/schemas.ts
index 09b037b96..b5b863369 100644
--- a/services/app-api/utils/validation/schemas.ts
+++ b/services/app-api/utils/validation/schemas.ts
@@ -1,7 +1,15 @@
 import * as yup from "yup";
-import { radioOptional, textOptional } from "./completionSchemas";
+import {
+  dropdownOptional,
+  radioOptional,
+  textOptional,
+} from "./completionSchemas";
 
 export const metadataValidationSchema = yup.object().shape({
+  newOrExistingProgram: radioOptional(),
+  existingProgramNameSelection: dropdownOptional(),
+  existingProgramNameSuggestion: yup.string(),
+  newProgramName: yup.string(),
   programName: yup.string(),
   reportType: yup.string(),
   locked: yup.bool(),
diff --git a/services/ui-src/src/components/fields/DropdownField.tsx b/services/ui-src/src/components/fields/DropdownField.tsx
index 5100098b7..56a529bb5 100644
--- a/services/ui-src/src/components/fields/DropdownField.tsx
+++ b/services/ui-src/src/components/fields/DropdownField.tsx
@@ -11,6 +11,7 @@ import { Box } from "@chakra-ui/react";
 import { ReportContext, EntityContext } from "components";
 // constants
 import { dropdownDefaultOptionText, dropdownNoReports } from "../../constants";
+import { mcparProgramList } from "forms/addEditMcparReport/mcparProgramList";
 // types
 import {
   AnyObject,
@@ -76,6 +77,13 @@ export const DropdownField = ({
             value: report.fieldDataId,
           })) ?? [];
       }
+    } else if (options === "programList") {
+      dropdownOptions = mcparProgramList[
+        state as keyof typeof mcparProgramList
+      ].map((option) => ({
+        label: option.label,
+        value: option.label,
+      }));
     } else if (typeof options === "string") {
       dropdownOptions =
         report?.fieldData[options]?.map((option: EntityShape) => ({
diff --git a/services/ui-src/src/components/modals/AddEditReportModal.test.tsx b/services/ui-src/src/components/modals/AddEditReportModal.test.tsx
index 40d36188c..5fbb496d9 100644
--- a/services/ui-src/src/components/modals/AddEditReportModal.test.tsx
+++ b/services/ui-src/src/components/modals/AddEditReportModal.test.tsx
@@ -71,6 +71,8 @@ const modalComponent = (
 const mockSelectedMcparReport = {
   ...mockMcparReport,
   fieldData: {
+    newProgramName: mockMcparReport.programName,
+    newOrExistingProgram: mockMcparReport.newOrExistingProgram,
     programName: mockMcparReport.programName,
     reportingPeriodEndDate: convertDateUtcToEt(
       mockMcparReport.reportingPeriodEndDate
@@ -220,7 +222,11 @@ describe("<AddEditProgramModal />", () => {
     });
 
     const fillForm = async (form: any) => {
-      const programNameField = form.querySelector("[name='programName']")!;
+      const isNewProgram = screen.getByLabelText(
+        "Add new program"
+      ) as HTMLInputElement;
+      await userEvent.click(isNewProgram);
+      const programNameField = form.querySelector("[name='newProgramName']")!;
       await userEvent.type(programNameField, "fake program name");
       const startDateField = form.querySelector(
         "[name='reportingPeriodStartDate']"
@@ -269,13 +275,20 @@ describe("<AddEditProgramModal />", () => {
         "[name='programIsPCCM']"
       )!;
 
+      const newOrExistingProgram = form.querySelectorAll(
+        "[name='newOrExistingProgram']"
+      )!;
+
+      expect(newOrExistingProgram[0]).toHaveProperty("checked", false);
+      expect(newOrExistingProgram[1]).toHaveProperty("checked", true);
+
       // yoy copy and pccm fields are disabled
       expect(copyFieldDataSourceId).toHaveProperty("disabled", true);
       expect(programIsPCCMField[0]).toHaveProperty("disabled", true);
       expect(programIsPCCMField[1]).toHaveProperty("disabled", true);
 
       // hydrated values are in the modal
-      const programNameField = form.querySelector("[name='programName']")!;
+      const programNameField = form.querySelector("[name='newProgramName']")!;
       const startDateField = form.querySelector(
         "[name='reportingPeriodStartDate']"
       )!;
diff --git a/services/ui-src/src/components/modals/AddEditReportModal.tsx b/services/ui-src/src/components/modals/AddEditReportModal.tsx
index 22f2a8dd6..90614f1eb 100644
--- a/services/ui-src/src/components/modals/AddEditReportModal.tsx
+++ b/services/ui-src/src/components/modals/AddEditReportModal.tsx
@@ -4,7 +4,11 @@ import { useFlags } from "launchdarkly-react-client-sdk";
 import { Form, Modal, ReportContext } from "components";
 import { Spinner } from "@chakra-ui/react";
 // constants
-import { DEFAULT_ANALYSIS_METHODS, States } from "../../constants";
+import {
+  DEFAULT_ANALYSIS_METHODS,
+  dropdownDefaultOptionText,
+  States,
+} from "../../constants";
 // form
 import mcparFormJson from "forms/addEditMcparReport/addEditMcparReport.json";
 import mlrFormJson from "forms/addEditMlrReport/addEditMlrReport.json";
@@ -22,6 +26,7 @@ import {
   calculateDueDate,
   convertDateEtToUtc,
   convertDateUtcToEt,
+  defineProgramName,
   otherSpecify,
   useStore,
 } from "utils";
@@ -84,7 +89,22 @@ export const AddEditReportModal = ({
 
   // MCPAR report payload
   const prepareMcparPayload = (formData: any) => {
-    const programName = formData["programName"];
+    const newOrExistingProgram = formData["newOrExistingProgram"];
+    const existingProgramNameSelection = formData[
+      "existingProgramNameSelection"
+    ] || {
+      label: dropdownDefaultOptionText,
+      value: "",
+    };
+    const existingProgramNameSuggestion =
+      formData["existingProgramNameSuggestion"] || "";
+    const newProgramName = formData["newProgramName"] || "";
+
+    const programName = defineProgramName(
+      newOrExistingProgram,
+      existingProgramNameSelection,
+      newProgramName
+    );
     const copyFieldDataSourceId = formData["copyFieldDataSourceId"];
     const dueDate = calculateDueDate(formData["reportingPeriodEndDate"]);
     const combinedData = formData["combinedData"] || false;
@@ -109,6 +129,10 @@ export const AddEditReportModal = ({
         locked: false,
         submissionCount: 0,
         previousRevisions: [],
+        newOrExistingProgram,
+        existingProgramNameSelection,
+        existingProgramNameSuggestion,
+        newProgramName,
       },
       fieldData: {
         reportingPeriodStartDate: convertDateUtcToEt(reportingPeriodStartDate),
diff --git a/services/ui-src/src/components/pages/Dashboard/DashboardPage.tsx b/services/ui-src/src/components/pages/Dashboard/DashboardPage.tsx
index 2a70c4780..8f59c61d7 100644
--- a/services/ui-src/src/components/pages/Dashboard/DashboardPage.tsx
+++ b/services/ui-src/src/components/pages/Dashboard/DashboardPage.tsx
@@ -24,7 +24,13 @@ import {
   SortableDashboardTable,
 } from "components";
 // types
-import { AnyObject, ReportMetadataShape, ReportKeys, ReportShape } from "types";
+import {
+  AnyObject,
+  ReportMetadataShape,
+  ReportKeys,
+  ReportShape,
+  ReportType,
+} from "types";
 // utils
 import {
   convertDateUtcToEt,
@@ -162,6 +168,10 @@ export const DashboardPage = ({ reportType }: Props) => {
           planTypeIncludedInProgram: report?.planTypeIncludedInProgram,
           "planTypeIncludedInProgram-otherText":
             report?.["planTypeIncludedInProgram-otherText"],
+          newOrExistingProgram: report?.newOrExistingProgram,
+          existingProgramNameSelection: report?.existingProgramNameSelection,
+          existingProgramNameSuggestion: report?.existingProgramNameSuggestion,
+          newProgramName: report?.newProgramName,
         },
         state: report.state,
         id: report.id,
@@ -169,6 +179,22 @@ export const DashboardPage = ({ reportType }: Props) => {
         submitterEmail: report.submitterEmail,
         submittedOnDate: submittedOnDate,
       };
+    } else if (reportType == ReportType.MCPAR) {
+      /*
+       * This elseif is used when a user is creating a brand new report on MCPAR
+       * specifically. We want the program name choicelist to default to an
+       * existing program name. This will hydrate it as such.
+       */
+      formData = {
+        fieldData: {
+          newOrExistingProgram: [
+            {
+              key: "newOrExistingProgram-isExistingProgram",
+              value: "Existing program",
+            },
+          ],
+        },
+      };
     }
     setSelectedReport(formData);
 
diff --git a/services/ui-src/src/forms/addEditMcparReport/addEditMcparReport.json b/services/ui-src/src/forms/addEditMcparReport/addEditMcparReport.json
index 256abf5f0..53679c56d 100644
--- a/services/ui-src/src/forms/addEditMcparReport/addEditMcparReport.json
+++ b/services/ui-src/src/forms/addEditMcparReport/addEditMcparReport.json
@@ -10,11 +10,66 @@
   },
   "fields": [
     {
-      "id": "programName",
-      "type": "text",
-      "validation": "text",
+      "id": "newOrExistingProgram",
+      "type": "radio",
+      "validation": "radio",
       "props": {
-        "label": "Program name (for new MCPAR)"
+        "label": "Is this MCPAR for an existing or new program?",
+        "hint": "Select from an existing program or add a new program.",
+        "choices": [
+          {
+            "id": "isExistingProgram",
+            "label": "Existing program",
+            "children": [
+              {
+                "id": "existingProgramNameSelection",
+                "type": "dropdown",
+                "validation": {
+                  "type": "dropdown",
+                  "nested": true,
+                  "parentFieldName": "newOrExistingProgram"
+                },
+                "props": {
+                  "label": "Program name",
+                  "hint": "Select from an existing program name.",
+                  "options": "programList"
+                }
+              },
+              {
+                "id": "existingProgramNameSuggestion",
+                "type": "text",
+                "validation": {
+                  "type": "textOptional",
+                  "nested": true,
+                  "parentFieldName": "newOrExistingProgram"
+                },
+                "props": {
+                  "label": "Rename selected program (optional)",
+                  "hint": "If you need to replace or rename the selected program, enter its new name. Note: this will not change the name of the program in this report. CMS will update it for a future report."
+                }
+              }
+            ]
+          },
+          {
+            "id": "isNewProgram",
+            "label": "Add new program",
+            "children": [
+              {
+                "id": "newProgramName",
+                "type": "text",
+                "validation": {
+                  "type": "text",
+                  "nested": true,
+                  "parentFieldName": "newOrExistingProgram"
+                },
+                "props": {
+                  "label": "Specify new program name",
+                  "hint": ""
+                }
+              }
+            ]
+          }
+        ]
       }
     },
     {
diff --git a/services/ui-src/src/forms/addEditMcparReport/mcparProgramList.ts b/services/ui-src/src/forms/addEditMcparReport/mcparProgramList.ts
new file mode 100644
index 000000000..72103a396
--- /dev/null
+++ b/services/ui-src/src/forms/addEditMcparReport/mcparProgramList.ts
@@ -0,0 +1,727 @@
+// ESP: program list (MCPAR)
+export const mcparProgramList = {
+  // Alabama
+  AL: [
+    {
+      id: "EIqjAqPHo4tS2geQTeiQrHVz",
+      label: "Alabama Coordinated Health Network (ACHN)",
+    },
+    {
+      id: "24KxJzGtP4NxlUJZrhGJKYEf",
+      label: "Alabama Integrated Care Network (ICN)",
+    },
+  ],
+  // Arkansas
+  AR: [
+    {
+      id: "v3YFWjfOyS69iESjUzy5jsxD",
+      label: "Provider Led Arkansas Shared Savings Entity (PASSE)",
+    },
+    {
+      id: "zaAyFy8QjFIjkpVtQs7LNCVl",
+      label: "Healthy Smiles",
+    },
+  ],
+  // Arizona
+  AZ: [
+    {
+      id: "5EjS7L6RPemb5qADp3aw2pG9",
+      label: "Arizona Complete Care (ACC)",
+    },
+    {
+      id: "wRaU5JxD4eMYHH5hjYFwDzXR",
+      label:
+        "Arizona Long-Term Care System Elderly and Physically Disabled (ALTCS-EPD)",
+    },
+    {
+      id: "ToObVfoavqbE69TPSICPmcJI",
+      label:
+        "Arizona Long-Term Care System Developmentally Disabled (ALTCS-DD)",
+    },
+    {
+      id: "mLhsbQt6FVEcs97UEhCsEDwg",
+      label: "Regional Behavioral Health Authority (RBHA)",
+    },
+    {
+      id: "b92Tk23BTj5XbwA9L6Fvh7BC",
+      label: "Comprehensive Health Plan (CHP)",
+    },
+  ],
+  // California
+  CA: [
+    {
+      id: "rVCN7urNI7SkpzeFlujE8TZn",
+      label: "Dental Managed Care",
+    },
+    {
+      id: "Fd2dPtWxBXfBaamNJxr2sjrO",
+      label: "AIDS Healthcare Foundation",
+    },
+    {
+      id: "M2E1tIoBn385OMRwaMkzYQZz",
+      label: "Drug MediCal - Organized Delivery System",
+    },
+    {
+      id: "hQrSN2BhHAC9U9yqXH4RXLGn",
+      label: "Specialty Mental Health",
+    },
+    {
+      id: "MjfEADVBox5Aotq2idjeft6M",
+      label: "Medi-Cal Managed Care program (MCMC)",
+    },
+  ],
+  // Colorado
+  CO: [
+    {
+      id: "gOCHAKMaw4rqO2iUYwCtVlrf",
+      label: "Accountable Care Collaborative (ACC)",
+    },
+    {
+      id: "B4JCwLTw9P22TuSu0CNj8HpP",
+      label: "Child Health Plan Plus (CHP+)",
+    },
+    {
+      id: "xtGIS3aubFMaiVCtspgb7P0q",
+      label: "Child Health Plan Plus (CHP+) Dental Care",
+    },
+  ],
+  // Delaware
+  DE: [
+    {
+      id: "IfwD2YzbQH2aUwZsD1pesohn",
+      label: "Delaware State Health Plan/Delaware State Health Plan Plus",
+    },
+  ],
+  // Washington, DC
+  DC: [
+    {
+      id: "fALQyWWaCnvIMyXQzI59b1F9",
+      label:
+        "Child and Adolescent Supplemental Security Income Program (CASSIP)",
+    },
+    {
+      id: "UWQwYFT5PndXIdGv0yHOo1Mm",
+      label: "DC Dual Choice D-SNP",
+    },
+    {
+      id: "MJxbwotStcthpiEg4Byc5KmI",
+      label: "District of Columbia Healthy Families Program (DCHFP)",
+    },
+  ],
+  // Florida
+  FL: [
+    {
+      id: "GtPVr3OIOsuwly2q6jRZsGU2",
+      label: "MomCare",
+    },
+    {
+      id: "YI4p6xUUkUVA7smiPuc1IPM7",
+      label: "D-SNP",
+    },
+  ],
+  // Georgia
+  GA: [
+    {
+      id: "Vs6Hir1djWORvNs8DSthy6pr",
+      label: "Georgia Families",
+    },
+    {
+      id: "IAd3zB248HmPVJd03TqJPpey",
+      label: "Georgia Families 360",
+    },
+    {
+      id: "EoikrSmwtoquDRTUv4C8V9Ak",
+      label: "Planning 4 Healthy Babies (P4HB)",
+    },
+    {
+      id: "jjUAdivEbz7rbobt6Bna3jH0",
+      label: "Pathways to Coverage",
+    },
+  ],
+  // Hawaii
+  HI: [
+    {
+      id: "dnKjBFbMv3SeGFtx9Y8GMhTe",
+      label: "Hawaii's QUEST Integration",
+    },
+    {
+      id: "jHfU3f0ICuHeVeHE00MkCllx",
+      label: "Community Care Services",
+    },
+  ],
+  // Idaho
+  ID: [
+    {
+      id: "gHBsWBrgn1AFataQthoaYmnm",
+      label: "Medicare Medicaid Coordinated Plan (MMCP)",
+    },
+    {
+      id: "DTDaMxL8OXHgLg9gLRRN02gX",
+      label: "Idaho Medicaid Plus (IMP)",
+    },
+    {
+      id: "xcPLN8yGw6aAkqK4VTUFJHYy",
+      label: "Idaho Behavioral Health Plan (IBHP)",
+    },
+    {
+      id: "5BA11vA9v6QDT0j3q3g0DEfb",
+      label: "Idaho Smiles",
+    },
+  ],
+  // Illinois
+  IL: [
+    {
+      id: "WBEu2ygvmGslPecHo9AGonCv",
+      label: "HealthChoice Illinois (HCI)",
+    },
+    {
+      id: "fKn31H2YY88dGwTyfrXqHEcm",
+      label: "Medicare-Medicaid Alignment Initiative (MMAI)",
+    },
+  ],
+  // Indiana
+  IN: [
+    {
+      id: "LNslmT5MsKEMU40sozAxvBVr",
+      label: "Healthy Indiana Plan (HIP)",
+    },
+    {
+      id: "sWF52qP8GO6848hunxl0EL9W",
+      label: "Hoosier Care Connect (HCC)",
+    },
+    {
+      id: "EclDc6a3V2AMynlgURas8OCx",
+      label: "Hoosier HealthWise (HHW)",
+    },
+    {
+      id: "SVQtk1ZRIUTfioK9fOl9ikCU",
+      label: "Pathways for Aging",
+    },
+  ],
+  // Iowa
+  IA: [
+    {
+      id: "JYMLHctuTITLQSYINNPhDbaO",
+      label: "Health Link",
+    },
+    {
+      id: "AIRheUY1geIqiumKruePsmJK",
+      label: "Dental Wellness Plan",
+    },
+    {
+      id: "B4fFkG4xYiUS3RAf0azA1btz",
+      label: "CHIP Hawki - Dental",
+    },
+  ],
+  // Kansas
+  KS: [
+    {
+      id: "rOuZXLtZnmHwwKdVi6Gf6Fx6",
+      label: "KanCare",
+    },
+  ],
+  // Kentucky
+  KY: [
+    {
+      id: "OjOZW0vISP2monSyFzoEmEKo",
+      label: "Kentucky Managed Care Organization Program (KYMCO)",
+    },
+  ],
+  // Louisiana
+  LA: [
+    {
+      id: "AyJwP3j6AajNBQ2SfXx2pI9D",
+      label: "Healthy Louisiana",
+    },
+    {
+      id: "bNWq7iTImJo7fdpWxFdGX0EB",
+      label: "Dental Benefit Program (DBP)",
+    },
+    {
+      id: "eNURfrWCAVqJsKD8GHBgBnJ7",
+      label: "Healthy Louisiana Coordinated System of Care Program (CSoC)",
+    },
+  ],
+  // Maine
+  ME: [
+    {
+      id: "HwE48AXxXf6eSHZc7qYlpyYK",
+      label: "Maine Non-Emergency Transportation (NET) Program",
+    },
+    {
+      id: "W2DGFiCmeXM7WuRhz6ugQNKg",
+      label: "Accountable Communities",
+    },
+  ],
+  // Maryland
+  MD: [
+    {
+      id: "yoAMiHu0i2T0lg4SNCvJSdrU",
+      label: "HealthChoice",
+    },
+  ],
+  // Massachusetts
+  MA: [
+    {
+      id: "mZDZkUqIJTzVsYqWwUkCpxDe",
+      label: "Accountable Care Organization Partnership Plan (ACPP)",
+    },
+    {
+      id: "Lxw9iYNsQ5msQrzCo9YPYFg0",
+      label: "Senior Care Options (SCO)",
+    },
+    {
+      id: "LlIehwl4PaaWTGKYtRuFtpa8",
+      label: "MCO Program",
+    },
+    {
+      id: "fIhvUbnPlwMi6h4Y0Mkb7WXX",
+      label:
+        "Primary Care Accountable Care Organization (Primary Care ACO or PCACO)",
+    },
+    {
+      id: "8tTtPlLsxV5mX6RQ4iKJtrLr",
+      label: "BH/SUD PIHP (Massachusetts Behavioral Health Partnership (MBHP))",
+    },
+    {
+      id: "NeHtD99KiHVS2ZUWnUqfwBtO",
+      label: "One Care",
+    },
+  ],
+  // Michigan
+  MI: [
+    {
+      id: "rKP1AuYdyVplrfjL771Q6CMb",
+      label: "Healthy Kids Dental (HKD)",
+    },
+    {
+      id: "I8Y6rQy4CjpVF7F7Lc3QzVEA",
+      label: "MI Choice",
+    },
+    {
+      id: "lH6nmhqusWyOMPyGao7mmhAB",
+      label: "Managed Specialty Services & Supports",
+    },
+    {
+      id: "020MTjgJZbMDf3uM3XHa6Zlb",
+      label: "Comprehensive Health Care Program (CHCP)",
+    },
+    {
+      id: "9j6moQolrYNkCzmzqsQKNBAg",
+      label: "Health Link",
+    },
+  ],
+  // Minnesotta
+  MN: [
+    {
+      id: "g3YiOeqUorkj8RKxZiGqdF1h",
+      label: "Minnesota Senior Health Options (MSHO)",
+    },
+    {
+      id: "Kvaa1JvEIoT1Vl15InEUjIOy",
+      label: "PMAP",
+    },
+    {
+      id: "i6sIFm9OSGx8aOokpsZRrK2C",
+      label: "Special Needs Basic Care (SNBC)",
+    },
+    {
+      id: "axtdsWz0pbF76hqgUOTThs7C",
+      label: "Minnesota Senior Care Plus (MSC+)",
+    },
+    {
+      id: "YdKa3xY2iqdVAsQfHd7O5g6Y",
+      label: "MinnesotaCare",
+    },
+  ],
+  // Mississippi
+  MS: [
+    {
+      id: "VmtV1Hv3OPaAztVuKv42tjCk",
+      label: "Mississippi Coordinated Access Network (MississippiCAN)",
+    },
+    {
+      id: "DmMnEfc3LDjokVJyWmydH1gU",
+      label: "MississippiCHIP",
+    },
+  ],
+  // Missouri
+  MO: [
+    {
+      id: "fhnimink8wMG8YFKnSJFb9I7",
+      label: "MO HealthNet Managed Care Plan",
+    },
+  ],
+  // Montana
+  MT: [
+    {
+      id: "Ykf5e7509dBfwaWu3ywQOctb",
+      label: "Tribal Health Improvement Plan (T-HIP)",
+    },
+  ],
+  // Nebraska
+  NE: [
+    {
+      id: "MLPFoImu6FrjJJpcG9v2t9Pp",
+      label: "Heritage Health",
+    },
+    {
+      id: "cr3LVfku8XlI5No4OyntQnu0",
+      label: "CHIP",
+    },
+    {
+      id: "HLIEvPjm8smRb4qZNTGHQ2lE",
+      label: "Substance Use Disorder Program",
+    },
+  ],
+  // Nevada
+  NV: [
+    {
+      id: "qCWS3fLpyXOEvwBeS37obe0J",
+      label: "Dental Benefits Administration Program (DBA)",
+    },
+    {
+      id: "qOMotuAh8DiLqfSOJz0JEyJS",
+      label: "Nevada Mandatory Health Maintenance Program",
+    },
+  ],
+  // New Hampshire
+  NH: [
+    {
+      id: "trskQUyjE3a2uvYhxBenjPvl",
+      label: "Medicaid Care Management (MCM)",
+    },
+    {
+      id: "OotA1OCKTrbmyA6eZUJ1DGqj",
+      label: "MCM-Dental Services",
+    },
+  ],
+  // New Jersey
+  NJ: [
+    {
+      id: "2UCpnNYg5DLmKJI089NeKthU",
+      label: "FIDE-SNP-Duals",
+    },
+    {
+      id: "8w3Kx3PmRyYrL7kDJJXX78II",
+      label: "NJ Family Care MLTSS",
+    },
+    {
+      id: "9m5aU8E4zOp7l3hL0XVHRlXy",
+      label: "NJ Family Care Acute Care",
+    },
+  ],
+  // New Mexico
+  NM: [
+    {
+      id: "eKwjZtIioFxg9mdrO1gA8Ymo",
+      label: "New Mexico Turquoise Care",
+    },
+  ],
+  // New York
+  NY: [
+    {
+      id: "yLC2ONYWuyUY4nP3dHhxyTj2",
+      label: "Behavioral Health and Recovery Plan (HARP)",
+    },
+    {
+      id: "VtDtt5Oi1aL0C83I8J1L0k7K",
+      label: "Managed Long Term Care Partial Cap (MLTC)",
+    },
+    {
+      id: "qWnUXf4GjHtLb5pANB0R0moL",
+      label: "Medicaid Advantage Plus (MAP)",
+    },
+    {
+      id: "DXphgy0JLdIo0Tquc5wOLBwB",
+      label: "HIV Special Needs Plan (HIV SNP)",
+    },
+    {
+      id: "MY9YSHhax4MxreBkKcx0vyci",
+      label:
+        "Fully Integrated Duals Advantage for Individuals with Intellectual & Developmental Disabilities (FIDA-IDD)",
+    },
+    {
+      id: "PoUqzdCA7hzGx2kKOCHEPMQn",
+      label: "Mainstream Managed Care (MMC)",
+    },
+  ],
+  // North Carolina
+  NC: [
+    {
+      id: "kANrY8P11CnhhemLZigpWors",
+      label: "Community Care of North Carolina (CCNC)",
+    },
+    {
+      id: "R5SmBcfye0cceFIQQf8MwGVk",
+      label: "Eastern Band of Cherokee Indians (EBCI) Tribal Option",
+    },
+    {
+      id: "IUkIdmITkjXdHceZnCI8d1P3",
+      label: "Medicaid Direct Behavioral Health",
+    },
+    {
+      id: "lh3WCIxBQOtenlb6YBSt3T5G",
+      label: "Standard Plan",
+    },
+    {
+      id: "hdWxSgcjxFcA34W5YnrGO4JE",
+      label: "BH I/DD Tailored Plan",
+    },
+  ],
+  // North Dakota
+  ND: [
+    {
+      id: "qnh3FrWp7qUnReQLr8Asb7Rt",
+      label: "ND Medicaid Expansion",
+    },
+  ],
+  // Ohio
+  OH: [
+    {
+      id: "o549cIUcz09qCovJ7xNegt3s",
+      label: "MyCare Ohio, Ohio's Integrated Care Delivery System (MCOP)",
+    },
+    {
+      id: "zE4g0MnKyum6ghJudwiqRiWo",
+      label: "Ohio Medicaid Managed Care Program (MMC)",
+    },
+    {
+      id: "OvZP8eoV2y9UmW9W0bOPAl7u",
+      label: "Single Pharmacy Benefit Manager (SBPM)",
+    },
+    {
+      id: "fzzOnYSm5xvGrr7h3qXhXV2g",
+      label: "Ohio RISE (Resilience through Integrated Systems and Excellence)",
+    },
+  ],
+  // Oklahoma
+  OK: [
+    {
+      id: "MNooqHYaV7few6V1zgNNMu8s",
+      label: "SoonerSelect Children's Specialty Program (CSP)",
+    },
+    {
+      id: "p9Z49lliZnUnkYzxsKjEnFlA",
+      label: "SoonerSelect Medical",
+    },
+    {
+      id: "xXGZkdQpblavQztQwUE8kS86",
+      label: "SoonerCare Choice",
+    },
+  ],
+  // Oregon
+  OR: [
+    {
+      id: "yHtx2dBNpIHLoUAFPUSw5ln4",
+      label: "Coordinated Care Organization (CCO)",
+    },
+  ],
+  // Pennsylvania
+  PA: [
+    {
+      id: "FfRFqER02jgFaK9lEcWiHzFb",
+      label: "Physical Health HealthChoices (PH-HC)",
+    },
+    {
+      id: "5QOSrEpZfJJeuPJU9vrinMjW",
+      label: "Behavioral Health HealthChoices (BH-HC)",
+    },
+    {
+      id: "tm1V6rhCHt9sq5aKPadu3Bia",
+      label: "Community HealthChoices (CHC)",
+    },
+    {
+      id: "l0xMakS2qBpApIjIvolMtvbd",
+      label: "Adult Community Autism Program (ACAP)",
+    },
+    {
+      id: "GEAeHfhMrDPZpjeDW2pkiOs7",
+      label: "Children's Health Insurance Program (CHIP)",
+    },
+  ],
+  // Puerto Rico
+  PR: [
+    {
+      id: "Q0y0OEd8RM3abELHmfF4bXRh",
+      label: "Platino: Dual-Special Needs Plan (D-SNP)",
+    },
+    {
+      id: "AYc3s2y30BFQZoLlvR1enLDX",
+      label: "The Vital Government Health Plan",
+    },
+  ],
+  // Rhode Island
+  RI: [
+    {
+      id: "TU3Zhb1IuZud7l0UUYg8vUrI",
+      label: "RIteCare MCO",
+    },
+    {
+      id: "Xk1M34EhUSO1BblZC8ii1qNF",
+      label: "RIteSmiles",
+    },
+    {
+      id: "XtLKxy0BCUkuJMwUOb7UaOw8",
+      label: "Rhode Island Integrated Care Initiative",
+    },
+  ],
+  // South Carolina
+  SC: [
+    {
+      id: "vAYRx4Gib5WLLEzZ6aXbxMzA",
+      label: "Healthy Connections Choices",
+    },
+    {
+      id: "lsRPa82TNqiTCiD9n56RXflS",
+      label: "Healthy Connections Prime",
+    },
+  ],
+  // Tennessee
+  TN: [
+    {
+      id: "RJIvS7tBNKYmEPN2lmMjxSXn",
+      label: "TennCare",
+    },
+    {
+      id: "jbggcYz5el7obt3Zbw5Jp0t8",
+      label: "TennCare Select",
+    },
+    {
+      id: "XVltP7POUgr95mlkZpXr9r3v",
+      label: "Adult Dental Program",
+    },
+    {
+      id: "mPtbliMlZ938gISzXR8in70S",
+      label: "CoverKids Program",
+    },
+  ],
+  // Texas
+  TX: [
+    {
+      id: "PtkXLdtfms2k93IqQkwORg2r",
+      label: "STAR Health",
+    },
+    {
+      id: "iRHocpaY5XvnVxZHH31J4ZWC",
+      label: "STAR Kids",
+    },
+    {
+      id: "BEbOycQSMxiLxoH3QoXIEA2g",
+      label: "STAR",
+    },
+    {
+      id: "PTO3vZY3dpGCV3TYgK3GmagR",
+      label: "Dental (Children's Medicaid Dental Services)",
+    },
+    {
+      id: "jna4N2cB18lPBmR83twxbYU8",
+      label: "Dual Demonstration Program",
+    },
+    {
+      id: "rjAHRGiCmEUGK8H5A7YLoCud",
+      label: "STAR+PLUS",
+    },
+  ],
+  // Utah
+  UT: [
+    {
+      id: "dMY7YePxerwyDIBcZNqRSzwo",
+      label: "Utah Healthy Outcomes for Medical Excellence (HOME)",
+    },
+    {
+      id: "ajJfzN52qZ9n18yrYMpAJPXJ",
+      label: "UT Medicaid Dental",
+    },
+    {
+      id: "lZM0Ux8MwzsaGcIiqf6GeGJe",
+      label: "UT Prepaid Mental Health Plan",
+    },
+    {
+      id: "of1IqqdUitWpL8B6fP9h49Fi",
+      label: "Utah Medicaid Integrated Counties (UMIC)",
+    },
+    {
+      id: "PYeSbQy8wz26GQUukofUjFoS",
+      label: "UT ACO",
+    },
+    {
+      id: "pG8qB66wy1cSauuc0sCGC7et",
+      label: "UT CHIP Dental",
+    },
+  ],
+  // Vermont
+  VT: [
+    {
+      id: "opuhRIuGgj3pLNNCEDOZLNuv",
+      label: "Vermont Global Commitment to Health",
+    },
+  ],
+  // Virginia
+  VA: [
+    {
+      id: "lhgkAzmUxkKBRJpnTL1gwkoP",
+      label: "Cardinal Care Managed Care",
+    },
+  ],
+  // Washington
+  WA: [
+    {
+      id: "i0qV5Y7MpOtHHfarqqZNEaVI",
+      label: "Apple Health Integrated Managed Care (IMC)",
+    },
+    {
+      id: "gojlp1XdVf14cGqHVj7JFrsZ",
+      label: "Integrated Foster Care (IFC)",
+    },
+    {
+      id: "F5NiWADoBRlwatzj375oMwGq",
+      label: "Behavioral Health Only Services (BHSO)",
+    },
+  ],
+  // West Virginia
+  WV: [
+    {
+      id: "bE1lVFcULXGQLQEgHeMNFZYw",
+      label: "Mountain Health Trust (MHT)",
+    },
+    {
+      id: "87QUwToKBG7WOttbewx45cqc",
+      label: "Mountain Heath Promise (MHP)",
+    },
+    {
+      id: "ns6glVkHfwAKeOMQ2vXhcEFD",
+      label: "WVCHIP (WVCHIP)",
+    },
+  ],
+  // Wisconsin
+  WI: [
+    {
+      id: "mzGvJmaG5Przlu0CfpfTxDYk",
+      label: "Care 4 Kids",
+    },
+    {
+      id: "o2ZilmecPMCmcXGgWXoFtFyD",
+      label: "BadgerCare Plus (BCP)",
+    },
+    {
+      id: "jRU1SSVvTWgOiNgBsteRou0K",
+      label: "Family Care",
+    },
+    {
+      id: "FvhGkHOthXkiZFroG4X5JmD6",
+      label: "Family Care Partnership",
+    },
+    {
+      id: "pKMy2Ws5IT2iInUxfBd1e1LB",
+      label: "SSI Managed Care (SSI)",
+    },
+  ],
+  // Wyoming
+  WY: [
+    {
+      id: "chzp3SWGykXBcYPiuKomisN7",
+      label: "Wyoming Medicaid's Care Management Entity (CME)",
+    },
+  ],
+};
diff --git a/services/ui-src/src/types/reportContext.ts b/services/ui-src/src/types/reportContext.ts
index 10244ded6..ff892312e 100644
--- a/services/ui-src/src/types/reportContext.ts
+++ b/services/ui-src/src/types/reportContext.ts
@@ -1,6 +1,12 @@
 // REPORT PROVIDER/CONTEXT
 
-import { AnyObject, Choice, ErrorVerbiage, ReportJson } from "types";
+import {
+  AnyObject,
+  Choice,
+  ErrorVerbiage,
+  ReportJson,
+  SelectedOption,
+} from "types";
 
 export interface ReportKeys {
   reportType: string;
@@ -32,6 +38,10 @@ export interface ReportMetadataShape extends ReportKeys {
   previousRevisions: string[];
   planTypeIncludedInProgram?: Choice[];
   "planTypeIncludedInProgram-otherText"?: string;
+  newOrExistingProgram?: Choice[];
+  existingProgramNameSelection?: SelectedOption;
+  existingProgramNameSuggestion?: string;
+  newProgramName?: string;
 }
 
 export interface ReportShape extends ReportMetadataShape {
diff --git a/services/ui-src/src/types/reports.ts b/services/ui-src/src/types/reports.ts
index 9ccfe041f..7bf812592 100644
--- a/services/ui-src/src/types/reports.ts
+++ b/services/ui-src/src/types/reports.ts
@@ -6,6 +6,7 @@ import {
   EntityType,
   FormJson,
   ScreenReaderCustomHeaderName,
+  SelectedOption,
   SortableHeadRow,
   State,
   TableContentShape,
@@ -309,6 +310,10 @@ export interface MCPARReportMetadata extends ReportMetadata {
   dueDate: number;
   combinedData: boolean;
   programIsPCCM: Choice[];
+  newOrExistingProgram: Choice[];
+  existingProgramNameSelection?: SelectedOption;
+  existingProgramNameSuggestion?: string;
+  newProgramName?: string;
 }
 
 export interface NAAARReportMetadata extends ReportMetadata {
diff --git a/services/ui-src/src/utils/forms/forms.test.ts b/services/ui-src/src/utils/forms/forms.test.ts
index d354bb2c8..3d4e6fef7 100644
--- a/services/ui-src/src/utils/forms/forms.test.ts
+++ b/services/ui-src/src/utils/forms/forms.test.ts
@@ -1,5 +1,6 @@
 import {
   createRepeatedFields,
+  defineProgramName,
   filterFormData,
   flattenFormFields,
   formFieldFactory,
@@ -11,7 +12,7 @@ import {
   sortFormErrors,
 } from "./forms";
 // types
-import { FormField } from "types";
+import { Choice, FormField } from "types";
 // utils
 import {
   mockDateField,
@@ -414,3 +415,82 @@ describe("utils/forms", () => {
     });
   });
 });
+
+describe("Test defineProgramName", () => {
+  describe("Happy Path", () => {
+    test("Existing Program Name", () => {
+      const newOrExistingProgram: Choice[] = [
+        {
+          key: "mockkey",
+          value: "Existing program",
+        },
+      ];
+      const existingProgramNameSelection = {
+        label: "existingProgramNameSelection",
+        value: "Accountable Care Organization Partnership Plan (ACPP)",
+      };
+
+      expect(
+        defineProgramName(newOrExistingProgram, existingProgramNameSelection)
+      ).toEqual(existingProgramNameSelection.value);
+    });
+
+    test("New Program Name", () => {
+      const newOrExistingProgram: Choice[] = [
+        {
+          key: "mockkey",
+          value: "Add new program",
+        },
+      ];
+      const newProgramName = "MockProgramName";
+
+      expect(
+        defineProgramName(newOrExistingProgram, undefined, newProgramName)
+      ).toEqual(newProgramName);
+    });
+  });
+  describe("Potential Error States", () => {
+    test("Choice not given", () => {
+      const newOrExistingProgram: Choice[] = [];
+      const existingProgramNameSelection = {
+        label: "existingProgramNameSelection",
+        value: "Accountable Care Organization Partnership Plan (ACPP)",
+      };
+      expect(() =>
+        defineProgramName(newOrExistingProgram, existingProgramNameSelection)
+      ).toThrow();
+    });
+
+    test("existingProgramNameSelection did not pass a value", () => {
+      const newOrExistingProgram: Choice[] = [
+        {
+          key: "mockkey",
+          value: "Existing program",
+        },
+      ];
+      const existingProgramNameSelection = {
+        label: "",
+        value: "",
+      };
+      expect(() =>
+        defineProgramName(newOrExistingProgram, existingProgramNameSelection)
+      ).toThrow();
+    });
+
+    test("newOrExistingProgram selected an unsupported value", () => {
+      const newOrExistingProgram: Choice[] = [
+        {
+          key: "mockkey",
+          value: "unsupportedValue",
+        },
+      ];
+      const existingProgramNameSelection = {
+        label: "existingProgramNameSelection",
+        value: "Accountable Care Organization Partnership Plan (ACPP)",
+      };
+      expect(() =>
+        defineProgramName(newOrExistingProgram, existingProgramNameSelection)
+      ).toThrow();
+    });
+  });
+});
diff --git a/services/ui-src/src/utils/forms/forms.ts b/services/ui-src/src/utils/forms/forms.ts
index bd776d04f..b326bdaa9 100644
--- a/services/ui-src/src/utils/forms/forms.ts
+++ b/services/ui-src/src/utils/forms/forms.ts
@@ -14,6 +14,8 @@ import {
 // types
 import {
   AnyObject,
+  Choice,
+  DropdownChoice,
   EntityType,
   FieldChoice,
   FormField,
@@ -339,3 +341,29 @@ export const getForm = (params: getFormParams) => {
   }
   return modifiedForm;
 };
+
+export const defineProgramName = (
+  newOrExistingProgram: Choice[],
+  existingProgramNameSelection?: DropdownChoice,
+  newProgramName?: string
+) => {
+  if (!newOrExistingProgram?.[0]?.value)
+    throw new Error(
+      "Program name radio field was not selected as an existing or new report"
+    );
+
+  switch (newOrExistingProgram[0].value) {
+    case "Existing program":
+      if (!existingProgramNameSelection?.value)
+        throw new Error(
+          "Program name dropdown selection did not have a value. Please double check the field is working properly."
+        );
+      return existingProgramNameSelection.value;
+    case "Add new program":
+      return newProgramName;
+    default:
+      throw new Error(
+        "A choice was made in the program name selection field that isn't supported. Please add your choice to this function (defineProgramName) or fix the typo in the addEditModalJson file."
+      );
+  }
+};
diff --git a/services/ui-src/src/utils/testing/mockReport.tsx b/services/ui-src/src/utils/testing/mockReport.tsx
index aa905dd56..c66cdc60b 100644
--- a/services/ui-src/src/utils/testing/mockReport.tsx
+++ b/services/ui-src/src/utils/testing/mockReport.tsx
@@ -471,6 +471,13 @@ export const mockMcparReport = {
   reportType: "MCPAR",
   formTemplate: mockReportJson,
   programName: "testProgram",
+  newProgramName: "testProgram",
+  newOrExistingProgram: [
+    {
+      key: "newOrExistingProgram-isNewProgram",
+      value: "Add new program",
+    },
+  ],
   status: ReportStatus.NOT_STARTED,
   dueDate: 168515200000,
   reportingPeriodStartDate: 162515200000,
diff --git a/tests/cypress/e2e/mcpar/dashboard.cy.js b/tests/cypress/e2e/mcpar/dashboard.cy.js
index 86ff29f2a..90cf4dcda 100644
--- a/tests/cypress/e2e/mcpar/dashboard.cy.js
+++ b/tests/cypress/e2e/mcpar/dashboard.cy.js
@@ -4,7 +4,12 @@ const currentDate = new Date().toISOString();
 
 const newReportInputArray = [
   {
-    name: "programName",
+    name: "newOrExistingProgram",
+    type: "radio",
+    value: "Add new program",
+  },
+  {
+    name: "newProgramName",
     type: "text",
     value: `automated test - ${currentDate}`,
   },
@@ -47,7 +52,7 @@ describe("MCPAR Dashboard Page - Program Creation/Editing/Archiving", () => {
     verifyElementsArePrefilled(newReportInputArray);
 
     // edit report name
-    cy.get(`[name='programName']`)
+    cy.get(`[name='newProgramName']`)
       .clear()
       .type(`Edited Program - ${currentDate}`);
     cy.get("button[type=submit]").contains("Save").click();
diff --git a/tests/cypress/e2e/mcpar/form.cy.js b/tests/cypress/e2e/mcpar/form.cy.js
index a9142362b..50e806a66 100644
--- a/tests/cypress/e2e/mcpar/form.cy.js
+++ b/tests/cypress/e2e/mcpar/form.cy.js
@@ -53,7 +53,8 @@ function fillOutMCPAR() {
   const programName = "automated test - " + today.toISOString();
   cy.visit("/mcpar");
   cy.get("button").contains("Add / copy a MCPAR").click();
-  cy.get('input[name="programName"]').type(programName);
+  cy.get('input[name="newOrExistingProgram"]').check("Add new program");
+  cy.get('input[name="newProgramName"]').type(programName);
   cy.get('input[name="reportingPeriodStartDate"]').type(
     lastYear.toLocaleDateString("en-US")
   );
@@ -90,7 +91,8 @@ function fillOutPartialMCPAR() {
   const programName = "automated test - " + today.toISOString();
   cy.visit("/mcpar");
   cy.get("button").contains("Add / copy a MCPAR").click();
-  cy.get('input[name="programName"]').type(programName);
+  cy.get('input[name="newOrExistingProgram"]').check("Add new program");
+  cy.get('input[name="newProgramName"]').type(programName);
   cy.get('input[name="reportingPeriodStartDate"]').type(
     lastYear.toLocaleDateString("en-US")
   );
diff --git a/tests/cypress/e2e/sidebar.cy.js b/tests/cypress/e2e/sidebar.cy.js
index e82a3451b..3bb71d758 100644
--- a/tests/cypress/e2e/sidebar.cy.js
+++ b/tests/cypress/e2e/sidebar.cy.js
@@ -20,7 +20,8 @@ describe("Sidebar integration tests", () => {
     // Create Report & nav to it
     const programName = `automated test - ${new Date().toISOString()}`;
     cy.get('button:contains("Add / copy a MCPAR")').click();
-    cy.get('input[name="programName"]').type(programName);
+    cy.get('input[name="newOrExistingProgram"]').check("Add new program");
+    cy.get('input[name="newProgramName"]').type(programName);
     cy.get('input[name="reportingPeriodStartDate"]').type("07142023");
     cy.get('input[name="reportingPeriodEndDate"]').type("07142026");
     cy.get('[name="combinedData"]').focused().click();


Reviews:
user: login: qlty-cloud-legacy[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-05T21:56:33Z
user: login: qlty-cloud-legacy[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-05T22:39:46Z
user: login: ntsummers1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:15:34Z
user: login: ntsummers1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:28:40Z
user: login: britt-mo
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:34:19Z
user: login: gmrabian
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:48:33Z
user: login: gmrabian
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:52:39Z
user: login: gmrabian
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:53:33Z
user: login: gmrabian
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:54:21Z
user: login: gmrabian
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:56:36Z
user: login: ntsummers1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:59:00Z
user: login: gmrabian
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:59:27Z
user: login: ntsummers1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T16:00:13Z
user: login: gmrabian
body: functionality looks good! a few comments to clarify how we are using this
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T16:00:24Z
user: login: ntsummers1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T16:10:52Z
user: login: ntsummers1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T16:11:32Z
user: login: gmrabian
body: I don't know if this case is out of scope, but I'm unable to create a copied report. Do users need to still fill out the first portion even for a copy?


https://github.com/user-attachments/assets/a773a440-fbe3-43d0-88c0-82b4b2942266


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T16:12:01Z
user: login: ntsummers1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T16:20:44Z
user: login: ntsummers1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T16:23:35Z
user: login: karla-vm
body: 💯 I have seen the issues you've laid out. I have fought them too. I believe this solution is graceful and amazing and I appreciate all of your hard work on it! 🏅 😭 👑 
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-06T17:59:38Z
user: login: bangbay-bluetiger
body: Looks good to me! Non-blocking comments.
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T18:19:39Z
user: login: ntsummers1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T18:34:37Z
user: login: ntsummers1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T18:45:55Z
user: login: bangbay-bluetiger
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T18:59:47Z

Review comments:
diff_hunk: @@ -162,3 +162,31 @@ export const calculateRemainingSeconds = (expiresAt?: any) => {
   if (!expiresAt) return 0;
   return (new Date(expiresAt).valueOf() - Date.now()) / 1000;
 };
+
+export const defineProgramName = (
+  todoProgramNameSelection: Choice[],
+  yes_todoProgramNameSelectionDropdown?: DropdownChoice,
+  no_todoProgramNameSelectionNewProgramName?: string
+) => {
+  //TODO - Seek clarity on this function and how it should operate.
path: services/ui-src/src/utils/other/time.ts
user: login: qlty-cloud-legacy[bot]
body: //TODO \- Seek clarity on this function and how it should operate\. <i>[ripgrep:TODO]</i><a href="#issue-f2d86a65d586c1649c60fe5c3532a889"></a>
created_at: 2025-05-05T21:56:33Z
author_association: NONE
diff_hunk: @@ -162,3 +162,29 @@ export const calculateRemainingSeconds = (expiresAt?: any) => {
   if (!expiresAt) return 0;
   return (new Date(expiresAt).valueOf() - Date.now()) / 1000;
 };
+
+export const defineProgramName = (
+  newOrExistingProgram: Choice[],
+  existingProgramNameSelection?: DropdownChoice,
+  newProgramName?: string
+) => {
+  //TODO - Seek clarity on this function and how it should operate.
path: services/ui-src/src/utils/other/time.ts
user: login: qlty-cloud-legacy[bot]
body: //TODO \- Seek clarity on this function and how it should operate\. <i>[ripgrep:TODO]</i><a href="#issue-f2d86a65d586c1649c60fe5c3532a889"></a>
created_at: 2025-05-05T22:39:46Z
author_association: NONE
diff_hunk: @@ -162,3 +162,29 @@ export const calculateRemainingSeconds = (expiresAt?: any) => {
   if (!expiresAt) return 0;
   return (new Date(expiresAt).valueOf() - Date.now()) / 1000;
 };
+
+export const defineProgramName = (
+  newOrExistingProgram: Choice[],
+  existingProgramNameSelection?: DropdownChoice,
+  newProgramName?: string
+) => {
+  //TODO - Seek clarity on this function and how it should operate.
path: services/ui-src/src/utils/other/time.ts
user: login: ntsummers1
body: Honest question here: How to handle these possible scenarios? It is technically possible with our typing/user choice that the values could be undefined. Does it become an empty string? Should there be some default program name in those scenarios?

created_at: 2025-05-06T15:15:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -217,6 +217,22 @@ export const dropdown = () =>
   object({ label: textSchema(), value: textSchema() }).required(
     error.REQUIRED_GENERIC
   );
+export const dropdownOptional = () =>
+  mixed().test({
+    message: error.INVALID_GENERIC,
+    test: (val) => {
+      switch (typeof val) {
+        case "object":
+          return object({ label: textSchema(), value: string() })
+            .required()
+            .isValid(val);
+        case "undefined":
+          return true;
+        default:
+          return false;
+      }
+    },
+  });
path: services/app-api/utils/validation/completionSchemas.ts
user: login: ntsummers1
body: I know this looks weird. I promise theres reasons behind the madness:

- Why is this different from the dropdownOptional below (In Ui-src)?
  Oh dear reader, its because yup validation is a hacky and wild west world that doesn't get out of its own way. I'd love nothing more to use the ui's dropdownOptional validation, but what happens is that yup will see that theres absolutely positively nothing passed for the dropdown field and will literally insert an `{ label: undefined, value: undefined }` into the report data because it wants to ruin your day. So how to get around that? See the above. 
- Is this field actually optional then? 
 yes! If the value isn't passed it goes through the undefined case
- Why the string for value then? Whats the discrepancy!
  Great question! Thats because to clear and reset the form we need to send the first choice in the dropdown list. The "Select one of the names" choice. And that is passing a value of an empty string. So thats how we support that case.


created_at: 2025-05-06T15:28:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -217,6 +217,22 @@ export const dropdown = () =>
   object({ label: textSchema(), value: textSchema() }).required(
     error.REQUIRED_GENERIC
   );
+export const dropdownOptional = () =>
+  mixed().test({
+    message: error.INVALID_GENERIC,
+    test: (val) => {
+      switch (typeof val) {
+        case "object":
+          return object({ label: textSchema(), value: string() })
+            .required()
+            .isValid(val);
+        case "undefined":
+          return true;
+        default:
+          return false;
+      }
+    },
+  });
path: services/app-api/utils/validation/completionSchemas.ts
user: login: britt-mo
body: just a general question about this--given the issues you've laid out, is there reason to look into replacing `yup` with a better alternative (as a future improvement)?
created_at: 2025-05-06T15:34:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,6 +15,10 @@ export interface ReportKeys {
 }
 
 export interface ReportMetadataShape extends ReportKeys {
+  newOrExistingProgram: Choice[];
path: services/app-api/utils/types/reportContext.ts
user: login: gmrabian
body: I'm seeing this field `newOrExistingProgram` required in all the new types, but we use this type for MLR and NAAAR and it doesn't exist on those reports, right?
created_at: 2025-05-06T15:48:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -162,3 +162,29 @@ export const calculateRemainingSeconds = (expiresAt?: any) => {
   if (!expiresAt) return 0;
   return (new Date(expiresAt).valueOf() - Date.now()) / 1000;
 };
+
+export const defineProgramName = (
+  newOrExistingProgram: Choice[],
+  existingProgramNameSelection?: DropdownChoice,
+  newProgramName?: string
+) => {
+  //TODO - Seek clarity on this function and how it should operate.
+  if (!newOrExistingProgram?.[0] || !newOrExistingProgram?.[0].value)
path: services/ui-src/src/utils/other/time.ts
user: login: gmrabian
body: nit: do we specifically need the empty array case? if not we can do `?.value` here to save the `or`
`!newOrExistingProgram?.[0]?.value`
created_at: 2025-05-06T15:52:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -162,3 +162,29 @@ export const calculateRemainingSeconds = (expiresAt?: any) => {
   if (!expiresAt) return 0;
   return (new Date(expiresAt).valueOf() - Date.now()) / 1000;
 };
+
+export const defineProgramName = (
path: services/ui-src/src/utils/other/time.ts
user: login: gmrabian
body: why is this in our time utility?
created_at: 2025-05-06T15:53:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -162,13 +168,33 @@ export const DashboardPage = ({ reportType }: Props) => {
           planTypeIncludedInProgram: report?.planTypeIncludedInProgram,
           "planTypeIncludedInProgram-otherText":
             report?.["planTypeIncludedInProgram-otherText"],
+          newOrExistingProgram: report.newOrExistingProgram,
path: services/ui-src/src/components/pages/Dashboard/DashboardPage.tsx
user: login: gmrabian
body: won't this be undefined for MLR and NAAAR? I'm actually surprised it doesn't throw an error in console
created_at: 2025-05-06T15:54:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -84,7 +89,22 @@ export const AddEditReportModal = ({
 
   // MCPAR report payload
   const prepareMcparPayload = (formData: any) => {
-    const programName = formData["programName"];
+    const newOrExistingProgram = formData["newOrExistingProgram"];
+    const existingProgramNameSelection = formData[
+      "existingProgramNameSelection"
+    ] || {
+      label: dropdownDefaultOptionText,
+      value: "",
+    };
+    const existingProgramNameSuggestion =
+      formData["existingProgramNameSuggestion"] || "";
+    const newProgramName = formData["newProgramName"] || "";
path: services/ui-src/src/components/modals/AddEditReportModal.tsx
user: login: gmrabian
body: suggestion: could we use `?.` here and let it be undefined?
created_at: 2025-05-06T15:56:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,6 +15,10 @@ export interface ReportKeys {
 }
 
 export interface ReportMetadataShape extends ReportKeys {
+  newOrExistingProgram: Choice[];
path: services/app-api/utils/types/reportContext.ts
user: login: ntsummers1
body: Great call out. 100% this typing needs to be changed to accommodate the differences between the reports.
created_at: 2025-05-06T15:58:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -84,7 +89,22 @@ export const AddEditReportModal = ({
 
   // MCPAR report payload
   const prepareMcparPayload = (formData: any) => {
-    const programName = formData["programName"];
+    const newOrExistingProgram = formData["newOrExistingProgram"];
+    const existingProgramNameSelection = formData[
+      "existingProgramNameSelection"
+    ] || {
+      label: dropdownDefaultOptionText,
+      value: "",
+    };
+    const existingProgramNameSuggestion =
+      formData["existingProgramNameSuggestion"] || "";
+    const newProgramName = formData["newProgramName"] || "";
path: services/ui-src/src/components/modals/AddEditReportModal.tsx
user: login: gmrabian
body: I guess we are strictly typing these as strings even if they are unused so maybe not. good as is 👍 
created_at: 2025-05-06T15:59:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -217,6 +217,22 @@ export const dropdown = () =>
   object({ label: textSchema(), value: textSchema() }).required(
     error.REQUIRED_GENERIC
   );
+export const dropdownOptional = () =>
+  mixed().test({
+    message: error.INVALID_GENERIC,
+    test: (val) => {
+      switch (typeof val) {
+        case "object":
+          return object({ label: textSchema(), value: string() })
+            .required()
+            .isValid(val);
+        case "undefined":
+          return true;
+        default:
+          return false;
+      }
+    },
+  });
path: services/app-api/utils/validation/completionSchemas.ts
user: login: ntsummers1
body: I would love to - Sunken cost fallacy though + amount of lift to swap at this point would be huge and I'm not sure I'm ready to go down that road 😅 
created_at: 2025-05-06T16:00:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -162,3 +162,29 @@ export const calculateRemainingSeconds = (expiresAt?: any) => {
   if (!expiresAt) return 0;
   return (new Date(expiresAt).valueOf() - Date.now()) / 1000;
 };
+
+export const defineProgramName = (
path: services/ui-src/src/utils/other/time.ts
user: login: ntsummers1
body: I can't speak for past Nick. But current Nick is thinking past Nick was a fool - Will fix!
created_at: 2025-05-06T16:10:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -84,7 +89,22 @@ export const AddEditReportModal = ({
 
   // MCPAR report payload
   const prepareMcparPayload = (formData: any) => {
-    const programName = formData["programName"];
+    const newOrExistingProgram = formData["newOrExistingProgram"];
+    const existingProgramNameSelection = formData[
+      "existingProgramNameSelection"
+    ] || {
+      label: dropdownDefaultOptionText,
+      value: "",
+    };
+    const existingProgramNameSuggestion =
+      formData["existingProgramNameSuggestion"] || "";
+    const newProgramName = formData["newProgramName"] || "";
path: services/ui-src/src/components/modals/AddEditReportModal.tsx
user: login: ntsummers1
body: 100% the reason why its like that. Didn't want to rock the boat.
created_at: 2025-05-06T16:11:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -162,3 +162,29 @@ export const calculateRemainingSeconds = (expiresAt?: any) => {
   if (!expiresAt) return 0;
   return (new Date(expiresAt).valueOf() - Date.now()) / 1000;
 };
+
+export const defineProgramName = (
+  newOrExistingProgram: Choice[],
+  existingProgramNameSelection?: DropdownChoice,
+  newProgramName?: string
+) => {
+  //TODO - Seek clarity on this function and how it should operate.
+  if (!newOrExistingProgram?.[0] || !newOrExistingProgram?.[0].value)
path: services/ui-src/src/utils/other/time.ts
user: login: ntsummers1
body: 👍 
created_at: 2025-05-06T16:20:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -162,13 +168,33 @@ export const DashboardPage = ({ reportType }: Props) => {
           planTypeIncludedInProgram: report?.planTypeIncludedInProgram,
           "planTypeIncludedInProgram-otherText":
             report?.["planTypeIncludedInProgram-otherText"],
+          newOrExistingProgram: report.newOrExistingProgram,
path: services/ui-src/src/components/pages/Dashboard/DashboardPage.tsx
user: login: ntsummers1
body: Youre right, and its actually been doing just fine handling these things in the past as `combinedData: report.combinedData,` is being passed just like this. I'll make this as optionally passed though to be clear it really could be!
created_at: 2025-05-06T16:23:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -217,6 +217,22 @@ export const dropdown = () =>
   object({ label: textSchema(), value: textSchema() }).required(
     error.REQUIRED_GENERIC
   );
+export const dropdownOptional = () =>
+  mixed().test({
+    message: error.INVALID_GENERIC,
+    test: (val) => {
+      switch (typeof val) {
+        case "object":
+          return object({ label: textSchema(), value: string() })
path: services/app-api/utils/validation/completionSchemas.ts
user: login: bangbay-bluetiger
body: Add unit tests for this validation.
created_at: 2025-05-06T18:11:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -339,3 +341,29 @@ export const getForm = (params: getFormParams) => {
   }
   return modifiedForm;
 };
+
+export const defineProgramName = (
+  newOrExistingProgram: Choice[],
+  existingProgramNameSelection?: DropdownChoice,
+  newProgramName?: string
+) => {
+  //TODO - Seek clarity on this function and how it should operate.
+  if (!newOrExistingProgram?.[0]?.value)
+    throw new Error(
+      "Program name radio field was not selected as an existing or new report"
+    );
+
+  if (newOrExistingProgram[0].value === "Existing program") {
path: services/ui-src/src/utils/forms/forms.ts
user: login: bangbay-bluetiger
body: Nit: Might be better to use a `switch` statement here.
created_at: 2025-05-06T18:18:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -339,3 +341,29 @@ export const getForm = (params: getFormParams) => {
   }
   return modifiedForm;
 };
+
+export const defineProgramName = (
+  newOrExistingProgram: Choice[],
+  existingProgramNameSelection?: DropdownChoice,
+  newProgramName?: string
+) => {
+  //TODO - Seek clarity on this function and how it should operate.
+  if (!newOrExistingProgram?.[0]?.value)
+    throw new Error(
+      "Program name radio field was not selected as an existing or new report"
+    );
+
+  if (newOrExistingProgram[0].value === "Existing program") {
path: services/ui-src/src/utils/forms/forms.ts
user: login: ntsummers1
body: Done!
created_at: 2025-05-06T18:34:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -217,6 +217,22 @@ export const dropdown = () =>
   object({ label: textSchema(), value: textSchema() }).required(
     error.REQUIRED_GENERIC
   );
+export const dropdownOptional = () =>
+  mixed().test({
+    message: error.INVALID_GENERIC,
+    test: (val) => {
+      switch (typeof val) {
+        case "object":
+          return object({ label: textSchema(), value: string() })
path: services/app-api/utils/validation/completionSchemas.ts
user: login: ntsummers1
body: Added :D 
created_at: 2025-05-06T18:45:55Z
author_association: CONTRIBUTOR

PR comments:
user: login: qlty-cloud-legacy[bot]
created_at: 2025-05-05T21:56:32Z
body: ### [2 new issues](https://qlty.sh/gh/Enterprise-CMCS/projects/macpro-mdct-mcr/pull/12155/issues)

|Tool|Category|Rule|Count|
|----|--------|----|-----|
|qlty|Duplication|Found 89 lines of similar code in 2 locations \(mass = 272\)|2|


<sub>This is from Qlty Cloud, the successor to Code Climate Quality. <a href="https://qlty.sh/d/migration-overview">Learn more</a>.</sub>
<a href="#analysis-summary-comment"></a>
author_association: NONE
user: login: qlty-cloud-legacy[bot]
created_at: 2025-05-06T16:38:56Z
body: Code Climate has analyzed commit f4e20f78 and detected **4 issues** on this pull request.

Here's the issue category breakdown:

| Category | Count |
|:---:|:---:|
| Duplication | 4 |


The test coverage on the diff in this pull request is **93.1%** (**90%** is the threshold).

This pull request will bring the total coverage in the repository to **97.1%** (**0.0%** change).

View more on [Code Climate](https://codeclimate.com/repos/644971a20bd7db00dfeaf21a/pull/12155).

author_association: NONE