external_link.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. from datetime import datetime
  2. from pydantic import BaseModel, Field, field_validator
  3. from backend.app.schemas.not_null import IgnoresNullForRequiredColumns
  4. class ExternalLinkBase(BaseModel):
  5. """Base schema for external links."""
  6. name: str = Field(..., min_length=1, max_length=50, description="Display name for the link")
  7. url: str = Field(..., min_length=1, max_length=500, description="External URL")
  8. icon: str = Field(default="link", max_length=50, description="Lucide icon name")
  9. open_in_new_tab: bool = False
  10. @field_validator("url")
  11. @classmethod
  12. def validate_url(cls, v: str) -> str:
  13. """Validate URL format."""
  14. if not v.startswith(("http://", "https://")):
  15. raise ValueError("URL must start with http:// or https://")
  16. return v
  17. class ExternalLinkCreate(ExternalLinkBase):
  18. """Schema for creating an external link."""
  19. pass
  20. class ExternalLinkUpdate(IgnoresNullForRequiredColumns):
  21. """Schema for updating an external link (all fields optional)."""
  22. __orm_table__ = "external_links"
  23. name: str | None = Field(default=None, min_length=1, max_length=50)
  24. url: str | None = Field(default=None, min_length=1, max_length=500)
  25. icon: str | None = Field(default=None, max_length=50)
  26. open_in_new_tab: bool | None = None
  27. @field_validator("url")
  28. @classmethod
  29. def validate_url(cls, v: str | None) -> str | None:
  30. """Validate URL format."""
  31. if v is not None and not v.startswith(("http://", "https://")):
  32. raise ValueError("URL must start with http:// or https://")
  33. return v
  34. class ExternalLinkResponse(ExternalLinkBase):
  35. """Response schema for external links."""
  36. id: int
  37. open_in_new_tab: bool
  38. custom_icon: str | None = None
  39. sort_order: int
  40. created_at: datetime
  41. updated_at: datetime
  42. # Set by the app the link points to, while it keeps reporting; None otherwise.
  43. badge_count: int | None = None
  44. model_config = {"from_attributes": True}
  45. class ExternalLinkBadgeSet(BaseModel):
  46. """An app's count for the sidebar link pointing at it."""
  47. url: str = Field(..., min_length=1, max_length=500, description="The app's address, as the link has it")
  48. count: int = Field(..., ge=0, le=1_000_000)
  49. @field_validator("url")
  50. @classmethod
  51. def validate_url(cls, v: str) -> str:
  52. if not v.startswith(("http://", "https://")):
  53. raise ValueError("URL must start with http:// or https://")
  54. return v
  55. class ExternalLinkReorder(BaseModel):
  56. """Schema for reordering external links."""
  57. ids: list[int] = Field(..., description="List of link IDs in desired order")