Skip to content
Open

Dev #885

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
3036c81
Reformat with ruff
maxachis Sep 12, 2025
7da2243
Merge pull request #872 from Police-Data-Accessibility-Project/mc_869…
maxachis Sep 12, 2025
dfa721b
Deprecate logic
maxachis Sep 15, 2025
1137200
Finish deprecating endpoints
maxachis Sep 15, 2025
08639ba
Merge pull request #873 from Police-Data-Accessibility-Project/mc_869…
maxachis Sep 15, 2025
3b313c0
Merge pull request #874 from Police-Data-Accessibility-Project/mc_sm_…
maxachis Sep 23, 2025
6c95104
Begin draft
maxachis Sep 30, 2025
1955d69
Add Meta URL Sync endpoint
maxachis Sep 30, 2025
f1a5518
Format with ruff
maxachis Sep 30, 2025
76e6e44
Merge pull request #878 from Police-Data-Accessibility-Project/mc_add…
maxachis Sep 30, 2025
9680b1f
Add agency ID as return value
maxachis Oct 3, 2025
8eac526
Merge pull request #879 from Police-Data-Accessibility-Project/mc_add…
maxachis Oct 3, 2025
5da6fc2
Retire Internet Archives endpoints
maxachis Oct 5, 2025
1a67b02
Ruff format and fix
maxachis Oct 5, 2025
5b95ca8
Merge pull request #880 from Police-Data-Accessibility-Project/mc_388…
maxachis Oct 5, 2025
e6c2374
Begin draft
maxachis Oct 9, 2025
fb7ff9a
Deprecate logic
maxachis Oct 9, 2025
f022ab2
Finish draft
maxachis Oct 9, 2025
0625bcd
Format with ruff
maxachis Oct 9, 2025
0377a9e
Merge pull request #882 from Police-Data-Accessibility-Project/mc_881…
maxachis Oct 9, 2025
b1ce640
Fix bug with search
maxachis Oct 9, 2025
7645b3c
Merge pull request #883 from Police-Data-Accessibility-Project/mc_881…
maxachis Oct 9, 2025
591f1b9
Fix bug for coverage start, coverage end, and municipality type valid…
maxachis Oct 9, 2025
c12551f
Merge pull request #884 from Police-Data-Accessibility-Project/mc_881…
maxachis Oct 9, 2025
15576f6
Fix bug for coverage start, coverage end, and municipality type valid…
maxachis Oct 9, 2025
c947a79
Fix bug for coverage start, coverage end, and municipality type valid…
maxachis Oct 9, 2025
8bab9bb
Removal `proposals` namespace and agency proposal logic
maxachis Oct 12, 2025
d9e8505
Remove data sources/agencies approval status and related logic
maxachis Oct 12, 2025
ceffd41
Merge pull request #886 from Police-Data-Accessibility-Project/mc_857…
maxachis Oct 12, 2025
6feb8bd
Add FastAPI component and Source Collector Followed Locations Sync
maxachis Oct 13, 2025
0a1fcd3
Format with Ruff
maxachis Oct 13, 2025
02e393a
Format with Ruff
maxachis Oct 13, 2025
1063715
Merge pull request #888 from Police-Data-Accessibility-Project/mc_sm_…
maxachis Oct 13, 2025
446ade2
Fix bugs in `app.py` and `execute.sh`
maxachis Oct 13, 2025
9bf080e
Fix bugs in `app.py`
maxachis Oct 13, 2025
d1af9b8
Fix bugs in `app.py`
maxachis Oct 13, 2025
afa77f3
Fix bugs in `app.py`
maxachis Oct 13, 2025
67575e7
Fix bugs in `app.py`
maxachis Oct 13, 2025
99211d7
Fix bugs in `app.py`
maxachis Oct 13, 2025
b8cc5b4
Fix bugs in `app.py`
maxachis Oct 13, 2025
431d1b8
Fix bugs in `app.py`
maxachis Oct 13, 2025
56dec89
Fix bugs in `app.py`
maxachis Oct 13, 2025
b7e7d97
Fix bugs in `app.py`
maxachis Oct 13, 2025
8f3e365
Fix bugs in `app.py`
maxachis Oct 13, 2025
433b716
Fix bugs in `app.py`
maxachis Oct 13, 2025
98b4392
Adjust test routes
maxachis Oct 13, 2025
ca1a2d1
Remove/modify deprecated agencies columns
maxachis Oct 21, 2025
cbb0f4c
Ruff format and fix
maxachis Oct 21, 2025
81e3ee5
Fix updated at trigger
maxachis Oct 21, 2025
2af1e32
Merge pull request #893 from Police-Data-Accessibility-Project/mc_upd…
maxachis Oct 21, 2025
5b126e7
Update data sources database columns
maxachis Oct 21, 2025
339a8e5
Format with ruff
maxachis Oct 21, 2025
6264a19
Removed unused test
maxachis Oct 21, 2025
efcc40e
Format with ruff
maxachis Oct 21, 2025
9e9e90c
Format with ruff
maxachis Oct 21, 2025
eb14471
Merge pull request #894 from Police-Data-Accessibility-Project/mc_upd…
maxachis Oct 21, 2025
9331886
Format with ruff
maxachis Oct 21, 2025
e75d4dc
Merge pull request #895 from Police-Data-Accessibility-Project/mc_upd…
maxachis Oct 21, 2025
091786d
Format with ruff
maxachis Oct 21, 2025
672922d
Merge pull request #896 from Police-Data-Accessibility-Project/mc_upd…
maxachis Oct 21, 2025
79d3470
Add new source manager v3 endpoints
maxachis Oct 28, 2025
3207e1b
Format with ruff
maxachis Oct 28, 2025
ddeb134
Add pyright ignore
maxachis Oct 28, 2025
d91d656
Adjust test to eliminate order variability.
maxachis Oct 28, 2025
aa87a73
Merge pull request #897 from Police-Data-Accessibility-Project/mc_864…
maxachis Oct 28, 2025
ed7919b
Re-add data source post endpoint (for now)
maxachis Oct 28, 2025
d7c4fcd
Format with ruff
maxachis Oct 28, 2025
1b5f951
Merge pull request #898 from Police-Data-Accessibility-Project/re_add…
maxachis Oct 28, 2025
a8a801f
Fix bug in get user id
maxachis Oct 28, 2025
3f3b286
Merge pull request #899 from Police-Data-Accessibility-Project/re_add…
maxachis Oct 28, 2025
7bae898
Fix bug in placement of `linked_agency_ids`
maxachis Oct 29, 2025
45c6351
Ruff format
maxachis Oct 29, 2025
e3de8a9
Merge pull request #901 from Police-Data-Accessibility-Project/re_add…
maxachis Oct 29, 2025
b03bf72
Fix bug in schema
maxachis Oct 31, 2025
d048753
Merge pull request #903 from Police-Data-Accessibility-Project/re_add…
maxachis Oct 31, 2025
243de63
Begin draft
maxachis Nov 7, 2025
4398b8b
Complete initial draft
maxachis Nov 8, 2025
3fc753f
Reformat with Ruff
maxachis Nov 8, 2025
8334642
Fix bugs in test
maxachis Nov 8, 2025
43dc094
Merge pull request #907 from Police-Data-Accessibility-Project/mc_900…
maxachis Nov 8, 2025
fb33822
Add full overwrite for updates
maxachis Nov 8, 2025
a9d4476
Reformat with ruff
maxachis Nov 8, 2025
c9d7198
Merge pull request #908 from Police-Data-Accessibility-Project/mc_864…
maxachis Nov 8, 2025
f0d2836
Normalize Meta URLs.
maxachis Nov 8, 2025
9b53dd2
Fix attribute error
maxachis Nov 8, 2025
617122e
Fix attribute error
maxachis Nov 8, 2025
a6c3133
Merge pull request #911 from Police-Data-Accessibility-Project/mc_909…
maxachis Nov 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 4 additions & 3 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,13 @@ Previously, SQLAlchemy CTEs and Subqueries were created and referenced via `.c.[
Instead, CTEs and Subqueries should be wrapped in classes positioned in separate `cte.py` files or `cte` subdirectories, where individual columns can be referenced via type-hinted properties that internally reference the `CTE` or `Subquery` attributes via `.c` access. These can then be imported into relevant files.

Example:

```python
from typing import final

from sqlalchemy import select, func

from db.models.implementations import LinkAgencyDataSource
from db.models.implementations.links.agency__data_source import LinkAgencyDataSource


@final
Expand All @@ -65,11 +66,11 @@ class AgencyIdsCTE:
func.unnest(LinkAgencyDataSource.agency_id).label("agency_ids"),
LinkAgencyDataSource.data_source_id,
).cte(name="agency_ids")

@property
def agency_ids(self) -> list[int]:
return self.query.c.agency_ids

@property
def data_source_id(self) -> int:
return self.query.c.data_source_id
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""Remove recent searches table constraint

Revision ID: 8c3153d94dfb
Revises: 2f8bd4749166
Create Date: 2025-10-09 16:46:49.858892

"""

from typing import Sequence, Union

from alembic import op


# revision identifiers, used by Alembic.
revision: str = "8c3153d94dfb"
down_revision: Union[str, None] = "2f8bd4749166"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
op.alter_column(
"recent_searches",
column_name="location_id",
nullable=True,
)


def downgrade() -> None:
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
"""Remove approval status for data sources and agencies

Revision ID: e51211c51b29
Revises: 8c3153d94dfb
Create Date: 2025-10-12 08:57:00.734088

"""

from typing import Sequence, Union

from alembic import op


# revision identifiers, used by Alembic.
revision: str = "e51211c51b29"
down_revision: Union[str, None] = "8c3153d94dfb"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def _delete_agencies_and_data_sources_without_approval():
op.execute("""DELETE FROM data_sources WHERE approval_status != 'approved'""")
op.execute("""DELETE FROM agencies WHERE approval_status != 'approved'""")


def upgrade() -> None:
_delete_agencies_and_data_sources_without_approval()
_drop_views()
_drop_columns()
_rebuild_views()
op.execute("drop trigger update_approval_status_updated_at on data_sources;")
op.execute("drop function update_approval_status_updated_at;")


def _rebuild_views():
op.execute("""
create materialized view distinct_source_urls as
SELECT DISTINCT rtrim(ltrim(ltrim(ltrim(data_sources.source_url::text, 'https://'::text), 'http://'::text),
'www.'::text), '/'::text) AS base_url,
data_sources.source_url AS original_url
FROM data_sources
WHERE data_sources.source_url IS NOT NULL;
""")
op.execute("""
create materialized view typeahead_agencies as
SELECT
a.id,
a.name,
a.jurisdiction_type,
l.state_iso,
l.locality_name AS municipality,
l.county_name
FROM
agencies a
LEFT JOIN link_agencies_locations lal ON lal.agency_id = a.id
LEFT JOIN locations_expanded l ON lal.location_id = l.id
""")
op.execute("""
create view data_sources_expanded
(name, description, source_url, agency_supplied, supplying_entity, agency_originated, agency_aggregation,
coverage_start, coverage_end, updated_at, detail_level, data_portal_type, update_method, readme_url,
originating_entity, retention_schedule, id, scraper_url, created_at, submission_notes,
agency_described_not_in_database, data_portal_type_other,
data_source_request, broken_source_url_as_of, access_notes, url_status, record_type_id,
record_type_name, access_types, tags, record_formats)
as
SELECT
ds.name,
ds.description,
ds.source_url,
ds.agency_supplied,
ds.supplying_entity,
ds.agency_originated,
ds.agency_aggregation,
ds.coverage_start,
ds.coverage_end,
ds.updated_at,
ds.detail_level,
ds.data_portal_type,
ds.update_method,
ds.readme_url,
ds.originating_entity,
ds.retention_schedule,
ds.id,
ds.scraper_url,
ds.created_at,
ds.submission_notes,
ds.agency_described_not_in_database,
ds.data_portal_type_other,
ds.data_source_request,
ds.broken_source_url_as_of,
ds.access_notes,
ds.url_status,
ds.record_type_id,
rt.name AS record_type_name,
ds.access_types,
ds.tags,
ds.record_formats
FROM
data_sources ds
LEFT JOIN record_types rt
ON ds.record_type_id = rt.id

""")


def _drop_views():
op.execute("""drop view data_sources_expanded""")
op.execute("""drop materialized view distinct_source_urls""")
op.execute("""drop materialized view typeahead_agencies""")


def _drop_columns():
op.drop_column(table_name="data_sources", column_name="approval_status")
op.drop_column(table_name="data_sources", column_name="last_approval_editor")
op.drop_column(table_name="data_sources", column_name="submitter_contact_info")
op.drop_column(table_name="data_sources", column_name="approval_status_updated_at")
op.drop_column(table_name="agencies", column_name="approval_status")
op.drop_column(table_name="agencies", column_name="last_approval_editor")
op.drop_column(table_name="agencies", column_name="creator_user_id")
op.drop_column(table_name="agencies", column_name="rejection_reason")
op.drop_column(table_name="agencies", column_name="submitter_contact")


def downgrade() -> None:
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""Remove unneeded agencies columns

Revision ID: a41df84338bb
Revises: e51211c51b29
Create Date: 2025-10-21 09:55:20.961243

"""

from typing import Sequence, Union

from alembic import op


# revision identifiers, used by Alembic.
revision: str = "a41df84338bb"
down_revision: Union[str, None] = "e51211c51b29"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None

AGENCIES_TABLE_NAME: str = "agencies"


def upgrade() -> None:
op.alter_column(
table_name=AGENCIES_TABLE_NAME,
column_name="agency_created",
new_column_name="created_at",
)
op.drop_column(AGENCIES_TABLE_NAME, "multi_agency")
op.drop_column(AGENCIES_TABLE_NAME, "airtable_agency_last_modified")
op.drop_column(AGENCIES_TABLE_NAME, "airtable_uid")
op.execute("""
DROP TRIGGER IF EXISTS set_agency_updated_at ON public.agencies
""")
op.execute("""
DROP FUNCTION IF EXISTS update_airtable_agency_last_modified_column
""")

op.execute("""
CREATE OR REPLACE FUNCTION update_agency_updated_at_column()

RETURNS TRIGGER language plpgsql AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$
""")

op.execute("""
CREATE TRIGGER set_agency_updated_at
BEFORE UPDATE ON public.agencies
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE FUNCTION update_agency_updated_at_column()
""")


def downgrade() -> None:
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
"""Clean up data sources table structure

Revision ID: a1a8d636f4dd
Revises: a41df84338bb
Create Date: 2025-10-21 11:33:46.002274

"""

from typing import Sequence, Union

from alembic import op


# revision identifiers, used by Alembic.
revision: str = "a1a8d636f4dd"
down_revision: Union[str, None] = "a41df84338bb"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None

DATA_SOURCES_TABLE_NAME: str = "data_sources"


def upgrade() -> None:
op.execute("""
drop view data_sources_expanded
""")

op.alter_column(
table_name=DATA_SOURCES_TABLE_NAME, column_name="record_type_id", nullable=True
)
# Drop columns
op.drop_column(
table_name=DATA_SOURCES_TABLE_NAME,
column_name="airtable_uid",
)
op.drop_column(
table_name=DATA_SOURCES_TABLE_NAME,
column_name="tags",
)
op.drop_column(
table_name=DATA_SOURCES_TABLE_NAME, column_name="broken_source_url_as_of"
)
op.drop_column(
table_name=DATA_SOURCES_TABLE_NAME,
column_name="record_download_option_provided",
)
op.drop_column(
table_name=DATA_SOURCES_TABLE_NAME, column_name="data_source_request"
)
op.drop_column(table_name=DATA_SOURCES_TABLE_NAME, column_name="submission_notes")

op.execute("""
create view data_sources_expanded
(name, description, source_url, agency_supplied, supplying_entity, agency_originated, agency_aggregation,
coverage_start, coverage_end, updated_at, detail_level, data_portal_type, update_method, readme_url,
originating_entity, retention_schedule, id, scraper_url, created_at,
agency_described_not_in_database, data_portal_type_other,
access_notes, url_status, record_type_id, record_type_name, access_types, record_formats)
as
SELECT
ds.name,
ds.description,
ds.source_url,
ds.agency_supplied,
ds.supplying_entity,
ds.agency_originated,
ds.agency_aggregation,
ds.coverage_start,
ds.coverage_end,
ds.updated_at,
ds.detail_level,
ds.data_portal_type,
ds.update_method,
ds.readme_url,
ds.originating_entity,
ds.retention_schedule,
ds.id,
ds.scraper_url,
ds.created_at,
ds.agency_described_not_in_database,
ds.data_portal_type_other,
ds.access_notes,
ds.url_status,
ds.record_type_id,
rt.name AS record_type_name,
ds.access_types,
ds.record_formats
FROM
data_sources ds
LEFT JOIN record_types rt
ON ds.record_type_id = rt.id

""")


def downgrade() -> None:
pass
Loading
Loading