diff --git a/backend/api/schemas/addresses_schemas.py b/backend/api/schemas/addresses_schemas.py index af0b168c..26d008b2 100644 --- a/backend/api/schemas/addresses_schemas.py +++ b/backend/api/schemas/addresses_schemas.py @@ -3,6 +3,7 @@ from geojson_pydantic import Feature, FeatureCollection, Point from geoalchemy2.shape import to_shape from typing import List +from datetime import datetime class AddressProperties(BaseModel): @@ -16,6 +17,7 @@ class AddressProperties(BaseModel): eas_fullid: str address: str + update_timestamp: datetime class AddressFeature(Feature): @@ -48,6 +50,7 @@ def from_sqlalchemy_model(address: Address): properties={ "eas_fullid": address.eas_fullid, "address": address.address, + "update_timestamp": address.update_timestamp, }, ) diff --git a/backend/api/schemas/landslide_schemas.py b/backend/api/schemas/landslide_schemas.py index 050fbfbb..1614e5e2 100644 --- a/backend/api/schemas/landslide_schemas.py +++ b/backend/api/schemas/landslide_schemas.py @@ -4,6 +4,7 @@ from geoalchemy2.shape import to_shape from typing import List import json +from datetime import datetime class LandslideProperties(BaseModel): @@ -17,6 +18,7 @@ class LandslideProperties(BaseModel): identifier: int gridcode: int + update_timestamp: datetime class LandslideFeature(Feature): @@ -53,6 +55,7 @@ def from_sqlalchemy_model(landslide_zone: LandslideZone): properties={ "identifier": landslide_zone.identifier, "gridcode": landslide_zone.gridcode, + "update_timestamp": landslide_zone.update_timestamp, }, ) diff --git a/backend/api/schemas/liquefaction_schemas.py b/backend/api/schemas/liquefaction_schemas.py index ddf38c89..eb92dfc9 100644 --- a/backend/api/schemas/liquefaction_schemas.py +++ b/backend/api/schemas/liquefaction_schemas.py @@ -4,6 +4,7 @@ from geoalchemy2.shape import to_shape from typing import List import json +from datetime import datetime class LiquefactionProperties(BaseModel): @@ -17,6 +18,7 @@ class LiquefactionProperties(BaseModel): identifier: int liq: str + update_timestamp: datetime class LiquefactionFeature(Feature): @@ -53,6 +55,7 @@ def from_sqlalchemy_model(liquefaction_zone: LiquefactionZone): properties={ "identifier": liquefaction_zone.identifier, "liq": liquefaction_zone.liq, + "update_timestamp": liquefaction_zone.update_timestamp, }, ) diff --git a/backend/api/schemas/seismic_schemas.py b/backend/api/schemas/seismic_schemas.py index de205af6..21cfd66a 100644 --- a/backend/api/schemas/seismic_schemas.py +++ b/backend/api/schemas/seismic_schemas.py @@ -4,6 +4,7 @@ from geoalchemy2.shape import to_shape from typing import List import json +from datetime import datetime class SeismicProperties(BaseModel): @@ -15,6 +16,7 @@ class SeismicProperties(BaseModel): """ identifier: int + update_timestamp: datetime class SeismicFeature(Feature): @@ -50,6 +52,7 @@ def from_sqlalchemy_model(seismic_hazard_zone: SeismicHazardZone): geometry=json.loads(seismic_hazard_zone.multipolygon_as_geosjon), properties={ "identifier": seismic_hazard_zone.identifier, + "update_timestamp": seismic_hazard_zone.update_timestamp, }, ) diff --git a/backend/api/schemas/soft_story_schemas.py b/backend/api/schemas/soft_story_schemas.py index 2960af25..2a293e87 100644 --- a/backend/api/schemas/soft_story_schemas.py +++ b/backend/api/schemas/soft_story_schemas.py @@ -4,6 +4,7 @@ from geoalchemy2.shape import to_shape from typing import List import json +from datetime import datetime class SoftStoryProperties(BaseModel): @@ -15,6 +16,7 @@ class SoftStoryProperties(BaseModel): """ identifier: int + update_timestamp: datetime class SoftStoryFeature(Feature): @@ -55,6 +57,7 @@ def from_sqlalchemy_model(soft_story: SoftStoryProperty): geometry={"type": "Point", "coordinates": coordinates}, properties={ "identifier": soft_story.identifier, + "update_timestamp": soft_story.update_timestamp, }, ) diff --git a/backend/api/schemas/tsunami_schemas.py b/backend/api/schemas/tsunami_schemas.py index dc93293f..0b72ab44 100644 --- a/backend/api/schemas/tsunami_schemas.py +++ b/backend/api/schemas/tsunami_schemas.py @@ -3,6 +3,7 @@ from geojson_pydantic import Feature, FeatureCollection, MultiPolygon from typing import List import json +from datetime import datetime class TsunamiProperties(BaseModel): @@ -16,6 +17,7 @@ class TsunamiProperties(BaseModel): identifier: int evacuate: str + update_timestamp: datetime class TsunamiFeature(Feature): @@ -52,6 +54,7 @@ def from_sqlalchemy_model(tsunami_zone: TsunamiZone): properties={ "identifier": tsunami_zone.identifier, "evacuate": tsunami_zone.evacuate, + "update_timestamp": tsunami_zone.update_timestamp, }, ) diff --git a/backend/api/tests/test_addresses.py b/backend/api/tests/test_addresses.py index 6c11c1e2..12706d29 100644 --- a/backend/api/tests/test_addresses.py +++ b/backend/api/tests/test_addresses.py @@ -2,8 +2,17 @@ from backend.api.tests.test_session_config import test_engine, test_session, client -def test_get_address(client): +def test_get_address_by_id(client): id = "495990-764765-0" - response = client.get(f"/api/addresses/{id}") - print(response) + response = client.get(f"/addresses/{id}") + response_dict = response.json() assert response.status_code == 200 + assert response_dict["properties"]["address"] == "46 AUBURN ST" + assert response_dict["geometry"]["coordinates"] == [-122.41228, 37.77967] + + +def test_get_addresses(client): + response = client.get(f"/addresses/") + response_dict = response.json() + assert response.status_code == 200 + assert len(response_dict) == 2 diff --git a/backend/api/tests/test_seismic.py b/backend/api/tests/test_seismic.py index 09fea25c..67d51840 100644 --- a/backend/api/tests/test_seismic.py +++ b/backend/api/tests/test_seismic.py @@ -1,50 +1,10 @@ import pytest -from fastapi.testclient import TestClient +from backend.api.tests.test_session_config import test_engine, test_session, client -# Will the .. be stable? -from ..main import app -from ..schemas.geo import Polygon - -@pytest.fixture -def client(): - return TestClient(app) - - -def test_delete_polygon(client): - response = client.delete("/api/polygons/1?table_name=seismic") - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False - - -def test_put_polygon(client): - response = client.put( - "/api/polygons/1?table_name=seismic", json=Polygon().model_dump() - ) - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False - - -def test_post_polygon(client): - response = client.put( - "/api/polygons/1?table_name=seismic", json=Polygon().model_dump() - ) - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False - - -def test_get_polygon(client): - response = client.get("/api/polygons/1?table_name=seismic") - assert response.status_code == 200 - # Temporary guaranteed failure until test is written - assert False - - -def test_get_seismic_risk(client): - response = client.get("/api/seismic-risk/address") +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 - # Temporary guaranteed failure until test is written - assert False + assert len(response_dict) == 2 diff --git a/backend/database/init.sql b/backend/database/init.sql index 78602eda..218925e4 100644 --- a/backend/database/init.sql +++ b/backend/database/init.sql @@ -5,7 +5,7 @@ create extension if not exists postgis; set search_path to public; -create table if not exists address ( +create table if not exists addresses ( eas_fullid varchar(255) primary key, address varchar(255) not null, unit_number varchar(255), @@ -16,23 +16,42 @@ create table if not exists address ( block varchar(255), lot varchar(255), cnn integer, - longitude str not null, - latitude str not null, + longitude float not null, + latitude float not null, zip_code integer not null, point Geometry(point, 4326) not null, supdist varchar(255), supervisor integer, supname varchar(255), nhood varchar(255), - sfdata_as_of date not null, + sfdata_as_of timestamp not null, created_timestamp timestamp, update_timestamp timestamp ); +create table if not exists seismic_hazard_zones ( + identifier integer primary key, + 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 address (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 15:11:26 PM'); +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.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 combined_risk (