input AccountAddressInput {
  accountId: ID!
  city: String!
  isActive: Boolean! = true
  isPrimary: Boolean! = false
  name: String!
  notes: String! = ""
  state: String!
  streetAddress: String!
  zipCode: String!
}

"""Physical address information for an account"""
type AccountAddressType implements Node {
  accountId: UUID!
  city: String!

  """The Globally Unique ID of this object"""
  id: ID!
  isActive: Boolean!
  isPrimary: Boolean!
  labors: [LaborType!]!
  name: String!
  notes: String!
  schedules: [ScheduleType!]!
  scopes: [ScopeType!]!
  services: [ServiceType!]!
  state: String!
  streetAddress: String!
  zipCode: String!
}

input AccountAddressUpdateInput {
  city: String = null
  id: ID!
  isActive: Boolean = null
  isPrimary: Boolean = null
  name: String = null
  notes: String = null
  state: String = null
  streetAddress: String = null
  zipCode: String = null
}

"""Contact information for an account"""
input AccountContactFilter {
  AND: AccountContactFilter
  DISTINCT: Boolean
  NOT: AccountContactFilter
  OR: AccountContactFilter
  accountId: UUID
  id: UUID
  isActive: Boolean
  isPrimary: Boolean
}

input AccountContactInput {
  accountId: ID!
  email: String = null
  firstName: String!
  isActive: Boolean! = true
  isPrimary: Boolean! = false
  lastName: String!
  notes: String! = ""
  phone: String = null
}

"""Contact information for an account"""
type AccountContactType implements Node {
  accountId: UUID!
  email: String!
  firstName: String!
  fullName: String!

  """The Globally Unique ID of this object"""
  id: ID!
  isActive: Boolean!
  isPrimary: Boolean!
  lastName: String!
  notes: String!
  phone: String
}

input AccountContactUpdateInput {
  email: String = null
  firstName: String = null
  id: ID!
  isActive: Boolean = null
  isPrimary: Boolean = null
  lastName: String = null
  notes: String = null
  phone: String = null
}

"""Account model belonging to a customer"""
input AccountFilter {
  AND: AccountFilter
  DISTINCT: Boolean
  NOT: AccountFilter
  OR: AccountFilter
  customerId: UUID
  id: UUID
  isActive: Boolean
  name: String
  search: String
}

input AccountInput {
  customerId: ID!
  endDate: Date = null
  name: String!
  startDate: Date!
  status: String!
}

"""Punchlist records for accounts"""
input AccountPunchlistFilter {
  AND: AccountPunchlistFilter
  DISTINCT: Boolean
  NOT: AccountPunchlistFilter
  OR: AccountPunchlistFilter
  accountId: UUID
  id: UUID
}

input AccountPunchlistInput {
  accountId: ID!
  date: Date!
}

"""Punchlist records for accounts"""
type AccountPunchlistType implements Node {
  accountId: UUID!
  date: Date!

  """The Globally Unique ID of this object"""
  id: ID!
}

input AccountPunchlistUpdateInput {
  accountId: ID = null
  date: Date = null
  id: ID!
}

"""Account model belonging to a customer"""
type AccountType implements Node {
  addresses: [AccountAddressType!]!
  contacts: [AccountContactType!]!
  customerId: UUID!
  endDate: Date

  """The Globally Unique ID of this object"""
  id: ID!

  """Check if the account is currently active based on dates and status"""
  isActive: Boolean!
  name: String!

  """Get the primary address for this account"""
  primaryAddress: AccountAddressType
  revenues: [RevenueType!]!
  startDate: Date!

  """Current status of the account"""
  status: StatusChoices!
}

input AccountUpdateInput {
  customerId: ID = null
  endDate: Date = null
  id: ID!
  name: String = null
  startDate: Date = null
  status: String = null
}

input AddParticipantInput {
  conversationId: ID!
  participantId: ID!
}

"""Address choices for a customer"""
enum AddressChoices {
  BILLING
  OFFICE
  OTHER
  SHIPPING
}

type AdminDashboardData {
  invoices: [InvoiceType!]!
  projectScopeTemplates: [ProjectScopeTemplateType!]!
  projects: [ProjectType!]!
  reports: [ReportType!]!
  serviceScopeTemplates: [ScopeTemplateType!]!
  services: [ServiceType!]!
}

input ArchiveConversationInput {
  conversationId: ID!
  isArchived: Boolean!
}

"""Area within a scope (e.g., Kitchen, Restrooms, Lobby)"""
input AreaFilter {
  AND: AreaFilter
  DISTINCT: Boolean
  NOT: AreaFilter
  OR: AreaFilter
  id: UUID
  scopeId: UUID
}

input AreaInput {
  name: String!
  order: Int! = 0
  scopeId: ID!
}

"""Reusable area definition belonging to a ScopeTemplate"""
input AreaTemplateFilter {
  AND: AreaTemplateFilter
  DISTINCT: Boolean
  NOT: AreaTemplateFilter
  OR: AreaTemplateFilter
  id: UUID
  scopeTemplateId: UUID

  """Case-insensitive search on name"""
  search: String = null
}

input AreaTemplateInput {
  name: String!
  order: Int = 0
  scopeTemplateId: ID!
}

"""Reusable area definition belonging to a ScopeTemplate"""
type AreaTemplateType implements Node {
  """The Globally Unique ID of this object"""
  id: ID!
  name: String!
  order: Int!
  scopeTemplateId: UUID!
  taskTemplates: [TaskTemplateType!]!
}

input AreaTemplateUpdateInput {
  id: ID!
  name: String = null
  order: Int = null
}

"""Area within a scope (e.g., Kitchen, Restrooms, Lobby)"""
type AreaType implements Node {
  """The Globally Unique ID of this object"""
  id: ID!
  name: String!
  order: Int!
  scopeId: UUID!
  tasks: [TaskType!]!
}

input AreaUpdateInput {
  id: ID!
  name: String = null
  order: Int = null
  scopeId: ID = null
}

input BoolBaseFilterLookup {
  """Exact match. Filter will be skipped on `null` value"""
  exact: Boolean

  """
  Exact match of items in a given list. Filter will be skipped on `null` value
  """
  inList: [Boolean!]

  """Assignment test. Filter will be skipped on `null` value"""
  isNull: Boolean
}

input CloseServiceSessionInput {
  serviceId: ID!
  taskIds: [ID!]!
}

"""
Conversation thread that groups messages together.
Can be linked to specific entities (Project, Service, Account, etc.) for context.
"""
input ConversationFilter {
  AND: ConversationFilter
  DISTINCT: Boolean
  NOT: ConversationFilter
  OR: ConversationFilter

  """Type of conversation (DIRECT, GROUP, SUPPORT)"""
  conversationType: ConversationTypeChoicesFilterLookup
  createdAt: DatetimeDatetimeFilterLookup
  id: UUIDFilterLookup

  """Whether this conversation is archived (system-wide)"""
  isArchived: BoolBaseFilterLookup

  """Timestamp of most recent message"""
  lastMessageAt: DatetimeDatetimeFilterLookup
}

input ConversationInput {
  conversationType: String!
  entityId: ID = null
  entityType: String = null
  metadata: String = null
  participantIds: [ID!]!
  subject: String!
}

"""
Links users (TeamProfile or CustomerProfile) to conversations.
Tracks per-user read status and preferences.
"""
type ConversationParticipantType implements Node {
  """Conversation this participant belongs to"""
  conversationId: UUID!
  createdAt: DateTime!

  """The Globally Unique ID of this object"""
  id: ID!

  """Whether participant has archived this conversation (user-specific)"""
  isArchived: Boolean!

  """Whether participant has muted notifications for this conversation"""
  isMuted: Boolean!

  """When participant joined the conversation"""
  joinedAt: DateTime!

  """Timestamp when participant last read messages in this conversation"""
  lastReadAt: DateTime
  participant: ParticipantType!

  """Number of unread messages for this participant"""
  unreadCount: Int!
  updatedAt: DateTime!
}

"""
Conversation thread that groups messages together.
Can be linked to specific entities (Project, Service, Account, etc.) for context.
"""
type ConversationType implements Node {
  canDelete: Boolean!

  """Type of conversation (DIRECT, GROUP, SUPPORT)"""
  conversationType: ConversationTypeChoices!
  createdAt: DateTime!
  createdBy: ParticipantType
  entity: EntityType

  """The Globally Unique ID of this object"""
  id: ID!

  """Whether this conversation is archived (system-wide)"""
  isArchived: Boolean!

  """Timestamp of most recent message"""
  lastMessageAt: DateTime
  messageCount: Int!
  messages(limit: Int = 50, offset: Int = 0): [MessageType!]!

  """Additional conversation metadata"""
  metadata: JSON!
  participants: [ConversationParticipantType!]!

  """Conversation subject/title"""
  subject: String!
  unreadCount: Int!
  updatedAt: DateTime!
}

"""Type of conversation"""
enum ConversationTypeChoices {
  DIRECT
  GROUP
  SUPPORT
}

input ConversationTypeChoicesFilterLookup {
  """
  Case-sensitive containment test. Filter will be skipped on `null` value
  """
  contains: ConversationTypeChoices

  """Case-sensitive ends-with. Filter will be skipped on `null` value"""
  endsWith: ConversationTypeChoices

  """Exact match. Filter will be skipped on `null` value"""
  exact: ConversationTypeChoices

  """
  Case-insensitive containment test. Filter will be skipped on `null` value
  """
  iContains: ConversationTypeChoices

  """Case-insensitive ends-with. Filter will be skipped on `null` value"""
  iEndsWith: ConversationTypeChoices

  """Case-insensitive exact match. Filter will be skipped on `null` value"""
  iExact: ConversationTypeChoices

  """
  Case-insensitive regular expression match. Filter will be skipped on `null` value
  """
  iRegex: ConversationTypeChoices

  """Case-insensitive starts-with. Filter will be skipped on `null` value"""
  iStartsWith: ConversationTypeChoices

  """
  Exact match of items in a given list. Filter will be skipped on `null` value
  """
  inList: [ConversationTypeChoices!]

  """Assignment test. Filter will be skipped on `null` value"""
  isNull: Boolean

  """
  Case-sensitive regular expression match. Filter will be skipped on `null` value
  """
  regex: ConversationTypeChoices

  """Case-sensitive starts-with. Filter will be skipped on `null` value"""
  startsWith: ConversationTypeChoices
}

"""A connection to a list of items."""
type ConversationTypeCursorConnection {
  """Contains the nodes in this connection"""
  edges: [ConversationTypeCursorEdge!]!

  """Pagination data for this connection"""
  pageInfo: PageInfo!

  """Total quantity of existing nodes."""
  totalCount: Int!
}

"""An edge in a connection."""
type ConversationTypeCursorEdge {
  """A cursor for use in pagination"""
  cursor: String!

  """The item at the end of the edge"""
  node: ConversationType!
}

input ConversationUpdateInput {
  id: ID!
  isArchived: Boolean = null
  metadata: String = null
  subject: String = null
}

input CreateProjectScopeFromTemplateInput {
  accountAddressId: ID = null
  accountId: ID = null
  description: String = null
  isActive: Boolean = true
  name: String = null
  projectId: ID!
  templateId: ID!
}

input CreateScopeFromTemplateInput {
  accountAddressId: ID = null
  accountId: ID!
  description: String = null
  isActive: Boolean = true
  name: String = null
  templateId: ID!
}

input CustomerAddressInput {
  addressType: String!
  city: String!
  customerId: ID!
  isActive: Boolean! = true
  isPrimary: Boolean! = false
  state: String!
  streetAddress: String!
  zipCode: String!
}

"""Address information for a customer"""
type CustomerAddressType implements Node {
  """Type of address"""
  addressType: AddressChoices!
  city: String!

  """The Globally Unique ID of this object"""
  id: ID!
  isActive: Boolean!
  isPrimary: Boolean!
  state: String!
  streetAddress: String!
  zipCode: String!
}

input CustomerAddressUpdateInput {
  addressType: String = null
  city: String = null
  id: ID!
  isActive: Boolean = null
  isPrimary: Boolean = null
  state: String = null
  streetAddress: String = null
  zipCode: String = null
}

"""Contact information for a customer"""
input CustomerContactFilter {
  AND: CustomerContactFilter
  DISTINCT: Boolean
  NOT: CustomerContactFilter
  OR: CustomerContactFilter
  customerId: UUID
  id: UUID
  isActive: Boolean
  isPrimary: Boolean
}

input CustomerContactInput {
  customerId: ID!
  email: String!
  firstName: String!
  isActive: Boolean! = true
  isPrimary: Boolean! = false
  lastName: String!
  notes: String! = ""
  phone: String!
}

"""Contact information for a customer"""
type CustomerContactType implements Node {
  email: String!
  firstName: String!
  fullName: String!

  """The Globally Unique ID of this object"""
  id: ID!
  isActive: Boolean!
  isPrimary: Boolean!
  lastName: String!
  notes: String!
  phone: String
}

input CustomerContactUpdateInput {
  email: String = null
  firstName: String = null
  id: ID!
  isActive: Boolean = null
  isPrimary: Boolean = null
  lastName: String = null
  notes: String = null
  phone: String = null
}

type CustomerDashboardData {
  invoices: [InvoiceType!]!
  projects: [ProjectType!]!
  services: [ServiceType!]!
}

"""Customer model with contact information"""
input CustomerFilter {
  AND: CustomerFilter
  DISTINCT: Boolean
  NOT: CustomerFilter
  OR: CustomerFilter
  id: UUID

  """Check if the customer is currently active based on dates and status"""
  isActive: Boolean = null
  search: String = null
}

input CustomerInput {
  billingEmail: String!
  billingTerms: String!
  endDate: Date = null
  name: String!
  startDate: Date!
  status: String!
  waveCustomerId: String = null
}

"""External/public-facing customer accounts"""
input CustomerProfileFilter {
  AND: CustomerProfileFilter
  DISTINCT: Boolean
  NOT: CustomerProfileFilter
  OR: CustomerProfileFilter

  """Customers this profile has access to"""
  customers: DjangoModelFilterInput
  id: UUID
}

input CustomerProfileInput {
  customerIds: [ID!] = null
  email: String = null
  firstName: String!
  lastName: String!
  notes: String = ""
  phone: String = null
  status: String! = "PENDING"
  userId: ID = null
}

"""External/public-facing customer accounts"""
type CustomerProfileType implements Node {
  """Customers this profile has access to"""
  customers: [CustomerType!]!
  email: String
  firstName: String!
  fullName: String!

  """The Globally Unique ID of this object"""
  id: ID!
  lastName: String!
  notes: String!

  """Unique identifier from Ory Kratos authentication system"""
  oryKratosId: String
  phone: String

  """Current status of the profile"""
  status: StatusChoices!
}

union CustomerProfileTypeTeamProfileType = CustomerProfileType | TeamProfileType

input CustomerProfileUpdateInput {
  customerIds: [ID!] = null
  email: String = null
  firstName: String = null
  id: ID!
  lastName: String = null
  notes: String = null
  phone: String = null
  status: String = null
  userId: ID = null
}

"""Customer model with contact information"""
type CustomerType implements Node {
  accounts: [AccountType!]!
  addresses: [CustomerAddressType!]!
  billingEmail: String!
  billingTerms: String!
  contacts: [CustomerContactType!]!
  endDate: Date

  """The Globally Unique ID of this object"""
  id: ID!

  """Check if the customer is currently active based on dates and status"""
  isActive: Boolean!
  name: String!
  startDate: Date!

  """Current status of the customer"""
  status: StatusChoices!

  """Wave customer ID"""
  waveCustomerId: String
}

input CustomerUpdateInput {
  billingEmail: String = null
  billingTerms: String = null
  endDate: Date = null
  id: ID!
  name: String = null
  startDate: Date = null
  status: String = null
  waveCustomerId: String = null
}

"""Date (isoformat)"""
scalar Date

input DateDateFilterLookup {
  day: IntComparisonFilterLookup

  """Exact match. Filter will be skipped on `null` value"""
  exact: Date

  """Greater than. Filter will be skipped on `null` value"""
  gt: Date

  """Greater than or equal to. Filter will be skipped on `null` value"""
  gte: Date

  """
  Exact match of items in a given list. Filter will be skipped on `null` value
  """
  inList: [Date!]

  """Assignment test. Filter will be skipped on `null` value"""
  isNull: Boolean
  isoWeekDay: IntComparisonFilterLookup
  isoYear: IntComparisonFilterLookup

  """Less than. Filter will be skipped on `null` value"""
  lt: Date

  """Less than or equal to. Filter will be skipped on `null` value"""
  lte: Date
  month: IntComparisonFilterLookup
  quarter: IntComparisonFilterLookup

  """Inclusive range test (between)"""
  range: DateRangeLookup
  week: IntComparisonFilterLookup
  weekDay: IntComparisonFilterLookup
  year: IntComparisonFilterLookup
}

enum DateOrdering {
  ASC
  DESC
}

input DateRangeLookup {
  end: Date = null
  start: Date = null
}

"""Date with time (isoformat)"""
scalar DateTime

input DatetimeDatetimeFilterLookup {
  date: IntComparisonFilterLookup
  day: IntComparisonFilterLookup

  """Exact match. Filter will be skipped on `null` value"""
  exact: DateTime

  """Greater than. Filter will be skipped on `null` value"""
  gt: DateTime

  """Greater than or equal to. Filter will be skipped on `null` value"""
  gte: DateTime
  hour: IntComparisonFilterLookup

  """
  Exact match of items in a given list. Filter will be skipped on `null` value
  """
  inList: [DateTime!]

  """Assignment test. Filter will be skipped on `null` value"""
  isNull: Boolean
  isoWeekDay: IntComparisonFilterLookup
  isoYear: IntComparisonFilterLookup

  """Less than. Filter will be skipped on `null` value"""
  lt: DateTime

  """Less than or equal to. Filter will be skipped on `null` value"""
  lte: DateTime
  minute: IntComparisonFilterLookup
  month: IntComparisonFilterLookup
  quarter: IntComparisonFilterLookup

  """Inclusive range test (between)"""
  range: DatetimeRangeLookup
  second: IntComparisonFilterLookup
  time: IntComparisonFilterLookup
  week: IntComparisonFilterLookup
  weekDay: IntComparisonFilterLookup
  year: IntComparisonFilterLookup
}

input DatetimeRangeLookup {
  end: DateTime = null
  start: DateTime = null
}

"""Decimal (fixed-point)"""
scalar Decimal

enum DeliveryStatusChoices {
  BOUNCED
  DELIVERED
  FAILED
  PENDING
  QUEUED
  SENDING
  SENT
}

type DjangoFileType {
  name: String!
  path: String!
  size: Int!
  url: String!
}

type DjangoImageType {
  height: Int!
  name: String!
  path: String!
  size: Int!
  url: String!
  width: Int!
}

input DjangoModelFilterInput {
  pk: ID!
}

type DjangoModelType {
  pk: ID!
}

type EntityType {
  account: AccountType
  customer: CustomerType
  entityId: ID!
  entityType: String!
  project: ProjectType
  service: ServiceType
}

"""
Event model to track system events that may trigger notifications.
Provides audit trail and basis for notification system.
"""
type EventType {
  createdAt: DateTime!

  """UUID of the entity that triggered this event"""
  entityId: ID!

  """Type of entity (e.g., 'Project', 'Report', 'Invoice')"""
  entityType: String!

  """Type of event that occurred"""
  eventType: EventTypeChoices!
  id: ID!

  """
  Additional event metadata (e.g., old_status, new_status, changed_fields)
  """
  metadata: JSON!
  triggeredById: ID
  triggeredByType: String
  updatedAt: DateTime!
}

enum EventTypeChoices {
  ACCOUNT_ADDRESS_CREATED
  ACCOUNT_ADDRESS_DELETED
  ACCOUNT_ADDRESS_UPDATED
  ACCOUNT_CONTACT_CREATED
  ACCOUNT_CONTACT_DELETED
  ACCOUNT_CONTACT_UPDATED
  ACCOUNT_CREATED
  ACCOUNT_DELETED
  ACCOUNT_PUNCHLIST_CREATED
  ACCOUNT_PUNCHLIST_DELETED
  ACCOUNT_PUNCHLIST_UPDATED
  ACCOUNT_STATUS_CHANGED
  ACCOUNT_UPDATED
  AREA_CREATED
  AREA_DELETED
  AREA_TEMPLATE_CREATED
  AREA_TEMPLATE_DELETED
  AREA_TEMPLATE_UPDATED
  AREA_UPDATED
  CONVERSATION_ARCHIVED
  CONVERSATION_CREATED
  CONVERSATION_PARTICIPANT_ADDED
  CONVERSATION_PARTICIPANT_REMOVED
  CUSTOMER_ADDRESS_CREATED
  CUSTOMER_ADDRESS_DELETED
  CUSTOMER_ADDRESS_UPDATED
  CUSTOMER_CONTACT_CREATED
  CUSTOMER_CONTACT_DELETED
  CUSTOMER_CONTACT_UPDATED
  CUSTOMER_CREATED
  CUSTOMER_DELETED
  CUSTOMER_PROFILE_ACCESS_GRANTED
  CUSTOMER_PROFILE_ACCESS_REVOKED
  CUSTOMER_PROFILE_CREATED
  CUSTOMER_PROFILE_DELETED
  CUSTOMER_PROFILE_UPDATED
  CUSTOMER_STATUS_CHANGED
  CUSTOMER_UPDATED
  INVOICE_CANCELLED
  INVOICE_GENERATED
  INVOICE_OVERDUE
  INVOICE_PAID
  INVOICE_SENT
  LABOR_RATE_CREATED
  LABOR_RATE_DELETED
  LABOR_RATE_UPDATED
  MESSAGE_DELETED
  MESSAGE_READ
  MESSAGE_RECEIVED
  MESSAGE_SENT
  MONITORING_COMMAND_EXECUTED
  MONITORING_INCOMPLETE_WORK_REMINDER
  MONITORING_NIGHTLY_ASSIGNMENTS
  PROJECT_CANCELLED
  PROJECT_COMPLETED
  PROJECT_CREATED
  PROJECT_DELETED
  PROJECT_DISPATCHED
  PROJECT_PUNCHLIST_CREATED
  PROJECT_PUNCHLIST_DELETED
  PROJECT_PUNCHLIST_UPDATED
  PROJECT_SCOPE_CATEGORY_CREATED
  PROJECT_SCOPE_CATEGORY_DELETED
  PROJECT_SCOPE_CATEGORY_UPDATED
  PROJECT_SCOPE_CREATED
  PROJECT_SCOPE_DELETED
  PROJECT_SCOPE_TASK_CREATED
  PROJECT_SCOPE_TASK_DELETED
  PROJECT_SCOPE_TASK_UPDATED
  PROJECT_SCOPE_TEMPLATE_INSTANTIATED
  PROJECT_SCOPE_UPDATED
  PROJECT_SESSION_CLOSED
  PROJECT_SESSION_OPENED
  PROJECT_SESSION_REVERTED
  PROJECT_STATUS_CHANGED
  PROJECT_TASK_COMPLETED
  PROJECT_TASK_UNCOMPLETED
  PROJECT_UPDATED
  PUNCHLIST_PRIORITY_CHANGED
  PUNCHLIST_STATUS_CHANGED
  REPORT_APPROVED
  REPORT_CREATED
  REPORT_DELETED
  REPORT_SUBMITTED
  REPORT_UPDATED
  REVENUE_RATE_CREATED
  REVENUE_RATE_DELETED
  REVENUE_RATE_UPDATED
  SCHEDULE_CREATED
  SCHEDULE_DELETED
  SCHEDULE_FREQUENCY_CHANGED
  SCHEDULE_UPDATED
  SCOPE_CREATED
  SCOPE_DELETED
  SCOPE_TEMPLATE_CREATED
  SCOPE_TEMPLATE_DELETED
  SCOPE_TEMPLATE_INSTANTIATED
  SCOPE_TEMPLATE_UPDATED
  SCOPE_UPDATED
  SERVICES_BULK_GENERATED
  SERVICE_CANCELLED
  SERVICE_COMPLETED
  SERVICE_CREATED
  SERVICE_DELETED
  SERVICE_DISPATCHED
  SERVICE_SESSION_CLOSED
  SERVICE_SESSION_OPENED
  SERVICE_SESSION_REVERTED
  SERVICE_STATUS_CHANGED
  SERVICE_TASK_COMPLETED
  SERVICE_TASK_UNCOMPLETED
  SERVICE_TEAM_ASSIGNED
  SERVICE_TEAM_UNASSIGNED
  SERVICE_UPDATED
  SESSION_IMAGE_DELETED
  SESSION_IMAGE_UPDATED
  SESSION_IMAGE_UPLOADED
  SESSION_MEDIA_INTERNAL_FLAGGED
  SESSION_NOTE_CREATED
  SESSION_NOTE_DELETED
  SESSION_NOTE_UPDATED
  SESSION_VIDEO_DELETED
  SESSION_VIDEO_UPDATED
  SESSION_VIDEO_UPLOADED
  TASK_COMPLETION_RECORDED
  TASK_CREATED
  TASK_DELETED
  TASK_TEMPLATE_CREATED
  TASK_TEMPLATE_DELETED
  TASK_TEMPLATE_UPDATED
  TASK_UPDATED
  TEAM_PROFILE_CREATED
  TEAM_PROFILE_DELETED
  TEAM_PROFILE_ROLE_CHANGED
  TEAM_PROFILE_UPDATED
}

"""Hungry Howies location records"""
input HungryHowiesLocationFilter {
  AND: HungryHowiesLocationFilter
  DISTINCT: Boolean
  NOT: HungryHowiesLocationFilter
  OR: HungryHowiesLocationFilter
  accountId: UUID
  id: UUID
  ovenType: HungryHowiesOvenChoices
  storeNumber: String
}

input HungryHowiesLocationInput {
  accountId: ID!
  ovenType: String = null
  storeNumber: String!
}

"""
HungryHowiesLocationNote(id, created_at, updated_at, content, author, internal, location)
"""
input HungryHowiesLocationNoteFilter {
  AND: HungryHowiesLocationNoteFilter
  DISTINCT: Boolean
  NOT: HungryHowiesLocationNoteFilter
  OR: HungryHowiesLocationNoteFilter
  authorId: UUID
  contentContains: String = null
  createdAfter: DateTime = null
  createdBefore: DateTime = null
  id: UUID

  """Internal notes are only visible to team members, not customers"""
  internal: Boolean
  locationId: UUID
}

input HungryHowiesLocationNoteInput {
  authorId: ID = null
  content: String!
  internal: Boolean! = true
  locationId: ID!
}

"""
HungryHowiesLocationNote(id, created_at, updated_at, content, author, internal, location)
"""
type HungryHowiesLocationNoteType implements Node {
  authorId: UUID
  content: String!
  createdAt: DateTime!

  """The Globally Unique ID of this object"""
  id: ID!

  """Internal notes are only visible to team members, not customers"""
  internal: Boolean!
  locationId: UUID!
  updatedAt: DateTime!
}

input HungryHowiesLocationNoteUpdateInput {
  authorId: ID = null
  content: String = null
  id: ID!
  internal: Boolean = null
}

"""Hungry Howies location records"""
type HungryHowiesLocationType implements Node {
  account: AccountType!

  """The Globally Unique ID of this object"""
  id: ID!
  notes: [HungryHowiesLocationNoteType!]!
  ovenType: HungryHowiesOvenChoices
  storeNumber: String!
}

input HungryHowiesLocationUpdateInput {
  accountId: ID = null
  id: ID!
  ovenType: String = null
  storeNumber: String = null
}

enum HungryHowiesOvenChoices {
  MIDDLEBY_MARSHALL
  OTHER
  XLT
}

"""Punchlist records for Hungry Howies projects"""
input HungryHowiesPunchlistFilter {
  AND: HungryHowiesPunchlistFilter
  DISTINCT: Boolean
  NOT: HungryHowiesPunchlistFilter
  OR: HungryHowiesPunchlistFilter
  id: UUID
  projectId: UUID
}

input HungryHowiesPunchlistInput {
  backCeiling: Boolean! = false
  backVents: Boolean! = false
  date: Date!
  endClean: Boolean! = false
  endLock: Boolean! = false
  endTrash: Boolean! = false
  equip: Boolean! = false
  equipCut: Boolean! = false
  equipDelivery: Boolean! = false
  equipDisp: Boolean! = false
  equipDough: Boolean! = false
  equipHotbox: Boolean! = false
  equipMake: Boolean! = false
  equipManager: Boolean! = false
  equipOther: Boolean! = false
  equipSinks: Boolean! = false
  equipSub: Boolean! = false
  exportedAt: DateTime = null
  kitchenCeiling: Boolean! = false
  kitchenOven: String! = ""
  kitchenOvenAlerts: Boolean! = false
  kitchenOvenDisassemble: Boolean! = false
  kitchenOvenExterior: Boolean! = false
  kitchenOvenReassemble: Boolean! = false
  kitchenPos: Boolean! = false
  kitchenQt: Boolean! = false
  kitchenVents: Boolean! = false
  kitchenWalls: Boolean! = false
  lobbyCeiling: Boolean! = false
  lobbyCounter: Boolean! = false
  lobbyPos: Boolean! = false
  lobbyVents: Boolean! = false
  notes: String! = ""
  pdfUrl: String = null
  projectId: ID!
  secondDate: DateTime = null
  secondVisit: Boolean! = false
  sheetUrl: String = null
}

"""Punchlist records for Hungry Howies projects"""
type HungryHowiesPunchlistType implements Node {
  backCeiling: Boolean!
  backVents: Boolean!
  date: Date!
  endClean: Boolean!
  endLock: Boolean!
  endTrash: Boolean!
  equip: Boolean!
  equipCut: Boolean!
  equipDelivery: Boolean!
  equipDisp: Boolean!
  equipDough: Boolean!
  equipHotbox: Boolean!
  equipMake: Boolean!
  equipManager: Boolean!
  equipOther: Boolean!
  equipSinks: Boolean!
  equipSub: Boolean!
  exportedAt: DateTime

  """The Globally Unique ID of this object"""
  id: ID!
  kitchenCeiling: Boolean!
  kitchenOven: String!
  kitchenOvenAlerts: Boolean!
  kitchenOvenDisassemble: Boolean!
  kitchenOvenExterior: Boolean!
  kitchenOvenReassemble: Boolean!
  kitchenPos: Boolean!
  kitchenQt: Boolean!
  kitchenVents: Boolean!
  kitchenWalls: Boolean!
  lobbyCeiling: Boolean!
  lobbyCounter: Boolean!
  lobbyPos: Boolean!
  lobbyVents: Boolean!
  notes: String!
  pdfUrl: String
  projectId: UUID!
  secondDate: DateTime
  secondVisit: Boolean!
  sheetUrl: String
}

input HungryHowiesPunchlistUpdateInput {
  backCeiling: Boolean = null
  backVents: Boolean = null
  date: Date = null
  endClean: Boolean = null
  endLock: Boolean = null
  endTrash: Boolean = null
  equip: Boolean = null
  equipCut: Boolean = null
  equipDelivery: Boolean = null
  equipDisp: Boolean = null
  equipDough: Boolean = null
  equipHotbox: Boolean = null
  equipMake: Boolean = null
  equipManager: Boolean = null
  equipOther: Boolean = null
  equipSinks: Boolean = null
  equipSub: Boolean = null
  exportedAt: DateTime = null
  id: ID!
  kitchenCeiling: Boolean = null
  kitchenOven: String = null
  kitchenOvenAlerts: Boolean = null
  kitchenOvenDisassemble: Boolean = null
  kitchenOvenExterior: Boolean = null
  kitchenOvenReassemble: Boolean = null
  kitchenPos: Boolean = null
  kitchenQt: Boolean = null
  kitchenVents: Boolean = null
  kitchenWalls: Boolean = null
  lobbyCeiling: Boolean = null
  lobbyCounter: Boolean = null
  lobbyPos: Boolean = null
  lobbyVents: Boolean = null
  notes: String = null
  pdfUrl: String = null
  projectId: ID = null
  secondDate: DateTime = null
  secondVisit: Boolean = null
  sheetUrl: String = null
}

input IntComparisonFilterLookup {
  """Exact match. Filter will be skipped on `null` value"""
  exact: Int

  """Greater than. Filter will be skipped on `null` value"""
  gt: Int

  """Greater than or equal to. Filter will be skipped on `null` value"""
  gte: Int

  """
  Exact match of items in a given list. Filter will be skipped on `null` value
  """
  inList: [Int!]

  """Assignment test. Filter will be skipped on `null` value"""
  isNull: Boolean

  """Less than. Filter will be skipped on `null` value"""
  lt: Int

  """Less than or equal to. Filter will be skipped on `null` value"""
  lte: Int

  """Inclusive range test (between)"""
  range: IntRangeLookup
}

input IntRangeLookup {
  end: Int = null
  start: Int = null
}

"""Status choices for an invoice"""
enum InvoiceChoices {
  CANCELLED
  DRAFT
  OVERDUE
  PAID
  SENT
}

"""Invoice records"""
input InvoiceFilter {
  AND: InvoiceFilter
  DISTINCT: Boolean
  NOT: InvoiceFilter
  OR: InvoiceFilter
  customerId: UUID
  id: UUID

  """Current status of the invoice"""
  status: InvoiceChoices
}

input InvoiceInput {
  customerId: ID!
  date: Date!
  datePaid: Date = null
  paymentType: String = null
  projectIds: [ID!] = null
  revenueIds: [ID!] = null
  status: String!
  waveInvoiceId: String = null
}

"""Invoice records"""
type InvoiceType implements Node {
  customerId: UUID!
  date: Date!
  datePaid: Date

  """The Globally Unique ID of this object"""
  id: ID!
  paymentType: PaymentChoices
  projects: [ProjectType!]!
  revenues: [RevenueType!]!

  """Current status of the invoice"""
  status: InvoiceChoices!

  """Wave invoice ID"""
  waveInvoiceId: String
}

input InvoiceUpdateInput {
  customerId: ID = null
  date: Date = null
  datePaid: Date = null
  id: ID!
  paymentType: String = null
  projectIds: [ID!] = null
  revenueIds: [ID!] = null
  status: String = null
  waveInvoiceId: String = null
}

"""
The `JSON` scalar type represents JSON values as specified by [ECMA-404](https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf).
"""
scalar JSON

type LaborBreakdown {
  grandTotal: Decimal!
  projects: [LaborBreakdownProject!]!
  projectsTotal: Decimal!
  services: [LaborBreakdownService!]!
  servicesTotal: Decimal!
  teamMemberId: ID!
  teamMemberName: String!
}

type LaborBreakdownProject {
  isTeamMemberAssigned: Boolean!
  laborShare: Decimal!
  projectId: ID!
  projectName: String!
  teamMemberCount: Int!
  totalLaborAmount: Decimal!
}

type LaborBreakdownService {
  isTeamMemberAssigned: Boolean!
  laborShare: Decimal!
  serviceId: ID!
  teamMemberCount: Int!
  totalLaborRate: Decimal!
}

"""Labor records for accounts"""
input LaborFilter {
  AND: LaborFilter
  DISTINCT: Boolean
  NOT: LaborFilter
  OR: LaborFilter
  accountAddressId: UUID
  id: UUID
}

input LaborInput {
  accountAddressId: ID!
  amount: Float!
  endDate: Date = null
  startDate: Date!
}

"""Labor records for accounts"""
type LaborType implements Node {
  accountAddressId: UUID
  amount: Decimal!
  endDate: Date

  """The Globally Unique ID of this object"""
  id: ID!
  startDate: Date!
}

input LaborUpdateInput {
  accountAddressId: ID = null
  amount: Float = null
  endDate: Date = null
  id: ID!
  startDate: Date = null
}

input MarkAsReadInput {
  conversationId: ID!
}

"""Individual message within a conversation."""
input MessageFilter {
  AND: MessageFilter
  DISTINCT: Boolean
  NOT: MessageFilter
  OR: MessageFilter

  """Conversation this message belongs to"""
  conversationId: UUIDFilterLookup
  createdAt: DatetimeDatetimeFilterLookup
  id: UUIDFilterLookup

  """Whether this is an automated system message"""
  isSystemMessage: BoolBaseFilterLookup
}

input MessageInput {
  attachments: String = null
  body: String!
  conversationId: ID!
  metadata: String = null
  replyToId: ID = null
}

"""
Tracks when individual messages are read by specific participants.
Allows for fine-grained read tracking beyond conversation-level.
"""
type MessageReadReceiptType implements Node {
  createdAt: DateTime!

  """The Globally Unique ID of this object"""
  id: ID!

  """Message that was read"""
  messageId: UUID!

  """When the message was read"""
  readAt: DateTime!
  reader: ParticipantType!
  updatedAt: DateTime!
}

"""Individual message within a conversation."""
type MessageType implements Node {
  """Array of attachment metadata (file paths, names, sizes, types)"""
  attachments: JSON!

  """Message content"""
  body: String!
  canDelete: Boolean!

  """Conversation this message belongs to"""
  conversationId: UUID!
  createdAt: DateTime!

  """The Globally Unique ID of this object"""
  id: ID!

  """Whether this is an automated system message"""
  isSystemMessage: Boolean!

  """Additional message metadata (formatting, mentions, etc.)"""
  metadata: JSON!
  readBy: [MessageReadReceiptType!]!
  replyTo: MessageType

  """Message this is replying to (for threading)"""
  replyToId: UUID
  sender: ParticipantType!
  updatedAt: DateTime!
}

"""A connection to a list of items."""
type MessageTypeCursorConnection {
  """Contains the nodes in this connection"""
  edges: [MessageTypeCursorEdge!]!

  """Pagination data for this connection"""
  pageInfo: PageInfo!

  """Total quantity of existing nodes."""
  totalCount: Int!
}

"""An edge in a connection."""
type MessageTypeCursorEdge {
  """A cursor for use in pagination"""
  cursor: String!

  """The item at the end of the edge"""
  node: MessageType!
}

type Mutation {
  """Add a participant to a conversation"""
  addParticipant(input: AddParticipantInput!): ConversationParticipantType!

  """Add a task completion to an active project session"""
  addProjectTaskCompletion(notes: String = null, projectId: ID!, taskId: ID!): ProjectSessionType!

  """Add a task completion to an active service session"""
  addTaskCompletion(notes: String = null, serviceId: ID!, taskId: ID!): ServiceSessionType!

  """Archive or unarchive a conversation"""
  archiveConversation(input: ArchiveConversationInput!): ConversationType!

  """Close the active ProjectSession"""
  closeProjectSession(input: ProjectSessionCloseInput!): ProjectSessionType!

  """Close the active service session and record completed tasks"""
  closeServiceSession(input: CloseServiceSessionInput!): ServiceSessionType!

  """Create a new account"""
  createAccount(input: AccountInput!): AccountType!

  """Create a new account address"""
  createAccountAddress(input: AccountAddressInput!): AccountAddressType!

  """Create a new account contact"""
  createAccountContact(input: AccountContactInput!): AccountContactType!

  """Create a new account punchlist"""
  createAccountPunchlist(input: AccountPunchlistInput!): AccountPunchlistType!

  """Create a new area"""
  createArea(input: AreaInput!): AreaType!

  """Create a new area template"""
  createAreaTemplate(input: AreaTemplateInput!): AreaTemplateType!

  """Create a new conversation"""
  createConversation(input: ConversationInput!): ConversationType!

  """Create a new customer"""
  createCustomer(input: CustomerInput!): CustomerType!

  """Create a new customer address"""
  createCustomerAddress(input: CustomerAddressInput!): CustomerAddressType!

  """Create a new customer contact"""
  createCustomerContact(input: CustomerContactInput!): CustomerContactType!

  """Create a new customer profile"""
  createCustomerProfile(input: CustomerProfileInput!): CustomerProfileType!

  """Create a new hungry howies punchlist"""
  createHhPunchlist(input: HungryHowiesPunchlistInput!): HungryHowiesPunchlistType!

  """Create a new Hungry Howies location"""
  createHungryHowiesLocation(input: HungryHowiesLocationInput!): HungryHowiesLocationType!

  """Create a new Hungry Howies location note"""
  createHungryHowiesLocationNote(input: HungryHowiesLocationNoteInput!): HungryHowiesLocationNoteType!

  """Create a new invoice"""
  createInvoice(input: InvoiceInput!): InvoiceType!

  """Create a new labor rate"""
  createLabor(input: LaborInput!): LaborType!

  """Create a notification rule (Admin only)"""
  createNotificationRule(input: NotificationRuleInput!): NotificationRuleType!

  """Create a new project"""
  createProject(input: ProjectInput!): ProjectType!

  """Create a Project Area Template"""
  createProjectAreaTemplate(input: ProjectAreaTemplateInput!): ProjectAreaTemplateType!

  """Create a new project punchlist"""
  createProjectPunchlist(input: ProjectPunchlistInput!): ProjectPunchlistType!

  """Create a new ProjectScope"""
  createProjectScope(input: ProjectScopeInput!): ProjectScopeType!

  """Create a ProjectScopeCategory"""
  createProjectScopeCategory(input: ProjectScopeCategoryInput!): ProjectScopeCategoryType!

  """
  Instantiate a ProjectScope (with Categories and Tasks) from a ProjectScopeTemplate
  """
  createProjectScopeFromTemplate(input: CreateProjectScopeFromTemplateInput!): ProjectScopeType!

  """Create a ProjectScopeTask"""
  createProjectScopeTask(input: ProjectScopeTaskInput!): ProjectScopeTaskType!

  """Create a new Project Scope Template"""
  createProjectScopeTemplate(input: ProjectScopeTemplateInput!): ProjectScopeTemplateType!

  """
  Create a ProjectScopeTemplate (and nested Categories/Tasks) from a JSON payload
  """
  createProjectScopeTemplateFromJson(payload: JSON!, replace: Boolean! = false): ProjectScopeTemplateType!

  """Create a new project session note"""
  createProjectSessionNote(input: ProjectSessionNoteInput!): ProjectSessionNoteType!

  """Create a Project Task Template"""
  createProjectTaskTemplate(input: ProjectTaskTemplateInput!): ProjectTaskTemplateType!

  """Create a new report"""
  createReport(input: ReportInput!): ReportType!

  """Create a new revenue rate"""
  createRevenue(input: RevenueInput!): RevenueType!

  """Create a new service schedule"""
  createSchedule(input: ScheduleInput!): ScheduleType!

  """Create a new scope"""
  createScope(input: ScopeInput!): ScopeType!

  """Instantiate a Scope (with Areas and Tasks) from a ScopeTemplate"""
  createScopeFromTemplate(input: CreateScopeFromTemplateInput!): ScopeType!

  """Create a new scope template"""
  createScopeTemplate(input: ScopeTemplateInput!): ScopeTemplateType!

  """Create a ScopeTemplate (and nested Areas/Tasks) from a JSON payload"""
  createScopeTemplateFromJson(payload: JSON!, replace: Boolean! = false): ScopeTemplateType!

  """Create a new service visit"""
  createService(input: ServiceInput!): ServiceType!

  """Create a new service session note"""
  createServiceSessionNote(input: ServiceSessionNoteInput!): ServiceSessionNoteType!

  """Create a new task"""
  createTask(input: TaskInput!): TaskType!

  """Create a new task completion"""
  createTaskCompletion(input: TaskCompletionInput!): TaskCompletionType!

  """Create a new task template"""
  createTaskTemplate(input: TaskTemplateInput!): TaskTemplateType!

  """Create a new team profile"""
  createTeamProfile(input: TeamProfileInput!): TeamProfileType!

  """Delete an existing account"""
  deleteAccount(id: ID!): ID!

  """Delete an existing account address"""
  deleteAccountAddress(id: ID!): ID!

  """Delete an existing account contact"""
  deleteAccountContact(id: ID!): ID!

  """Delete an existing account punchlist"""
  deleteAccountPunchlist(id: ID!): ID!

  """Delete an existing area"""
  deleteArea(id: ID!): ID!

  """Delete an existing area template"""
  deleteAreaTemplate(id: ID!): ID!

  """Delete a conversation"""
  deleteConversation(id: ID!): ID!

  """Delete an existing customer"""
  deleteCustomer(id: ID!): ID!

  """Delete an existing customer address"""
  deleteCustomerAddress(id: ID!): ID!

  """Delete an existing customer contact"""
  deleteCustomerContact(id: ID!): ID!

  """Delete an existing customer profile"""
  deleteCustomerProfile(id: ID!): ID!

  """Delete an existing hungry howies punchlist"""
  deleteHhPunchlist(id: ID!): ID!

  """Delete a Hungry Howies location"""
  deleteHungryHowiesLocation(id: ID!): ID!

  """Delete a Hungry Howies location note"""
  deleteHungryHowiesLocationNote(id: ID!): ID!

  """Delete an existing invoice"""
  deleteInvoice(id: ID!): ID!

  """Delete an existing labor rate"""
  deleteLabor(id: ID!): ID!

  """Delete a message"""
  deleteMessage(id: ID!): ID!

  """Delete a notification"""
  deleteNotification(id: ID!): ID!

  """Delete a notification rule (Admin only)"""
  deleteNotificationRule(id: ID!): ID!

  """Delete an existing project"""
  deleteProject(id: ID!): ID!

  """Delete a Project Area Template"""
  deleteProjectAreaTemplate(id: ID!): ID!

  """Delete an existing project punchlist"""
  deleteProjectPunchlist(id: ID!): ID!

  """Delete a ProjectScope"""
  deleteProjectScope(id: ID!): ID!

  """Delete a ProjectScopeCategory"""
  deleteProjectScopeCategory(id: ID!): ID!

  """Delete a ProjectScopeTask"""
  deleteProjectScopeTask(id: ID!): ID!

  """Delete a Project Scope Template"""
  deleteProjectScopeTemplate(id: ID!): ID!

  """Delete a ProjectSession image"""
  deleteProjectSessionImage(id: ID!): ID!

  """Delete a project session note"""
  deleteProjectSessionNote(id: ID!): ID!

  """Delete a ProjectSession video"""
  deleteProjectSessionVideo(id: ID!): ID!

  """Delete a Project Task Template"""
  deleteProjectTaskTemplate(id: ID!): ID!

  """Delete an existing report"""
  deleteReport(id: ID!): ID!

  """Delete an existing revenue rate"""
  deleteRevenue(id: ID!): ID!

  """Delete an existing service schedule"""
  deleteSchedule(id: ID!): ID!

  """Delete an existing scope"""
  deleteScope(id: ID!): ID!

  """Delete an existing scope template"""
  deleteScopeTemplate(id: ID!): ID!

  """Delete an existing service visit"""
  deleteService(id: ID!): ID!

  """Delete a ServiceSession image"""
  deleteServiceSessionImage(id: ID!): ID!

  """Delete a service session note"""
  deleteServiceSessionNote(id: ID!): ID!

  """Delete a ServiceSession video"""
  deleteServiceSessionVideo(id: ID!): ID!

  """Delete an existing task"""
  deleteTask(id: ID!): ID!

  """Delete an existing task completion"""
  deleteTaskCompletion(id: ID!): ID!

  """Delete an existing task template"""
  deleteTaskTemplate(id: ID!): ID!

  """Delete an existing team profile"""
  deleteTeamProfile(id: ID!): ID!

  """Generate service visits for a given month (all-or-nothing)"""
  generateServicesByMonth(input: ServiceGenerationInput!): [ServiceType!]!

  """Mark all notifications as read for current user"""
  markAllNotificationsAsRead: Int!

  """Mark conversation as read"""
  markConversationAsRead(input: MarkAsReadInput!): ConversationType!

  """Mark notification as read"""
  markNotificationAsRead(id: ID!): NotificationType!

  """Mute or unmute a conversation"""
  muteConversation(input: MuteConversationInput!): ConversationType!

  """Start a new ProjectSession for a scheduled project"""
  openProjectSession(input: ProjectSessionStartInput!): ProjectSessionType!

  """Open a service session for a scheduled service"""
  openServiceSession(input: OpenServiceSessionInput!): ServiceSessionType!

  """Remove a participant from a conversation"""
  removeParticipant(input: RemoveParticipantInput!): ID!

  """Remove a task completion from an active project session"""
  removeProjectTaskCompletion(projectId: ID!, taskId: ID!): ProjectSessionType!

  """Remove a task completion from an active service session"""
  removeTaskCompletion(serviceId: ID!, taskId: ID!): ServiceSessionType!

  """
  Revert the active ProjectSession back to scheduled (deletes the active session)
  """
  revertProjectSession(input: ProjectSessionRevertInput!): Boolean!

  """
  Revert an active service session back to scheduled (deletes the active session)
  """
  revertServiceSession(input: RevertServiceSessionInput!): Boolean!

  """Send a message in a conversation"""
  sendMessage(input: MessageInput!): MessageType!

  """Update an existing account"""
  updateAccount(input: AccountUpdateInput!): AccountType!

  """Update an existing account address"""
  updateAccountAddress(input: AccountAddressUpdateInput!): AccountAddressType!

  """Update an existing account contact"""
  updateAccountContact(input: AccountContactUpdateInput!): AccountContactType!

  """Update an existing account punchlist"""
  updateAccountPunchlist(input: AccountPunchlistUpdateInput!): AccountPunchlistType!

  """Update an existing area"""
  updateArea(input: AreaUpdateInput!): AreaType!

  """Update an existing area template"""
  updateAreaTemplate(input: AreaTemplateUpdateInput!): AreaTemplateType!

  """Update a conversation"""
  updateConversation(input: ConversationUpdateInput!): ConversationType!

  """Update an existing customer"""
  updateCustomer(input: CustomerUpdateInput!): CustomerType!

  """Update an existing customer address"""
  updateCustomerAddress(input: CustomerAddressUpdateInput!): CustomerAddressType!

  """Update an existing customer contact"""
  updateCustomerContact(input: CustomerContactUpdateInput!): CustomerContactType!

  """Update an existing customer profile"""
  updateCustomerProfile(input: CustomerProfileUpdateInput!): CustomerProfileType!

  """Update an existing hungry howies punchlist"""
  updateHhPunchlist(input: HungryHowiesPunchlistUpdateInput!): HungryHowiesPunchlistType!

  """Update an existing Hungry Howies location"""
  updateHungryHowiesLocation(input: HungryHowiesLocationUpdateInput!): HungryHowiesLocationType!

  """Update an existing Hungry Howies location note"""
  updateHungryHowiesLocationNote(input: HungryHowiesLocationNoteUpdateInput!): HungryHowiesLocationNoteType!

  """Update an existing invoice"""
  updateInvoice(input: InvoiceUpdateInput!): InvoiceType!

  """Update an existing labor rate"""
  updateLabor(input: LaborUpdateInput!): LaborType!

  """Update a notification rule (Admin only)"""
  updateNotificationRule(input: NotificationRuleUpdateInput!): NotificationRuleType!

  """Update an existing project"""
  updateProject(input: ProjectUpdateInput!): ProjectType!

  """Update a Project Area Template"""
  updateProjectAreaTemplate(input: ProjectAreaTemplateUpdateInput!): ProjectAreaTemplateType!

  """Update an existing project punchlist"""
  updateProjectPunchlist(input: ProjectPunchlistUpdateInput!): ProjectPunchlistType!

  """Update an existing ProjectScope"""
  updateProjectScope(input: ProjectScopeUpdateInput!): ProjectScopeType!

  """Update a ProjectScopeCategory"""
  updateProjectScopeCategory(input: ProjectScopeCategoryUpdateInput!): ProjectScopeCategoryType!

  """Update a ProjectScopeTask"""
  updateProjectScopeTask(input: ProjectScopeTaskUpdateInput!): ProjectScopeTaskType!

  """Update an existing Project Scope Template"""
  updateProjectScopeTemplate(input: ProjectScopeTemplateUpdateInput!): ProjectScopeTemplateType!

  """Update an existing ProjectSession image (e.g., title)"""
  updateProjectSessionImage(input: ProjectSessionImageUpdateInput!): ProjectSessionImageType!

  """Update an existing project session note"""
  updateProjectSessionNote(input: ProjectSessionNoteUpdateInput!): ProjectSessionNoteType!

  """Update an existing ProjectSession video (e.g., title)"""
  updateProjectSessionVideo(input: ProjectSessionVideoUpdateInput!): ProjectSessionVideoType!

  """Update a Project Task Template"""
  updateProjectTaskTemplate(input: ProjectTaskTemplateUpdateInput!): ProjectTaskTemplateType!

  """Update an existing report"""
  updateReport(input: ReportUpdateInput!): ReportType!

  """Update an existing revenue rate"""
  updateRevenue(input: RevenueUpdateInput!): RevenueType!

  """Update an existing service schedule"""
  updateSchedule(input: ScheduleUpdateInput!): ScheduleType!

  """Update an existing scope"""
  updateScope(input: ScopeUpdateInput!): ScopeType!

  """Update an existing scope template"""
  updateScopeTemplate(input: ScopeTemplateUpdateInput!): ScopeTemplateType!

  """Update an existing service visit"""
  updateService(input: ServiceUpdateInput!): ServiceType!

  """Update an existing ServiceSession image (e.g., title)"""
  updateServiceSessionImage(input: ServiceSessionImageUpdateInput!): ServiceSessionImageType!

  """Update an existing service session note"""
  updateServiceSessionNote(input: ServiceSessionNoteUpdateInput!): ServiceSessionNoteType!

  """Update an existing ServiceSession video (e.g., title)"""
  updateServiceSessionVideo(input: ServiceSessionVideoUpdateInput!): ServiceSessionVideoType!

  """Update an existing task"""
  updateTask(input: TaskUpdateInput!): TaskType!

  """Update an existing task completion"""
  updateTaskCompletion(input: TaskCompletionUpdateInput!): TaskCompletionType!

  """Update an existing task template"""
  updateTaskTemplate(input: TaskTemplateUpdateInput!): TaskTemplateType!

  """Update an existing team profile"""
  updateTeamProfile(input: TeamProfileUpdateInput!): TeamProfileType!

  """Upload an image to a ProjectSession"""
  uploadProjectSessionImage(file: Upload!, internal: Boolean! = true, notes: String = null, sessionId: ID!, title: String = null): ProjectSessionImageType!

  """Upload a video to a ProjectSession"""
  uploadProjectSessionVideo(file: Upload!, internal: Boolean! = true, notes: String = null, sessionId: ID!, title: String = null): ProjectSessionVideoType!

  """Upload an image to a ServiceSession"""
  uploadServiceSessionImage(file: Upload!, internal: Boolean! = true, notes: String = null, sessionId: ID!, title: String = null): ServiceSessionImageType!

  """Upload a video to a ServiceSession"""
  uploadServiceSessionVideo(file: Upload!, internal: Boolean! = true, notes: String = null, sessionId: ID!, title: String = null): ServiceSessionVideoType!
}

input MuteConversationInput {
  conversationId: ID!
  isMuted: Boolean!
}

"""An object with a Globally Unique ID"""
interface Node {
  """The Globally Unique ID of this object"""
  id: ID!
}

enum NotificationChannelChoices {
  EMAIL
  IN_APP
  SMS
}

"""Track delivery attempts for a notification via specific channels."""
type NotificationDeliveryType {
  """Number of delivery attempts"""
  attempts: Int!

  """Delivery channel (IN_APP, EMAIL, SMS)"""
  channel: NotificationChannelChoices!
  createdAt: DateTime!

  """Timestamp when delivery was confirmed (if supported by channel)"""
  deliveredAt: DateTime

  """Error message from failed delivery attempts"""
  errorMessage: String!

  """External service ID (e.g., Twilio message SID, email message ID)"""
  externalId: String!
  id: ID!

  """Timestamp of last delivery attempt"""
  lastAttemptAt: DateTime

  """Additional delivery metadata"""
  metadata: JSON!

  """Notification being delivered"""
  notification: NotificationType!

  """Timestamp when successfully sent"""
  sentAt: DateTime

  """Current delivery status"""
  status: DeliveryStatusChoices!
  updatedAt: DateTime!
}

input NotificationRuleInput {
  channels: [NotificationChannelChoices!]!
  conditions: JSON = null
  description: String = ""
  eventTypes: [EventTypeChoices!]!
  isActive: Boolean = true
  name: String!
  targetCustomerProfileIds: [ID!] = null
  targetRoles: [RoleChoices!] = null
  targetTeamProfileIds: [ID!] = null
  templateBody: String = ""
  templateSubject: String = ""
}

"""Admin-defined rules for generating notifications based on events."""
type NotificationRuleType {
  """Delivery channels for notifications (IN_APP, EMAIL, SMS)"""
  channels: [NotificationChannelChoices!]!

  """
  Additional conditions for when this rule applies (e.g., {'status': 'COMPLETED'})
  """
  conditions: JSON!
  createdAt: DateTime!

  """Description of when and how this rule applies"""
  description: String!

  """List of event types that trigger this rule"""
  eventTypes: [EventTypeChoices!]!
  id: ID!

  """Whether this rule is currently active"""
  isActive: Boolean!

  """Descriptive name for this notification rule"""
  name: String!
  targetCustomerProfileIds: [ID!]!

  """
  Roles that should receive notifications (empty = all authenticated users)
  """
  targetRoles: [RoleChoices!]!
  targetTeamProfileIds: [ID!]!

  """Template for notification body (supports variables)"""
  templateBody: String!

  """Template for notification subject (supports variables)"""
  templateSubject: String!
  updatedAt: DateTime!
}

input NotificationRuleUpdateInput {
  channels: [NotificationChannelChoices!] = null
  conditions: JSON = null
  description: String = null
  eventTypes: [EventTypeChoices!] = null
  id: ID!
  isActive: Boolean = null
  name: String = null
  targetCustomerProfileIds: [ID!] = null
  targetRoles: [RoleChoices!] = null
  targetTeamProfileIds: [ID!] = null
  templateBody: String = null
  templateSubject: String = null
}

enum NotificationStatusChoices {
  FAILED
  PENDING
  READ
  SENT
}

"""Individual notification instance sent to a specific recipient."""
type NotificationType {
  """Optional URL for action button (e.g., link to project detail)"""
  actionUrl: String!

  """Notification body content"""
  body: String!
  createdAt: DateTime!

  """Event that triggered this notification"""
  event: EventType!
  id: ID!
  isRead: Boolean!

  """Additional notification metadata"""
  metadata: JSON!

  """Timestamp when notification was marked as read"""
  readAt: DateTime
  recipientId: ID!
  recipientType: String!

  """Rule that generated this notification"""
  rule: NotificationRuleType

  """Current status of the notification"""
  status: NotificationStatusChoices!

  """Notification subject line"""
  subject: String!
  updatedAt: DateTime!
}

input OpenServiceSessionInput {
  serviceId: ID!
}

"""Information to aid in pagination."""
type PageInfo {
  """When paginating forwards, the cursor to continue."""
  endCursor: String

  """When paginating forwards, are there more items?"""
  hasNextPage: Boolean!

  """When paginating backwards, are there more items?"""
  hasPreviousPage: Boolean!

  """When paginating backwards, the cursor to continue."""
  startCursor: String
}

type ParticipantType {
  customerProfile: CustomerProfileType
  teamProfile: TeamProfileType
}

"""Payment choices for a transaction"""
enum PaymentChoices {
  BANK_TRANSFER
  CASH
  CHECK
  CREDIT_CARD
}

"""Reusable category definition belonging to a ProjectScopeTemplate"""
input ProjectAreaTemplateFilter {
  AND: ProjectAreaTemplateFilter
  DISTINCT: Boolean
  NOT: ProjectAreaTemplateFilter
  OR: ProjectAreaTemplateFilter
  id: UUID

  """Case-insensitive search on name"""
  nameSearch: String = null
  order: Int
  scopeTemplateId: UUID
}

input ProjectAreaTemplateInput {
  name: String!
  order: Int! = 0
  scopeTemplateId: ID!
}

"""Reusable category definition belonging to a ProjectScopeTemplate"""
type ProjectAreaTemplateType implements Node {
  """The Globally Unique ID of this object"""
  id: ID!
  name: String!
  order: Int!
  scopeTemplateId: UUID!
  taskTemplates: [ProjectTaskTemplateType!]!
}

"""A connection to a list of items."""
type ProjectAreaTemplateTypeCursorConnection {
  """Contains the nodes in this connection"""
  edges: [ProjectAreaTemplateTypeCursorEdge!]!

  """Pagination data for this connection"""
  pageInfo: PageInfo!

  """Total quantity of existing nodes."""
  totalCount: Int!
}

"""An edge in a connection."""
type ProjectAreaTemplateTypeCursorEdge {
  """A cursor for use in pagination"""
  cursor: String!

  """The item at the end of the edge"""
  node: ProjectAreaTemplateType!
}

input ProjectAreaTemplateUpdateInput {
  id: ID!
  name: String = null
  order: Int = null
}

"""Project records for customers"""
input ProjectFilter {
  AND: ProjectFilter
  DISTINCT: Boolean
  NOT: ProjectFilter
  OR: ProjectFilter

  """
  If set, the project uses this account address; otherwise, fill the address fields below
  """
  accountAddressId: UUIDFilterLookup
  customerId: UUIDFilterLookup
  date: DateDateFilterLookup
  id: UUIDFilterLookup

  """Current status of the project"""
  status: ServiceChoicesFilterLookup
  teamMembers: DjangoModelFilterInput
}

input ProjectInput {
  accountAddressId: ID = null
  amount: Float!
  calendarEventId: String = null
  city: String = null
  customerId: ID!
  date: Date!
  labor: Float!
  name: String!
  notes: String = null
  scopeId: ID = null
  state: String = null
  status: String!
  streetAddress: String = null
  teamMemberIds: [ID!] = null
  waveServiceId: String = null
  zipCode: String = null
}

"""Punchlist records for projects"""
input ProjectPunchlistFilter {
  AND: ProjectPunchlistFilter
  DISTINCT: Boolean
  NOT: ProjectPunchlistFilter
  OR: ProjectPunchlistFilter
  id: UUID
  projectId: UUID
}

input ProjectPunchlistInput {
  date: Date!
  projectId: ID!
}

"""Punchlist records for projects"""
type ProjectPunchlistType implements Node {
  date: Date!

  """The Globally Unique ID of this object"""
  id: ID!
  projectId: UUID!
}

input ProjectPunchlistUpdateInput {
  date: Date = null
  id: ID!
  projectId: ID = null
}

"""Category of work definition for a project"""
input ProjectScopeCategoryFilter {
  AND: ProjectScopeCategoryFilter
  DISTINCT: Boolean
  NOT: ProjectScopeCategoryFilter
  OR: ProjectScopeCategoryFilter
  id: UUID
  order: Int
  scopeId: UUID
}

input ProjectScopeCategoryInput {
  name: String!
  order: Int! = 0
  scopeId: ID!
}

"""Category of work definition for a project"""
type ProjectScopeCategoryType implements Node {
  """The Globally Unique ID of this object"""
  id: ID!
  name: String!
  order: Int!
  projectTasks: [ProjectScopeTaskType!]!
  scopeId: UUID!
}

"""A connection to a list of items."""
type ProjectScopeCategoryTypeCursorConnection {
  """Contains the nodes in this connection"""
  edges: [ProjectScopeCategoryTypeCursorEdge!]!

  """Pagination data for this connection"""
  pageInfo: PageInfo!

  """Total quantity of existing nodes."""
  totalCount: Int!
}

"""An edge in a connection."""
type ProjectScopeCategoryTypeCursorEdge {
  """A cursor for use in pagination"""
  cursor: String!

  """The item at the end of the edge"""
  node: ProjectScopeCategoryType!
}

input ProjectScopeCategoryUpdateInput {
  id: ID!
  name: String = null
  order: Int = null
}

"""Scope of work definition for a project"""
input ProjectScopeFilter {
  AND: ProjectScopeFilter
  DISTINCT: Boolean
  NOT: ProjectScopeFilter
  OR: ProjectScopeFilter
  accountAddressId: UUID
  accountId: UUID
  id: UUID
  isActive: Boolean
  projectId: UUID
}

input ProjectScopeInput {
  accountAddressId: ID = null
  accountId: ID = null
  description: String = null
  isActive: Boolean = true
  name: String!
  projectId: ID!
}

"""Record of a task template being completed during a project"""
input ProjectScopeTaskCompletionFilter {
  AND: ProjectScopeTaskCompletionFilter
  DISTINCT: Boolean
  NOT: ProjectScopeTaskCompletionFilter
  OR: ProjectScopeTaskCompletionFilter
  accountAddressId: UUID
  accountId: UUID
  completedById: UUID
  id: UUID
  projectId: UUID
  taskId: UUID
}

"""Record of a task template being completed during a project"""
type ProjectScopeTaskCompletionType implements Node {
  accountAddressId: UUID
  completedAt: DateTime!
  completedById: UUID!

  """The Globally Unique ID of this object"""
  id: ID!
  notes: String!
  projectId: UUID!
  taskId: UUID!
}

"""Specific task definition for a project"""
input ProjectScopeTaskFilter {
  AND: ProjectScopeTaskFilter
  DISTINCT: Boolean
  NOT: ProjectScopeTaskFilter
  OR: ProjectScopeTaskFilter
  categoryId: UUID
  id: UUID
  order: Int
}

input ProjectScopeTaskInput {
  categoryId: ID!
  checklistDescription: String = ""
  description: String!
  estimatedMinutes: Int = null
  order: Int! = 0
}

"""Specific task definition for a project"""
type ProjectScopeTaskType implements Node {
  categoryId: UUID!
  checklistDescription: String!
  description: String!
  estimatedMinutes: Int

  """The Globally Unique ID of this object"""
  id: ID!
  order: Int!
}

"""A connection to a list of items."""
type ProjectScopeTaskTypeCursorConnection {
  """Contains the nodes in this connection"""
  edges: [ProjectScopeTaskTypeCursorEdge!]!

  """Pagination data for this connection"""
  pageInfo: PageInfo!

  """Total quantity of existing nodes."""
  totalCount: Int!
}

"""An edge in a connection."""
type ProjectScopeTaskTypeCursorEdge {
  """A cursor for use in pagination"""
  cursor: String!

  """The item at the end of the edge"""
  node: ProjectScopeTaskType!
}

input ProjectScopeTaskUpdateInput {
  checklistDescription: String = null
  description: String = null
  estimatedMinutes: Int = null
  id: ID!
  order: Int = null
}

"""
Reusable blueprint for creating a ProjectScope with Categories and Tasks
"""
input ProjectScopeTemplateFilter {
  AND: ProjectScopeTemplateFilter
  DISTINCT: Boolean
  NOT: ProjectScopeTemplateFilter
  OR: ProjectScopeTemplateFilter

  """Case-insensitive search on description"""
  descriptionSearch: String = null
  id: UUID
  isActive: Boolean

  """Case-insensitive search on name"""
  nameSearch: String = null
}

input ProjectScopeTemplateInput {
  description: String = ""
  isActive: Boolean = true
  name: String!
}

"""
Reusable blueprint for creating a ProjectScope with Categories and Tasks
"""
type ProjectScopeTemplateType implements Node {
  categoryTemplates: [ProjectAreaTemplateType!]!
  description: String!

  """The Globally Unique ID of this object"""
  id: ID!
  isActive: Boolean!
  name: String!
}

input ProjectScopeTemplateUpdateInput {
  description: String = null
  id: ID!
  isActive: Boolean = null
  name: String = null
}

"""Scope of work definition for a project"""
type ProjectScopeType implements Node {
  accountAddressId: UUID
  accountId: UUID
  description: String!

  """The Globally Unique ID of this object"""
  id: ID!
  isActive: Boolean!
  name: String!
  projectAreas: [ProjectScopeCategoryType!]!
  projectId: UUID!
}

input ProjectScopeUpdateInput {
  accountAddressId: ID = null
  accountId: ID = null
  description: String = null
  id: ID!
  isActive: Boolean = null
  name: String = null
}

input ProjectSessionCloseInput {
  completedTaskIds: [ID!] = null
  projectId: ID!
}

"""Project session records"""
input ProjectSessionFilter {
  AND: ProjectSessionFilter
  DISTINCT: Boolean
  NOT: ProjectSessionFilter
  OR: ProjectSessionFilter
  accountAddressId: UUIDFilterLookup
  accountId: UUIDFilterLookup
  createdById: UUIDFilterLookup
  customerId: UUIDFilterLookup
  date: DateDateFilterLookup
  end: DatetimeDatetimeFilterLookup
  id: UUIDFilterLookup
  projectId: UUIDFilterLookup
  scopeId: UUIDFilterLookup
  start: DatetimeDatetimeFilterLookup
  teamMemberId: String
}

"""
ProjectSessionImage(id, created_at, updated_at, title, content_type, width, height, uploaded_by_team_profile, notes, internal, project_session, image, thumbnail)
"""
input ProjectSessionImageFilter {
  AND: ProjectSessionImageFilter
  DISTINCT: Boolean
  NOT: ProjectSessionImageFilter
  OR: ProjectSessionImageFilter
  createdAfter: DateTime = null
  createdBefore: DateTime = null
  id: UUID
  projectSessionId: UUID
  titleContains: String = null
  uploadedByTeamProfileId: UUID
}

"""
ProjectSessionImage(id, created_at, updated_at, title, content_type, width, height, uploaded_by_team_profile, notes, internal, project_session, image, thumbnail)
"""
type ProjectSessionImageType implements Node {
  contentType: String!
  createdAt: DateTime!
  height: Int!

  """The Globally Unique ID of this object"""
  id: ID!
  image: DjangoImageType!
  internal: Boolean!
  notes: String!
  projectSessionId: UUID!
  thumbnail: DjangoImageType
  title: String!
  uploadedByTeamProfileId: UUID
  width: Int!
}

input ProjectSessionImageUpdateInput {
  id: ID!
  internal: Boolean = null
  notes: String = null
  title: String = null
}

"""Notes attached to project sessions"""
input ProjectSessionNoteFilter {
  AND: ProjectSessionNoteFilter
  DISTINCT: Boolean
  NOT: ProjectSessionNoteFilter
  OR: ProjectSessionNoteFilter
  authorId: UUID
  contentContains: String = null
  createdAfter: DateTime = null
  createdBefore: DateTime = null
  id: UUID

  """Internal notes are only visible to team members, not customers"""
  internal: Boolean
  sessionId: UUID
}

input ProjectSessionNoteInput {
  authorId: ID = null
  content: String!
  internal: Boolean! = true
  sessionId: ID!
}

"""Notes attached to project sessions"""
type ProjectSessionNoteType implements Node {
  authorId: UUID
  content: String!
  createdAt: DateTime!

  """The Globally Unique ID of this object"""
  id: ID!

  """Internal notes are only visible to team members, not customers"""
  internal: Boolean!
  sessionId: UUID!
  updatedAt: DateTime!
}

input ProjectSessionNoteUpdateInput {
  authorId: ID = null
  content: String = null
  id: ID!
  internal: Boolean = null
}

input ProjectSessionRevertInput {
  projectId: ID!
}

input ProjectSessionStartInput {
  projectId: ID!
}

"""Project session records"""
type ProjectSessionType implements Node {
  accountAddressId: UUID
  accountId: UUID
  closedById: UUID
  completedTasks: [ProjectScopeTaskCompletionType!]!
  createdById: UUID!
  customerId: UUID!
  date: Date!
  durationSeconds: Int!
  end: DateTime

  """The Globally Unique ID of this object"""
  id: ID!

  """A session is active if it has not been closed."""
  isActive: Boolean!
  notes: [ProjectSessionNoteType!]!
  photos: [ProjectSessionImageType!]!
  projectId: UUID!
  scopeId: UUID!
  start: DateTime!
  videos: [ProjectSessionVideoType!]!
}

"""Video attached to a ProjectSession for documentation."""
input ProjectSessionVideoFilter {
  AND: ProjectSessionVideoFilter
  DISTINCT: Boolean
  NOT: ProjectSessionVideoFilter
  OR: ProjectSessionVideoFilter
  createdAfter: DateTime = null
  createdBefore: DateTime = null
  id: UUID
  internal: Boolean
  maxDuration: Int = null
  minDuration: Int = null
  projectSessionId: UUID
  titleContains: String = null
  uploadedByTeamProfileId: UUID
}

"""Video attached to a ProjectSession for documentation."""
type ProjectSessionVideoType implements Node {
  contentType: String!
  createdAt: DateTime!

  """Video duration in seconds"""
  durationSeconds: Int!

  """File size in bytes"""
  fileSizeBytes: Int!
  height: Int!

  """The Globally Unique ID of this object"""
  id: ID!
  internal: Boolean!
  notes: String!
  projectSessionId: UUID!
  thumbnail: DjangoImageType
  title: String!
  uploadedByTeamProfileId: UUID
  video: DjangoFileType!
  width: Int!
}

input ProjectSessionVideoUpdateInput {
  id: ID!
  internal: Boolean = null
  notes: String = null
  title: String = null
}

"""Reusable task definition belonging to a ProjectAreaTemplate"""
input ProjectTaskTemplateFilter {
  AND: ProjectTaskTemplateFilter
  DISTINCT: Boolean
  NOT: ProjectTaskTemplateFilter
  OR: ProjectTaskTemplateFilter
  areaTemplateId: UUID

  """Case-insensitive search on description"""
  descriptionSearch: String = null
  estimatedMinutes: Int
  id: UUID
  order: Int
}

input ProjectTaskTemplateInput {
  areaTemplateId: ID!
  checklistDescription: String = ""
  description: String!
  estimatedMinutes: Int = null
  order: Int! = 0
}

"""Reusable task definition belonging to a ProjectAreaTemplate"""
type ProjectTaskTemplateType implements Node {
  areaTemplateId: UUID!
  checklistDescription: String!
  description: String!
  estimatedMinutes: Int

  """The Globally Unique ID of this object"""
  id: ID!
  order: Int!
}

"""A connection to a list of items."""
type ProjectTaskTemplateTypeCursorConnection {
  """Contains the nodes in this connection"""
  edges: [ProjectTaskTemplateTypeCursorEdge!]!

  """Pagination data for this connection"""
  pageInfo: PageInfo!

  """Total quantity of existing nodes."""
  totalCount: Int!
}

"""An edge in a connection."""
type ProjectTaskTemplateTypeCursorEdge {
  """A cursor for use in pagination"""
  cursor: String!

  """The item at the end of the edge"""
  node: ProjectTaskTemplateType!
}

input ProjectTaskTemplateUpdateInput {
  checklistDescription: String = null
  description: String = null
  estimatedMinutes: Int = null
  id: ID!
  order: Int = null
}

"""Project records for customers"""
type ProjectType implements Node {
  """
  If set, the project uses this account address; otherwise, fill the address fields below
  """
  accountAddressId: UUID
  amount: Decimal!

  """External calendar event ID"""
  calendarEventId: String
  city: String
  customerId: UUID!
  date: Date!

  """The Globally Unique ID of this object"""
  id: ID!
  labor: Decimal!
  name: String!
  notes: String
  scopeId: UUID
  state: String

  """Current status of the project"""
  status: ServiceChoices!
  streetAddress: String
  teamMembers: [DjangoModelType!]!

  """Wave service ID"""
  waveServiceId: String
  zipCode: String
}

"""A connection to a list of items."""
type ProjectTypeCursorConnection {
  """Contains the nodes in this connection"""
  edges: [ProjectTypeCursorEdge!]!

  """Pagination data for this connection"""
  pageInfo: PageInfo!

  """Total quantity of existing nodes."""
  totalCount: Int!
}

"""An edge in a connection."""
type ProjectTypeCursorEdge {
  """A cursor for use in pagination"""
  cursor: String!

  """The item at the end of the edge"""
  node: ProjectType!
}

input ProjectUpdateInput {
  accountAddressId: ID = null
  amount: Float = null
  calendarEventId: String = null
  city: String = null
  customerId: ID = null
  date: Date = null
  id: ID!
  labor: Float = null
  name: String = null
  notes: String = null
  scopeId: ID = null
  state: String = null
  status: String = null
  streetAddress: String = null
  teamMemberIds: [ID!] = null
  waveServiceId: String = null
  zipCode: String = null
}

type Query {
  account(
    """The ID of the object."""
    id: ID!
  ): AccountType
  accountAddress(
    """The ID of the object."""
    id: ID!
  ): AccountAddressType
  accountContact(
    """The ID of the object."""
    id: ID!
  ): AccountContactType
  accountContacts(filters: AccountContactFilter): [AccountContactType!]!
  accountPunchlist(
    """The ID of the object."""
    id: ID!
  ): AccountPunchlistType
  accountPunchlists(filters: AccountPunchlistFilter): [AccountPunchlistType!]!
  accounts(filters: AccountFilter): [AccountType!]!

  """Get the active project session for a given project"""
  activeProjectSession(projectId: UUID!): ProjectSessionType

  """Get the active service session for a given service"""
  activeServiceSession(serviceId: UUID!): ServiceSessionType

  """
  Consolidated dashboard data for admin/team leader users. Returns all services, projects, invoices, reports, and scope templates for the given month in a single optimized query.
  """
  adminDashboard(invoiceStatus: String = null, month: String!): AdminDashboardData!
  area(
    """The ID of the object."""
    id: ID!
  ): AreaType
  areaTemplate(
    """The ID of the object."""
    id: ID!
  ): AreaTemplateType
  areaTemplates(filters: AreaTemplateFilter): [AreaTemplateType!]!
  areas(filters: AreaFilter): [AreaType!]!
  conversation(
    """The ID of the object."""
    id: ID!
  ): ConversationType
  conversations(filters: ConversationFilter): [ConversationType!]!
  customer(
    """The ID of the object."""
    id: ID!
  ): CustomerType
  customerAddress(
    """The ID of the object."""
    id: ID!
  ): CustomerAddressType
  customerContact(
    """The ID of the object."""
    id: ID!
  ): CustomerContactType
  customerContacts(filters: CustomerContactFilter): [CustomerContactType!]!

  """
  Consolidated dashboard data for customer users. Returns services, projects, and invoices for the customer.
  """
  customerDashboard(customerId: ID!): CustomerDashboardData!
  customerProfile(
    """The ID of the object."""
    id: ID!
  ): CustomerProfileType
  customerProfiles(filters: CustomerProfileFilter): [CustomerProfileType!]!
  customers(filters: CustomerFilter): [CustomerType!]!

  """Get event by ID"""
  event(id: ID!): EventType

  """Get all events"""
  events(limit: Int = 50, offset: Int = 0): [EventType!]!

  """
  Return conversations linked to a specific entity (Project, Service, Account, etc.)
  """
  getConversationsByEntity(
    """Returns the items in the list that come after the specified cursor."""
    after: String = null

    """Returns the items in the list that come before the specified cursor."""
    before: String = null
    entityId: ID!
    entityType: String!
    filters: ConversationFilter

    """Returns the first n items from the list."""
    first: Int = null

    """Returns the items in the list that come after the specified cursor."""
    last: Int = null
  ): ConversationTypeCursorConnection!

  """Return messages for a specific conversation"""
  getMessagesByConversation(
    """Returns the items in the list that come after the specified cursor."""
    after: String = null

    """Returns the items in the list that come before the specified cursor."""
    before: String = null
    conversationId: ID!
    filters: MessageFilter

    """Returns the first n items from the list."""
    first: Int = null
    includeSystem: Boolean! = true

    """Returns the items in the list that come after the specified cursor."""
    last: Int = null
  ): MessageTypeCursorConnection!

  """Return conversations for the authenticated user (inbox)"""
  getMyConversations(
    """Returns the items in the list that come after the specified cursor."""
    after: String = null

    """Returns the items in the list that come before the specified cursor."""
    before: String = null
    filters: ConversationFilter

    """Returns the first n items from the list."""
    first: Int = null
    includeArchived: Boolean! = false

    """Returns the items in the list that come after the specified cursor."""
    last: Int = null
  ): ConversationTypeCursorConnection!

  """Return area templates for a given ProjectScopeTemplate"""
  getProjectAreaTemplates(
    """Returns the items in the list that come after the specified cursor."""
    after: String = null

    """Returns the items in the list that come before the specified cursor."""
    before: String = null
    filters: ProjectAreaTemplateFilter

    """Returns the first n items from the list."""
    first: Int = null

    """Returns the items in the list that come after the specified cursor."""
    last: Int = null
    scopeTemplateId: ID!
  ): ProjectAreaTemplateTypeCursorConnection!

  """Return categories for a given ProjectScope"""
  getProjectScopeCategories(
    """Returns the items in the list that come after the specified cursor."""
    after: String = null

    """Returns the items in the list that come before the specified cursor."""
    before: String = null
    filters: ProjectScopeCategoryFilter

    """Returns the first n items from the list."""
    first: Int = null

    """Returns the items in the list that come after the specified cursor."""
    last: Int = null
    scopeId: ID!
  ): ProjectScopeCategoryTypeCursorConnection!

  """Return tasks for a given ProjectScopeCategory"""
  getProjectScopeTasks(
    """Returns the items in the list that come after the specified cursor."""
    after: String = null

    """Returns the items in the list that come before the specified cursor."""
    before: String = null
    categoryId: ID!
    filters: ProjectScopeTaskFilter

    """Returns the first n items from the list."""
    first: Int = null

    """Returns the items in the list that come after the specified cursor."""
    last: Int = null
  ): ProjectScopeTaskTypeCursorConnection!

  """Return task templates for a given ProjectAreaTemplate"""
  getProjectTaskTemplates(
    """Returns the items in the list that come after the specified cursor."""
    after: String = null
    areaTemplateId: ID!

    """Returns the items in the list that come before the specified cursor."""
    before: String = null
    filters: ProjectTaskTemplateFilter

    """Returns the first n items from the list."""
    first: Int = null

    """Returns the items in the list that come after the specified cursor."""
    last: Int = null
  ): ProjectTaskTemplateTypeCursorConnection!

  """Return projects that include the given TeamProfile ID as a team member"""
  getProjectsByTeamMember(
    """Returns the items in the list that come after the specified cursor."""
    after: String = null

    """Returns the items in the list that come before the specified cursor."""
    before: String = null
    filters: ProjectFilter

    """Returns the first n items from the list."""
    first: Int = null

    """Returns the items in the list that come after the specified cursor."""
    last: Int = null
    ordering: DateOrdering = DESC
    teamProfileId: ID!
  ): ProjectTypeCursorConnection!

  """Return services that include the given TeamProfile ID as a team member"""
  getServicesByTeamMember(
    """Returns the items in the list that come after the specified cursor."""
    after: String = null

    """Returns the items in the list that come before the specified cursor."""
    before: String = null
    filters: ServiceFilter

    """Returns the first n items from the list."""
    first: Int = null

    """Returns the items in the list that come after the specified cursor."""
    last: Int = null
    ordering: DateOrdering = DESC
    teamProfileId: ID!
  ): ServiceTypeCursorConnection!
  hhPunchlist(
    """The ID of the object."""
    id: ID!
  ): HungryHowiesPunchlistType
  hhPunchlists(filters: HungryHowiesPunchlistFilter): [HungryHowiesPunchlistType!]!
  hungryHowiesLocation(
    """The ID of the object."""
    id: ID!
  ): HungryHowiesLocationType
  hungryHowiesLocationNote(
    """The ID of the object."""
    id: ID!
  ): HungryHowiesLocationNoteType
  hungryHowiesLocationNotes(filters: HungryHowiesLocationNoteFilter): [HungryHowiesLocationNoteType!]!
  hungryHowiesLocations(filters: HungryHowiesLocationFilter): [HungryHowiesLocationType!]!
  invoice(
    """The ID of the object."""
    id: ID!
  ): InvoiceType
  invoices(filters: InvoiceFilter): [InvoiceType!]!
  labor(
    """The ID of the object."""
    id: ID!
  ): LaborType
  labors(filters: LaborFilter): [LaborType!]!

  """Get the currently authenticated user's profile"""
  me: CustomerProfileTypeTeamProfileType
  message(
    """The ID of the object."""
    id: ID!
  ): MessageType
  messages(filters: MessageFilter): [MessageType!]!

  """Get notifications for current user"""
  myNotifications(limit: Int = 50, offset: Int = 0, unreadOnly: Boolean = false): [NotificationType!]!

  """Get unread notification count for current user"""
  myUnreadNotificationCount: Int!

  """Get notification by ID"""
  notification(id: ID!): NotificationType

  """Get notification delivery status"""
  notificationDeliveries(notificationId: ID!): [NotificationDeliveryType!]!

  """Get notification rule by ID"""
  notificationRule(id: ID!): NotificationRuleType

  """Get all notification rules"""
  notificationRules(isActive: Boolean = null): [NotificationRuleType!]!
  project(
    """The ID of the object."""
    id: ID!
  ): ProjectType
  projectAreaTemplate(
    """The ID of the object."""
    id: ID!
  ): ProjectAreaTemplateType
  projectAreaTemplates(filters: ProjectAreaTemplateFilter): [ProjectAreaTemplateType!]!
  projectPunchlist(
    """The ID of the object."""
    id: ID!
  ): ProjectPunchlistType
  projectPunchlists(filters: ProjectPunchlistFilter): [ProjectPunchlistType!]!
  projectScope(
    """The ID of the object."""
    id: ID!
  ): ProjectScopeType
  projectScopeCategories(filters: ProjectScopeCategoryFilter): [ProjectScopeCategoryType!]!
  projectScopeCategory(
    """The ID of the object."""
    id: ID!
  ): ProjectScopeCategoryType
  projectScopeTask(
    """The ID of the object."""
    id: ID!
  ): ProjectScopeTaskType
  projectScopeTaskCompletion(
    """The ID of the object."""
    id: ID!
  ): ProjectScopeTaskCompletionType
  projectScopeTaskCompletions(filters: ProjectScopeTaskCompletionFilter): [ProjectScopeTaskCompletionType!]!
  projectScopeTasks(filters: ProjectScopeTaskFilter): [ProjectScopeTaskType!]!
  projectScopeTemplate(
    """The ID of the object."""
    id: ID!
  ): ProjectScopeTemplateType
  projectScopeTemplates(filters: ProjectScopeTemplateFilter): [ProjectScopeTemplateType!]!
  projectScopes(filters: ProjectScopeFilter): [ProjectScopeType!]!
  projectSession(
    """The ID of the object."""
    id: ID!
  ): ProjectSessionType
  projectSessionImage(
    """The ID of the object."""
    id: ID!
  ): ProjectSessionImageType
  projectSessionImages(filters: ProjectSessionImageFilter): [ProjectSessionImageType!]!
  projectSessionNote(
    """The ID of the object."""
    id: ID!
  ): ProjectSessionNoteType
  projectSessionNotes(filters: ProjectSessionNoteFilter): [ProjectSessionNoteType!]!
  projectSessionVideo(
    """The ID of the object."""
    id: ID!
  ): ProjectSessionVideoType
  projectSessionVideos(filters: ProjectSessionVideoFilter): [ProjectSessionVideoType!]!
  projectSessions(filters: ProjectSessionFilter): [ProjectSessionType!]!
  projectTaskTemplate(
    """The ID of the object."""
    id: ID!
  ): ProjectTaskTemplateType
  projectTaskTemplates(filters: ProjectTaskTemplateFilter): [ProjectTaskTemplateType!]!
  projects(filters: ProjectFilter): [ProjectType!]!
  report(
    """The ID of the object."""
    id: ID!
  ): ReportType
  reports(filters: ReportFilter): [ReportType!]!
  revenue(
    """The ID of the object."""
    id: ID!
  ): RevenueType
  revenues(filters: RevenueFilter): [RevenueType!]!
  schedule(
    """The ID of the object."""
    id: ID!
  ): ScheduleType
  schedules(filters: ScheduleFilter): [ScheduleType!]!
  scope(
    """The ID of the object."""
    id: ID!
  ): ScopeType
  scopeTemplate(
    """The ID of the object."""
    id: ID!
  ): ScopeTemplateType
  scopeTemplates(filters: ScopeTemplateFilter): [ScopeTemplateType!]!
  scopes(filters: ScopeFilter): [ScopeType!]!
  service(
    """The ID of the object."""
    id: ID!
  ): ServiceType
  serviceSession(
    """The ID of the object."""
    id: ID!
  ): ServiceSessionType
  serviceSessionImage(
    """The ID of the object."""
    id: ID!
  ): ServiceSessionImageType
  serviceSessionImages(filters: ServiceSessionImageFilter): [ServiceSessionImageType!]!
  serviceSessionNote(
    """The ID of the object."""
    id: ID!
  ): ServiceSessionNoteType
  serviceSessionNotes(filters: ServiceSessionNoteFilter): [ServiceSessionNoteType!]!
  serviceSessionVideo(
    """The ID of the object."""
    id: ID!
  ): ServiceSessionVideoType
  serviceSessionVideos(filters: ServiceSessionVideoFilter): [ServiceSessionVideoType!]!
  serviceSessions(filters: ServiceSessionFilter): [ServiceSessionType!]!
  services(filters: ServiceFilter): [ServiceType!]!
  task(
    """The ID of the object."""
    id: ID!
  ): TaskType
  taskCompletion(
    """The ID of the object."""
    id: ID!
  ): TaskCompletionType
  taskCompletions(filters: TaskCompletionFilter): [TaskCompletionType!]!
  taskTemplate(
    """The ID of the object."""
    id: ID!
  ): TaskTemplateType
  taskTemplates(filters: TaskTemplateFilter): [TaskTemplateType!]!
  tasks(filters: TaskFilter): [TaskType!]!

  """
  Consolidated dashboard data for team member users. Returns services and projects assigned to the requesting user.
  """
  teamDashboard(month: String!, teamProfileId: ID!): TeamDashboardData!
  teamProfile(
    """The ID of the object."""
    id: ID!
  ): TeamProfileType
  teamProfiles: [TeamProfileType!]!

  """Get unread message count for the authenticated user"""
  unreadMessageCount: Int!
}

input RemoveParticipantInput {
  conversationId: ID!
  participantId: ID!
}

"""Report records"""
input ReportFilter {
  AND: ReportFilter
  DISTINCT: Boolean
  NOT: ReportFilter
  OR: ReportFilter
  date: Date
  id: UUID
  teamMemberId: UUID
}

input ReportInput {
  date: Date!
  projectIds: [ID!] = null
  serviceIds: [ID!] = null
  teamMemberId: ID!
}

"""Report records"""
type ReportType implements Node {
  date: Date!

  """The Globally Unique ID of this object"""
  id: ID!
  laborBreakdown: LaborBreakdown!
  projects: [ProjectType!]!
  projectsLaborTotal: Decimal!
  services: [ServiceType!]!
  servicesLaborTotal: Decimal!
  teamMemberId: UUID!
  totalLaborValue: Decimal!
}

input ReportUpdateInput {
  date: Date = null
  id: ID!
  projectIds: [ID!] = null
  serviceIds: [ID!] = null
  teamMemberId: ID = null
}

"""Revenue records for accounts"""
input RevenueFilter {
  AND: RevenueFilter
  DISTINCT: Boolean
  NOT: RevenueFilter
  OR: RevenueFilter
  accountId: UUID
  id: UUID
}

input RevenueInput {
  accountId: ID!
  amount: Float!
  endDate: Date = null
  startDate: Date!
  waveServiceId: String = null
}

"""Revenue records for accounts"""
type RevenueType implements Node {
  accountId: UUID!
  amount: Decimal!
  endDate: Date

  """The Globally Unique ID of this object"""
  id: ID!
  startDate: Date!

  """Wave service ID"""
  waveServiceId: String
}

input RevenueUpdateInput {
  accountId: ID = null
  amount: Float = null
  endDate: Date = null
  id: ID!
  startDate: Date = null
  waveServiceId: String = null
}

input RevertServiceSessionInput {
  serviceId: ID!
}

enum RoleChoices {
  ADMIN
  TEAM_LEADER
  TEAM_MEMBER
}

"""Service schedules for accounts."""
input ScheduleFilter {
  AND: ScheduleFilter
  DISTINCT: Boolean
  NOT: ScheduleFilter
  OR: ScheduleFilter
  accountAddressId: UUID
  id: UUID
}

input ScheduleInput {
  accountAddressId: ID!
  endDate: Date = null
  fridayService: Boolean! = false
  mondayService: Boolean! = false
  name: String = null
  saturdayService: Boolean! = false
  scheduleException: String = null
  startDate: Date!
  sundayService: Boolean! = false
  thursdayService: Boolean! = false
  tuesdayService: Boolean! = false
  wednesdayService: Boolean! = false
  weekendService: Boolean! = false
}

"""Service schedules for accounts."""
type ScheduleType implements Node {
  accountAddressId: UUID

  """Optional date when this schedule expires"""
  endDate: Date
  fridayService: Boolean!

  """The Globally Unique ID of this object"""
  id: ID!
  mondayService: Boolean!
  name: String
  saturdayService: Boolean!

  """Notes about any exceptions or special requirements for this schedule"""
  scheduleException: String

  """Date when this schedule becomes active"""
  startDate: Date!
  sundayService: Boolean!
  thursdayService: Boolean!
  tuesdayService: Boolean!
  wednesdayService: Boolean!

  """
  When enabled, represents a single service visit on Friday that can be performed any time between Friday-Sunday and verified by Monday morning. Individual Fri/Sat/Sun service flags must be disabled when this is enabled.
  """
  weekendService: Boolean!
}

input ScheduleUpdateInput {
  accountAddressId: ID
  endDate: Date = null
  fridayService: Boolean = null
  id: ID!
  mondayService: Boolean = null
  name: String = null
  saturdayService: Boolean = null
  scheduleException: String = null
  startDate: Date = null
  sundayService: Boolean = null
  thursdayService: Boolean = null
  tuesdayService: Boolean = null
  wednesdayService: Boolean = null
  weekendService: Boolean = null
}

"""Scope of work definition for an account address"""
input ScopeFilter {
  AND: ScopeFilter
  DISTINCT: Boolean
  NOT: ScopeFilter
  OR: ScopeFilter
  accountAddressId: UUID
  accountId: UUID
  id: UUID
  isActive: Boolean
  search: String = null
}

input ScopeInput {
  accountAddressId: ID = null
  accountId: ID!
  description: String! = ""
  isActive: Boolean! = true
  name: String!
}

"""Reusable blueprint for creating a Scope with Areas and Tasks"""
input ScopeTemplateFilter {
  AND: ScopeTemplateFilter
  DISTINCT: Boolean
  NOT: ScopeTemplateFilter
  OR: ScopeTemplateFilter
  id: UUID
  isActive: Boolean = null

  """Case-insensitive search on name or description"""
  search: String = null
}

input ScopeTemplateInput {
  description: String = null
  isActive: Boolean = true
  name: String!
}

"""Reusable blueprint for creating a Scope with Areas and Tasks"""
type ScopeTemplateType implements Node {
  areaTemplates: [AreaTemplateType!]!
  description: String!

  """The Globally Unique ID of this object"""
  id: ID!
  isActive: Boolean!
  name: String!
}

input ScopeTemplateUpdateInput {
  description: String = null
  id: ID!
  isActive: Boolean = null
  name: String = null
}

"""Scope of work definition for an account address"""
type ScopeType implements Node {
  accountAddressId: UUID
  accountId: UUID!
  areas: [AreaType!]!
  description: String!

  """The Globally Unique ID of this object"""
  id: ID!
  isActive: Boolean!
  name: String!
}

input ScopeUpdateInput {
  accountAddressId: ID = null
  accountId: ID = null
  description: String = null
  id: ID!
  isActive: Boolean = null
  name: String = null
}

"""Status choices for a service workflow"""
enum ServiceChoices {
  CANCELLED
  COMPLETED
  IN_PROGRESS
  SCHEDULED
}

input ServiceChoicesFilterLookup {
  """
  Case-sensitive containment test. Filter will be skipped on `null` value
  """
  contains: ServiceChoices

  """Case-sensitive ends-with. Filter will be skipped on `null` value"""
  endsWith: ServiceChoices

  """Exact match. Filter will be skipped on `null` value"""
  exact: ServiceChoices

  """
  Case-insensitive containment test. Filter will be skipped on `null` value
  """
  iContains: ServiceChoices

  """Case-insensitive ends-with. Filter will be skipped on `null` value"""
  iEndsWith: ServiceChoices

  """Case-insensitive exact match. Filter will be skipped on `null` value"""
  iExact: ServiceChoices

  """
  Case-insensitive regular expression match. Filter will be skipped on `null` value
  """
  iRegex: ServiceChoices

  """Case-insensitive starts-with. Filter will be skipped on `null` value"""
  iStartsWith: ServiceChoices

  """
  Exact match of items in a given list. Filter will be skipped on `null` value
  """
  inList: [ServiceChoices!]

  """Assignment test. Filter will be skipped on `null` value"""
  isNull: Boolean

  """
  Case-sensitive regular expression match. Filter will be skipped on `null` value
  """
  regex: ServiceChoices

  """Case-sensitive starts-with. Filter will be skipped on `null` value"""
  startsWith: ServiceChoices
}

"""Service records for accounts"""
input ServiceFilter {
  AND: ServiceFilter
  DISTINCT: Boolean
  NOT: ServiceFilter
  OR: ServiceFilter
  accountAddressId: UUIDFilterLookup
  accountId: UUIDFilterLookup
  date: DateDateFilterLookup
  id: UUIDFilterLookup

  """Current status of the service"""
  status: ServiceChoicesFilterLookup
  teamMembers: DjangoModelFilterInput
}

input ServiceGenerationInput {
  accountAddressId: ID!
  month: Int!
  scheduleId: ID!
  year: Int!
}

input ServiceInput {
  accountAddressId: ID!
  accountId: ID = null
  calendarEventId: String = null
  date: Date!
  notes: String = null
  status: String!
  teamMemberIds: [ID!] = null
}

"""Service session records"""
input ServiceSessionFilter {
  AND: ServiceSessionFilter
  DISTINCT: Boolean
  NOT: ServiceSessionFilter
  OR: ServiceSessionFilter
  accountAddressId: UUIDFilterLookup
  createdById: UUIDFilterLookup
  end: DatetimeDatetimeFilterLookup
  id: UUIDFilterLookup

  """A session is active if it has not been closed."""
  isActive: Boolean = null
  serviceId: UUIDFilterLookup
  start: DatetimeDatetimeFilterLookup
  teamMemberId: String
}

"""
ServiceSessionImage(id, created_at, updated_at, title, content_type, width, height, uploaded_by_team_profile, notes, internal, service_session, image, thumbnail)
"""
input ServiceSessionImageFilter {
  AND: ServiceSessionImageFilter
  DISTINCT: Boolean
  NOT: ServiceSessionImageFilter
  OR: ServiceSessionImageFilter
  createdAfter: DateTime = null
  createdBefore: DateTime = null
  id: UUID
  serviceSessionId: UUID
  titleContains: String = null
  uploadedByTeamProfileId: UUID
}

"""
ServiceSessionImage(id, created_at, updated_at, title, content_type, width, height, uploaded_by_team_profile, notes, internal, service_session, image, thumbnail)
"""
type ServiceSessionImageType implements Node {
  contentType: String!
  createdAt: DateTime!
  height: Int!

  """The Globally Unique ID of this object"""
  id: ID!
  image: DjangoImageType!
  internal: Boolean!
  notes: String!
  serviceSessionId: UUID!
  thumbnail: DjangoImageType
  title: String!
  uploadedByTeamProfileId: UUID
  width: Int!
}

input ServiceSessionImageUpdateInput {
  id: ID!
  internal: Boolean = null
  notes: String = null
  title: String = null
}

"""Notes attached to service sessions"""
input ServiceSessionNoteFilter {
  AND: ServiceSessionNoteFilter
  DISTINCT: Boolean
  NOT: ServiceSessionNoteFilter
  OR: ServiceSessionNoteFilter
  authorId: UUID
  contentContains: String = null
  createdAfter: DateTime = null
  createdBefore: DateTime = null
  id: UUID

  """Internal notes are only visible to team members, not customers"""
  internal: Boolean
  sessionId: UUID
}

input ServiceSessionNoteInput {
  authorId: ID = null
  content: String!
  internal: Boolean! = true
  sessionId: ID!
}

"""Notes attached to service sessions"""
type ServiceSessionNoteType implements Node {
  authorId: UUID
  content: String!
  createdAt: DateTime!

  """The Globally Unique ID of this object"""
  id: ID!

  """Internal notes are only visible to team members, not customers"""
  internal: Boolean!
  sessionId: UUID!
  updatedAt: DateTime!
}

input ServiceSessionNoteUpdateInput {
  authorId: ID = null
  content: String = null
  id: ID!
  internal: Boolean = null
}

"""Service session records"""
type ServiceSessionType implements Node {
  accountAddressId: UUID!
  accountId: UUID!
  completedTasks: [TaskCompletionType!]!
  customerId: UUID!
  durationSeconds: Int!
  end: DateTime

  """The Globally Unique ID of this object"""
  id: ID!

  """A session is active if it has not been closed."""
  isActive: Boolean!
  notes: [ServiceSessionNoteType!]!
  photos: [ServiceSessionImageType!]!
  scopeId: UUID!
  serviceId: UUID!
  start: DateTime!
  videos: [ServiceSessionVideoType!]!
}

"""Video attached to a ServiceSession for documentation."""
input ServiceSessionVideoFilter {
  AND: ServiceSessionVideoFilter
  DISTINCT: Boolean
  NOT: ServiceSessionVideoFilter
  OR: ServiceSessionVideoFilter
  createdAfter: DateTime = null
  createdBefore: DateTime = null
  id: UUID
  internal: Boolean
  maxDuration: Int = null
  minDuration: Int = null
  serviceSessionId: UUID
  titleContains: String = null
  uploadedByTeamProfileId: UUID
}

"""Video attached to a ServiceSession for documentation."""
type ServiceSessionVideoType implements Node {
  contentType: String!
  createdAt: DateTime!

  """Video duration in seconds"""
  durationSeconds: Int!

  """File size in bytes"""
  fileSizeBytes: Int!
  height: Int!

  """The Globally Unique ID of this object"""
  id: ID!
  internal: Boolean!
  notes: String!
  serviceSessionId: UUID!
  thumbnail: DjangoImageType
  title: String!
  uploadedByTeamProfileId: UUID
  video: DjangoFileType!
  width: Int!
}

input ServiceSessionVideoUpdateInput {
  id: ID!
  internal: Boolean = null
  notes: String = null
  title: String = null
}

"""Service records for accounts"""
type ServiceType implements Node {
  accountAddressId: UUID
  accountId: UUID

  """External calendar event ID"""
  calendarEventId: String
  date: Date!

  """The Globally Unique ID of this object"""
  id: ID!
  notes: String

  """Current status of the service"""
  status: ServiceChoices!
  teamMembers: [DjangoModelType!]!
}

"""A connection to a list of items."""
type ServiceTypeCursorConnection {
  """Contains the nodes in this connection"""
  edges: [ServiceTypeCursorEdge!]!

  """Pagination data for this connection"""
  pageInfo: PageInfo!

  """Total quantity of existing nodes."""
  totalCount: Int!
}

"""An edge in a connection."""
type ServiceTypeCursorEdge {
  """A cursor for use in pagination"""
  cursor: String!

  """The item at the end of the edge"""
  node: ServiceType!
}

input ServiceUpdateInput {
  accountAddressId: ID = null
  accountId: ID = null
  calendarEventId: String = null
  date: Date = null
  id: ID!
  notes: String = null
  status: String = null
  teamMemberIds: [ID!] = null
}

"""Status choices for a Customer, Account, or a future model"""
enum StatusChoices {
  ACTIVE
  INACTIVE
  PENDING
}

type Subscription {
  """Subscribe to account address creation events"""
  accountAddressCreated: AccountAddressType!

  """Subscribe to account address deletion events"""
  accountAddressDeleted: ID!

  """Subscribe to account address updates"""
  accountAddressUpdated: AccountAddressType!

  """Subscribe to account contact creation events"""
  accountContactCreated: AccountContactType!

  """Subscribe to account contact deletion events"""
  accountContactDeleted: ID!

  """Subscribe to account contact updates"""
  accountContactUpdated: AccountContactType!

  """Subscribe to account creation events"""
  accountCreated: AccountType!

  """Subscribe to account deletion events"""
  accountDeleted: ID!

  """Subscribe to account punchlist creation events"""
  accountPunchlistCreated: AccountPunchlistType!

  """Subscribe to account punchlist deletion events"""
  accountPunchlistDeleted: ID!

  """Subscribe to account punchlist updates"""
  accountPunchlistUpdated: AccountPunchlistType!

  """Subscribe to account updates"""
  accountUpdated: AccountType!

  """Subscribe to area creation events"""
  areaCreated: AreaType!

  """Subscribe to area deletion events"""
  areaDeleted: ID!

  """Subscribe to area template creation events"""
  areaTemplateCreated: AreaTemplateType!

  """Subscribe to area template deletion events"""
  areaTemplateDeleted: ID!

  """Subscribe to area template updates"""
  areaTemplateUpdated: AreaTemplateType!

  """Subscribe to area updates"""
  areaUpdated: AreaType!

  """Subscribe to new conversations"""
  conversationCreated: ConversationType!

  """Subscribe to conversation deletion events"""
  conversationDeleted: ID!

  """Subscribe to conversation read events"""
  conversationRead(conversationId: ID!): ConversationType!

  """Subscribe to conversation updates"""
  conversationUpdated: ConversationType!

  """Subscribe to customer address creation events"""
  customerAddressCreated: CustomerAddressType!

  """Subscribe to customer address deletion events"""
  customerAddressDeleted: ID!

  """Subscribe to customer address updates"""
  customerAddressUpdated: CustomerAddressType!

  """Subscribe to customer contact creation events"""
  customerContactCreated: CustomerContactType!

  """Subscribe to customer contact deletion events"""
  customerContactDeleted: ID!

  """Subscribe to customer contact updates"""
  customerContactUpdated: CustomerContactType!

  """Subscribe to customer creation events"""
  customerCreated: CustomerType!

  """Subscribe to customer deletion events"""
  customerDeleted: ID!

  """Subscribe to customer profile creation events"""
  customerProfileCreated: CustomerProfileType!

  """Subscribe to customer profile deletion events"""
  customerProfileDeleted: ID!

  """Subscribe to customer profile updates"""
  customerProfileUpdated: CustomerProfileType!

  """Subscribe to customer updates"""
  customerUpdated: CustomerType!

  """Subscribe to hungry howies punchlist creation events"""
  hhPunchlistCreated: HungryHowiesPunchlistType!

  """Subscribe to hungry howies punchlist deletion events"""
  hhPunchlistDeleted: ID!

  """Subscribe to hungry howies punchlist updates"""
  hhPunchlistUpdated: HungryHowiesPunchlistType!

  """Subscribe to invoice creation events"""
  invoiceCreated: InvoiceType!

  """Subscribe to invoice deletion events"""
  invoiceDeleted: ID!

  """Subscribe to invoice updates"""
  invoiceUpdated: InvoiceType!

  """Subscribe to labor creation events"""
  laborCreated: LaborType!

  """Subscribe to labor deletion events"""
  laborDeleted: ID!

  """Subscribe to labor updates"""
  laborUpdated: LaborType!

  """Subscribe to message deletion events"""
  messageDeleted(conversationId: ID!): ID!

  """Subscribe to new messages across all conversations"""
  messageReceived: MessageType!

  """Subscribe to new messages in a specific conversation"""
  messageSent(conversationId: ID!): MessageType!

  """Subscribe to participant changes"""
  participantAdded(conversationId: ID!): ConversationType!

  """Subscribe to project area template creation events"""
  projectAreaTemplateCreated: ProjectAreaTemplateType!

  """Subscribe to project area template deletion events"""
  projectAreaTemplateDeleted: ID!

  """Subscribe to project area template updates"""
  projectAreaTemplateUpdated: ProjectAreaTemplateType!

  """Subscribe to project creation events"""
  projectCreated: ProjectType!

  """Subscribe to project deletion events"""
  projectDeleted: ID!

  """Subscribe to project punchlist creation events"""
  projectPunchlistCreated: ProjectPunchlistType!

  """Subscribe to project punchlist deletion events"""
  projectPunchlistDeleted: ID!

  """Subscribe to project punchlist updates"""
  projectPunchlistUpdated: ProjectPunchlistType!

  """Subscribe to project scope category creation events"""
  projectScopeCategoryCreated: ProjectScopeCategoryType!

  """Subscribe to project scope category deletion events"""
  projectScopeCategoryDeleted: ID!

  """Subscribe to project scope category updates"""
  projectScopeCategoryUpdated: ProjectScopeCategoryType!

  """Subscribe to project scope creation events"""
  projectScopeCreated: ProjectScopeType!

  """Subscribe to project scope deletion events"""
  projectScopeDeleted: ID!

  """Subscribe to project scope task creation events"""
  projectScopeTaskCreated: ProjectScopeTaskType!

  """Subscribe to project scope task deletion events"""
  projectScopeTaskDeleted: ID!

  """Subscribe to project scope task updates"""
  projectScopeTaskUpdated: ProjectScopeTaskType!

  """Subscribe to project scope template creation events"""
  projectScopeTemplateCreated: ProjectScopeTemplateType!

  """Subscribe to project scope template deletion events"""
  projectScopeTemplateDeleted: ID!

  """Subscribe to project scope template updates"""
  projectScopeTemplateUpdated: ProjectScopeTemplateType!

  """Subscribe to project scope updates"""
  projectScopeUpdated: ProjectScopeType!

  """Subscribe to project task template creation events"""
  projectTaskTemplateCreated: ProjectTaskTemplateType!

  """Subscribe to project task template deletion events"""
  projectTaskTemplateDeleted: ID!

  """Subscribe to project task template updates"""
  projectTaskTemplateUpdated: ProjectTaskTemplateType!

  """Subscribe to project updates"""
  projectUpdated: ProjectType!

  """Subscribe to report creation events"""
  reportCreated: ReportType!

  """Subscribe to report deletion events"""
  reportDeleted: ID!

  """Subscribe to report updates"""
  reportUpdated: ReportType!

  """Subscribe to revenue creation events"""
  revenueCreated: RevenueType!

  """Subscribe to revenue deletion events"""
  revenueDeleted: ID!

  """Subscribe to revenue updates"""
  revenueUpdated: RevenueType!

  """Subscribe to schedule creation events"""
  scheduleCreated: ScheduleType!

  """Subscribe to schedule deletion events"""
  scheduleDeleted: ID!

  """Subscribe to schedule updates"""
  scheduleUpdated: ScheduleType!

  """Subscribe to scope creation events"""
  scopeCreated: ScopeType!

  """Subscribe to scopes created from a template"""
  scopeCreatedFromTemplate: ScopeType!

  """Subscribe to scope deletion events"""
  scopeDeleted: ID!

  """Subscribe to scope template creation events"""
  scopeTemplateCreated: ScopeTemplateType!

  """Subscribe to scope template deletion events"""
  scopeTemplateDeleted: ID!

  """Subscribe to scope template updates"""
  scopeTemplateUpdated: ScopeTemplateType!

  """Subscribe to scope updates"""
  scopeUpdated: ScopeType!

  """Subscribe to service visit creation events"""
  serviceCreated: ServiceType!

  """Subscribe to service visit deletion events"""
  serviceDeleted: ID!

  """Subscribe to service visit updates"""
  serviceUpdated: ServiceType!

  """Subscribe to task completion creation events"""
  taskCompletionCreated: TaskCompletionType!

  """Subscribe to task completion deletion events"""
  taskCompletionDeleted: ID!

  """Subscribe to task completion updates"""
  taskCompletionUpdated: TaskCompletionType!

  """Subscribe to task creation events"""
  taskCreated: TaskType!

  """Subscribe to task deletion events"""
  taskDeleted: ID!

  """Subscribe to task template creation events"""
  taskTemplateCreated: TaskTemplateType!

  """Subscribe to task template deletion events"""
  taskTemplateDeleted: ID!

  """Subscribe to task template updates"""
  taskTemplateUpdated: TaskTemplateType!

  """Subscribe to task updates"""
  taskUpdated: TaskType!

  """Subscribe to team profile creation events"""
  teamProfileCreated: TeamProfileType!

  """Subscribe to team profile deletion events"""
  teamProfileDeleted: ID!

  """Subscribe to team profile updates"""
  teamProfileUpdated: TeamProfileType!
}

"""Record of a task template being completed during a service visit"""
input TaskCompletionFilter {
  AND: TaskCompletionFilter
  DISTINCT: Boolean
  NOT: TaskCompletionFilter
  OR: TaskCompletionFilter
  completedById: UUID
  id: UUID
  month: Int
  serviceId: UUID
  taskId: UUID
  year: Int
}

input TaskCompletionInput {
  completedAt: DateTime!
  completedById: ID!
  notes: String! = ""
  serviceId: ID!
  taskId: ID!
}

"""Record of a task template being completed during a service visit"""
type TaskCompletionType implements Node {
  accountAddressId: UUID
  completedAt: DateTime!
  completedById: UUID!

  """The Globally Unique ID of this object"""
  id: ID!
  month: Int!
  notes: String!
  serviceId: UUID!
  taskId: UUID!
  year: Int!
}

input TaskCompletionUpdateInput {
  completedAt: DateTime = null
  completedById: ID = null
  id: ID!
  notes: String = null
  serviceId: ID = null
  taskId: ID = null
}

"""Individual task template within an area"""
input TaskFilter {
  AND: TaskFilter
  DISTINCT: Boolean
  NOT: TaskFilter
  OR: TaskFilter
  areaId: UUID

  """How often the task should be performed"""
  frequency: TaskFrequencyChoices
  id: UUID
}

enum TaskFrequencyChoices {
  ANNUAL
  AS_NEEDED
  DAILY
  MONTHLY
  QUARTERLY
  TRIANNUAL
  WEEKLY
}

input TaskInput {
  areaId: ID!
  checklistDescription: String = null
  description: String!
  estimatedMinutes: Int = null
  frequency: String!
  isConditional: Boolean! = false
  order: Int! = 0
}

"""Reusable task definition belonging to an AreaTemplate"""
input TaskTemplateFilter {
  AND: TaskTemplateFilter
  DISTINCT: Boolean
  NOT: TaskTemplateFilter
  OR: TaskTemplateFilter
  areaTemplateId: UUID

  """Case-insensitive search on description"""
  descriptionSearch: String = null

  """How often the task should be performed"""
  frequency: String = null
  id: UUID

  """Task marked 'where applicable'"""
  isConditional: Boolean = null
}

input TaskTemplateInput {
  areaTemplateId: ID!
  checklistDescription: String = null
  description: String!
  estimatedMinutes: Int = null
  frequency: String!
  isConditional: Boolean = false
  order: Int = 0
}

"""Reusable task definition belonging to an AreaTemplate"""
type TaskTemplateType implements Node {
  areaTemplateId: UUID!
  checklistDescription: String!
  description: String!
  estimatedMinutes: Int

  """How often the task should be performed"""
  frequency: TaskFrequencyChoices!

  """The Globally Unique ID of this object"""
  id: ID!

  """Task marked 'where applicable'"""
  isConditional: Boolean!
  order: Int!
}

input TaskTemplateUpdateInput {
  checklistDescription: String = null
  description: String = null
  estimatedMinutes: Int = null
  frequency: String = null
  id: ID!
  isConditional: Boolean = null
  order: Int = null
}

"""Individual task template within an area"""
type TaskType implements Node {
  areaId: UUID!
  checklistDescription: String!
  description: String!
  estimatedMinutes: Int

  """How often the task should be performed"""
  frequency: TaskFrequencyChoices!

  """The Globally Unique ID of this object"""
  id: ID!

  """Task marked 'where applicable'"""
  isConditional: Boolean!
  order: Int!
}

input TaskUpdateInput {
  areaId: ID = null
  checklistDescription: String = null
  description: String = null
  estimatedMinutes: Int = null
  frequency: String = null
  id: ID!
  isConditional: Boolean = null
  order: Int = null
}

type TeamDashboardData {
  projects: [ProjectType!]!
  reports: [ReportType!]!
  services: [ServiceType!]!
}

input TeamProfileInput {
  email: String = null
  firstName: String!
  lastName: String!
  notes: String = null
  phone: String = null
  role: String!
  status: String! = "PENDING"
  userId: ID = null
}

"""Internal team member accounts"""
type TeamProfileType implements Node {
  email: String
  firstName: String!
  fullName: String!

  """The Globally Unique ID of this object"""
  id: ID!
  lastName: String!
  notes: String!

  """Unique identifier from Ory Kratos authentication system"""
  oryKratosId: String
  phone: String

  """Role of the team member"""
  role: RoleChoices!

  """Current status of the profile"""
  status: StatusChoices!
}

input TeamProfileUpdateInput {
  email: String = null
  firstName: String = null
  id: ID!
  lastName: String = null
  notes: String = null
  phone: String = null
  role: String = null
  status: String = null
  userId: ID = null
}

scalar UUID

input UUIDFilterLookup {
  """
  Case-sensitive containment test. Filter will be skipped on `null` value
  """
  contains: UUID

  """Case-sensitive ends-with. Filter will be skipped on `null` value"""
  endsWith: UUID

  """Exact match. Filter will be skipped on `null` value"""
  exact: UUID

  """
  Case-insensitive containment test. Filter will be skipped on `null` value
  """
  iContains: UUID

  """Case-insensitive ends-with. Filter will be skipped on `null` value"""
  iEndsWith: UUID

  """Case-insensitive exact match. Filter will be skipped on `null` value"""
  iExact: UUID

  """
  Case-insensitive regular expression match. Filter will be skipped on `null` value
  """
  iRegex: UUID

  """Case-insensitive starts-with. Filter will be skipped on `null` value"""
  iStartsWith: UUID

  """
  Exact match of items in a given list. Filter will be skipped on `null` value
  """
  inList: [UUID!]

  """Assignment test. Filter will be skipped on `null` value"""
  isNull: Boolean

  """
  Case-sensitive regular expression match. Filter will be skipped on `null` value
  """
  regex: UUID

  """Case-sensitive starts-with. Filter will be skipped on `null` value"""
  startsWith: UUID
}

scalar Upload