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

[Issue #3874] Create Rough Tables for Opportunity Applicate package #3906

Open
wants to merge 44 commits into
base: main
Choose a base branch
from

Conversation

babebe
Copy link
Collaborator

@babebe babebe commented Feb 14, 2025

Summary

Fixes #{3874}

Time to review: 15 mins

Rough Tables Created
opportunity_application_form
opportunity_competition_form
opportunity_competition
opportunity_competition_assistance_listing
opportunity_competition_instruction

Factories created

@@ -451,3 +457,80 @@ class OpportunityChangeAudit(ApiSchemaTable, TimestampMixin):
BigInteger, ForeignKey(Opportunity.opportunity_id), primary_key=True, index=True
)
opportunity: Mapped[Opportunity] = relationship(Opportunity)


class OpportunityCompetition(ApiSchemaTable, TimestampMixin):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could we put these in a competition_models.py file - just want to avoid the opportunity file getting really long, and there are going to be a lot of additional tables we need for this. We can also name the tables without prefixing with Opportunity - they're all sorta a part of it, but separate enough

Comment on lines 98 to 100
opportunity_competition: Mapped[list["OpportunityCompetition"]] = relationship(
back_populates="opportunity", uselist=True, cascade="all, delete-orphan"
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

FYI - if you move these models to another file, you might hit an issue with this having a circular import. You can work around that by adding the import to the if TYPE_CHECKING line towards the top of this file: https://github.com/HHS/simpler-grants-gov/blob/main/api/src/db/models/opportunity_models.py#L26

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

__tablename__ = "opportunity_competition_assistance_listing"

competition_id: Mapped[uuid.UUID] = mapped_column(
UUID, ForeignKey(OpportunityCompetition.competition_id), index=True, primary_key=True
Copy link
Collaborator

Choose a reason for hiding this comment

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

We don't need to index if it's the primary key - I might have something like that on some of our many-to-many tables, but that was a holdover from me testing some performance ideas a while back (I don't think they ever worked?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, makes sense. Removed

opportunity = factory.SubFactory(OpportunityFactory)
opportunity_id = factory.LazyAttribute(lambda o: o.opportunity.opportunity_id)

competition_id = Generators.UuidObj
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could we put the primary key at the top of the factories? I generally just keep everything in the same order as the class itself.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Moved to top

Comment on lines 1834 to 1836
legacy_competition_id = sometimes_none(factory.Faker("random_int", min=1, max=15))
public_competition_id = sometimes_none(factory.Faker("random_int", min=1, max=15))
legacy_package_id = sometimes_none(factory.Faker("random_int", min=1, max=15))
Copy link
Collaborator

Choose a reason for hiding this comment

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

For these, my recommendation:

  • don't set legacy_competition_id -> it's a pointer back to the old system, only our transform logic will ever care about it / want it set.
  • public_competition_id -> It's actually a string with some variance in how it can be set, I'd just put something like ABC<number> to make it look sorta like the old system (keep the sometimes_none)
  • legacy_package_id - This looks to be formatted as PKG<number>, probably just do that as well? (keep the sometimes_none).

)

grace_period = factory.Faker("random_int", min=1, max=10)
contact_info = sometimes_none(factory.Faker("sentence"))
Copy link
Collaborator

Choose a reason for hiding this comment

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

I setup a contact info faker provider previously, could use agency_contact_description for this to get it to roughly look like contact info

Comment on lines 1868 to 1873
form_id = Generators.UuidObj
form_name = factory.Faker("sentence")
form_version = factory.Faker("sentence")
is_active = False
description = factory.Faker("sentence")
agency_code_id = factory.Faker("sentence")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Some suggestions:

form_version: Mapped[str]
is_active: Mapped[bool]
description: Mapped[str]
agency_code_id: Mapped[str]
Copy link
Collaborator

Choose a reason for hiding this comment

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

On second thought, let's just name this agency_code like we have on the opportunity

form_name: Mapped[str]
form_version: Mapped[str]
is_active: Mapped[bool]
description: Mapped[str]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yknow what, on second thought, I don't even know what this description refers to, let's drop this column. It's not on the form UI, so let's hold off on it for now

sa.Column("form_id", sa.UUID(), nullable=False),
sa.Column("form_name", sa.Text(), nullable=False),
sa.Column("form_version", sa.Text(), nullable=False),
sa.Column("is_active", sa.Boolean(), nullable=False),
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should think through the lifecycle a bit more than just currently active or inactive. Do we need to have a "available after"/"available until" kind of dates when a form is "depreciated" or "retired?" For example what if SF-424 v4 is live now and v5 gets approved and added to the system. Do all applications switch immediately? Do new application packages only show v5 when selecting what forms to add? Is there a period where both remain pick-able when setting up an application package? Even if we just have active, I think it'd be good to have this be a date/time and have it be called like inactive_at and that date then controls if it's shown and also provides more of a history of when it became inactivated, can be set for a future date, etc.

If we want to move this forward in the short term, maybe just make this a timestamp instead of boolean and re-name it accordingly and then we can always add an "active_at" column in the future if we need more specifics of a lifecycle.

Copy link
Collaborator Author

@babebe babebe Feb 18, 2025

Choose a reason for hiding this comment

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

@mdragon These were initially considered basic columns, with the plan to add more as needed. I believe it's a good idea to include both inactive_at and active_at columns, as it's generally better for each column to serve a single purpose rather than combining logic. Thoughts?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think that makes sense for now and then yes, we absolutely shouldn't try to make perfect tables out of the gate and anticipate revisions and improvements as we work with the tables and learn more about the functionality. 👍🏻

Copy link
Collaborator Author

@babebe babebe Feb 18, 2025

Choose a reason for hiding this comment

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

Added inactive_at -nullable and active_at-non-nullable datetime columns and updated factory

@babebe babebe requested a review from mdragon February 18, 2025 18:26
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.

4 participants