Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: 410 Report Verification - LFO #2714

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from

Conversation

shon-button
Copy link
Contributor

@shon-button shon-button commented Jan 21, 2025

Addresses 410

🚀 Impact:

  • Model Splitting: The ReportVerification model was split to move visit-related fields (visit_name, visit_type, other_facility_name, other_facility_coordinates) into a new model, ReportVerificationVisit
  • New Relationship: ForeignKey relationship from ReportVerificationVisit to ReportVerification
  • New Constraint: CheckConstraint in ReportVerificationVisit to enforce that visit_coordinates must be provided when is_other_visit=True
  • Database schemas: updated to introduce the new verification_visit table

📝 To Dos:

  • Possibly refactor the RJSF schema(s) to apply all rules, unless this is not possible when applying rules based on dynamic values. See tech debt ticket for more details: 536

🔬 Local Testing:

  1. From terminal command, start the api server:
cd bc_obps
make reset_db
make run
  1. From terminal command, start the app development server:
cd bciers && yarn dev-all

Tests SFO "Site(s) Visited" conditional fields*

  1. Navigate to http://localhost:3000
  2. Click button "Log in with Business BCeID"
  3. Navigate to Bugle SFO - Registered verification step: http://localhost:3000/reporting/reports/1/verification
  4. Complete the form with field value Site(s) Visited= "None"
  5. Click button Save & Continue
    Expected Results
  • Form data is saved to the database
  • Attachment page is displayed
  1. Navigate to Bugle SFO - Registered verification step: http://localhost:3000/reporting/reports/1/verification
    Expected Results
  • Form data is displayed from the database
    image
  1. Complete the form with field value Site(s) Visited= "Other"
  2. Click button Save & Continue
    Expected Results
  • Form data is saved to the database
  • Attachment page is displayed
  1. Navigate to Bugle SFO - Registered verification step: http://localhost:3000/reporting/reports/1/verification
    Expected Results
  • Form data is displayed from the database
    image
  1. Complete the form with field value Site(s) Visited= "Facility 22"
  2. Click button Save & Continue
    Expected Results
  • Form data is saved to the database
  • Attachment page is displayed
  1. Navigate to Bugle SFO - Registered verification step: http://localhost:3000/reporting/reports/1/verification
    Expected Results
  • Form data is displayed from the database
    image

Tests LFO "Site(s) Visited" conditional fields*

  1. Navigate to http://localhost:3000
  2. Click button "Log in with Business BCeID"
  3. Navigate to Banana LFO - Registered verification step: http://localhost:3000/reporting/reports/2/verification
  4. Complete the form with field value Site(s) Visited= "None"
  5. Click button Save & Continue
    Expected Results
  • Form data is saved to the database
  • Attachment page is displayed
  1. Navigate to Banana LFO - Registered verification step: http://localhost:3000/reporting/reports/2/verification
    Expected Results
  • Form data is displayed from the database
    image
  1. Complete the form with field value Site(s) Visited= "Other"
  2. Click button Save & Continue
    Expected Results
  • Form data is saved to the database
  • Attachment page is displayed
  1. Navigate to ``Banana LFO - Registered verification step: http://localhost:3000/reporting/reports/2/verification
    Expected Results
  • Form data is displayed from the database
    image
  1. Complete the form with field value Site(s) Visited= "Facility 1"
  2. Click button Save & Continue
    Expected Results
  • Form data is saved to the database
  • Attachment page is displayed
  1. Navigate to Banana LFO - Registered verification step: http://localhost:3000/reporting/reports/2/verification
    Expected Results
  • Form data is displayed from the database
    image

@shon-button shon-button force-pushed the feat/410-verification-lfo branch 8 times, most recently from 1c5ce43 to 26f888f Compare January 24, 2025 20:45
Copy link
Contributor

@pbastia pbastia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!! I've left a few comments, mostly small stuff.

I think there's some RJSF features that we can use to cut down on the schema/data manipulation, ideally we're writing code where only the form drives the data, and the components only needs to (hopefully not too much) transform it before submitting it to the API

constraints = [
models.CheckConstraint(
name="other_facility_must_have_coordinates",
check=~Q(is_other_visit=True) | Q(visit_coordinates__isnull=False),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to exclude the case "is_other_visit=True and visit_coordinates__isnull=True"

check=~(Q(is_other_visit=True) & Q(visit_coordinates__isnull=True))

Comment on lines 11 to 15
verification_body_name: str = Field(...)
accredited_by: str = Field(...)
scope_of_verification: str = Field(...)
threats_to_independence: bool = Field(...)
verification_conclusion: str = Field(...)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are redundant with the fields = ... in the Meta class, we can just delete these lines

Comment on lines 32 to 35
visit_name: str = Field(...)
visit_type: str = Field(choices=ReportVerificationVisit.VisitType.choices)
is_other_visit: bool = Field(...)
visit_coordinates: str = Field(required=False)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, I think the choices and required options will be inferred from the model if we just remove these lines

report_verification_visits: List[ReportVerificationVisitSchema] = Field(default_factory=list)

class Meta(BaseReportVerification.Meta):
fields = BaseReportVerification.Meta.fields + ['report_version']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all these schemas we could actually generate them dynamically, since they're just a subset of the fields on the model: https://django-ninja.dev/guides/response/django-pydantic-create-schema/

@@ -13,17 +15,19 @@ class ReportVerificationService:
@staticmethod
def get_report_verification_by_version_id(
report_version_id: int,
) -> ReportVerification:
) -> ReportVerificationOut:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should consider decoupling the service layer from the API layer who owns these data structures. The service layer can declare similar types, or just return the Model types

Comment on lines 85 to 83
# Fetch ReportVerificationVisit instances corresponding to the IDs
visit_instances_to_keep = ReportVerificationVisit.objects.filter(id__in=visit_ids_to_keep)

# Update report_verification_visits
report_verification.report_verification_visits.set(visit_instances_to_keep)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is necessary, all the ReportVerificationVisit models have been created with the right report_verification field set, and this is not an m2m relationship.
We can remove these few lines

Comment on lines 14 to 25
# Create related ReportVerificationVisit instances and link them
report_verification_visits = baker.make_recipe(
"reporting.tests.utils.report_verification_visit",
_quantity=2,
)

# Attach the visits to the report_verification instance
self.report_verification.report_verification_visits.set(report_verification_visits)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Create related ReportVerificationVisit instances and link them
report_verification_visits = baker.make_recipe(
"reporting.tests.utils.report_verification_visit",
_quantity=2,
)
# Attach the visits to the report_verification instance
self.report_verification.report_verification_visits.set(report_verification_visits)
# Create related ReportVerificationVisit instances and link them
report_verification_visits = baker.make_recipe(
"reporting.tests.utils.report_verification_visit",
report_verification=report_verification,
_quantity=2,
)

is_other_visit: true,
visit_coordinates: formData.visit_others.visit_coordinates || "",
});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure there is a way to bake this in to the rjsf structure instead, with if then else or oneOf / anyOf. Happy to try to pair on that if you want!

}
}

// 🔄 Update the form data state with the modified data
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a LOT of logic to run on every single key stroke on the form. I think it would be very helpful to try to build this logic into the schema itself instead

initialData.visit_types = undefined;
initialData.visit_others = [{}];
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like work that could be done on the server by the API layer (maybe in django ninja schema?): preparing the data for the form and the client page

@shon-button shon-button force-pushed the feat/410-verification-lfo branch 3 times, most recently from 3040f10 to 8485ae0 Compare January 27, 2025 19:26
@shon-button shon-button marked this pull request as ready for review January 27, 2025 19:27
@shon-button shon-button force-pushed the feat/410-verification-lfo branch 8 times, most recently from 89adb34 to 4b98d13 Compare January 31, 2025 17:26
chore: update verification service

chore: cleanup

chore: cleanup

test: verification api get

chore: add verification operation type

chore: ad shared verification schema properties

chore: add verification dependacncies

chore: shared schemas

chore: refactor SFO updateReportVerificationVisits

chore: cleanup

chore: cleanup
chore: cleanup

chore: cleanup

chore: cleanup
chore: cleanup

chore: cleanup

chore: cleanup

chore: cleanup
@shon-button shon-button force-pushed the feat/410-verification-lfo branch 2 times, most recently from a92a6ca to 6e2de0b Compare January 31, 2025 20:38
chore: cleanup

chore: cleanup

chore: cleanup

chore: cleanup

chore: cleanup

chore: cleanup
@shon-button shon-button force-pushed the feat/410-verification-lfo branch from 01fe7f5 to 487640d Compare January 31, 2025 21:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants