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

Draft
wants to merge 3 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

🔬 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 WIP

  1. Navigate to http://localhost:3000
  2. Click button "Log in with Business BCeID"
  3. Navigate to Bugle SFO - Registered: http://localhost:3000/reporting/reports/1/verification
    image
  4. Navigate to Banana LFO - Registered: http://localhost:3000/reporting/reports/2/verification
    image

@shon-button shon-button force-pushed the feat/410-verification-lfo branch 6 times, most recently from 38b4e0b to ed75993 Compare January 23, 2025 16:46
@shon-button shon-button force-pushed the feat/410-verification-lfo branch from 94022f2 to 828d63c Compare January 24, 2025 15:28
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
@shon-button shon-button force-pushed the feat/410-verification-lfo branch 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 +90
# 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 +21
# 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

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