feat(knowledge): add service library

This commit is contained in:
DS | Schubert 2026-07-03 10:25:52 +02:00
parent ecab0fe6b6
commit 228da8f814
32 changed files with 2878 additions and 6 deletions

View file

@ -0,0 +1,200 @@
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