feat(manufacturing): enrich inventory list with customer/user details and filters

The inventory list and detail page previously only showed raw
customer_id / user_list references. list_devices now batch-resolves
customer names and user display names/emails (via Firestore get_all(),
avoiding an N+1 round trip per device) and exposes them as
customer_name / users on DeviceInventoryItem. Search now matches
against device name, console name, customer name, and assigned users
in addition to serial/owner/batch.

Also adds hw_types (multi-select board type) and has_users filters to
GET /manufacturing/devices, and carries console_name through for
display. DeviceInventoryDetail is updated to show and use all of this
(customer name, assigned users, new UI components for signal/charts).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-21 18:34:08 +03:00
co-authored by Claude Sonnet 5
parent b07bdafd85
commit 6686faad6b
4 changed files with 197 additions and 27 deletions
+13
View File
@@ -80,6 +80,12 @@ class BatchResponse(BaseModel):
created_at: str
class DeviceUserSummary(BaseModel):
user_id: str
display_name: str = ""
email: str = ""
class DeviceInventoryItem(BaseModel):
id: str
serial_number: str
@@ -91,9 +97,16 @@ class DeviceInventoryItem(BaseModel):
owner: Optional[str] = None
assigned_to: Optional[str] = None
device_name: Optional[str] = None
# Console-only friendly name (mirrors devices.models.DeviceCreate.console_name).
# Only populated once a device has been claimed/onboarded in the app — null
# for freshly manufactured inventory, which is expected and should render
# as a graceful fallback (e.g. serial number) on the frontend.
console_name: Optional[str] = None
lifecycle_history: Optional[List["LifecycleEntry"]] = None
customer_id: Optional[str] = None
customer_name: Optional[str] = None
user_list: Optional[List[str]] = None
users: Optional[List[DeviceUserSummary]] = None
class DeviceInventoryListResponse(BaseModel):