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 2716] Create user tables for basic login.gov #2760

Merged
merged 29 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
118b2cd
add user tables
babebe Nov 7, 2024
32a30cb
fix lookup column, add migration script
babebe Nov 7, 2024
21659f4
Create ERD diagram and Update OpenAPI spec
nava-platform-bot Nov 7, 2024
3f0e051
[Issue #2729] OpenSearch should return an accurate count of total res…
chouinar Nov 7, 2024
7cb5499
[no ticket] update labeler action version (#2769)
coilysiren Nov 7, 2024
f30cbf3
[Issue 2665] Add gh-transform-and-load command to scheduled jobs (#2759)
DavidDudas-Intuitial Nov 7, 2024
8b88155
[Issue 2665] Add new job to initialize EtlDb (#2778)
DavidDudas-Intuitial Nov 7, 2024
419b3aa
[no ticket] Fix infinite state locks (#2779)
coilysiren Nov 7, 2024
20b20ed
clean
babebe Nov 7, 2024
5423ba6
Merge branch 'main' into 2716/basic-user-tables
babebe Nov 7, 2024
2d7d03b
migration file
babebe Nov 7, 2024
13e5c78
migration file
babebe Nov 8, 2024
e08aa94
delete old migration file
babebe Nov 8, 2024
e66e66a
Merge branch 'main' into 2716/basic-user-tables
babebe Nov 8, 2024
739a1f8
update LinkExternalUserFactory.external_user_id to generate uuid
babebe Nov 8, 2024
4113135
index external_user_id field
babebe Nov 8, 2024
5c30c91
update migration script
babebe Nov 8, 2024
162cd05
Merge branch '2716/basic-user-tables' of https://github.com/HHS/simpl…
babebe Nov 8, 2024
cba71ce
rm first&last name from user models
babebe Nov 12, 2024
cb7ff81
rm local erd
babebe Nov 12, 2024
8bd60a6
rm old migration file
babebe Nov 12, 2024
746abd5
add new migration file
babebe Nov 12, 2024
0ca0e87
Create ERD diagram and Update OpenAPI spec
nava-platform-bot Nov 12, 2024
09bd823
merge main
babebe Nov 12, 2024
c3860f6
Merge branch '2716/basic-user-tables' of https://github.com/HHS/simpl…
babebe Nov 12, 2024
b8d50ef
cleanup
babebe Nov 12, 2024
6e3ef27
Merge branch 'main' of https://github.com/HHS/simpler-grants-gov into…
babebe Nov 12, 2024
ba1173a
rm first&last name from factories
babebe Nov 12, 2024
06eacb8
Merge branch 'main' of https://github.com/HHS/simpler-grants-gov into…
babebe Nov 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions api/src/constants/lookup_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,7 @@ class AgencySubmissionNotificationSetting(StrEnum):
class OpportunityAttachmentType(StrEnum):
NOTICE_OF_FUNDING_OPPORTUNITY = "notice_of_funding_opportunity"
OTHER = "other"


class ExternalUserType(StrEnum):
LOGIN_GOV = "login_gov"
130 changes: 130 additions & 0 deletions api/src/db/migrations/versions/2024_11_12_add_basic_user_tables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
"""add_basic_user_tables

Revision ID: 65e962033cc6
Revises: 3640e31e6a85
Create Date: 2024-11-12 17:14:12.947794

"""

import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "65e962033cc6"
down_revision = "3640e31e6a85"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"lk_external_user_type",
sa.Column("external_user_type_id", sa.Integer(), nullable=False),
sa.Column("description", sa.Text(), nullable=False),
sa.Column(
"created_at",
sa.TIMESTAMP(timezone=True),
server_default=sa.text("now()"),
nullable=False,
),
sa.Column(
"updated_at",
sa.TIMESTAMP(timezone=True),
server_default=sa.text("now()"),
nullable=False,
),
sa.PrimaryKeyConstraint("external_user_type_id", name=op.f("lk_external_user_type_pkey")),
schema="api",
)
op.create_table(
"user",
sa.Column("user_id", sa.UUID(), nullable=False),
sa.Column(
"created_at",
sa.TIMESTAMP(timezone=True),
server_default=sa.text("now()"),
nullable=False,
),
sa.Column(
"updated_at",
sa.TIMESTAMP(timezone=True),
server_default=sa.text("now()"),
nullable=False,
),
sa.PrimaryKeyConstraint("user_id", name=op.f("user_pkey")),
schema="api",
)
op.create_table(
"link_external_user",
sa.Column("link_external_user_id", sa.UUID(), nullable=False),
sa.Column("external_user_id", sa.Text(), nullable=False),
sa.Column("user_id", sa.UUID(), nullable=False),
sa.Column("external_user_type_id", sa.Integer(), nullable=False),
sa.Column("email", sa.Text(), nullable=False),
sa.Column(
"created_at",
sa.TIMESTAMP(timezone=True),
server_default=sa.text("now()"),
nullable=False,
),
sa.Column(
"updated_at",
sa.TIMESTAMP(timezone=True),
server_default=sa.text("now()"),
nullable=False,
),
sa.ForeignKeyConstraint(
["external_user_type_id"],
["api.lk_external_user_type.external_user_type_id"],
name=op.f("link_external_user_external_user_type_id_lk_external_user_type_fkey"),
),
sa.ForeignKeyConstraint(
["user_id"], ["api.user.user_id"], name=op.f("link_external_user_user_id_user_fkey")
),
sa.PrimaryKeyConstraint("link_external_user_id", name=op.f("link_external_user_pkey")),
schema="api",
)
op.create_index(
op.f("link_external_user_external_user_id_idx"),
"link_external_user",
["external_user_id"],
unique=True,
schema="api",
)
op.create_index(
op.f("link_external_user_external_user_type_id_idx"),
"link_external_user",
["external_user_type_id"],
unique=False,
schema="api",
)
op.create_index(
op.f("link_external_user_user_id_idx"),
"link_external_user",
["user_id"],
unique=False,
schema="api",
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(
op.f("link_external_user_user_id_idx"), table_name="link_external_user", schema="api"
)
op.drop_index(
op.f("link_external_user_external_user_type_id_idx"),
table_name="link_external_user",
schema="api",
)
op.drop_index(
op.f("link_external_user_external_user_id_idx"),
table_name="link_external_user",
schema="api",
)
op.drop_table("link_external_user", schema="api")
op.drop_table("user", schema="api")
op.drop_table("lk_external_user_type", schema="api")
# ### end Alembic commands ###
3 changes: 2 additions & 1 deletion api/src/db/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging

from . import agency_models, base, lookup_models, opportunity_models
from . import agency_models, base, lookup_models, opportunity_models, user_models
from .transfer import topportunity_models

logger = logging.getLogger(__name__)
Expand All @@ -15,4 +15,5 @@
"lookup_models",
"topportunity_models",
"agency_models",
"user_models",
]
17 changes: 17 additions & 0 deletions api/src/db/models/lookup_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
AgencyDownloadFileType,
AgencySubmissionNotificationSetting,
ApplicantType,
ExternalUserType,
FundingCategory,
FundingInstrument,
OpportunityAttachmentType,
Expand Down Expand Up @@ -114,6 +115,8 @@
]
)

EXTERNAL_USER_TYPE_CONFIG = LookupConfig([LookupStr(ExternalUserType.LOGIN_GOV, 1)])


@LookupRegistry.register_lookup(OPPORTUNITY_CATEGORY_CONFIG)
class LkOpportunityCategory(LookupTable, TimestampMixin):
Expand Down Expand Up @@ -227,3 +230,17 @@ def from_lookup(cls, lookup: Lookup) -> "LkOpportunityAttachmentType":
opportunity_attachment_type_id=lookup.lookup_val,
description=lookup.get_description(),
)


@LookupRegistry.register_lookup(EXTERNAL_USER_TYPE_CONFIG)
class LkExternalUserType(LookupTable, TimestampMixin):
__tablename__ = "lk_external_user_type"

external_user_type_id: Mapped[int] = mapped_column(primary_key=True)
description: Mapped[str]

@classmethod
def from_lookup(cls, lookup: Lookup) -> "LkExternalUserType":
return LkExternalUserType(
external_user_type_id=lookup.lookup_val, description=lookup.get_description()
)
35 changes: 35 additions & 0 deletions api/src/db/models/user_models.py
babebe marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import uuid

from sqlalchemy import ForeignKey
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column, relationship

from src.adapters.db.type_decorators.postgres_type_decorators import LookupColumn
from src.db.models.base import ApiSchemaTable, TimestampMixin
from src.db.models.lookup_models import LkExternalUserType


class User(ApiSchemaTable, TimestampMixin):
__tablename__ = "user"

user_id: Mapped[uuid.UUID] = mapped_column(UUID, primary_key=True)


class LinkExternalUser(ApiSchemaTable, TimestampMixin):
__tablename__ = "link_external_user"

link_external_user_id: Mapped[uuid.UUID] = mapped_column(UUID, primary_key=True)

external_user_id: Mapped[str] = mapped_column(index=True, unique=True)

user_id: Mapped[uuid.UUID] = mapped_column(UUID, ForeignKey(User.user_id), index=True)
user: Mapped[User] = relationship(User)

external_user_type: Mapped[int] = mapped_column(
"external_user_type_id",
LookupColumn(LkExternalUserType),
ForeignKey(LkExternalUserType.external_user_type_id),
index=True,
)

email: Mapped[str]
24 changes: 24 additions & 0 deletions api/tests/src/db/models/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@
import src.db.models.opportunity_models as opportunity_models
import src.db.models.staging as staging
import src.db.models.transfer.topportunity_models as transfer_topportunity_models
import src.db.models.user_models as user_models
import src.util.datetime_util as datetime_util
from src.constants.lookup_constants import (
AgencyDownloadFileType,
AgencySubmissionNotificationSetting,
ApplicantType,
ExternalUserType,
FundingCategory,
FundingInstrument,
OpportunityAttachmentType,
Expand Down Expand Up @@ -1833,3 +1835,25 @@ class Meta:

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


class UserFactory(BaseFactory):
class Meta:
model = user_models.User

user_id = Generators.UuidObj


class LinkExternalUserFactory(BaseFactory):
class Meta:
model = user_models.LinkExternalUser

link_external_user_id = Generators.UuidObj
external_user_id = Generators.UuidObj

user = factory.SubFactory(UserFactory)
user_id = factory.LazyAttribute(lambda s: s.user.user_id)

external_user_type_id = factory.fuzzy.FuzzyChoice(ExternalUserType)

email = factory.Faker("email")
Binary file modified documentation/api/database/erds/api-schema.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.