Backend: UTC nel DB, +00:00 nelle API, ora italiana solo in presentazione (#42)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
"""Pydantic schemas for Measurement operations."""
|
||||
from datetime import datetime
|
||||
from src.backend.models.api.tipi import UtcDateTime, UtcNaiveInput
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
@@ -54,8 +54,8 @@ class MeasurementResponse(BaseModel):
|
||||
# Who let this value stand, when it was out of tolerance. Null on a value in
|
||||
# tolerance - and on one that is not and is still waiting for an answer.
|
||||
supervisor_id: Optional[int] = None
|
||||
authorised_at: Optional[datetime] = None
|
||||
measured_at: datetime
|
||||
authorised_at: Optional[UtcDateTime] = None
|
||||
measured_at: UtcDateTime
|
||||
synced_to_csv: bool
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ class CycleMeasurementResponse(BaseModel):
|
||||
subtask_id: int
|
||||
value: float
|
||||
pass_fail: str
|
||||
measured_at: datetime
|
||||
measured_at: UtcDateTime
|
||||
|
||||
|
||||
class CurrentCycleResponse(BaseModel):
|
||||
@@ -114,8 +114,8 @@ class MeasurementQuery(BaseModel):
|
||||
measured_by: Optional[int] = None
|
||||
lot_number: Optional[str] = None
|
||||
serial_number: Optional[str] = None
|
||||
date_from: Optional[datetime] = None
|
||||
date_to: Optional[datetime] = None
|
||||
date_from: UtcNaiveInput = None
|
||||
date_to: UtcNaiveInput = None
|
||||
pass_fail: Optional[str] = Field(None, pattern="^(pass|warning|fail)$")
|
||||
page: int = Field(1, ge=1)
|
||||
per_page: int = Field(50, ge=1, le=500)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""Pydantic schemas for production runs and their events."""
|
||||
from datetime import datetime
|
||||
from src.backend.models.api.tipi import UtcDateTime
|
||||
from typing import Literal, Optional
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
@@ -21,7 +21,7 @@ class ProductionEventResponse(BaseModel):
|
||||
supervisor_id: Optional[int]
|
||||
task_id: Optional[int] = None
|
||||
note: Optional[str]
|
||||
created_at: datetime
|
||||
created_at: UtcDateTime
|
||||
|
||||
|
||||
class ProductionRunResponse(BaseModel):
|
||||
@@ -36,11 +36,11 @@ class ProductionRunResponse(BaseModel):
|
||||
serial_number: Optional[str]
|
||||
status: str
|
||||
measurement_interval_minutes: Optional[int]
|
||||
next_measurement_at: Optional[datetime]
|
||||
next_measurement_at: Optional[UtcDateTime]
|
||||
cycle_count: int
|
||||
started_at: datetime
|
||||
paused_at: Optional[datetime]
|
||||
closed_at: Optional[datetime]
|
||||
started_at: UtcDateTime
|
||||
paused_at: Optional[UtcDateTime]
|
||||
closed_at: Optional[UtcDateTime]
|
||||
closed_by: Optional[int]
|
||||
statistics_path: Optional[str] = None
|
||||
|
||||
@@ -49,7 +49,7 @@ class ProductionRunResponse(BaseModel):
|
||||
# overdue is a fact the operator must see, not deduce.
|
||||
seconds_to_next_measurement: Optional[int] = None
|
||||
overdue: bool = False
|
||||
server_time: Optional[datetime] = None
|
||||
server_time: Optional[UtcDateTime] = None
|
||||
|
||||
# The measurement tasks of this run's version, in execution order. The client
|
||||
# needs them to bring the operator back to the measurement when the interval
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""Pydantic schemas for Recipe and RecipeVersion operations."""
|
||||
from datetime import datetime
|
||||
from src.backend.models.api.tipi import UtcDateTime
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
@@ -51,7 +51,7 @@ class RecipeVersionResponse(BaseModel):
|
||||
version_number: int
|
||||
is_current: bool
|
||||
created_by: int
|
||||
created_at: datetime
|
||||
created_at: UtcDateTime
|
||||
change_notes: Optional[str] = None
|
||||
tasks: list["TaskResponse"] = []
|
||||
|
||||
@@ -72,7 +72,7 @@ class RecipeResponse(BaseModel):
|
||||
requires_serial: bool = False
|
||||
allow_manual_input: bool = False
|
||||
created_by: int
|
||||
created_at: datetime
|
||||
created_at: UtcDateTime
|
||||
active: bool
|
||||
current_version: Optional[RecipeVersionResponse] = None
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""Pydantic schemas for Station and StationRecipeAssignment."""
|
||||
from datetime import datetime
|
||||
from src.backend.models.api.tipi import UtcDateTime
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
@@ -29,7 +29,7 @@ class StationResponse(BaseModel):
|
||||
notes: Optional[str]
|
||||
active: bool
|
||||
created_by: int
|
||||
created_at: datetime
|
||||
created_at: UtcDateTime
|
||||
|
||||
|
||||
class StationRecipeAssignmentCreate(BaseModel):
|
||||
@@ -42,7 +42,7 @@ class StationRecipeAssignmentResponse(BaseModel):
|
||||
station_id: int
|
||||
recipe_id: int
|
||||
assigned_by: int
|
||||
assigned_at: datetime
|
||||
assigned_at: UtcDateTime
|
||||
|
||||
|
||||
class RecipeSummary(BaseModel):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""Pydantic schemas for SPC statistics responses."""
|
||||
from datetime import datetime
|
||||
from src.backend.models.api.tipi import UtcDateTime, UtcNaiveInput
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -10,8 +10,8 @@ class StatisticsQuery(BaseModel):
|
||||
recipe_id: int
|
||||
version_id: Optional[int] = None
|
||||
subtask_id: Optional[int] = None
|
||||
date_from: Optional[datetime] = None
|
||||
date_to: Optional[datetime] = None
|
||||
date_from: UtcNaiveInput = None
|
||||
date_to: UtcNaiveInput = None
|
||||
operator_id: Optional[int] = None
|
||||
lot_number: Optional[str] = None
|
||||
serial_number: Optional[str] = None
|
||||
@@ -20,7 +20,7 @@ class StatisticsQuery(BaseModel):
|
||||
class ControlChartData(BaseModel):
|
||||
"""Data for X-bar/R control chart."""
|
||||
values: list[float]
|
||||
timestamps: list[datetime]
|
||||
timestamps: list[UtcDateTime]
|
||||
mean: float
|
||||
ucl: float # Upper Control Limit
|
||||
lcl: float # Lower Control Limit
|
||||
@@ -60,7 +60,7 @@ class CapabilityData(BaseModel):
|
||||
|
||||
class TrendData(BaseModel):
|
||||
"""Temporal trend data for capability indices."""
|
||||
dates: list[datetime]
|
||||
dates: list[UtcDateTime]
|
||||
cpk_values: list[Optional[float]]
|
||||
ppk_values: list[Optional[float]]
|
||||
n_per_period: list[int]
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
"""Shared Pydantic types for datetimes (#42): UTC in the DB, explicit +00:00 on the wire."""
|
||||
from datetime import datetime
|
||||
from typing import Annotated, Optional
|
||||
|
||||
from pydantic import AfterValidator, PlainSerializer
|
||||
|
||||
from src.backend.utils.tempo import as_utc_naive, to_utc_aware
|
||||
|
||||
UtcDateTime = Annotated[
|
||||
datetime, PlainSerializer(lambda v: to_utc_aware(v).isoformat(), return_type=str)
|
||||
]
|
||||
|
||||
# Input: aware values are converted to UTC naive, naive is taken as UTC.
|
||||
UtcNaiveInput = Annotated[Optional[datetime], AfterValidator(as_utc_naive)]
|
||||
@@ -1,5 +1,5 @@
|
||||
"""Pydantic schemas for User operations."""
|
||||
from datetime import datetime
|
||||
from src.backend.models.api.tipi import UtcDateTime
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
@@ -48,8 +48,8 @@ class UserResponse(BaseModel):
|
||||
language_pref: str
|
||||
theme_pref: str
|
||||
active: bool
|
||||
created_at: datetime
|
||||
last_login: Optional[datetime] = None
|
||||
created_at: UtcDateTime
|
||||
last_login: Optional[UtcDateTime] = None
|
||||
|
||||
|
||||
class UserPasswordChange(BaseModel):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""Pydantic schemas for the vision execution response."""
|
||||
from datetime import datetime
|
||||
from src.backend.models.api.tipi import UtcDateTime
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
@@ -28,4 +28,4 @@ class VisionReferenceImageResponse(BaseModel):
|
||||
note: str | None = None
|
||||
station_id: int | None = None
|
||||
device_code: str | None = None
|
||||
acquired_at: datetime
|
||||
acquired_at: UtcDateTime
|
||||
|
||||
Reference in New Issue
Block a user