Files
leocrm/app/plugins/builtins/calendar/schemas.py
T

171 lines
4.9 KiB
Python
Raw Normal View History

"""Pydantic schemas for the Calendar plugin."""
from __future__ import annotations
from datetime import UTC, datetime
from typing import Any
from pydantic import BaseModel, Field, field_validator
def _ensure_utc(v: datetime | None) -> datetime | None:
"""Convert naive datetimes to UTC to prevent local-time shifts in DB storage."""
if v is not None and isinstance(v, datetime) and v.tzinfo is None:
return v.replace(tzinfo=UTC)
return v
class CalendarCreate(BaseModel):
name: str = Field(..., min_length=1, max_length=200)
color: str = Field("#3B82F6", max_length=20)
type: str = Field("personal", pattern="^(personal|team|project|company)$")
class CalendarUpdate(BaseModel):
name: str | None = Field(None, min_length=1, max_length=200)
color: str | None = Field(None, max_length=20)
class CalendarResponse(BaseModel):
id: str
name: str
color: str
type: str
owner_id: str
ics_token: str | None = None
created_at: datetime | None = None
updated_at: datetime | None = None
class ShareRequest(BaseModel):
user_id: str | None = None
group_id: str | None = None
permission: str = Field(..., pattern="^(read|write)$")
class ShareResponse(BaseModel):
id: str
calendar_id: str
user_id: str | None = None
group_id: str | None = None
permission: str
class EntryCreate(BaseModel):
calendar_id: str
entry_type: str = Field(..., pattern="^(appointment|task)$")
subtype: str = Field("normal", pattern="^(normal|follow_up|private)$")
title: str = Field(..., min_length=1, max_length=500)
description: str | None = None
start_at: datetime | None = None
_ensure_utc_start = field_validator("start_at")(lambda cls, v: _ensure_utc(v))
end_at: datetime | None = None
_ensure_utc_end = field_validator("end_at")(lambda cls, v: _ensure_utc(v))
all_day: bool = False
location: str | None = Field(None, max_length=500)
due_date: datetime | None = None
_ensure_utc_due = field_validator("due_date")(lambda cls, v: _ensure_utc(v))
priority: str = Field("medium", pattern="^(low|medium|high)$")
status: str = Field("open", pattern="^(open|in_progress|done|cancelled)$")
assigned_to: str | None = None
reminder: dict[str, Any] | None = None
recurrence: dict[str, Any] | None = None
class EntryUpdate(BaseModel):
calendar_id: str | None = None
subtype: str | None = Field(None, pattern="^(normal|follow_up|private)$")
title: str | None = Field(None, min_length=1, max_length=500)
description: str | None = None
start_at: datetime | None = None
_ensure_utc_start = field_validator("start_at")(lambda cls, v: _ensure_utc(v))
end_at: datetime | None = None
_ensure_utc_end = field_validator("end_at")(lambda cls, v: _ensure_utc(v))
all_day: bool | None = None
location: str | None = Field(None, max_length=500)
due_date: datetime | None = None
_ensure_utc_due = field_validator("due_date")(lambda cls, v: _ensure_utc(v))
priority: str | None = Field(None, pattern="^(low|medium|high)$")
status: str | None = Field(None, pattern="^(open|in_progress|done|cancelled)$")
assigned_to: str | None = None
reminder: dict[str, Any] | None = None
recurrence: dict[str, Any] | None = None
class EntryResponse(BaseModel):
id: str
calendar_id: str
entry_type: str
subtype: str
title: str
description: str | None = None
start_at: datetime | None = None
end_at: datetime | None = None
all_day: bool
location: str | None = None
due_date: datetime | None = None
priority: str
status: str
assigned_to: str | None = None
reminder: dict[str, Any] | None = None
recurrence: dict[str, Any] | None = None
created_by: str
created_at: datetime | None = None
updated_at: datetime | None = None
links: list[dict] = []
subtasks: list[dict] = []
class LinkRequest(BaseModel):
entity_type: str = Field(..., pattern="^(company|contact)$")
entity_id: str
class SubtaskCreate(BaseModel):
title: str = Field(..., min_length=1, max_length=500)
class SubtaskResponse(BaseModel):
id: str
entry_id: str
title: str
completed: bool
class SubtaskUpdate(BaseModel):
completed: bool | None = None
title: str | None = Field(None, min_length=1, max_length=500)
class BulkAction(BaseModel):
entry_ids: list[str] = Field(..., min_length=1)
action: str = Field(..., pattern="^(open|in_progress|done|cancelled|delete)$")
class ResourceCreate(BaseModel):
name: str = Field(..., min_length=1, max_length=200)
type: str = Field(..., pattern="^(room|equipment)$")
class ResourceResponse(BaseModel):
id: str
name: str
type: str
class BookResourceRequest(BaseModel):
resource_id: str
class ResourceBookingResponse(BaseModel):
id: str
resource_id: str
entry_id: str
start_at: datetime
end_at: datetime
class ImportResult(BaseModel):
entries_created: int
errors: list[str] = []