fix: restore historical order visibility for HartOMat admins
This commit is contained in:
@@ -9,6 +9,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|||||||
from sqlalchemy import select, func, update, or_, and_
|
from sqlalchemy import select, func, update, or_, and_
|
||||||
|
|
||||||
from app.database import get_db
|
from app.database import get_db
|
||||||
|
from app.domains.auth.models import PM_ROLES
|
||||||
from app.models.audit_log import AuditLog
|
from app.models.audit_log import AuditLog
|
||||||
from app.models.user import User
|
from app.models.user import User
|
||||||
from app.utils.auth import get_current_user
|
from app.utils.auth import get_current_user
|
||||||
@@ -45,7 +46,7 @@ class MarkReadRequest(BaseModel):
|
|||||||
def _visibility_filter(user: User):
|
def _visibility_filter(user: User):
|
||||||
"""Rows visible to this user: targeted at them, or broadcast (null) if admin/PM."""
|
"""Rows visible to this user: targeted at them, or broadcast (null) if admin/PM."""
|
||||||
targeted = AuditLog.target_user_id == user.id
|
targeted = AuditLog.target_user_id == user.id
|
||||||
if user.role.value in ("admin", "project_manager"):
|
if user.role.value in PM_ROLES:
|
||||||
broadcast = AuditLog.target_user_id.is_(None)
|
broadcast = AuditLog.target_user_id.is_(None)
|
||||||
return and_(AuditLog.notification == True, or_(targeted, broadcast)) # noqa: E712
|
return and_(AuditLog.notification == True, or_(targeted, broadcast)) # noqa: E712
|
||||||
return and_(AuditLog.notification == True, targeted) # noqa: E712
|
return and_(AuditLog.notification == True, targeted) # noqa: E712
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ from app.models.cad_file import CadFile
|
|||||||
from app.models.order import Order, OrderStatus
|
from app.models.order import Order, OrderStatus
|
||||||
from app.models.order_item import OrderItem, ItemStatus
|
from app.models.order_item import OrderItem, ItemStatus
|
||||||
from app.models.user import User
|
from app.models.user import User
|
||||||
|
from app.domains.auth.models import PM_ROLES
|
||||||
from app.schemas.order import OrderItemOut
|
from app.schemas.order import OrderItemOut
|
||||||
from app.utils.auth import get_current_user
|
from app.utils.auth import get_current_user
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ router = APIRouter(prefix="/orders", tags=["order_items"])
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_privileged(user: User) -> bool:
|
def _is_privileged(user: User) -> bool:
|
||||||
return user.role.value in ("admin", "project_manager")
|
return user.role.value in PM_ROLES
|
||||||
|
|
||||||
|
|
||||||
async def _get_order_and_item(
|
async def _get_order_and_item(
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ from app.models.product import Product
|
|||||||
from app.models.output_type import OutputType
|
from app.models.output_type import OutputType
|
||||||
from app.models.cad_file import CadFile
|
from app.models.cad_file import CadFile
|
||||||
from app.models.user import User
|
from app.models.user import User
|
||||||
|
from app.domains.auth.models import PM_ROLES
|
||||||
from app.schemas.order import OrderCreate, OrderOut, OrderDetailOut, OrderItemOut, RejectOrderRequest
|
from app.schemas.order import OrderCreate, OrderOut, OrderDetailOut, OrderItemOut, RejectOrderRequest
|
||||||
from app.schemas.order_line import OrderLineCreate, OrderLineOut
|
from app.schemas.order_line import OrderLineCreate, OrderLineOut
|
||||||
from app.schemas.product import ProductOut
|
from app.schemas.product import ProductOut
|
||||||
@@ -35,7 +36,7 @@ router = APIRouter(prefix="/orders", tags=["orders"])
|
|||||||
|
|
||||||
|
|
||||||
def _is_privileged(user: User) -> bool:
|
def _is_privileged(user: User) -> bool:
|
||||||
return user.role.value in ("admin", "project_manager")
|
return user.role.value in PM_ROLES
|
||||||
|
|
||||||
|
|
||||||
def _result_path_to_url(result_path: str) -> str | None:
|
def _result_path_to_url(result_path: str) -> str | None:
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from pydantic import BaseModel
|
|||||||
|
|
||||||
from app.config import settings
|
from app.config import settings
|
||||||
from app.database import get_db
|
from app.database import get_db
|
||||||
|
from app.domains.auth.models import PM_ROLES
|
||||||
from app.models.cad_file import CadFile, ProcessingStatus
|
from app.models.cad_file import CadFile, ProcessingStatus
|
||||||
from app.models.order import Order
|
from app.models.order import Order
|
||||||
from app.models.order_item import OrderItem
|
from app.models.order_item import OrderItem
|
||||||
@@ -491,7 +492,7 @@ async def add_material_alias_from_validation(
|
|||||||
from app.domains.materials.models import Material, MaterialAlias
|
from app.domains.materials.models import Material, MaterialAlias
|
||||||
|
|
||||||
# Gate to admin/PM
|
# Gate to admin/PM
|
||||||
if user.role.value not in ("admin", "project_manager"):
|
if user.role.value not in PM_ROLES:
|
||||||
raise HTTPException(status_code=403, detail="Admin or project_manager required")
|
raise HTTPException(status_code=403, detail="Admin or project_manager required")
|
||||||
|
|
||||||
# Verify the validation exists
|
# Verify the validation exists
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from datetime import datetime
|
|||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from app.domains.auth.models import PM_ROLES
|
||||||
from app.domains.admin.models import DashboardConfig
|
from app.domains.admin.models import DashboardConfig
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -59,7 +60,7 @@ def get_default_widgets_for_role(role: str) -> list[dict]:
|
|||||||
admin / project_manager: KPI + analytics defaults.
|
admin / project_manager: KPI + analytics defaults.
|
||||||
client: RecentRenders + ProductionStats only.
|
client: RecentRenders + ProductionStats only.
|
||||||
"""
|
"""
|
||||||
if role in ("admin", "project_manager"):
|
if role in PM_ROLES:
|
||||||
return [w.copy() for w in _DEFAULT_ADMIN_WIDGETS]
|
return [w.copy() for w in _DEFAULT_ADMIN_WIDGETS]
|
||||||
return [w.copy() for w in _DEFAULT_CLIENT_WIDGETS]
|
return [w.copy() for w in _DEFAULT_CLIENT_WIDGETS]
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import api from './client'
|
|||||||
import type { Product } from './products'
|
import type { Product } from './products'
|
||||||
import type { OutputType } from './outputTypes'
|
import type { OutputType } from './outputTypes'
|
||||||
|
|
||||||
|
const DEFAULT_ORDER_LIMIT = 200
|
||||||
|
|
||||||
export interface RenderLog {
|
export interface RenderLog {
|
||||||
renderer?: string
|
renderer?: string
|
||||||
type?: string
|
type?: string
|
||||||
@@ -132,7 +134,12 @@ export interface OrderDetail extends Order {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function listOrders(params?: { status?: string; skip?: number; limit?: number }) {
|
export async function listOrders(params?: { status?: string; skip?: number; limit?: number }) {
|
||||||
const res = await api.get<Order[]>('/orders', { params })
|
const res = await api.get<Order[]>('/orders', {
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
limit: params?.limit ?? DEFAULT_ORDER_LIMIT,
|
||||||
|
},
|
||||||
|
})
|
||||||
return res.data
|
return res.data
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +156,7 @@ export async function searchOrders(params: {
|
|||||||
statuses: params.statuses?.join(',') || '',
|
statuses: params.statuses?.join(',') || '',
|
||||||
date_from: params.date_from || '',
|
date_from: params.date_from || '',
|
||||||
date_to: params.date_to || '',
|
date_to: params.date_to || '',
|
||||||
limit: params.limit || 50,
|
limit: params.limit ?? DEFAULT_ORDER_LIMIT,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return res.data
|
return res.data
|
||||||
|
|||||||
Reference in New Issue
Block a user