diff --git a/api/docker-compose.yml b/api/docker-compose.yml index 44cb64454..a364c74c3 100644 --- a/api/docker-compose.yml +++ b/api/docker-compose.yml @@ -3,7 +3,7 @@ version: '3' services: grants-db: - image: postgres:14-alpine + image: postgres:15-alpine container_name: grants-db command: postgres -c "log_lock_waits=on" -N 1000 -c "fsync=off" env_file: ./local.env diff --git a/api/src/db/migrations/versions/2024_05_02_add_unique_constraint_for_summary.py b/api/src/db/migrations/versions/2024_05_02_add_unique_constraint_for_summary.py new file mode 100644 index 000000000..8ed298dfb --- /dev/null +++ b/api/src/db/migrations/versions/2024_05_02_add_unique_constraint_for_summary.py @@ -0,0 +1,37 @@ +"""add unique constraint for summary + +Revision ID: 24061ff82646 +Revises: 1ddd1d051a99 +Create Date: 2024-05-02 10:11:35.832837 + +""" +from alembic import op + +# revision identifiers, used by Alembic. +revision = "24061ff82646" +down_revision = "1ddd1d051a99" +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_unique_constraint( + op.f("opportunity_summary_is_forecast_uniq"), + "opportunity_summary", + ["is_forecast", "revision_number", "opportunity_id"], + schema="api", + postgresql_nulls_not_distinct=True, + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_constraint( + op.f("opportunity_summary_is_forecast_uniq"), + "opportunity_summary", + schema="api", + type_="unique", + ) + # ### end Alembic commands ### diff --git a/api/src/db/models/base.py b/api/src/db/models/base.py index ee739fb91..3844a1ad6 100644 --- a/api/src/db/models/base.py +++ b/api/src/db/models/base.py @@ -100,7 +100,7 @@ def __rich_repr__(self) -> Iterable[tuple[str, Any]]: class ApiSchemaTable(Base): __abstract__ = True - __table_args__ = {"schema": Schemas.API} + __table_args__: Any = {"schema": Schemas.API} @declarative_mixin diff --git a/api/src/db/models/opportunity_models.py b/api/src/db/models/opportunity_models.py index 9f19dcd4f..2f8287298 100644 --- a/api/src/db/models/opportunity_models.py +++ b/api/src/db/models/opportunity_models.py @@ -1,6 +1,6 @@ from datetime import date -from sqlalchemy import BigInteger, ForeignKey +from sqlalchemy import BigInteger, ForeignKey, UniqueConstraint from sqlalchemy.ext.associationproxy import AssociationProxy, association_proxy from sqlalchemy.orm import Mapped, mapped_column, relationship @@ -86,6 +86,16 @@ def opportunity_status(self) -> OpportunityStatus | None: class OpportunitySummary(ApiSchemaTable, TimestampMixin): __tablename__ = "opportunity_summary" + __table_args__ = ( + # nulls not distinct makes it so nulls work in the unique constraint + UniqueConstraint( + "is_forecast", "revision_number", "opportunity_id", postgresql_nulls_not_distinct=True + ), + # Need to define the table args like this to inherit whatever we set on the super table + # otherwise we end up overwriting things and Alembic remakes the whole table + ApiSchemaTable.__table_args__, + ) + opportunity_summary_id: Mapped[int] = mapped_column(BigInteger, primary_key=True) opportunity_id: Mapped[int] = mapped_column( diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index bf3352c40..707c3ad10 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -33,7 +33,7 @@ export default function RootLayout({ children }: LayoutProps) { {children} {process.env.NEXT_PUBLIC_ENVIRONMENT === "prod" && ( - + )} ); diff --git a/frontend/src/constants/environments.ts b/frontend/src/constants/environments.ts index aea740956..01ab36724 100644 --- a/frontend/src/constants/environments.ts +++ b/frontend/src/constants/environments.ts @@ -4,13 +4,16 @@ */ const PUBLIC_ENV_VARS_BY_ENV = { development: { - GOOGLE_TAG_ID: "GTM-MV57HMHS", + GOOGLE_TAG_MANAGER_ID: "GTM-MV57HMHS", + GOOGLE_ANALYTICS_ID: "G-6MDCC5EZW2", }, test: { - GOOGLE_TAG_ID: "GTM-MV57HMHS", + GOOGLE_TAG_MANAGER_ID: "GTM-MV57HMHS", + GOOGLE_ANALYTICS_ID: "G-6MDCC5EZW2", }, production: { - GOOGLE_TAG_ID: "GTM-MV57HMHS", + GOOGLE_TAG_MANAGER_ID: "GTM-MV57HMHS", + GOOGLE_ANALYTICS_ID: "G-6MDCC5EZW2", }, } as const; diff --git a/frontend/src/pages/_app.tsx b/frontend/src/pages/_app.tsx index 10db979da..5cf80b206 100644 --- a/frontend/src/pages/_app.tsx +++ b/frontend/src/pages/_app.tsx @@ -20,7 +20,7 @@ function MyApp({ Component, pageProps }: AppProps) { {process.env.NEXT_PUBLIC_ENVIRONMENT === "prod" && ( - + )}