diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 77cbac75..4cc0f4ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,7 +83,7 @@ jobs: run: docker compose up -d - name: Run Backend Tests - run: docker compose run backend pytest backend/database/tests + run: docker compose run backend pytest backend - name: Run Frontend Tests run: docker compose run frontend npm test diff --git a/backend/api/models/landslide_zones.py b/backend/api/models/landslide_zones.py index a2c7bf48..36afe9cd 100644 --- a/backend/api/models/landslide_zones.py +++ b/backend/api/models/landslide_zones.py @@ -24,10 +24,10 @@ class LandslideZone(Base): identifier: Mapped[int] = mapped_column(Integer, primary_key=True) geometry: Mapped[Geometry] = mapped_column(Geometry("MULTIPOLYGON", srid=4326)) gridcode: Mapped[int] = mapped_column(Integer) - sum_shape: Mapped[str] = mapped_column(Float) - shape_length: Mapped[str] = mapped_column(Float) - shape_length_1: Mapped[str] = mapped_column(Float) - shape_area: Mapped[str] = mapped_column(Float) + sum_shape: Mapped[float] = mapped_column(Float) + shape_length: Mapped[float] = mapped_column(Float) + shape_length_1: Mapped[float] = mapped_column(Float) + shape_area: Mapped[float] = mapped_column(Float) update_timestamp: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), onupdate=func.now() ) diff --git a/backend/api/models/tsunami.py b/backend/api/models/tsunami.py index f56a1e6b..092e78f3 100644 --- a/backend/api/models/tsunami.py +++ b/backend/api/models/tsunami.py @@ -25,7 +25,7 @@ class TsunamiZone(Base): identifier: Mapped[int] = mapped_column(Integer, primary_key=True) evacuate: Mapped[str] = mapped_column(String(_STRING_LENGTH), nullable=False) county: Mapped[str] = mapped_column(String(_STRING_LENGTH), nullable=False) - globalID: Mapped[str] = mapped_column(String(_STRING_LENGTH), nullable=False) + global_id: Mapped[str] = mapped_column(String(_STRING_LENGTH), nullable=False) shape_length: Mapped[float] = mapped_column(Float, nullable=True) shape_area: Mapped[float] = mapped_column(Float, nullable=True) geometry: Mapped[Geometry] = mapped_column( diff --git a/backend/api/routers/landslide_api.py b/backend/api/routers/landslide_api.py index 869f9dc3..1d26c241 100644 --- a/backend/api/routers/landslide_api.py +++ b/backend/api/routers/landslide_api.py @@ -11,7 +11,7 @@ from backend.api.models.landslide_zones import LandslideZone router = APIRouter( - prefix="/landslides", + prefix="/landslide-zones", tags=[Tags.LANDSLIDE], ) diff --git a/backend/api/routers/tsunami_api.py b/backend/api/routers/tsunami_api.py index 25c06907..e2275486 100644 --- a/backend/api/routers/tsunami_api.py +++ b/backend/api/routers/tsunami_api.py @@ -9,7 +9,7 @@ router = APIRouter( - prefix="/tsunami", + prefix="/tsunami-zones", tags=[Tags.TSUNAMI], ) diff --git a/backend/api/tests/test_addresses.py b/backend/api/tests/test_addresses.py index 12706d29..f8f970a9 100644 --- a/backend/api/tests/test_addresses.py +++ b/backend/api/tests/test_addresses.py @@ -15,4 +15,4 @@ def test_get_addresses(client): response = client.get(f"/addresses/") response_dict = response.json() assert response.status_code == 200 - assert len(response_dict) == 2 + assert len(response_dict["features"]) == 2 diff --git a/backend/api/tests/test_combined_risks.py b/backend/api/tests/test_combined_risks.py deleted file mode 100644 index 3f22d051..00000000 --- a/backend/api/tests/test_combined_risks.py +++ /dev/null @@ -1,49 +0,0 @@ -""" -Test the API of combined_risks.py. -""" - -import pytest -from fastapi.testclient import TestClient - -# Will the .. be stable? -from ..main import app -from ..schemas.geo import Polygon - - -@pytest.fixture -def client(): - return TestClient(app) - - -def test_delete_combined_risks(client): - response = client.delete("/api/combined-risks/address") - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False - - -def test_put_combined_risks(client): - response = client.put( - "/api/combined-risks/address", - json={"soft-story": True, "seismic": True, "tsunami": True}, - ) - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False - - -def test_post_combined_risks(client): - response = client.post( - "/api/combined-risks/address", - json={"soft-story": True, "seismic": True, "tsunami": True}, - ) - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False - - -def test_get_combined_risks(client): - response = client.get("/api/combined-risks/address") - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False diff --git a/backend/api/tests/test_landslide.py b/backend/api/tests/test_landslide.py new file mode 100644 index 00000000..22336314 --- /dev/null +++ b/backend/api/tests/test_landslide.py @@ -0,0 +1,10 @@ +import pytest +from backend.api.tests.test_session_config import test_engine, test_session, client + + +def test_get_landslide_zones(client): + response = client.get(f"/landslide-zones/") + response_dict = response.json() + print(response_dict["features"]) + assert response.status_code == 200 + assert len(response_dict["features"]) == 2 diff --git a/backend/api/tests/test_liquefaction.py b/backend/api/tests/test_liquefaction.py new file mode 100644 index 00000000..fe0b21c3 --- /dev/null +++ b/backend/api/tests/test_liquefaction.py @@ -0,0 +1,9 @@ +import pytest +from backend.api.tests.test_session_config import test_engine, test_session, client + + +def test_get_liquefaction_zones(client): + response = client.get(f"/liquefaction-zones/") + response_dict = response.json() + assert response.status_code == 200 + assert len(response_dict["features"]) == 3 diff --git a/backend/api/tests/test_polygons.py b/backend/api/tests/test_polygons.py deleted file mode 100644 index 666e4f01..00000000 --- a/backend/api/tests/test_polygons.py +++ /dev/null @@ -1,53 +0,0 @@ -""" -Test the API of polygons.py. -""" - -import pytest -from fastapi.testclient import TestClient -from ..schemas.geo import Polygon -from ..main import app - - -@pytest.fixture -def client(): - return TestClient(app) - - -def test_post_polygon(client): - table_name = "seismic" - response = client.put( - "/api/polygons/?table_name={table_name}", json=Polygon().model_dump() - ) - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False - - -def test_put_polygon(client): - polygon_id = 1 - table_name = "seismic" - response = client.put( - "/api/polygons/{polygon_id}?table_name={table_name}", - json=Polygon().model_dump(), - ) - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False - - -def test_get_polygon(client): - polygon_id = 1 - table_name = "seismic" - response = client.get("/api/polygons/{polygon_id}?table_name={table_name}") - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False - - -def test_delete_polygon(client): - polygon_id = 1 - table_name = "seismic" - response = client.delete("/api/polygons/{polygon_id}?table_name={table_name}") - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False diff --git a/backend/api/tests/test_seismic.py b/backend/api/tests/test_seismic.py index 67d51840..5ae6ba1c 100644 --- a/backend/api/tests/test_seismic.py +++ b/backend/api/tests/test_seismic.py @@ -5,6 +5,5 @@ def test_get_seismic_hazard_zones(client): response = client.get(f"/seismic-zones/") response_dict = response.json() - print(response_dict) assert response.status_code == 200 - assert len(response_dict) == 2 + assert len(response_dict["features"]) == 2 diff --git a/backend/api/tests/test_soft_story.py b/backend/api/tests/test_soft_story.py index 2f9591d6..5b994d09 100644 --- a/backend/api/tests/test_soft_story.py +++ b/backend/api/tests/test_soft_story.py @@ -1,43 +1,9 @@ -""" -Test the API of soft_story.py. -""" - import pytest -from fastapi.testclient import TestClient - -# Will the .. be stable? -from ..main import app -from ..schemas.geo import Polygon - - -@pytest.fixture -def client(): - return TestClient(app) - - -def test_delete_soft_story(client): - response = client.delete("/api/soft-story/address") - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False - - -def test_put_soft_story(client): - response = client.put("/api/soft-story/address?soft-story=true") - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False - - -def test_post_soft_story(client): - response = client.put("/api/soft-story/address?soft-story=true") - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False +from backend.api.tests.test_session_config import test_engine, test_session, client -def test_get_soft_story(client): - response = client.get("/api/soft-story/address") +def test_get_soft_stories(client): + response = client.get(f"/soft-stories/") + response_dict = response.json() assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False + assert len(response_dict["features"]) == 6 diff --git a/backend/api/tests/test_tsunami.py b/backend/api/tests/test_tsunami.py index 14290c5a..57b93882 100644 --- a/backend/api/tests/test_tsunami.py +++ b/backend/api/tests/test_tsunami.py @@ -1,54 +1,9 @@ -""" -Test the API of tsunami.py. -""" - import pytest -from fastapi.testclient import TestClient - -# Will the .. be stable? -from ..main import app -from ..schemas.geo import Polygon - - -@pytest.fixture -def client(): - return TestClient(app) - - -def test_delete_tsunami_polygon(client): - response = client.delete("/api/polygons/1?table_name=tsunami") - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False - - -def test_put_tsunami_polygon(client): - response = client.put( - "/api/polygons/1?table_name=tsunami", json=Polygon().model_dump() - ) - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False - - -def test_post_tsunami_polygon(client): - response = client.put( - "/api/polygons/1?table_name=tsunami", json=Polygon().model_dump() - ) - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False - - -def test_get_tsunami_polygon(client): - response = client.get("/api/polygons/1?table_name=tsunami") - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False +from backend.api.tests.test_session_config import test_engine, test_session, client -def test_get_tsunami_risk(client): - response = client.get("/api/tsunami-risk/addresss") +def test_get_tsunami_zones(client): + response = client.get(f"/tsunami-zones/") + response_dict = response.json() assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False + assert len(response_dict["features"]) == 1 diff --git a/backend/database/init.sql b/backend/database/init.sql index 218925e4..285d4fd4 100644 --- a/backend/database/init.sql +++ b/backend/database/init.sql @@ -34,25 +34,38 @@ create table if not exists seismic_hazard_zones ( geometry Geometry(multipolygon, 4326) not null, update_timestamp timestamp ); --- Potential functions to creat a Point: ST_MakePoint(-122.41228, 37.77967); ST_GeomFromText('POINT(-122.41228, 37.77967)', 4326); ST_SetSRID(ST_MakePoint(-122.41228, 37.77967), 4326) -insert into addresses (eas_fullid, address, unit_number, address_number, street_name, street_type, parcel_number, block, lot, cnn, longitude, latitude, zip_code, point, supdist, supervisor, supname, nhood, sfdata_as_of, created_timestamp, update_timestamp) values - ('495990-764765-0', '46 AUBURN ST', '', 46, 'AUBURN', 'ST', '', '', '', 830000, -122.41228, 37.77967, 94133, ST_SetSRID(ST_MakePoint(-122.41228, 37.77967), 4326), 'SUPERVISORIAL DISTRICT 3', 3, 'Aaron Peskin', 'Nob Hill', '2024/10/28 03:40:00 AM', '2024/10/28 10:11:26 PM', '2024/11/28 5:11:26 PM'), - ('12345-678-9', '10 TEST ST', '', 10, 'TEST', 'ST', '', '', '', 800050, -122.41509, 37.64097, 94000, ST_SetSRID(ST_MakePoint(-122.41509, 37.64097), 4326), 'SUPERVISORIAL DISTRICT 2', 2, 'User Name', 'Nob Hill', '2024/10/29 03:40:00 AM', '2024/10/29 10:11:26 PM', '2024/11/29 5:11:26 PM'); -insert into seismic_hazard_zones (identifier, geometry, update_timestamp) values - (1, ST_GeomFromText('MULTIPOLYGON( - ((-122.5 37.7, -122.4 37.7, -122.4 37.8, -122.5 37.8, -122.5 37.7)), - ((-122.6 37.6, -122.5 37.6, -122.5 37.7, -122.6 37.7, -122.6 37.6)) - )', 4326), - '2024/12/16 5:10:00 PM'), +create table if not exists liquefaction_zones ( + identifier integer primary key, + geometry Geometry(multipolygon, 4326) not null, + liq varchar(255), + shape_length float, + shape_area float, + update_timestamp timestamp +); - (2, ST_GeomFromText('MULTIPOLYGON( - ((-122.4 37.8, -122.3 37.8, -122.35 37.85, -122.4 37.8)), - ((-122.5 37.7, -122.4 37.7, -122.4 37.8, -122.5 37.8, -122.5 37.7)) - )', 4326), - '2024/12/17 3:10:00 PM'); +create table if not exists landslide_zones ( + identifier integer primary key, + geometry Geometry(multipolygon, 4326) not null, + gridcode integer, + sum_shape float, + shape_length float, + shape_length_1 float, + shape_area float, + update_timestamp timestamp +); +create table if not exists tsunami_zones ( + identifier integer primary key, + evacuate varchar(255) not null, + county varchar(255) not null, + global_id varchar(255) not null, + shape_length float, + shape_area float, + geometry Geometry(multipolygon, 4326) not null, + update_timestamp timestamp +); create table if not exists combined_risk ( id serial primary key, @@ -63,22 +76,81 @@ create table if not exists combined_risk ( liquefaction_risk boolean not null default false ); -/*create table if not exists soft_story_addresses ( +create table if not exists soft_story_properties ( identifier integer not null, block varchar(255), lot varchar(255), parcel_number varchar(255), property_address varchar(255), - address varchar(255), + address varchar(255) not null, tier integer, status varchar(255), bos_district integer, - --point: Mapped[Geometry] = mapped_column(Geometry("POINT", srid=4326)) + point Geometry(point, 4326), sfdata_as_of timestamp, - sfdata_loaded_at timestamp - --update_timestamp timestamp + sfdata_loaded_at timestamp, + update_timestamp timestamp ); -*/ + +insert into addresses (eas_fullid, address, unit_number, address_number, street_name, street_type, parcel_number, block, lot, cnn, longitude, latitude, zip_code, point, supdist, supervisor, supname, nhood, sfdata_as_of, created_timestamp, update_timestamp) values + ('495990-764765-0', '46 AUBURN ST', '', 46, 'AUBURN', 'ST', '', '', '', 830000, -122.41228, 37.77967, 94133, ST_SetSRID(ST_MakePoint(-122.41228, 37.77967), 4326), 'SUPERVISORIAL DISTRICT 3', 3, 'Aaron Peskin', 'Nob Hill', '2024/10/28 03:40:00 AM', '2024/10/28 10:11:26 PM', '2024/11/28 5:11:26 PM'), + ('12345-678-9', '10 TEST ST', '', 10, 'TEST', 'ST', '', '', '', 800050, -122.41509, 37.64097, 94000, ST_SetSRID(ST_MakePoint(-122.41509, 37.64097), 4326), 'SUPERVISORIAL DISTRICT 2', 2, 'User Name', 'Nob Hill', '2024/10/29 03:40:00 AM', '2024/10/29 10:11:26 PM', '2024/11/29 5:11:26 PM'); + +insert into seismic_hazard_zones (identifier, geometry, update_timestamp) values + (1, ST_GeomFromText('MULTIPOLYGON( + ((-122.5 37.7, -122.4 37.7, -122.4 37.8, -122.5 37.8, -122.5 37.7)), + ((-122.6 37.6, -122.5 37.6, -122.5 37.7, -122.6 37.7, -122.6 37.6)) + )', 4326), + '2024/12/16 5:10:00 PM'), + + (2, ST_GeomFromText('MULTIPOLYGON(((-122.5 37.7, -122.5 37.8, -122.4 37.8, -122.4 37.7, -122.5 37.7)), + ((-122.6 37.6, -122.6 37.7, -122.5 37.7, -122.5 37.6, -122.6 37.6)))', 4326), + '2024/12/17 3:10:00 PM'); + +insert into landslide_zones ( + identifier, geometry, gridcode, sum_shape, shape_length, shape_area, update_timestamp +) values + (3, ST_GeomFromText('MULTIPOLYGON( + ((-122.5 37.7, -121.9 30.7, -122.4 37.8, -122.5 37.8, -122.5 37.7)), + ((-122.6 37.6, -121.5 37.6, -122.5 37.7, -122.6 37.7, -122.6 37.6)) + )', 4326), 8, 1000.00, 25.8, 12.0, '2024-12-10 20:20:00'), + + (4, ST_GeomFromText('MULTIPOLYGON( + ((-122.5 37.7, -122.5 37.9, -122.3 37.9, -122.3 37.7, -122.5 37.7)), + ((-122.4 37.75, -122.4 37.85, -122.35 37.85, -122.35 37.75, -122.4 37.75)) + )', 4326), 3, 897.6, 12.2, 87.0, '2024-12-10 13:15:00'), + + (5, ST_GeomFromText('MULTIPOLYGON( + ((-122.5 37.7, -122.5 37.8, -122.4 37.8, -122.4 37.7, -122.5 37.7)), + ((-122.48 37.73, -122.48 37.77, -122.46 37.77, -122.46 37.73, -122.48 37.73)) + )', 4326), 10, 56.11, 18.3, 43.1, '2024-12-10 13:15:00'); + +insert into liquefaction_zones (identifier, geometry, liq, shape_length, shape_area, update_timestamp) values + (6, ST_GeomFromText('MULTIPOLYGON( + ((-121.0 37.6, -121.9 30.7, -122.4 37.8, -122.5 37.8, -121.0 37.6)), + ((-123.1 33.6, -121.5 37.6, -122.5 37.7, -122.6 37.7, -123.1 33.6)) + )', 4326), + 'H', 25.8, 12.0, '2024/12/19 8:20:00 PM'), + + (7, ST_GeomFromText('MULTIPOLYGON( + ((-125.9 37.8, -121.3 37.8, -122.35 37.85, -125.9 37.8)), + ((-122.5 37.7, -129.4 37.7, -122.4 37.8, -122.5 37.8, -122.5 37.7)) + )', 4326), + 'VH', 12.2, 87.0, '2024/12/19 1:15:00 PM'), + (8, ST_GeomFromText('MULTIPOLYGON( + ((-123.9 37.8, -123.3 37.8, -122.35 37.85, -123.9 37.8)), + ((-124.0 27.9, -127.4 37.7, -122.4 37.8, -122.5 37.8, -124.0 27.9)) + )', 4326), + 'H', 123.4, 432.1, '2024/12/19 1:15:00 PM') + ; + +insert into tsunami_zones (identifier, evacuate, county, global_id, shape_length, shape_area, geometry, update_timestamp) values + (9, 'Yes, Tsunami Hazard Area', 'San Francisco', 'd63b7111-a144-49ca-aa79-69f69721e3d3', 123.45, 67.8, ST_GeomFromText('MULTIPOLYGON( + ((-122.5 37.7, -122.5 37.9, -122.3 37.9, -122.3 37.7, -122.5 37.7)), + ((-122.4 37.75, -122.4 37.85, -122.35 37.85, -122.35 37.75, -122.4 37.75)) + )', 4326), + '2024/12/16 5:10:00 PM'); + insert into combined_risk (address, soft_story_risk, seismic_hazard_risk, landslide_risk, liquefaction_risk) values ('3560 PIERCE ST, SAN FRANCISCO CA', true, false, false, false), ('3484 18TH ST, SAN FRANCISCO CA', true, true, false, true), @@ -86,14 +158,6 @@ insert into combined_risk (address, soft_story_ri ('106 HAIGHT ST, SAN FRANCISCO CA', true, true, true, true), ('3852 CALIFORNIA ST, SAN FRANCISCO CA', false, true, false, true); ---add point column between bos_district and sfdata_as_of ---Here they are in order for our rows ---POINT (-122.424966202 37.762929444) ---POINT (-122.412108664 37.805406258) ---POINT (-122.507457108 37.756334425) ---POINT (-122.444181708 37.771944708) ---POINT (-122.479013074 37.764537366) ---POINT (-122.400877183 37.753556427) --add update_timestamp column after sfdata_loaded_at --this column will be filled with data generated at runtime by our code @@ -101,11 +165,11 @@ insert into combined_risk (address, soft_story_ri --status column is a varchar in the database but must be transformed into a boolean for use --possibly keep the booleans in the transformed database in memory between updates -/*insert into soft_story_addresses (identifier, block, lot, parcel_number, property_address, address, tier, status, bos_district, sfdata_as_of, sfdata_loaded_at) values - (1, 3578, 71, 3578071, '3549 17TH ST', '3549 17TH ST, SAN FRANCISCO CA', 3, 'Work Complete CFC Issued', 8, '2024/11/04 03:18:13 AM', '2024/11/04 03:30:26 AM'), - (2, 41, 4, 41004, '2231 POWELL ST', '2231 POWELL ST, SAN FRANCISCO CA', 3, 'Non-Compliant', 3, '2024/11/04 03:18:13 AM', '2024/11/04 03:30:26 AM'), - (3, 1896, 46, 1896046, '1612 48TH AV', '1612 48TH AV, SAN FRANCISCO CA', 3, 'Work Complete, CFC Issued', 4, '2024/11/04 03:18:13 AM', '2024/11/04 03:30:26 AM'), - (4, 1222, 55, 1222055, '253 CENTRAL AV', '253 CENTRAL AV, SAN FRANCISCO CA', 3, 'Work Complete, CFC Issued', 5, '2024/11/04 03:18:13 AM', '2024/11/04 03:30:26 AM'), - (5, 1730, 49, 1730049, '1240 21ST AV', '1240 21ST AV, SAN FRANCISCO CA', 3, 'Work Complete, CFC Issued', 4, '2024/11/04 03:18:13 AM', '2024/11/04 03:30:26 AM'), - (6, 4217, 12, 4217012, '2120 24TH ST', '2120 24TH ST, SAN FRANCISCO CA', 3, 'Work Complete, CFC Issued', 10, '2024/11/04 03:18:13 AM', '2024/11/04 03:30:26 AM'); - */ \ No newline at end of file +insert into soft_story_properties (identifier, block, lot, parcel_number, property_address, address, tier, status, bos_district, point, sfdata_as_of, sfdata_loaded_at, update_timestamp) values + (1, 3578, 71, 3578071, '3549 17TH ST', '3549 17TH ST, SAN FRANCISCO CA', 3, 'Work Complete CFC Issued', 8, ST_SetSRID(ST_MakePoint(-122.424966202, 37.762929444), 4326), '2024/11/04 03:18:13 AM', '2024/11/04 03:30:26 AM', '2024/11/28 5:11:26 PM'), + (2, 41, 4, 41004, '2231 POWELL ST', '2231 POWELL ST, SAN FRANCISCO CA', 3, 'Non-Compliant', 3, ST_SetSRID(ST_MakePoint(-122.412108664, 37.805406258), 4326), '2024/11/04 03:18:13 AM', '2024/11/04 03:30:26 AM', '2024/11/28 5:11:26 PM'), + (3, 1896, 46, 1896046, '1612 48TH AV', '1612 48TH AV, SAN FRANCISCO CA', 3, 'Work Complete, CFC Issued', 4, ST_SetSRID(ST_MakePoint(-122.507457108, 37.756334425), 4326), '2024/11/04 03:18:13 AM', '2024/11/04 03:30:26 AM', '2024/11/28 5:11:26 PM'), + (4, 1222, 55, 1222055, '253 CENTRAL AV', '253 CENTRAL AV, SAN FRANCISCO CA', 3, 'Work Complete, CFC Issued', 5, ST_SetSRID(ST_MakePoint(-122.444181708, 37.771944708), 4326), '2024/11/04 03:18:13 AM', '2024/11/04 03:30:26 AM', '2024/11/28 5:11:26 PM'), + (5, 1730, 49, 1730049, '1240 21ST AV', '1240 21ST AV, SAN FRANCISCO CA', 3, 'Work Complete, CFC Issued', 4, ST_SetSRID(ST_MakePoint(-122.479013074, 37.764537366), 4326), '2024/11/04 03:18:13 AM', '2024/11/04 03:30:26 AM', '2024/11/28 5:11:26 PM'), + (6, 4217, 12, 4217012, '2120 24TH ST', '2120 24TH ST, SAN FRANCISCO CA', 3, 'Work Complete, CFC Issued', 10, ST_SetSRID(ST_MakePoint(-122.400877183, 37.753556427), 4326), '2024/11/04 03:18:13 AM', '2024/11/04 03:30:26 AM', '2024/11/28 5:11:26 PM'); + \ No newline at end of file diff --git a/backend/etl/address_data_handler.py b/backend/etl/address_data_handler.py index 65014115..7d51e4c5 100644 --- a/backend/etl/address_data_handler.py +++ b/backend/etl/address_data_handler.py @@ -32,18 +32,18 @@ def parse_data(self, data: dict) -> list[dict]: address = { "eas_fullid": props.get("eas_fullid"), "address": props.get("address"), - "unit_number": props.get("address", None), + "unit_number": props.get("unit_number", None), "address_number": int(props.get("address_number", None)), "street_name": props.get("street_name"), "street_type": props.get("street_type", None), - "parcel_number": props.get("street_type", None), + "parcel_number": props.get("parcel_number", None), "block": props.get("block", None), "lot": props.get("lot", None), "cnn": props.get("cnn", None), "longitude": props.get("longitude"), "latitude": props.get("latitude"), "zip_code": int(props.get("zip_code")), - "point": f"Point({geom_latitude} {geom_longitude})", + "point": f"Point({geom_longitude} {geom_latitude})", "supdist": props.get("supdist", None), "supervisor": int(props.get("supervisor", None)), "supname": props.get("supname", None), diff --git a/backend/etl/soft_story_properties_data_handler.py b/backend/etl/soft_story_properties_data_handler.py index 7e259a5b..60492dfa 100644 --- a/backend/etl/soft_story_properties_data_handler.py +++ b/backend/etl/soft_story_properties_data_handler.py @@ -38,7 +38,7 @@ def parse_data(self, data: dict) -> list[dict]: "status": properties.get("status"), "bos_district": properties.get("bos_district"), "point": ( - f"Point({geom_latitude} {geom_longitude})" if geometry else None + f"Point({geom_longitude} {geom_latitude})" if geometry else None ), "sfdata_as_of": properties.get("data_as_of"), "sfdata_loaded_at": properties.get("data_loaded_at"), diff --git a/backend/etl/tsunami_data_handler.py b/backend/etl/tsunami_data_handler.py index eb8f66f7..e92b93a8 100644 --- a/backend/etl/tsunami_data_handler.py +++ b/backend/etl/tsunami_data_handler.py @@ -43,7 +43,7 @@ def parse_data(self, data: dict) -> list[dict]: "identifier": int(properties.get("OBJECTID")), "evacuate": properties.get("Evacuate"), "county": properties.get("County"), - "globalID": properties.get("GlobalID"), + "global_id": properties.get("GlobalID"), "shape_length": properties.get("Shape__Length", None), "shape_area": properties.get("Shape__Area", None), "geometry": geoalchemy_multipolygon, diff --git a/compose.yaml b/compose.yaml index 956fa9eb..60a9f587 100644 --- a/compose.yaml +++ b/compose.yaml @@ -41,6 +41,12 @@ services: - ./backend/database:/docker-entrypoint-initdb.d # Mount the SQL scripts directory ports: - 5433:5432 + healthcheck: + test: [ "CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}" ] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s db: image: postgis-custom container_name: my_postgis_db