Skip to content

Commit

Permalink
Create migration of geomstatus enum, delete geometries api (#2052)
Browse files Browse the repository at this point in the history
* feat: create geometrylog table to store bad and new geoms

* feat: add geometrylog migration in fmtm base schema

* feat: add migration of geomstatus enum

* feat: delete geometries api

* fix: add none for optional fields

* feat: implement roles in the endpoints
  • Loading branch information
Sujanadh authored Jan 2, 2025
1 parent d05d4c3 commit 2d5ed16
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 11 deletions.
17 changes: 13 additions & 4 deletions src/backend/app/db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1750,8 +1750,8 @@ class DbGeometryLog(BaseModel):

geom: dict
status: GeomStatus
project_id: Optional[int]
task_id: Optional[int]
project_id: Optional[int] = None
task_id: Optional[int] = None

@classmethod
async def create(
Expand Down Expand Up @@ -1792,13 +1792,22 @@ async def create(
async def delete(
cls,
db: Connection,
project_id: int,
id: int,
) -> bool:
"""Delete a geometry."""
async with db.cursor() as cur:
await cur.execute(
"""
DELETE FROM geometrylog WHERE id = %(id)s;
DELETE FROM geometrylog WHERE project_id=%(project_id)s AND id = %(id)s;
""",
{"id": id},
{"project_id": project_id, "id": id},
)
if cur.rowcount == 0:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND,
detail=f"""
Geometry log with project_id {project_id}
and geom_id {id} not found.
""",
)
46 changes: 44 additions & 2 deletions src/backend/app/projects/project_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
from app.auth.auth_deps import login_required, mapper_login_required
from app.auth.auth_schemas import AuthUser, OrgUserDict, ProjectUserDict
from app.auth.providers.osm import check_osm_user, init_osm_auth
from app.auth.roles import mapper, org_admin, project_manager
from app.auth.roles import check_access, mapper, org_admin, project_manager
from app.central import central_crud, central_deps, central_schemas
from app.config import settings
from app.db.database import db_conn
Expand Down Expand Up @@ -1260,16 +1260,37 @@ async def download_task_boundaries(
@router.post("/{project_id}/geometries")
async def create_geom_log(
geom_log: project_schemas.GeometryLogIn,
current_user: Annotated[ProjectUserDict, Depends(mapper)],
db: Annotated[Connection, Depends(db_conn)],
):
"""Creates a new entry in the geometries log table.
It allows mappers to create new geom.
But needs a validator to invalidate (BAD status) the geom.
Returns:
geometries (DbGeometryLog): The created geometries log entry.
Raises:
HTTPException: If the geometries log creation fails.
HTTPException: If user do not have permission.
Or if the geometries log creation fails.
"""
db_user = current_user.get("user")
db_project = current_user.get("project")

if geom_log.status == "BAD":
access = await check_access(
db_user,
db,
project_id=db_project.id,
role=ProjectRole.PROJECT_MANAGER, # later change this to validator
)
if not access:
raise HTTPException(
status_code=HTTPStatus.FORBIDDEN,
detail="You don't have permission to do this operation.",
)

geometries = await DbGeometryLog.create(db, geom_log)
if not geometries:
raise HTTPException(
Expand All @@ -1278,3 +1299,24 @@ async def create_geom_log(
)

return geometries


@router.delete("/{project_id}/geometries")
async def delete_geom_log(
geom_id: int,
project_user: Annotated[
ProjectUserDict, Depends(project_manager)
], # later change this to validator
db: Annotated[Connection, Depends(db_conn)],
):
"""Delete geometry from geometry log table.
Returns: HTTP 204 response.
Raises:
HTTPException: If the geometries log deletion fails.
"""
project_id = project_user.get("project").id
await DbGeometryLog.delete(db, project_id, geom_id)
log.info(f"Deletion of geom {geom_id} from project {project_id} is successful")
return Response(status_code=HTTPStatus.NO_CONTENT)
4 changes: 2 additions & 2 deletions src/backend/app/projects/project_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ class GeometryLogIn(BaseModel):

status: GeomStatus
geom: dict
project_id: Optional[int]
task_id: Optional[int]
project_id: Optional[int] = None
task_id: Optional[int] = None

@field_validator("geom", mode="before")
@classmethod
Expand Down
11 changes: 8 additions & 3 deletions src/backend/migrations/002-create-geometry-log.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@

BEGIN;

CREATE TABLE geometrylog (
CREATE TYPE public.geomstatus AS ENUM (
'BAD',
'NEW'
);
ALTER TYPE public.geomstatus OWNER TO fmtm;

CREATE TABLE public.geometrylog (
id SERIAL PRIMARY KEY,
geom GEOMETRY NOT NULL,
status geomstatus,
project_id int,
task_id int
);

ALTER TABLE geometrylog OWNER TO fmtm;
ALTER TABLE public.geometrylog OWNER TO fmtm;

-- Indexes for efficient querying
CREATE INDEX idx_geometrylog ON geometrylog USING gist (geom);
Expand Down
5 changes: 5 additions & 0 deletions src/backend/migrations/init/fmtm_base_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ CREATE TYPE public.entitystate AS ENUM (
);
ALTER TYPE public.entitystate OWNER TO fmtm;

CREATE TYPE public.geomstatus AS ENUM (
'BAD',
'NEW'
);
ALTER TYPE public.geomstatus OWNER TO fmtm;

-- Extra

Expand Down
1 change: 1 addition & 0 deletions src/backend/migrations/revert/002-create-geometry-log.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
BEGIN;

DROP TABLE IF EXISTS geometrylog;
DROP TYPE IF EXISTS geomstatus;

-- Commit the transaction

Expand Down

0 comments on commit 2d5ed16

Please sign in to comment.