diff --git a/src/dispatch/case/models.py b/src/dispatch/case/models.py index 95eb1fd72aa4..192d7d6356e4 100644 --- a/src/dispatch/case/models.py +++ b/src/dispatch/case/models.py @@ -1,4 +1,5 @@ """Models and schemas for the Dispatch case management system.""" + from collections import Counter, defaultdict from datetime import datetime from typing import Any @@ -78,6 +79,7 @@ class Case(Base, TimeStampMixin, ProjectMixin): """SQLAlchemy model for a Case, representing an incident or issue in the system.""" + __table_args__ = (UniqueConstraint("name", "project_id"),) id = Column(Integer, primary_key=True) @@ -231,18 +233,20 @@ def total_cost_new(self): class SignalRead(DispatchBase): """Pydantic model for reading signal data.""" + id: PrimaryKey name: str owner: str - description: str | None - variant: str | None + description: str | None = None + variant: str | None = None external_id: str - external_url: str | None + external_url: str | None = None workflow_instances: list[WorkflowInstanceRead] | None = [] class SignalInstanceRead(DispatchBase): """Pydantic model for reading signal instance data.""" + created_at: datetime entities: list[EntityRead] | None = [] raw: Any @@ -252,21 +256,24 @@ class SignalInstanceRead(DispatchBase): class ProjectRead(DispatchBase): """Pydantic model for reading project data.""" - id: PrimaryKey | None + + id: PrimaryKey | None = None name: NameStr - display_name: str | None - color: str | None + display_name: str | None = None + color: str | None = None allow_self_join: bool | None = Field(True, nullable=True) + # Pydantic models... class CaseBase(DispatchBase): """Base Pydantic model for case data.""" + title: str - description: str | None - resolution: str | None - resolution_reason: CaseResolutionReason | None - status: CaseStatus | None - visibility: Visibility | None + description: str | None = None + resolution: str | None = None + resolution_reason: CaseResolutionReason | None = None + status: CaseStatus | None = None + visibility: Visibility | None = None @field_validator("title") @classmethod @@ -287,42 +294,46 @@ def description_required(cls, v): class CaseCreate(CaseBase): """Pydantic model for creating a new case.""" - assignee: ParticipantUpdate | None - case_priority: CasePriorityCreate | None - case_severity: CaseSeverityCreate | None - case_type: CaseTypeCreate | None - dedicated_channel: bool | None - project: ProjectRead | None - reporter: ParticipantUpdate | None + + assignee: ParticipantUpdate | None = None + case_priority: CasePriorityCreate | None = None + case_severity: CaseSeverityCreate | None = None + case_type: CaseTypeCreate | None = None + dedicated_channel: bool | None = None + project: ProjectRead | None = None + reporter: ParticipantUpdate | None = None tags: list[TagRead] | None = [] event: bool | None = False class CaseReadBasic(DispatchBase): """Pydantic model for reading basic case data.""" + id: PrimaryKey - name: NameStr | None + name: NameStr | None = None class IncidentReadBasic(DispatchBase): """Pydantic model for reading basic incident data.""" + id: PrimaryKey - name: NameStr | None + name: NameStr | None = None class CaseReadMinimal(CaseBase): """Pydantic model for reading minimal case data.""" + id: PrimaryKey - name: NameStr | None - status: CaseStatus | None # Used in table and for action disabling + name: NameStr | None = None + status: CaseStatus | None = None # Used in table and for action disabling closed_at: datetime | None = None reported_at: datetime | None = None - dedicated_channel: bool | None # Used by CaseStatus component + dedicated_channel: bool | None = None # Used by CaseStatus component case_type: CaseTypeRead case_severity: CaseSeverityRead case_priority: CasePriorityRead project: ProjectRead - assignee: ParticipantReadMinimal | None + assignee: ParticipantReadMinimal | None = None case_costs: list[CaseCostReadMinimal] = [] @@ -331,8 +342,9 @@ class CaseReadMinimal(CaseBase): class CaseRead(CaseBase): """Pydantic model for reading detailed case data.""" + id: PrimaryKey - assignee: ParticipantRead | None + assignee: ParticipantRead | None = None case_costs: list[CaseCostRead] = [] case_priority: CasePriorityRead case_severity: CaseSeverityRead @@ -352,7 +364,7 @@ class CaseRead(CaseBase): project: ProjectRead related: list[CaseReadMinimal] | None = [] reported_at: datetime | None = None - reporter: ParticipantRead | None + reporter: ParticipantRead | None = None signal_instances: list[SignalInstanceRead] | None = [] storage: StorageRead | None = None tags: list[TagRead] | None = [] @@ -367,15 +379,16 @@ class CaseRead(CaseBase): class CaseUpdate(CaseBase): """Pydantic model for updating case data.""" - assignee: ParticipantUpdate | None + + assignee: ParticipantUpdate | None = None case_costs: list[CaseCostUpdate] = [] - case_priority: CasePriorityBase | None - case_severity: CaseSeverityBase | None - case_type: CaseTypeBase | None + case_priority: CasePriorityBase | None = None + case_severity: CaseSeverityBase | None = None + case_type: CaseTypeBase | None = None closed_at: datetime | None = None duplicates: list[CaseReadBasic] | None = [] related: list[CaseRead] | None = [] - reporter: ParticipantUpdate | None + reporter: ParticipantUpdate | None = None escalated_at: datetime | None = None incidents: list[IncidentReadBasic] | None = [] reported_at: datetime | None = None @@ -408,9 +421,11 @@ def find_exclusive(cls, tags: list[TagRead] | None) -> list[TagRead] | None: class CasePagination(Pagination): """Pydantic model for paginated minimal case results.""" + items: list[CaseReadMinimal] = [] class CaseExpandedPagination(Pagination): """Pydantic model for paginated expanded case results.""" + items: list[CaseRead] = [] diff --git a/src/dispatch/case/priority/models.py b/src/dispatch/case/priority/models.py index 527aa87614fa..d53b8510b6db 100644 --- a/src/dispatch/case/priority/models.py +++ b/src/dispatch/case/priority/models.py @@ -1,4 +1,5 @@ """Models and schemas for the Dispatch case priority system.""" + from sqlalchemy import Column, Integer, String, Boolean from sqlalchemy.sql.schema import UniqueConstraint from sqlalchemy.event import listen @@ -11,6 +12,7 @@ class CasePriority(Base, ProjectMixin): """SQLAlchemy model for a case priority, representing the priority level of a case.""" + __table_args__ = (UniqueConstraint("name", "project_id"),) id = Column(Integer, primary_key=True) name = Column(String) @@ -27,7 +29,9 @@ class CasePriority(Base, ProjectMixin): search_vector = Column(TSVectorType("name", "description")) -default_listener_doc = """Ensure only one default priority per project by listening to the 'default' field.""" +default_listener_doc = ( + """Ensure only one default priority per project by listening to the 'default' field.""" +) listen(CasePriority.default, "set", ensure_unique_default_per_project) @@ -35,31 +39,36 @@ class CasePriority(Base, ProjectMixin): # Pydantic models class CasePriorityBase(DispatchBase): """Base Pydantic model for case priority data.""" + color: str | None = None - default: bool | None - page_assignee: bool | None + default: bool | None = None + page_assignee: bool | None = None description: str | None = None - enabled: bool | None + enabled: bool | None = None name: NameStr - project: ProjectRead | None - view_order: int | None + project: ProjectRead | None = None + view_order: int | None = None class CasePriorityCreate(CasePriorityBase): """Pydantic model for creating a new case priority.""" + pass class CasePriorityUpdate(CasePriorityBase): """Pydantic model for updating a case priority.""" + pass class CasePriorityRead(CasePriorityBase): """Pydantic model for reading case priority data.""" - id: PrimaryKey | None + + id: PrimaryKey | None = None class CasePriorityPagination(Pagination): """Pydantic model for paginated case priority results.""" + items: list[CasePriorityRead] = [] diff --git a/src/dispatch/case/severity/models.py b/src/dispatch/case/severity/models.py index 0c9a1e213d17..91a3ed12a0df 100644 --- a/src/dispatch/case/severity/models.py +++ b/src/dispatch/case/severity/models.py @@ -12,6 +12,7 @@ class CaseSeverity(Base, ProjectMixin): """SQLAlchemy model for a case severity, representing the severity level of a case.""" + __table_args__ = (UniqueConstraint("name", "project_id"),) id = Column(Integer, primary_key=True) name = Column(String) @@ -39,30 +40,35 @@ class CaseSeverity(Base, ProjectMixin): # Pydantic models class CaseSeverityBase(DispatchBase): """Base Pydantic model for case severity data.""" + color: str | None = None - default: bool | None + default: bool | None = None description: str | None = None - enabled: bool | None + enabled: bool | None = None name: NameStr - project: ProjectRead | None - view_order: int | None + project: ProjectRead | None = None + view_order: int | None = None class CaseSeverityCreate(CaseSeverityBase): """Pydantic model for creating a new case severity.""" + pass class CaseSeverityUpdate(CaseSeverityBase): """Pydantic model for updating a case severity.""" + pass class CaseSeverityRead(CaseSeverityBase): """Pydantic model for reading case severity data.""" + id: PrimaryKey class CaseSeverityPagination(Pagination): """Pydantic model for paginated case severity results.""" + items: list[CaseSeverityRead] = [] diff --git a/src/dispatch/case_cost_type/models.py b/src/dispatch/case_cost_type/models.py index 9157403e6db3..59299e8a9342 100644 --- a/src/dispatch/case_cost_type/models.py +++ b/src/dispatch/case_cost_type/models.py @@ -40,8 +40,8 @@ class CaseCostTypeBase(DispatchBase): description: str | None = None category: str | None = None details: dict | None = {} - created_at: datetime | None - editable: bool | None + created_at: datetime | None = None + editable: bool | None = None model_type: str | None = Field(None, nullable=False) diff --git a/src/dispatch/cost_model/models.py b/src/dispatch/cost_model/models.py index ad25807b07e1..69e15f7417f2 100644 --- a/src/dispatch/cost_model/models.py +++ b/src/dispatch/cost_model/models.py @@ -67,6 +67,7 @@ class CostModel(Base, TimeStampMixin, ProjectMixin): # Pydantic Models class CostModelActivityBase(DispatchBase): """Base class for cost model activity resources""" + plugin_event: PluginEventRead response_time_seconds: int | None = 300 enabled: bool | None = Field(True, nullable=True) @@ -81,7 +82,7 @@ class CostModelActivityRead(CostModelActivityBase): class CostModelActivityUpdate(CostModelActivityBase): - id: PrimaryKey | None + id: PrimaryKey | None = None class CostModelBase(DispatchBase): diff --git a/src/dispatch/data/alert/models.py b/src/dispatch/data/alert/models.py index 5f01d8a1c876..db2221b23d77 100644 --- a/src/dispatch/data/alert/models.py +++ b/src/dispatch/data/alert/models.py @@ -30,7 +30,7 @@ class AlertCreate(AlertBase): class AlertUpdate(AlertBase): - id: PrimaryKey | None + id: PrimaryKey | None = None class AlertRead(AlertBase): diff --git a/src/dispatch/data/query/models.py b/src/dispatch/data/query/models.py index 240b9bd887a2..210acc70df60 100644 --- a/src/dispatch/data/query/models.py +++ b/src/dispatch/data/query/models.py @@ -63,7 +63,7 @@ class QueryCreate(QueryBase): class QueryUpdate(QueryBase): - id: PrimaryKey | None + id: PrimaryKey | None = None class QueryRead(QueryBase): diff --git a/src/dispatch/data/source/models.py b/src/dispatch/data/source/models.py index d651a9351a44..1946d28ad906 100644 --- a/src/dispatch/data/source/models.py +++ b/src/dispatch/data/source/models.py @@ -133,13 +133,13 @@ class SourceBase(DispatchBase): incidents: list[IncidentRead | None] = [] queries: list[QueryReadMinimal | None] = [] alerts: list[AlertRead | None] = [] - cost: float | None + cost: float | None = None owner: ServiceRead | None = None - source_type: SourceTypeRead | None - source_environment: SourceEnvironmentRead | None - source_data_format: SourceDataFormatRead | None - source_status: SourceStatusRead | None - source_transport: SourceTransportRead | None + source_type: SourceTypeRead | None = None + source_environment: SourceEnvironmentRead | None = None + source_data_format: SourceDataFormatRead | None = None + source_status: SourceStatusRead | None = None + source_transport: SourceTransportRead | None = None project: ProjectRead @@ -148,7 +148,7 @@ class SourceCreate(SourceBase): class SourceUpdate(SourceBase): - id: PrimaryKey | None + id: PrimaryKey | None = None class SourceRead(SourceBase): diff --git a/src/dispatch/definition/models.py b/src/dispatch/definition/models.py index e3afba53e314..17913f7999f2 100644 --- a/src/dispatch/definition/models.py +++ b/src/dispatch/definition/models.py @@ -42,8 +42,8 @@ class Definition(Base, ProjectMixin): class DefinitionTerm(DispatchBase): - id: PrimaryKey | None - text: str | None + id: PrimaryKey | None = None + text: str | None = None # Pydantic models... diff --git a/src/dispatch/document/models.py b/src/dispatch/document/models.py index b3be6bceaba0..94b650418648 100644 --- a/src/dispatch/document/models.py +++ b/src/dispatch/document/models.py @@ -83,7 +83,7 @@ class DocumentCreate(DocumentBase): class DocumentUpdate(DocumentBase): """Pydantic model for updating a document resource.""" - filters: list[SearchFilterRead] | None + filters: list[SearchFilterRead] | None = None tags: list[TagRead] | None = [] @field_validator("tags") diff --git a/src/dispatch/email_templates/models.py b/src/dispatch/email_templates/models.py index 05fe3a1c232c..acb894091d99 100644 --- a/src/dispatch/email_templates/models.py +++ b/src/dispatch/email_templates/models.py @@ -23,7 +23,7 @@ class EmailTemplatesBase(DispatchBase): welcome_text: str | None = None welcome_body: str | None = None components: str | None = None - enabled: bool | None + enabled: bool | None = None class EmailTemplatesCreate(EmailTemplatesBase): @@ -36,7 +36,7 @@ class EmailTemplatesUpdate(EmailTemplatesBase): class EmailTemplatesRead(EmailTemplatesBase): id: PrimaryKey - project: ProjectRead | None + project: ProjectRead | None = None created_at: datetime | None = None updated_at: datetime | None = None diff --git a/src/dispatch/entity/models.py b/src/dispatch/entity/models.py index 92e474e36248..8e8b7a6739a4 100644 --- a/src/dispatch/entity/models.py +++ b/src/dispatch/entity/models.py @@ -63,13 +63,13 @@ def __hash__(self): class EntityUpdate(EntityBase): - id: PrimaryKey | None - entity_type: EntityTypeUpdate | None + id: PrimaryKey | None = None + entity_type: EntityTypeUpdate | None = None class EntityRead(EntityBase): id: PrimaryKey - entity_type: EntityTypeRead | None + entity_type: EntityTypeRead | None = None project: ProjectRead diff --git a/src/dispatch/entity_type/models.py b/src/dispatch/entity_type/models.py index 8a1636e10696..eb7525426ab9 100644 --- a/src/dispatch/entity_type/models.py +++ b/src/dispatch/entity_type/models.py @@ -48,17 +48,17 @@ class SignalRead(DispatchBase): id: PrimaryKey name: str owner: str - conversation_target: str | None - description: str | None - variant: str | None + conversation_target: str | None = None + description: str | None = None + variant: str | None = None class EntityTypeBase(DispatchBase): - name: NameStr | None + name: NameStr | None = None description: str | None = None jpath: str | None = None scope: EntityScopeEnum | None = Field(EntityScopeEnum.single, nullable=False) - enabled: bool | None + enabled: bool | None = None signals: list[SignalRead | None] = Field([], nullable=True) regular_expression: str | None = None @@ -82,7 +82,7 @@ class EntityTypeReadMinimal(DispatchBase): name: NameStr description: str | None = None scope: EntityScopeEnum - enabled: bool | None + enabled: bool | None = None regular_expression: str | None = None diff --git a/src/dispatch/feedback/incident/models.py b/src/dispatch/feedback/incident/models.py index 865736d2ee63..653907c6df59 100644 --- a/src/dispatch/feedback/incident/models.py +++ b/src/dispatch/feedback/incident/models.py @@ -57,7 +57,7 @@ class FeedbackUpdate(FeedbackBase): class FeedbackRead(FeedbackBase): id: PrimaryKey - project: ProjectRead | None + project: ProjectRead | None = None class FeedbackPagination(Pagination): diff --git a/src/dispatch/feedback/service/models.py b/src/dispatch/feedback/service/models.py index 0da24e10440b..e4ef5d837309 100644 --- a/src/dispatch/feedback/service/models.py +++ b/src/dispatch/feedback/service/models.py @@ -40,14 +40,14 @@ class ServiceFeedback(TimeStampMixin, FeedbackMixin, Base): # Pydantic models class ServiceFeedbackBase(DispatchBase): feedback: str | None = None - hours: float | None - individual: IndividualContactReadMinimal | None + hours: float | None = None + individual: IndividualContactReadMinimal | None = None rating: ServiceFeedbackRating = ServiceFeedbackRating.little_effort - schedule: str | None - shift_end_at: datetime | None - shift_start_at: datetime | None - project: ProjectRead | None - created_at: datetime | None + schedule: str | None = None + shift_end_at: datetime | None = None + shift_start_at: datetime | None = None + project: ProjectRead | None = None + created_at: datetime | None = None details: list[dict | None] = Field([], nullable=True) @@ -61,7 +61,7 @@ class ServiceFeedbackUpdate(ServiceFeedbackBase): class ServiceFeedbackRead(ServiceFeedbackBase): id: PrimaryKey - project: ProjectRead | None + project: ProjectRead | None = None class ServiceFeedbackPagination(Pagination): diff --git a/src/dispatch/feedback/service/reminder/models.py b/src/dispatch/feedback/service/reminder/models.py index 9f14ed7ad8b3..46f3c2c2637d 100644 --- a/src/dispatch/feedback/service/reminder/models.py +++ b/src/dispatch/feedback/service/reminder/models.py @@ -25,12 +25,12 @@ class ServiceFeedbackReminder(TimeStampMixin, Base): # Pydantic models class ServiceFeedbackReminderBase(DispatchBase): - reminder_at: datetime | None - individual: IndividualContactRead | None - project: ProjectRead | None - schedule_id: str | None - schedule_name: str | None - shift_end_at: datetime | None + reminder_at: datetime | None = None + individual: IndividualContactRead | None = None + project: ProjectRead | None = None + schedule_id: str | None = None + schedule_name: str | None = None + shift_end_at: datetime | None = None details: list[dict | None] = Field([], nullable=True) @@ -40,7 +40,7 @@ class ServiceFeedbackReminderCreate(ServiceFeedbackReminderBase): class ServiceFeedbackReminderUpdate(ServiceFeedbackReminderBase): id: PrimaryKey = None - reminder_at: datetime | None + reminder_at: datetime | None = None class ServiceFeedbackReminderRead(ServiceFeedbackReminderBase): diff --git a/src/dispatch/forms/models.py b/src/dispatch/forms/models.py index 024a320c3907..7454b28a3205 100644 --- a/src/dispatch/forms/models.py +++ b/src/dispatch/forms/models.py @@ -36,17 +36,17 @@ class Forms(TimeStampMixin, ProjectMixin, Base): # Pydantic models class FormsBase(DispatchBase): - form_type: FormsTypeRead | None - creator: IndividualContactReadMinimal | None + form_type: FormsTypeRead | None = None + creator: IndividualContactReadMinimal | None = None form_data: str | None = None attorney_form_data: str | None = None status: str | None = None attorney_status: str | None = None - project: ProjectRead | None - incident: IncidentReadBasic | None + project: ProjectRead | None = None + incident: IncidentReadBasic | None = None attorney_questions: str | None = None attorney_analysis: str | None = None - score: int | None + score: int | None = None class FormsCreate(FormsBase): @@ -59,7 +59,7 @@ class FormsUpdate(FormsBase): class FormsRead(FormsBase): id: PrimaryKey - project: ProjectRead | None + project: ProjectRead | None = None created_at: datetime | None = None updated_at: datetime | None = None diff --git a/src/dispatch/forms/type/models.py b/src/dispatch/forms/type/models.py index 2196f62dbd7d..8dd9dba98088 100644 --- a/src/dispatch/forms/type/models.py +++ b/src/dispatch/forms/type/models.py @@ -39,13 +39,13 @@ class FormsType(ProjectMixin, TimeStampMixin, Base): class FormsTypeBase(DispatchBase): name: NameStr description: str | None = None - enabled: bool | None + enabled: bool | None = None form_schema: str | None = None attorney_form_schema: str | None = None scoring_schema: str | None = None - creator: IndividualContactReadMinimal | None - project: ProjectRead | None - service: ServiceRead | None + creator: IndividualContactReadMinimal | None = None + project: ProjectRead | None = None + service: ServiceRead | None = None class FormsTypeCreate(FormsTypeBase): diff --git a/src/dispatch/incident/models.py b/src/dispatch/incident/models.py index 462bce5a6dd9..a98795f8ee78 100644 --- a/src/dispatch/incident/models.py +++ b/src/dispatch/incident/models.py @@ -240,9 +240,9 @@ def participant_observer(self, participants): class ProjectRead(DispatchBase): """Pydantic model for reading a project resource.""" - id: PrimaryKey | None + id: PrimaryKey | None = None name: NameStr - color: str | None + color: str | None = None stable_priority: IncidentPriorityRead | None = None allow_self_join: bool | None = True display_name: str | None = None @@ -252,7 +252,7 @@ class CaseRead(DispatchBase): """Pydantic model for reading a case resource.""" id: PrimaryKey - name: NameStr | None + name: NameStr | None = None class TaskRead(DispatchBase): @@ -260,13 +260,13 @@ class TaskRead(DispatchBase): id: PrimaryKey assignees: list[ParticipantRead | None] = [] - created_at: datetime | None + created_at: datetime | None = None description: str | None = None status: TaskStatus = TaskStatus.open - owner: ParticipantRead | None + owner: ParticipantRead | None = None weblink: AnyHttpUrl | None = None - resolve_by: datetime | None - resolved_at: datetime | None + resolve_by: datetime | None = None + resolved_at: datetime | None = None ticket: TicketRead | None = None @@ -284,9 +284,9 @@ class IncidentBase(DispatchBase): title: str description: str - resolution: str | None - status: IncidentStatus | None - visibility: Visibility | None + resolution: str | None = None + status: IncidentStatus | None = None + visibility: Visibility | None = None @field_validator("title") @classmethod @@ -310,11 +310,11 @@ class IncidentCreate(IncidentBase): commander: ParticipantUpdate | None = None commander_email: str | None = None - incident_priority: IncidentPriorityCreate | None - incident_severity: IncidentSeverityCreate | None - incident_type: IncidentTypeCreate | None - project: ProjectRead | None - reporter: ParticipantUpdate | None + incident_priority: IncidentPriorityCreate | None = None + incident_severity: IncidentSeverityCreate | None = None + incident_type: IncidentTypeCreate | None = None + project: ProjectRead | None = None + reporter: ParticipantUpdate | None = None tags: list[TagRead] | None = [] @@ -322,7 +322,7 @@ class IncidentReadBasic(DispatchBase): """Pydantic model for reading a basic incident resource.""" id: PrimaryKey - name: NameStr | None + name: NameStr | None = None class IncidentReadMinimal(IncidentBase): @@ -330,8 +330,8 @@ class IncidentReadMinimal(IncidentBase): id: PrimaryKey closed_at: datetime | None = None - commander: ParticipantReadMinimal | None - commanders_location: str | None + commander: ParticipantReadMinimal | None = None + commanders_location: str | None = None created_at: datetime | None = None duplicates: list[IncidentReadBasic] | None = [] incident_costs: list[IncidentCostRead] | None = [] @@ -340,26 +340,26 @@ class IncidentReadMinimal(IncidentBase): incident_review_document: DocumentRead | None = None incident_severity: IncidentSeverityReadMinimal incident_type: IncidentTypeReadMinimal - name: NameStr | None - participants_location: str | None - participants_team: str | None + name: NameStr | None = None + participants_location: str | None = None + participants_team: str | None = None project: ProjectRead reported_at: datetime | None = None - reporter: ParticipantReadMinimal | None - reporters_location: str | None + reporter: ParticipantReadMinimal | None = None + reporters_location: str | None = None stable_at: datetime | None = None storage: StorageRead | None = None summary: str | None = None tags: list[TagRead] | None = [] tasks: list[TaskReadMinimal] | None = [] - total_cost: float | None + total_cost: float | None = None class IncidentUpdate(IncidentBase): """Pydantic model for updating an incident resource.""" cases: list[CaseRead] | None = [] - commander: ParticipantUpdate | None + commander: ParticipantUpdate | None = None delay_executive_report_reminder: datetime | None = None delay_tactical_report_reminder: datetime | None = None duplicates: list[IncidentReadBasic] | None = [] @@ -368,7 +368,7 @@ class IncidentUpdate(IncidentBase): incident_severity: IncidentSeverityBase incident_type: IncidentTypeBase reported_at: datetime | None = None - reporter: ParticipantUpdate | None + reporter: ParticipantUpdate | None = None stable_at: datetime | None = None summary: str | None = None tags: list[TagRead] | None = [] @@ -398,8 +398,8 @@ class IncidentRead(IncidentBase): id: PrimaryKey cases: list[CaseRead] | None = [] closed_at: datetime | None = None - commander: ParticipantRead | None - commanders_location: str | None + commander: ParticipantRead | None = None + commanders_location: str | None = None conference: ConferenceRead | None = None conversation: ConversationRead | None = None created_at: datetime | None = None @@ -412,16 +412,16 @@ class IncidentRead(IncidentBase): incident_priority: IncidentPriorityRead incident_severity: IncidentSeverityRead incident_type: IncidentTypeRead - last_executive_report: ReportRead | None - last_tactical_report: ReportRead | None - name: NameStr | None + last_executive_report: ReportRead | None = None + last_tactical_report: ReportRead | None = None + name: NameStr | None = None participants: list[ParticipantRead] | None = [] - participants_location: str | None - participants_team: str | None + participants_location: str | None = None + participants_team: str | None = None project: ProjectRead reported_at: datetime | None = None - reporter: ParticipantRead | None - reporters_location: str | None + reporter: ParticipantRead | None = None + reporters_location: str | None = None stable_at: datetime | None = None storage: StorageRead | None = None summary: str | None = None @@ -429,7 +429,7 @@ class IncidentRead(IncidentBase): tasks: list[TaskRead] | None = [] terms: list[TermRead] | None = [] ticket: TicketRead | None = None - total_cost: float | None + total_cost: float | None = None workflow_instances: list[WorkflowInstanceRead] | None = [] diff --git a/src/dispatch/incident/priority/models.py b/src/dispatch/incident/priority/models.py index ae855b4d3f74..25c715910218 100644 --- a/src/dispatch/incident/priority/models.py +++ b/src/dispatch/incident/priority/models.py @@ -1,4 +1,5 @@ """Models for incident priority resources in the Dispatch application.""" + from pydantic import StrictBool from sqlalchemy import Column, Integer, String, Boolean @@ -12,6 +13,7 @@ class IncidentPriority(Base, ProjectMixin): """SQLAlchemy model for incident priority resources.""" + __allow_unmapped__ = True __table_args__ = (UniqueConstraint("name", "project_id"),) id = Column(Integer, primary_key=True) @@ -39,14 +41,16 @@ class IncidentPriority(Base, ProjectMixin): class ProjectRead(DispatchBase): """Pydantic model for reading a project resource.""" - id: PrimaryKey | None + + id: PrimaryKey | None = None name: NameStr - display_name: str | None + display_name: str | None = None # Pydantic models... class IncidentPriorityBase(DispatchBase): """Base Pydantic model for incident priority resources.""" + name: NameStr description: str | None = None page_commander: StrictBool | None = None @@ -62,21 +66,25 @@ class IncidentPriorityBase(DispatchBase): class IncidentPriorityCreate(IncidentPriorityBase): """Pydantic model for creating an incident priority resource.""" + pass class IncidentPriorityUpdate(IncidentPriorityBase): """Pydantic model for updating an incident priority resource.""" + pass class IncidentPriorityRead(IncidentPriorityBase): """Pydantic model for reading an incident priority resource.""" + id: PrimaryKey class IncidentPriorityReadMinimal(DispatchBase): """Pydantic model for reading a minimal incident priority resource.""" + id: PrimaryKey name: NameStr description: str | None = None @@ -91,4 +99,5 @@ class IncidentPriorityReadMinimal(DispatchBase): class IncidentPriorityPagination(Pagination): """Pydantic model for paginated incident priority results.""" + items: list[IncidentPriorityRead] = [] diff --git a/src/dispatch/incident_role/models.py b/src/dispatch/incident_role/models.py index c0eb3e62fd7e..4e7e10c61c2a 100644 --- a/src/dispatch/incident_role/models.py +++ b/src/dispatch/incident_role/models.py @@ -64,19 +64,19 @@ class IncidentRole(Base, TimeStampMixin, ProjectMixin): # Pydantic models class IncidentRoleBase(DispatchBase): - enabled: bool | None - tags: list[TagRead] | None - order: PositiveInt | None - incident_types: list[IncidentTypeRead] | None - incident_priorities: list[IncidentPriorityRead] | None - service: ServiceRead | None - individual: IndividualContactRead | None - engage_next_oncall: bool | None + enabled: bool | None = None + tags: list[TagRead] | None = None + order: PositiveInt | None = None + incident_types: list[IncidentTypeRead] | None = None + incident_priorities: list[IncidentPriorityRead] | None = None + service: ServiceRead | None = None + individual: IndividualContactRead | None = None + engage_next_oncall: bool | None = None class IncidentRoleCreateUpdate(IncidentRoleBase): id: PrimaryKey | None = None - project: ProjectRead | None + project: ProjectRead | None = None class IncidentRolesCreateUpdate(DispatchBase): diff --git a/src/dispatch/monitor/models.py b/src/dispatch/monitor/models.py index d7d02dca5b53..fbd90d4172a3 100644 --- a/src/dispatch/monitor/models.py +++ b/src/dispatch/monitor/models.py @@ -28,8 +28,8 @@ class Monitor(Base, ResourceMixin, TimeStampMixin): class MonitorBase(ResourceBase): - enabled: bool | None - status: dict | None + enabled: bool | None = None + status: dict | None = None class MonitorCreate(MonitorBase): diff --git a/src/dispatch/notification/models.py b/src/dispatch/notification/models.py index 5d7088028ac2..9f9b5cef923b 100644 --- a/src/dispatch/notification/models.py +++ b/src/dispatch/notification/models.py @@ -63,23 +63,23 @@ class NotificationBase(EvergreenBase): description: str | None = None type: NotificationTypeEnum target: str - enabled: bool | None + enabled: bool | None = None class NotificationCreate(NotificationBase): - filters: list[SearchFilterRead | None] = None + filters: list[SearchFilterRead | None] = [] project: ProjectRead class NotificationUpdate(NotificationBase): - filters: list[SearchFilterUpdate | None] + filters: list[SearchFilterUpdate | None] = [] class NotificationRead(NotificationBase): id: PrimaryKey created_at: datetime | None = None updated_at: datetime | None = None - filters: list[SearchFilterRead | None] + filters: list[SearchFilterRead | None] = [] class NotificationPagination(Pagination): diff --git a/src/dispatch/participant_activity/models.py b/src/dispatch/participant_activity/models.py index 959bc6adf93f..48fa0bd26dad 100644 --- a/src/dispatch/participant_activity/models.py +++ b/src/dispatch/participant_activity/models.py @@ -33,8 +33,8 @@ class ParticipantActivity(Base): # Pydantic Models class ParticipantActivityBase(DispatchBase): plugin_event: PluginEventRead - started_at: datetime | None - ended_at: datetime | None + started_at: datetime | None = None + ended_at: datetime | None = None participant: ParticipantRead incident: IncidentRead | None = None case: CaseRead | None = None diff --git a/src/dispatch/participant_role/models.py b/src/dispatch/participant_role/models.py index 67a523ccce1c..e742e71d0d67 100644 --- a/src/dispatch/participant_role/models.py +++ b/src/dispatch/participant_role/models.py @@ -35,7 +35,7 @@ class ParticipantRoleRead(ParticipantRoleBase): id: PrimaryKey assumed_at: datetime | None = None renounced_at: datetime | None = None - activity: int | None + activity: int | None = None class ParticipantRoleReadMinimal(ParticipantRoleRead): diff --git a/src/dispatch/plugin/models.py b/src/dispatch/plugin/models.py index 599decc4b55b..4ba88d733077 100644 --- a/src/dispatch/plugin/models.py +++ b/src/dispatch/plugin/models.py @@ -191,21 +191,21 @@ class PluginEventPagination(Pagination): class PluginInstanceRead(PluginBase): id: PrimaryKey - enabled: bool | None - configuration: dict | None + enabled: bool | None = None + configuration: dict | None = None configuration_schema: Any plugin: PluginRead - project: ProjectRead | None - broken: bool | None + project: ProjectRead | None = None + broken: bool | None = None class PluginInstanceReadMinimal(PluginBase): id: PrimaryKey - enabled: bool | None + enabled: bool | None = None configuration_schema: Any plugin: PluginRead - project: ProjectRead | None - broken: bool | None + project: ProjectRead | None = None + broken: bool | None = None class PluginInstanceCreate(PluginBase): @@ -217,8 +217,8 @@ class PluginInstanceCreate(PluginBase): class PluginInstanceUpdate(PluginBase): id: PrimaryKey = None - enabled: bool | None - configuration: dict | None + enabled: bool | None = None + configuration: dict | None = None class KeyValue(DispatchBase): diff --git a/src/dispatch/plugins/dispatch_slack/case/interactive.py b/src/dispatch/plugins/dispatch_slack/case/interactive.py index e2c4851e7502..6a865ba0cf92 100644 --- a/src/dispatch/plugins/dispatch_slack/case/interactive.py +++ b/src/dispatch/plugins/dispatch_slack/case/interactive.py @@ -818,7 +818,7 @@ def handle_snooze_preview_event( title = form_data[DefaultBlockIds.title_input] name_taken = signal_service.get_signal_filter_by_name( - db_session=db_session, project_id=context["subject"].project_id, name=title + db_session=db_session, project_id=int(context["subject"].project_id), name=title ) if name_taken: modal = Modal( @@ -837,7 +837,7 @@ def handle_snooze_preview_event( return ack(response_action="update", view=modal) if form_data.get(DefaultBlockIds.entity_select): - entity_ids = [entity["value"] for entity in form_data[DefaultBlockIds.entity_select]] + entity_ids = [int(entity["value"]) for entity in form_data[DefaultBlockIds.entity_select]] preview_signal_instances = entity_service.get_signal_instances_with_entities( db_session=db_session, @@ -929,7 +929,7 @@ def handle_snooze_submission_event( user (DispatchUser): The Dispatch user who submitted the form. """ mfa_plugin = plugin_service.get_active_instance( - db_session=db_session, project_id=context["subject"].project_id, plugin_type="auth-mfa" + db_session=db_session, project_id=int(context["subject"].project_id), plugin_type="auth-mfa" ) mfa_enabled = True if mfa_plugin else False @@ -2558,7 +2558,7 @@ def engagement_button_approve_click( engagement = signal_service.get_signal_engagement( db_session=db_session, - signal_engagement_id=context["subject"].engagement_id, + signal_engagement_id=int(context["subject"].engagement_id), ) mfa_plugin = plugin_service.get_active_instance( @@ -2962,7 +2962,7 @@ def handle_engagement_deny_submission_event( engagement = signal_service.get_signal_engagement( db_session=db_session, - signal_engagement_id=metadata["engagement_id"], + signal_engagement_id=int(metadata["engagement_id"]), ) send_success_modal( client=client, diff --git a/src/dispatch/route/models.py b/src/dispatch/route/models.py index 5ca31b1e7392..cb9eb5cec2ae 100644 --- a/src/dispatch/route/models.py +++ b/src/dispatch/route/models.py @@ -34,7 +34,7 @@ class RecommendationMatchBase(DispatchBase): class RecommendationBase(DispatchBase): - matches: list[RecommendationMatchBase | None] + matches: list[RecommendationMatchBase | None] = [] class RouteBase(DispatchBase): diff --git a/src/dispatch/search_filter/models.py b/src/dispatch/search_filter/models.py index 6fa5bb752c71..5bd0e0864ee5 100644 --- a/src/dispatch/search_filter/models.py +++ b/src/dispatch/search_filter/models.py @@ -44,29 +44,29 @@ class SearchFilter(Base, ProjectMixin, TimeStampMixin): # Pydantic models... class IndividualContactRead(DispatchBase): - id: PrimaryKey | None + id: PrimaryKey | None = None name: str email: str class TeamRead(DispatchBase): - id: PrimaryKey | None + id: PrimaryKey | None = None name: str class ServiceRead(DispatchBase): - id: PrimaryKey | None + id: PrimaryKey | None = None name: str class NotificationRead(DispatchBase): - id: PrimaryKey | None + id: PrimaryKey | None = None name: str class SearchFilterBase(DispatchBase): description: str | None = None - enabled: bool | None + enabled: bool | None = None expression: list[dict] name: NameStr subject: SearchFilterSubject = SearchFilterSubject.incident @@ -84,8 +84,8 @@ class SearchFilterRead(SearchFilterBase): id: PrimaryKey created_at: datetime | None = None updated_at: datetime | None = None - project: ProjectRead | None - creator: UserRead | None + project: ProjectRead | None = None + creator: UserRead | None = None individuals: list[IndividualContactRead | None] = [] notifications: list[NotificationRead | None] = [] services: list[ServiceRead | None] = [] diff --git a/src/dispatch/signal/models.py b/src/dispatch/signal/models.py index b13981fb621f..817707412307 100644 --- a/src/dispatch/signal/models.py +++ b/src/dispatch/signal/models.py @@ -316,28 +316,28 @@ class SignalFilterPagination(Pagination): class SignalBase(DispatchBase): - case_priority: CasePriorityRead | None - case_type: CaseTypeRead | None - conversation_target: str | None + case_priority: CasePriorityRead | None = None + case_type: CaseTypeRead | None = None + conversation_target: str | None = None create_case: bool | None = True created_at: datetime | None = None default: bool | None = False - description: str | None + description: str | None = None enabled: bool | None = False - external_id: str | None - external_url: str | None + external_id: str | None = None + external_url: str | None = None name: str - oncall_service: Service | None + oncall_service: Service | None = None owner: str project: ProjectRead - source: SourceBase | None - variant: str | None - lifecycle: str | None - runbook: str | None + source: SourceBase | None = None + variant: str | None = None + lifecycle: str | None = None + runbook: str | None = None genai_enabled: bool | None = True - genai_model: str | None - genai_system_message: str | None - genai_prompt: str | None + genai_model: str | None = None + genai_system_message: str | None = None + genai_prompt: str | None = None class SignalCreate(SignalBase): @@ -372,21 +372,21 @@ class SignalPagination(Pagination): class AdditionalMetadata(DispatchBase): - name: str | None - value: Any | None - type: str | None - important: bool | None + name: str | None = None + value: Any | None = None + type: str | None = None + important: bool | None = None class SignalStats(DispatchBase): - num_signal_instances_alerted: int | None - num_signal_instances_snoozed: int | None - num_snoozes_active: int | None - num_snoozes_expired: int | None + num_signal_instances_alerted: int | None = None + num_signal_instances_snoozed: int | None = None + num_snoozes_active: int | None = None + num_snoozes_expired: int | None = None class SignalInstanceBase(DispatchBase): - project: ProjectRead | None + project: ProjectRead | None = None case: CaseReadMinimal | None = None canary: bool | None = False entities: list[EntityRead] | None = [] diff --git a/src/dispatch/tag/models.py b/src/dispatch/tag/models.py index 6b8bd8dfcbef..58d0ea240c1f 100644 --- a/src/dispatch/tag/models.py +++ b/src/dispatch/tag/models.py @@ -54,7 +54,7 @@ class TagUpdate(TagBase): class TagRead(TagBase): id: PrimaryKey - tag_type: TagTypeRead | None + tag_type: TagTypeRead | None = None project: ProjectRead diff --git a/src/dispatch/task/models.py b/src/dispatch/task/models.py index 0a5cbf0df38b..867f90a6aab5 100644 --- a/src/dispatch/task/models.py +++ b/src/dispatch/task/models.py @@ -89,37 +89,37 @@ def __declare_last__(cls): # Pydantic models class TaskBase(ResourceBase): assignees: list[ParticipantRead | None] = [] - created_at: datetime | None - creator: ParticipantRead | None + created_at: datetime | None = None + creator: ParticipantRead | None = None description: str | None = None incident: IncidentReadBasic - owner: ParticipantRead | None + owner: ParticipantRead | None = None priority: str | None = None - resolve_by: datetime | None - resolved_at: datetime | None + resolve_by: datetime | None = None + resolved_at: datetime | None = None resource_id: str | None = None source: str | None = None status: TaskStatus = TaskStatus.open - updated_at: datetime | None + updated_at: datetime | None = None class TaskCreate(TaskBase): assignees: list[ParticipantUpdate | None] = [] - creator: ParticipantUpdate | None - owner: ParticipantUpdate | None - resource_type: str | None + creator: ParticipantUpdate | None = None + owner: ParticipantUpdate | None = None + resource_type: str | None = None status: TaskStatus = TaskStatus.open class TaskUpdate(TaskBase): assignees: list[ParticipantUpdate | None] = [] - owner: ParticipantUpdate | None - creator: ParticipantUpdate | None + owner: ParticipantUpdate | None = None + creator: ParticipantUpdate | None = None class TaskRead(TaskBase): id: PrimaryKey - project: ProjectRead | None + project: ProjectRead | None = None ticket: TicketRead | None = None diff --git a/src/dispatch/team/models.py b/src/dispatch/team/models.py index b031593da2f4..ef3f785d7f47 100644 --- a/src/dispatch/team/models.py +++ b/src/dispatch/team/models.py @@ -66,8 +66,8 @@ class TeamContactUpdate(TeamContactBase): class TeamContactRead(TeamContactBase): id: PrimaryKey filters: list[SearchFilterRead | None] = [] - created_at: datetime - updated_at: datetime + created_at: datetime | None = None + updated_at: datetime | None = None class TeamPagination(Pagination):