feat: add bulk external observation publishing
This commit is contained in:
@@ -75,7 +75,9 @@ def reject_observation(
|
|||||||
return observation
|
return observation
|
||||||
|
|
||||||
|
|
||||||
def publish_observation(session: Session, observation: ExternalObservation) -> CatchReport:
|
def publish_observation(
|
||||||
|
session: Session, observation: ExternalObservation, *, commit: bool = True,
|
||||||
|
) -> CatchReport:
|
||||||
if observation.catch_report is not None and observation.status == "published":
|
if observation.catch_report is not None and observation.status == "published":
|
||||||
return observation.catch_report
|
return observation.catch_report
|
||||||
if observation.status == "rejected":
|
if observation.status == "rejected":
|
||||||
@@ -138,7 +140,8 @@ def publish_observation(session: Session, observation: ExternalObservation) -> C
|
|||||||
observation.catch_report = report
|
observation.catch_report = report
|
||||||
observation.status = "published"
|
observation.status = "published"
|
||||||
observation.reviewed_at = now
|
observation.reviewed_at = now
|
||||||
session.commit()
|
if commit:
|
||||||
|
session.commit()
|
||||||
return report
|
return report
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from rf4_research.media_assets import publish_quality_upgrades, rollback_quality
|
|||||||
from ..media_catalog import MEDIA_ROOT, review_assets, review_file
|
from ..media_catalog import MEDIA_ROOT, review_assets, review_file
|
||||||
from ..models import CatchReport, CommunityImportRun, DataSource, ExternalObservation, Fish, ModerationEvent, ModerationStatus, OfficialRecordImport, SourceType, Waterbody
|
from ..models import CatchReport, CommunityImportRun, DataSource, ExternalObservation, Fish, ModerationEvent, ModerationStatus, OfficialRecordImport, SourceType, Waterbody
|
||||||
from ..public_cache import public_cache
|
from ..public_cache import public_cache
|
||||||
from ..schemas import AdminCatchReportOut, AdminMediaDecision, AdminMediaReviewOut, AdminMediaRollback, AdminModerationHistoryOut, AdminSourceStatusOut, CatchReportCreated, ExternalAliasSuggestionOut, ExternalObservationAction, ExternalObservationBulkDecision, ExternalObservationBulkMapping, ExternalObservationBulkResult, ExternalObservationDecision, ExternalObservationMapping, ExternalObservationOut, ExternalObservationPublished, ImportRunOut, ModerationBulkResult, ModerationBulkUpdate, ModerationUpdate
|
from ..schemas import AdminCatchReportOut, AdminMediaDecision, AdminMediaReviewOut, AdminMediaRollback, AdminModerationHistoryOut, AdminSourceStatusOut, CatchReportCreated, ExternalAliasSuggestionOut, ExternalObservationAction, ExternalObservationBulkAction, ExternalObservationBulkDecision, ExternalObservationBulkMapping, ExternalObservationBulkResult, ExternalObservationDecision, ExternalObservationMapping, ExternalObservationOut, ExternalObservationPublished, ImportRunOut, ModerationBulkResult, ModerationBulkUpdate, ModerationUpdate
|
||||||
from ..storage import delete_screenshot, signed_screenshot_url
|
from ..storage import delete_screenshot, signed_screenshot_url
|
||||||
from ..time_utils import aware
|
from ..time_utils import aware
|
||||||
|
|
||||||
@@ -389,6 +389,30 @@ def admin_publish_external_observation(
|
|||||||
return ExternalObservationPublished(observation_id=observation.id, catch_report_id=report.id, status=observation.status)
|
return ExternalObservationPublished(observation_id=observation.id, catch_report_id=report.id, status=observation.status)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/api/v1/admin/external-observations/bulk-publish", response_model=ExternalObservationBulkResult)
|
||||||
|
def admin_publish_external_observations_bulk(
|
||||||
|
payload: ExternalObservationBulkAction, db: Db, _: Annotated[str, Depends(_admin)],
|
||||||
|
) -> ExternalObservationBulkResult:
|
||||||
|
ids = [item.id for item in payload.items]
|
||||||
|
observations = list(db.scalars(select(ExternalObservation).where(ExternalObservation.id.in_(ids)).with_for_update()))
|
||||||
|
expected = {item.id: item.expected_version for item in payload.items}
|
||||||
|
if len({item.id for item in observations}) != len(ids) or any(
|
||||||
|
item.status in {"rejected", "withdrawn"} or item.moderation_version != expected[item.id]
|
||||||
|
for item in observations
|
||||||
|
):
|
||||||
|
raise HTTPException(status_code=409, detail="one or more observations changed; reload the queue")
|
||||||
|
try:
|
||||||
|
for item in observations:
|
||||||
|
item.moderation_version += 1
|
||||||
|
publish_observation(db, item, commit=False)
|
||||||
|
db.commit()
|
||||||
|
except ExternalReviewError as exc:
|
||||||
|
db.rollback()
|
||||||
|
raise HTTPException(status_code=409, detail=str(exc)) from exc
|
||||||
|
public_cache.invalidate()
|
||||||
|
return ExternalObservationBulkResult(updated=len(observations))
|
||||||
|
|
||||||
|
|
||||||
@router.patch("/api/v1/admin/external-observations/{observation_id}/reject", response_model=ExternalObservationOut)
|
@router.patch("/api/v1/admin/external-observations/{observation_id}/reject", response_model=ExternalObservationOut)
|
||||||
def admin_reject_external_observation(
|
def admin_reject_external_observation(
|
||||||
observation_id: UUID, payload: ExternalObservationDecision, db: Db,
|
observation_id: UUID, payload: ExternalObservationDecision, db: Db,
|
||||||
|
|||||||
@@ -413,6 +413,10 @@ class ExternalObservationBulkDecision(BaseModel):
|
|||||||
items: list[ExternalObservationBulkItem] = Field(min_length=1, max_length=50)
|
items: list[ExternalObservationBulkItem] = Field(min_length=1, max_length=50)
|
||||||
|
|
||||||
|
|
||||||
|
class ExternalObservationBulkAction(BaseModel):
|
||||||
|
items: list[ExternalObservationBulkItem] = Field(min_length=1, max_length=50)
|
||||||
|
|
||||||
|
|
||||||
class ExternalObservationBulkMapping(BaseModel):
|
class ExternalObservationBulkMapping(BaseModel):
|
||||||
fish_slug: str
|
fish_slug: str
|
||||||
waterbody_slug: str
|
waterbody_slug: str
|
||||||
|
|||||||
Reference in New Issue
Block a user