Add ContactThreadRead model to track when users last viewed each contact thread. Contacts with messages newer than the last read time show a blue dot in the sidebar. Opening a thread automatically marks it as read via markThreadRead mutation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
279 lines
5.3 KiB
GraphQL
279 lines
5.3 KiB
GraphQL
type Query {
|
|
me: MePayload!
|
|
chatMessages: [PilotMessage!]!
|
|
chatConversations: [Conversation!]!
|
|
contacts: [Contact!]!
|
|
communications: [CommItem!]!
|
|
contactInboxes: [ContactInbox!]!
|
|
calendar(dateRange: CalendarDateRange): [CalendarEvent!]!
|
|
deals: [Deal!]!
|
|
feed: [FeedCard!]!
|
|
pins: [CommPin!]!
|
|
documents: [WorkspaceDocument!]!
|
|
getClientTimeline(contactId: ID!, limit: Int): [ClientTimelineItem!]!
|
|
}
|
|
|
|
type Mutation {
|
|
login(phone: String!, password: String!): MutationResult!
|
|
logout: MutationResult!
|
|
createChatConversation(title: String): Conversation!
|
|
selectChatConversation(id: ID!): MutationResult!
|
|
archiveChatConversation(id: ID!): MutationResult!
|
|
sendPilotMessage(text: String!): MutationResult!
|
|
confirmLatestChangeSet: MutationResult!
|
|
rollbackLatestChangeSet: MutationResult!
|
|
rollbackChangeSetItems(changeSetId: ID!, itemIds: [ID!]!): MutationResult!
|
|
logPilotNote(text: String!): MutationResult!
|
|
toggleContactPin(contact: String!, text: String!): PinToggleResult!
|
|
createCalendarEvent(input: CreateCalendarEventInput!): CalendarEvent!
|
|
archiveCalendarEvent(input: ArchiveCalendarEventInput!): CalendarEvent!
|
|
createCommunication(input: CreateCommunicationInput!): MutationWithIdResult!
|
|
createWorkspaceDocument(input: CreateWorkspaceDocumentInput!): WorkspaceDocument!
|
|
deleteWorkspaceDocument(id: ID!): MutationWithIdResult!
|
|
updateCommunicationTranscript(id: ID!, transcript: [String!]!): MutationWithIdResult!
|
|
updateFeedDecision(id: ID!, decision: String!, decisionNote: String): MutationWithIdResult!
|
|
setContactInboxHidden(inboxId: ID!, hidden: Boolean!): MutationResult!
|
|
markThreadRead(contactId: ID!): MutationResult!
|
|
}
|
|
|
|
type MutationResult {
|
|
ok: Boolean!
|
|
}
|
|
|
|
type MutationWithIdResult {
|
|
ok: Boolean!
|
|
id: ID!
|
|
}
|
|
|
|
type PinToggleResult {
|
|
ok: Boolean!
|
|
pinned: Boolean!
|
|
}
|
|
|
|
input CalendarDateRange {
|
|
from: String
|
|
to: String
|
|
}
|
|
|
|
input CreateCalendarEventInput {
|
|
title: String!
|
|
start: String!
|
|
end: String
|
|
contact: String
|
|
note: String
|
|
archived: Boolean
|
|
archiveNote: String
|
|
}
|
|
|
|
input ArchiveCalendarEventInput {
|
|
id: ID!
|
|
archiveNote: String
|
|
}
|
|
|
|
input CreateCommunicationInput {
|
|
contact: String!
|
|
channel: String
|
|
kind: String
|
|
direction: String
|
|
text: String
|
|
audioUrl: String
|
|
at: String
|
|
durationSec: Int
|
|
transcript: [String!]
|
|
}
|
|
|
|
input CreateWorkspaceDocumentInput {
|
|
title: String!
|
|
owner: String
|
|
scope: String!
|
|
summary: String!
|
|
body: String
|
|
}
|
|
|
|
type MePayload {
|
|
user: MeUser!
|
|
team: MeTeam!
|
|
conversation: Conversation!
|
|
}
|
|
|
|
type MeUser {
|
|
id: ID!
|
|
phone: String!
|
|
name: String!
|
|
}
|
|
|
|
type MeTeam {
|
|
id: ID!
|
|
name: String!
|
|
}
|
|
|
|
type Conversation {
|
|
id: ID!
|
|
title: String!
|
|
createdAt: String!
|
|
updatedAt: String!
|
|
lastMessageAt: String
|
|
lastMessageText: String
|
|
}
|
|
|
|
type PilotMessage {
|
|
id: ID!
|
|
role: String!
|
|
text: String!
|
|
messageKind: String
|
|
requestId: String
|
|
eventType: String
|
|
phase: String
|
|
transient: Boolean
|
|
thinking: [String!]!
|
|
tools: [String!]!
|
|
toolRuns: [PilotToolRun!]!
|
|
changeSetId: String
|
|
changeStatus: String
|
|
changeSummary: String
|
|
changeItems: [PilotChangeItem!]!
|
|
createdAt: String!
|
|
}
|
|
|
|
type PilotChangeItem {
|
|
id: ID!
|
|
entity: String!
|
|
entityId: String
|
|
action: String!
|
|
title: String!
|
|
before: String!
|
|
after: String!
|
|
rolledBack: Boolean!
|
|
}
|
|
|
|
type PilotToolRun {
|
|
name: String!
|
|
status: String!
|
|
input: String!
|
|
output: String!
|
|
at: String!
|
|
}
|
|
|
|
type ClientTimelineItem {
|
|
id: ID!
|
|
contactId: String!
|
|
contentType: String!
|
|
contentId: String!
|
|
datetime: String!
|
|
message: CommItem
|
|
calendarEvent: CalendarEvent
|
|
recommendation: FeedCard
|
|
document: WorkspaceDocument
|
|
}
|
|
|
|
type Contact {
|
|
id: ID!
|
|
name: String!
|
|
avatar: String!
|
|
channels: [String!]!
|
|
lastContactAt: String!
|
|
lastMessageText: String!
|
|
lastMessageChannel: String!
|
|
hasUnread: Boolean!
|
|
description: String!
|
|
}
|
|
|
|
type CommItem {
|
|
id: ID!
|
|
at: String!
|
|
contactId: String!
|
|
contact: String!
|
|
contactInboxId: String!
|
|
sourceExternalId: String!
|
|
sourceTitle: String!
|
|
channel: String!
|
|
kind: String!
|
|
direction: String!
|
|
text: String!
|
|
audioUrl: String!
|
|
duration: String!
|
|
waveform: [Float!]!
|
|
transcript: [String!]!
|
|
deliveryStatus: String
|
|
}
|
|
|
|
type ContactInbox {
|
|
id: ID!
|
|
contactId: String!
|
|
contactName: String!
|
|
channel: String!
|
|
sourceExternalId: String!
|
|
title: String!
|
|
isHidden: Boolean!
|
|
lastMessageAt: String!
|
|
updatedAt: String!
|
|
}
|
|
|
|
type CalendarEvent {
|
|
id: ID!
|
|
title: String!
|
|
start: String!
|
|
end: String!
|
|
contact: String!
|
|
note: String!
|
|
isArchived: Boolean!
|
|
createdAt: String!
|
|
archiveNote: String!
|
|
archivedAt: String!
|
|
}
|
|
|
|
type Deal {
|
|
id: ID!
|
|
contact: String!
|
|
title: String!
|
|
stage: String!
|
|
amount: String!
|
|
nextStep: String!
|
|
summary: String!
|
|
currentStepId: String!
|
|
steps: [DealStep!]!
|
|
}
|
|
|
|
type DealStep {
|
|
id: ID!
|
|
title: String!
|
|
description: String!
|
|
status: String!
|
|
dueAt: String!
|
|
order: Int!
|
|
completedAt: String!
|
|
}
|
|
|
|
type FeedCard {
|
|
id: ID!
|
|
at: String!
|
|
contact: String!
|
|
text: String!
|
|
proposal: FeedProposal!
|
|
decision: String!
|
|
decisionNote: String!
|
|
}
|
|
|
|
type FeedProposal {
|
|
title: String!
|
|
details: [String!]!
|
|
key: String!
|
|
}
|
|
|
|
type CommPin {
|
|
id: ID!
|
|
contact: String!
|
|
text: String!
|
|
}
|
|
|
|
type WorkspaceDocument {
|
|
id: ID!
|
|
title: String!
|
|
type: String!
|
|
owner: String!
|
|
scope: String!
|
|
updatedAt: String!
|
|
summary: String!
|
|
body: String!
|
|
}
|