d6508e0ae8
Implementazione completa del backend FastAPI: - Modelli SQLAlchemy: User, Recipe, RecipeVersion, RecipeTask, RecipeSubtask, Measurement, AccessLog, SystemSetting, RecipeVersionAudit - Schemas Pydantic v2 per tutti i CRUD + statistiche SPC - Middleware: API Key auth (X-API-Key) con role checking + access logging - Router: auth, users, recipes, tasks, measurements, files, settings - Services: auth (bcrypt+secrets), recipe (copy-on-write versioning), measurement (auto pass/fail con UTL/UWL/LWL/LTL) - Alembic env.py con import modelli attivi - Fix architect review: no double-commit, recipe_id subquery filter, user_id in access logs, type annotations corrette Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
95 lines
2.5 KiB
Python
95 lines
2.5 KiB
Python
"""Pydantic schemas for SPC statistics responses."""
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class StatisticsQuery(BaseModel):
|
|
"""Common query parameters for statistics endpoints."""
|
|
recipe_id: int
|
|
version_id: Optional[int] = None
|
|
subtask_id: Optional[int] = None
|
|
date_from: Optional[datetime] = None
|
|
date_to: Optional[datetime] = None
|
|
operator_id: Optional[int] = None
|
|
lot_number: Optional[str] = None
|
|
serial_number: Optional[str] = None
|
|
|
|
|
|
class ControlChartData(BaseModel):
|
|
"""Data for X-bar/R control chart."""
|
|
values: list[float]
|
|
timestamps: list[datetime]
|
|
mean: float
|
|
ucl: float # Upper Control Limit
|
|
lcl: float # Lower Control Limit
|
|
utl: Optional[float] = None
|
|
uwl: Optional[float] = None
|
|
lwl: Optional[float] = None
|
|
ltl: Optional[float] = None
|
|
nominal: Optional[float] = None
|
|
out_of_control: list[int] = [] # Indices of OOC points
|
|
|
|
|
|
class HistogramData(BaseModel):
|
|
"""Data for histogram with normal curve."""
|
|
bins: list[float]
|
|
counts: list[int]
|
|
normal_x: list[float]
|
|
normal_y: list[float]
|
|
mean: float
|
|
std_dev: float
|
|
n: int
|
|
|
|
|
|
class CapabilityData(BaseModel):
|
|
"""Capability indices."""
|
|
cp: Optional[float] = None
|
|
cpk: Optional[float] = None
|
|
pp: Optional[float] = None
|
|
ppk: Optional[float] = None
|
|
mean: float
|
|
std_dev: float
|
|
n: int
|
|
utl: Optional[float] = None
|
|
ltl: Optional[float] = None
|
|
nominal: Optional[float] = None
|
|
|
|
|
|
class TrendData(BaseModel):
|
|
"""Temporal trend data for capability indices."""
|
|
dates: list[datetime]
|
|
cpk_values: list[Optional[float]]
|
|
ppk_values: list[Optional[float]]
|
|
n_per_period: list[int]
|
|
|
|
|
|
class SummaryData(BaseModel):
|
|
"""Pass/fail/warning summary counts."""
|
|
total: int
|
|
pass_count: int
|
|
warning_count: int
|
|
fail_count: int
|
|
pass_rate: float
|
|
warning_rate: float
|
|
fail_rate: float
|
|
|
|
|
|
class AlertData(BaseModel):
|
|
"""Western Electric rules violations."""
|
|
rule: str
|
|
description: str
|
|
points: list[int] # Indices of violating points
|
|
severity: str = Field(..., pattern="^(info|warning|critical)$")
|
|
|
|
|
|
class StatisticsResponse(BaseModel):
|
|
"""Combined statistics response."""
|
|
summary: SummaryData
|
|
capability: Optional[CapabilityData] = None
|
|
control_chart: Optional[ControlChartData] = None
|
|
histogram: Optional[HistogramData] = None
|
|
trend: Optional[TrendData] = None
|
|
alerts: list[AlertData] = []
|