Prepare ERP source for Gitea deployment

This commit is contained in:
A R R R Associates
2026-06-20 15:01:44 +05:30
commit 5c75eb6bd9
450 changed files with 67698 additions and 0 deletions
+127
View File
@@ -0,0 +1,127 @@
from __future__ import annotations
from fastapi import APIRouter, Form, Request
from fastapi.responses import JSONResponse, RedirectResponse
from app.core.db.common import CommonSessionLocal
from app.core.security.csrf import get_or_create_csrf_token, validate_csrf
from app.core.security.session_auth import get_current_user
from app.core.templating import templates
from app.modules.alerts.service import ALERT_PRIORITIES, count_unread_alerts, list_my_alerts, mark_alert_read, mark_all_alerts_read
from app.modules.core.rbac.deps import get_user_permissions, get_user_roles
router = APIRouter(prefix="/alerts", tags=["alerts-ui"])
def _redirect_login():
return RedirectResponse(url="/login", status_code=303)
def _base_ctx(request: Request, db, current_user, **ctx):
base = {
"request": request,
"current_user": current_user,
"current_user_roles": get_user_roles(db, current_user.id),
"current_user_permissions": get_user_permissions(db, current_user.id),
"csrf_token": get_or_create_csrf_token(request),
}
base.update(ctx)
return base
@router.get("/poll")
def poll_unread_alerts(request: Request, limit: int = 5):
"""Lightweight polling endpoint used by the base layout toast popup.
Returns a small list of unread alerts for the logged-in user. It does not
mark alerts as read; the normal /alerts page and existing read actions
continue to control read status.
"""
db = CommonSessionLocal()
try:
current_user = get_current_user(request, db)
if not current_user:
return JSONResponse({"authenticated": False, "unread_count": 0, "alerts": []}, status_code=401)
safe_limit = max(1, min(int(limit or 5), 10))
rows = list_my_alerts(db, current_user, status="unread", priority="all", limit=safe_limit)
payload = []
for row in rows:
created_at = getattr(row, "created_at_utc", None)
payload.append(
{
"id": row.id,
"title": row.title or "Alert",
"message": row.message or "",
"priority": row.priority or "normal",
"alert_type": row.alert_type or "general",
"target_url": row.target_url or "/alerts",
"created_at_utc": created_at.isoformat() if created_at else None,
}
)
return JSONResponse(
{
"authenticated": True,
"unread_count": count_unread_alerts(db, current_user),
"alerts": payload,
}
)
finally:
db.close()
@router.get("")
def alerts_list(request: Request, status: str = "all", priority: str = "all"):
db = CommonSessionLocal()
try:
current_user = get_current_user(request, db)
if not current_user:
return _redirect_login()
status = status if status in {"all", "unread", "read"} else "all"
priority = priority if priority in ALERT_PRIORITIES else "all"
rows = list_my_alerts(db, current_user, status=status, priority=priority, limit=150)
return templates.TemplateResponse(
"modules/alerts/templates/alerts/list.html",
_base_ctx(
request,
db,
current_user,
title="My Alerts",
alerts=rows,
status=status,
priority=priority,
priorities=ALERT_PRIORITIES,
unread_count=count_unread_alerts(db, current_user),
),
)
finally:
db.close()
@router.post("/{alert_id}/read")
def mark_read(request: Request, alert_id: int, csrf_token: str = Form(...)):
db = CommonSessionLocal()
try:
current_user = get_current_user(request, db)
if not current_user:
return _redirect_login()
validate_csrf(request, csrf_token)
mark_alert_read(db, current_user, alert_id)
return RedirectResponse(url="/alerts", status_code=303)
finally:
db.close()
@router.post("/read-all")
def mark_all_read(request: Request, csrf_token: str = Form(...)):
db = CommonSessionLocal()
try:
current_user = get_current_user(request, db)
if not current_user:
return _redirect_login()
validate_csrf(request, csrf_token)
mark_all_alerts_read(db, current_user)
return RedirectResponse(url="/alerts", status_code=303)
finally:
db.close()