200 lines
5.2 KiB
Python
200 lines
5.2 KiB
Python
from datetime import datetime
|
|
from typing import Literal
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field, HttpUrl, field_validator
|
|
|
|
DocumentType = Literal[
|
|
"manual",
|
|
"service_manual",
|
|
"schematic",
|
|
"alignment",
|
|
"parts_list",
|
|
"firmware",
|
|
"datasheet",
|
|
"service_bulletin",
|
|
"other",
|
|
]
|
|
NoteType = Literal["repair", "known_fault", "alignment", "spare_part", "general"]
|
|
NoteSeverity = Literal["low", "medium", "high", "critical", ""]
|
|
|
|
|
|
def normalize_text(value: object) -> str:
|
|
if value is None:
|
|
return ""
|
|
return str(value).strip()
|
|
|
|
|
|
def normalize_tags(value: object) -> list[str]:
|
|
if value is None or value == "":
|
|
return []
|
|
if isinstance(value, str):
|
|
parts = value.split(",")
|
|
elif isinstance(value, list):
|
|
parts = value
|
|
else:
|
|
parts = []
|
|
seen: set[str] = set()
|
|
tags: list[str] = []
|
|
for part in parts:
|
|
tag = str(part).strip()
|
|
key = tag.lower()
|
|
if tag and key not in seen:
|
|
seen.add(key)
|
|
tags.append(tag)
|
|
return tags
|
|
|
|
|
|
class KnowledgeManufacturerBase(BaseModel):
|
|
name: str = Field(min_length=2, max_length=160)
|
|
website: HttpUrl | None = None
|
|
notes: str = ""
|
|
|
|
@field_validator("name", "notes", mode="before")
|
|
@classmethod
|
|
def normalize_text_fields(cls, value: object) -> str:
|
|
return normalize_text(value)
|
|
|
|
|
|
class KnowledgeManufacturerCreate(KnowledgeManufacturerBase):
|
|
pass
|
|
|
|
|
|
class KnowledgeManufacturerUpdate(KnowledgeManufacturerBase):
|
|
pass
|
|
|
|
|
|
class KnowledgeManufacturerResponse(KnowledgeManufacturerBase):
|
|
id: int
|
|
slug: str
|
|
website: str
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class KnowledgeDeviceBase(BaseModel):
|
|
manufacturer_id: int
|
|
name: str = Field(min_length=2, max_length=180)
|
|
model_number: str = Field(default="", max_length=120)
|
|
device_type: str = Field(default="", max_length=80)
|
|
frequency_range: str = Field(default="", max_length=120)
|
|
production_year_from: int | None = Field(default=None, ge=1900, le=2100)
|
|
production_year_to: int | None = Field(default=None, ge=1900, le=2100)
|
|
notes: str = ""
|
|
|
|
@field_validator("name", "model_number", "device_type", "frequency_range", "notes", mode="before")
|
|
@classmethod
|
|
def normalize_text_fields(cls, value: object) -> str:
|
|
return normalize_text(value)
|
|
|
|
|
|
class KnowledgeDeviceCreate(KnowledgeDeviceBase):
|
|
pass
|
|
|
|
|
|
class KnowledgeDeviceUpdate(KnowledgeDeviceBase):
|
|
pass
|
|
|
|
|
|
class KnowledgeDeviceResponse(KnowledgeDeviceBase):
|
|
id: int
|
|
slug: str
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
manufacturer: KnowledgeManufacturerResponse
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class KnowledgeDocumentBase(BaseModel):
|
|
manufacturer_id: int
|
|
device_id: int | None = None
|
|
title: str = Field(min_length=2, max_length=255)
|
|
document_type: DocumentType
|
|
language: str = Field(default="de", min_length=2, max_length=20)
|
|
external_url: HttpUrl | None = None
|
|
paperless_document_id: str = Field(default="", max_length=120)
|
|
description: str = ""
|
|
tags: list[str] = Field(default_factory=list)
|
|
|
|
@field_validator("title", "language", "paperless_document_id", "description", mode="before")
|
|
@classmethod
|
|
def normalize_text_fields(cls, value: object) -> str:
|
|
return normalize_text(value)
|
|
|
|
@field_validator("tags", mode="before")
|
|
@classmethod
|
|
def normalize_tag_fields(cls, value: object) -> list[str]:
|
|
return normalize_tags(value)
|
|
|
|
|
|
class KnowledgeDocumentCreate(KnowledgeDocumentBase):
|
|
pass
|
|
|
|
|
|
class KnowledgeDocumentUpdate(KnowledgeDocumentBase):
|
|
pass
|
|
|
|
|
|
class KnowledgeDocumentResponse(KnowledgeDocumentBase):
|
|
id: int
|
|
slug: str
|
|
external_url: str
|
|
file_name: str
|
|
file_path: str
|
|
mime_type: str
|
|
file_size: int
|
|
checksum_sha256: str
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
manufacturer: KnowledgeManufacturerResponse
|
|
device: KnowledgeDeviceResponse | None = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class KnowledgeNoteBase(BaseModel):
|
|
manufacturer_id: int | None = None
|
|
device_id: int | None = None
|
|
title: str = Field(min_length=2, max_length=255)
|
|
content: str = Field(min_length=1)
|
|
note_type: NoteType = "general"
|
|
severity: NoteSeverity = ""
|
|
tags: list[str] = Field(default_factory=list)
|
|
|
|
@field_validator("title", "content", "severity", mode="before")
|
|
@classmethod
|
|
def normalize_text_fields(cls, value: object) -> str:
|
|
return normalize_text(value)
|
|
|
|
@field_validator("tags", mode="before")
|
|
@classmethod
|
|
def normalize_tag_fields(cls, value: object) -> list[str]:
|
|
return normalize_tags(value)
|
|
|
|
|
|
class KnowledgeNoteCreate(KnowledgeNoteBase):
|
|
pass
|
|
|
|
|
|
class KnowledgeNoteUpdate(KnowledgeNoteBase):
|
|
pass
|
|
|
|
|
|
class KnowledgeNoteResponse(KnowledgeNoteBase):
|
|
id: int
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
manufacturer: KnowledgeManufacturerResponse | None = None
|
|
device: KnowledgeDeviceResponse | None = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class KnowledgeSearchResult(BaseModel):
|
|
entity_type: str
|
|
id: int
|
|
title: str
|
|
subtitle: str = ""
|
|
href: str
|