SysOps: deploy-all — 2026-06-09 10:41 UTC
This commit is contained in:
+98
-1
@@ -7,7 +7,7 @@ from fastapi import APIRouter, HTTPException, Query
|
||||
from fastapi.responses import StreamingResponse
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from app.db import execute_returning, fetch_all, fetch_one
|
||||
from app.db import execute, execute_returning, fetch_all, fetch_one
|
||||
from app.middleware import log_agent_event
|
||||
from app import retail_scrapers
|
||||
from app import retail_enrichment
|
||||
@@ -35,6 +35,49 @@ class CrmLinkIn(BaseModel):
|
||||
notes: Optional[str] = None
|
||||
|
||||
|
||||
class SupermarketCreateIn(BaseModel):
|
||||
name: str
|
||||
chain: str
|
||||
address: str
|
||||
postcode: str = "0000AA"
|
||||
city: str
|
||||
province: Optional[str] = None
|
||||
phone: Optional[str] = None
|
||||
email: Optional[str] = None
|
||||
website: Optional[str] = None
|
||||
manager_name: Optional[str] = None
|
||||
employee_count: Optional[int] = None
|
||||
store_type: Optional[str] = None
|
||||
partnership_status: str = "none"
|
||||
halal_certified: bool = False
|
||||
has_halal_section: bool = False
|
||||
halal_certifier: Optional[str] = None
|
||||
data_source: str = "manual"
|
||||
|
||||
|
||||
class SupermarketPatchIn(BaseModel):
|
||||
name: Optional[str] = None
|
||||
chain: Optional[str] = None
|
||||
address: Optional[str] = None
|
||||
postcode: Optional[str] = None
|
||||
city: Optional[str] = None
|
||||
province: Optional[str] = None
|
||||
phone: Optional[str] = None
|
||||
email: Optional[str] = None
|
||||
website: Optional[str] = None
|
||||
manager_name: Optional[str] = None
|
||||
employee_count: Optional[int] = None
|
||||
store_type: Optional[str] = None
|
||||
size_m2: Optional[int] = None
|
||||
partnership_status: Optional[str] = None
|
||||
halal_certified: Optional[bool] = None
|
||||
has_halal_section: Optional[bool] = None
|
||||
halal_certifier: Optional[str] = None
|
||||
halal_certificate_number: Optional[str] = None
|
||||
organic_section: Optional[bool] = None
|
||||
alcohol_section: Optional[bool] = None
|
||||
|
||||
|
||||
STORE_SELECT = """
|
||||
SELECT s.*,
|
||||
a.population AS area_population,
|
||||
@@ -360,6 +403,60 @@ def get_supermarket(store_id: int) -> dict[str, Any]:
|
||||
return data
|
||||
|
||||
|
||||
@router.post("/supermarkets")
|
||||
def create_supermarket(payload: SupermarketCreateIn) -> dict[str, Any]:
|
||||
row = execute_returning(
|
||||
"""INSERT INTO supermarkets (
|
||||
name, chain, address, postcode, city, province, phone, email, website,
|
||||
manager_name, employee_count, store_type, partnership_status,
|
||||
halal_certified, has_halal_section, halal_certifier, data_source, last_updated
|
||||
) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,NOW())
|
||||
RETURNING id""",
|
||||
(
|
||||
payload.name.strip(), payload.chain.strip(), payload.address.strip(),
|
||||
payload.postcode.strip().upper(), payload.city.strip(), payload.province,
|
||||
payload.phone, payload.email, payload.website, payload.manager_name,
|
||||
payload.employee_count, payload.store_type, payload.partnership_status,
|
||||
payload.halal_certified, payload.has_halal_section, payload.halal_certifier,
|
||||
payload.data_source,
|
||||
),
|
||||
)
|
||||
store_id = int(row["id"])
|
||||
log_agent_event(
|
||||
agent_name="retail_crm",
|
||||
event_type="create",
|
||||
title=f"Handmatig filiaal toegevoegd: {payload.name} ({payload.chain})",
|
||||
)
|
||||
return {"ok": True, "item": _row(fetch_one(f"{STORE_SELECT} WHERE s.id = %s", (store_id,)))}
|
||||
|
||||
|
||||
@router.patch("/supermarkets/{store_id}")
|
||||
def patch_supermarket(store_id: int, payload: SupermarketPatchIn) -> dict[str, Any]:
|
||||
existing = fetch_one("SELECT id FROM supermarkets WHERE id = %s", (store_id,))
|
||||
if not existing:
|
||||
raise HTTPException(404, "Supermarket not found")
|
||||
data = payload.model_dump(exclude_unset=True)
|
||||
if not data:
|
||||
raise HTTPException(400, "Geen velden om bij te werken")
|
||||
allowed = set(SupermarketPatchIn.model_fields.keys())
|
||||
sets: list[str] = []
|
||||
params: list[Any] = []
|
||||
for key, val in data.items():
|
||||
if key not in allowed:
|
||||
continue
|
||||
sets.append(f"{key} = %s")
|
||||
params.append(val)
|
||||
sets.append("last_updated = NOW()")
|
||||
params.append(store_id)
|
||||
execute(f"UPDATE supermarkets SET {', '.join(sets)} WHERE id = %s", tuple(params))
|
||||
log_agent_event(
|
||||
agent_name="retail_crm",
|
||||
event_type="update",
|
||||
title=f"Supermarkt #{store_id} data aangevuld",
|
||||
)
|
||||
return {"ok": True, "item": _row(fetch_one(f"{STORE_SELECT} WHERE s.id = %s", (store_id,)))}
|
||||
|
||||
|
||||
@router.get("/scrape/chains")
|
||||
def list_scrape_chains() -> dict[str, Any]:
|
||||
return {"chains": retail_scrapers.list_chains()}
|
||||
|
||||
Reference in New Issue
Block a user