nomadweb/backend/app/services/platform_store.py
eric 48408d3079 feat: complete NomadCNA parity layer with platform APIs and pages
Add services, videos, AI assistant, map/weather, gigs post, notifications settings, static legal pages, Google OAuth, payment router, real-user matching, newsletter, and content submission — all using nomadweb UI patterns.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-30 10:13:17 -05:00

142 lines
3.5 KiB
Python

"""Platform persistence: leads, submissions, volunteers, reports, newsletter."""
from __future__ import annotations
import json
import secrets
from datetime import datetime, timezone
from pathlib import Path
STORE_PATH = Path(__file__).resolve().parents[1] / "data" / "platform_store.json"
_leads: list[dict] = []
_submissions: list[dict] = []
_volunteers: list[dict] = []
_reports: list[dict] = []
_newsletter: list[dict] = []
_notif_prefs: dict[str, dict] = {}
def _now() -> str:
return datetime.now(timezone.utc).strftime("%Y-%m-%d")
def _persist() -> None:
STORE_PATH.parent.mkdir(parents=True, exist_ok=True)
STORE_PATH.write_text(json.dumps({
"leads": _leads,
"submissions": _submissions,
"volunteers": _volunteers,
"reports": _reports,
"newsletter": _newsletter,
"notif_prefs": _notif_prefs,
}, ensure_ascii=False), encoding="utf-8")
def _restore() -> None:
global _leads, _submissions, _volunteers, _reports, _newsletter, _notif_prefs
if not STORE_PATH.exists():
return
try:
data = json.loads(STORE_PATH.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError):
return
_leads = data.get("leads") or []
_submissions = data.get("submissions") or []
_volunteers = data.get("volunteers") or []
_reports = data.get("reports") or []
_newsletter = data.get("newsletter") or []
_notif_prefs = data.get("notif_prefs") or {}
_restore()
def add_service_lead(service_id: str, user_id: str | None, name: str, email: str, message: str) -> dict:
item = {
"id": secrets.token_hex(6),
"service_id": service_id,
"user_id": user_id or "",
"name": name,
"email": email,
"message": message,
"created_at": _now(),
}
_leads.append(item)
_persist()
return item
def add_content_submission(user_id: str | None, name: str, title: str, content_type: str, url: str, notes: str) -> dict:
item = {
"id": secrets.token_hex(6),
"user_id": user_id or "",
"name": name,
"title": title,
"content_type": content_type,
"url": url,
"notes": notes,
"status": "pending",
"created_at": _now(),
}
_submissions.append(item)
_persist()
return item
def add_volunteer(city_slug: str, user_id: str | None, name: str, email: str, message: str) -> dict:
item = {
"id": secrets.token_hex(6),
"city_slug": city_slug,
"user_id": user_id or "",
"name": name,
"email": email,
"message": message,
"created_at": _now(),
}
_volunteers.append(item)
_persist()
return item
def add_report(reporter_id: str | None, target_type: str, target_id: str, reason: str) -> dict:
item = {
"id": secrets.token_hex(6),
"reporter_id": reporter_id or "",
"target_type": target_type,
"target_id": target_id,
"reason": reason,
"status": "open",
"created_at": _now(),
}
_reports.append(item)
_persist()
return item
def subscribe_newsletter(email: str, source: str = "site") -> dict:
for n in _newsletter:
if n["email"] == email:
return {"ok": True, "message": "已订阅"}
_newsletter.append({"email": email, "source": source, "created_at": _now()})
_persist()
return {"ok": True, "message": "订阅成功"}
def get_notif_prefs(user_id: str) -> dict:
return _notif_prefs.get(user_id) or {
"email": True,
"push": False,
"match": True,
"meetup": True,
"community": True,
"marketing": False,
"quiet_hours": "",
}
def set_notif_prefs(user_id: str, prefs: dict) -> dict:
_notif_prefs[user_id] = {**get_notif_prefs(user_id), **prefs}
_persist()
return _notif_prefs[user_id]