Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
151 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
a0f336d
Add cors middleware
maxachis Nov 10, 2025
c781820
Merge pull request #912 from Police-Data-Accessibility-Project/mc_fas…
maxachis Nov 10, 2025
0185223
Push cors middleware to pirmary starlette app, add explicit origins.
maxachis Nov 10, 2025
69ae0b7
Merge pull request #914 from Police-Data-Accessibility-Project/mc_fas…
maxachis Nov 10, 2025
247c24a
Add dev origins
maxachis Nov 10, 2025
0be6dca
Merge pull request #915 from Police-Data-Accessibility-Project/mc_fas…
maxachis Nov 10, 2025
1b58677
Add dev origins
maxachis Nov 10, 2025
56e5464
Merge pull request #916 from Police-Data-Accessibility-Project/mc_fas…
maxachis Nov 10, 2025
3eb9f20
Add dev origins
maxachis Nov 10, 2025
33bed8f
Merge pull request #917 from Police-Data-Accessibility-Project/mc_fas…
maxachis Nov 10, 2025
1792c86
Clean up `/user` `GET` logic
maxachis Nov 12, 2025
75e27bb
Add logic for catching null record type
maxachis Nov 12, 2025
f052943
Add try-catch logic
maxachis Nov 13, 2025
7887bd2
Ruff format and fix test bug
maxachis Nov 13, 2025
68f25ec
Add additional test for minimal data source post
maxachis Nov 13, 2025
37d3d7a
Format with ruff
maxachis Nov 13, 2025
259c3d2
Merge pull request #921 from Police-Data-Accessibility-Project/mc_900…
maxachis Nov 13, 2025
667e167
Fix bug with duplicate record categories appearing
maxachis Nov 13, 2025
e4520e2
Merge pull request #922 from Police-Data-Accessibility-Project/mc_900…
maxachis Nov 13, 2025
3d2c3f0
Update source collector permission to SOURCE_COLLECTOR_DATA_SOURCES
maxachis Nov 14, 2025
629612c
Add stack trace print to sync query errors
maxachis Nov 14, 2025
603622a
Add stack trace print to `get_access_info` and replace return None wi…
maxachis Nov 14, 2025
ef42e78
Fix query builder to properly return sync message
maxachis Nov 14, 2025
6c31f68
Correct bug in `value_if_enum`
maxachis Nov 15, 2025
4f38cbc
raise BadRequest on expired signature
maxachis Nov 16, 2025
057eaa1
Update access_types and record_formats attributes to not accept null
maxachis Nov 16, 2025
6315f05
Refine authorization to properly raise bad request in expected cases
maxachis Nov 16, 2025
2e7637d
Add translation into FastAPI exception
maxachis Nov 16, 2025
6efc0f8
Adjust to raise Unauthorized on expired token
maxachis Nov 16, 2025
2793751
Remove redundant raising of HTTPException
maxachis Nov 16, 2025
40a9d79
Remove redundant logic
maxachis Nov 16, 2025
9868cee
Add logic for Idempotency with Meta URL and Data Source adds
maxachis Nov 17, 2025
24e678d
Format with ruff
maxachis Nov 17, 2025
7510e40
Merge pull request #926 from Police-Data-Accessibility-Project/mc_868…
maxachis Nov 17, 2025
a4f3832
Add no-op logic
maxachis Nov 18, 2025
0887745
Add logic for including internet archive URLs and URL status
maxachis Nov 18, 2025
03d7843
Format with ruff
maxachis Nov 18, 2025
92655cc
Merge pull request #927 from Police-Data-Accessibility-Project/mc_sc_…
maxachis Nov 18, 2025
faac653
Rename `source-manager` namespace to `sync`
maxachis Nov 19, 2025
3ca897c
Merge pull request #929 from Police-Data-Accessibility-Project/mc_928…
maxachis Nov 19, 2025
2552d2e
Rename link tables
maxachis Nov 19, 2025
7bfc3e4
Format with ruff
maxachis Nov 19, 2025
7af743a
Format with ruff
maxachis Nov 19, 2025
e6a75a8
Merge pull request #930 from Police-Data-Accessibility-Project/mc_910…
maxachis Nov 19, 2025
e9c6f5f
Rename federal query
maxachis Nov 20, 2025
3230e39
Change table references
maxachis Nov 20, 2025
a7259dc
Change table references
maxachis Nov 20, 2025
041f5ad
Change table references
maxachis Nov 20, 2025
81a8629
Correct typo
maxachis Nov 23, 2025
4bf06eb
Add Fuzzy Match to agencies typeahead
maxachis Nov 27, 2025
dafe900
Merge pull request #932 from Police-Data-Accessibility-Project/mc_708…
maxachis Nov 27, 2025
2baa0a6
Update permissions logic
maxachis Nov 28, 2025
a533173
Format with ruff
maxachis Nov 28, 2025
d1a7b63
Fix breaking test
maxachis Nov 28, 2025
89fcfcc
Merge pull request #933 from Police-Data-Accessibility-Project/mc_877…
maxachis Nov 28, 2025
77a53a1
Begin draft
maxachis Nov 28, 2025
07a451b
Correct broken logic
maxachis Nov 28, 2025
2571698
Format
maxachis Nov 28, 2025
190164d
Add pyright ignore
maxachis Nov 28, 2025
d1aef05
Add pyright ignore
maxachis Nov 28, 2025
0fc28d1
Merge pull request #934 from Police-Data-Accessibility-Project/mc_740…
maxachis Nov 28, 2025
35be5f5
Update typeaheads to allow pagination
maxachis Dec 1, 2025
dd2424d
Update ruff
maxachis Dec 1, 2025
07b6dc8
Merge pull request #935 from Police-Data-Accessibility-Project/mc_740…
maxachis Dec 1, 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