feat(p8): calendar/meeting schema + enums + events + migration
Task 8.1: 12 Calendar/Meeting tables (meeting_request, meeting, participant, transcript, segment, summary, generic action_item + meeting link, provider account, calendar_event, availability_window, sync_cursor) + 13 enums; migration calendar-init. Adds calendar.meeting.requested/scheduled/reminder.queued/ summarized events. resetDb truncates the new tables. Kernel already had the MEETING_REQUEST / MEETING_FOLLOWUP / callback.meetingRef stubs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -189,6 +189,101 @@ enum IiosAiClaimValidation {
|
||||
REJECTED
|
||||
}
|
||||
|
||||
// ─── Calendar / Meeting enums (P8) ────────────────────────────────
|
||||
|
||||
enum IiosMeetingType {
|
||||
ZOOM
|
||||
PHONE
|
||||
IN_PERSON
|
||||
CALLBACK
|
||||
INTERNAL
|
||||
}
|
||||
|
||||
enum IiosMeetingStatus {
|
||||
REQUESTED
|
||||
SCHEDULED
|
||||
CONFIRMED
|
||||
CANCELLED
|
||||
COMPLETED
|
||||
NO_SHOW
|
||||
}
|
||||
|
||||
enum IiosMeetingRequestStatus {
|
||||
PENDING
|
||||
PROPOSED
|
||||
ACCEPTED
|
||||
DECLINED
|
||||
SCHEDULED
|
||||
CANCELLED
|
||||
}
|
||||
|
||||
enum IiosParticipantRole {
|
||||
ORGANIZER
|
||||
REQUIRED
|
||||
OPTIONAL
|
||||
}
|
||||
|
||||
enum IiosAttendanceStatus {
|
||||
INVITED
|
||||
ACCEPTED
|
||||
DECLINED
|
||||
TENTATIVE
|
||||
ATTENDED
|
||||
NO_SHOW
|
||||
}
|
||||
|
||||
enum IiosParticipantVisibility {
|
||||
FULL
|
||||
LIMITED
|
||||
NONE
|
||||
}
|
||||
|
||||
enum IiosConsentStatus {
|
||||
UNKNOWN
|
||||
GRANTED
|
||||
DENIED
|
||||
REVOKED
|
||||
}
|
||||
|
||||
enum IiosTranscriptStatus {
|
||||
PENDING
|
||||
READY
|
||||
BLOCKED
|
||||
}
|
||||
|
||||
enum IiosSummaryStatus {
|
||||
PROPOSED
|
||||
APPROVED
|
||||
PUBLISHED
|
||||
REJECTED
|
||||
}
|
||||
|
||||
enum IiosActionItemStatus {
|
||||
OPEN
|
||||
IN_PROGRESS
|
||||
DONE
|
||||
CANCELLED
|
||||
}
|
||||
|
||||
enum IiosCalendarProviderType {
|
||||
SIMULATED
|
||||
GOOGLE
|
||||
OUTLOOK
|
||||
ICS
|
||||
}
|
||||
|
||||
enum IiosCalendarSyncStatus {
|
||||
IDLE
|
||||
SYNCING
|
||||
ERROR
|
||||
}
|
||||
|
||||
enum IiosCalendarEventStatus {
|
||||
CONFIRMED
|
||||
TENTATIVE
|
||||
CANCELLED
|
||||
}
|
||||
|
||||
// ─── Kernel tables ────────────────────────────────────────────────
|
||||
|
||||
/// Frozen six-vector scope. orgId + appId are REQUIRED (no global-by-null).
|
||||
@@ -843,3 +938,220 @@ model IiosEmbeddingRef {
|
||||
|
||||
@@unique([sourceType, sourceId, version])
|
||||
}
|
||||
|
||||
// ─── Calendar / Meeting SDK tables (P8) — interaction specialization ────────
|
||||
|
||||
/// A request to schedule/reschedule/cancel a meeting. Genesis: a P4 callback
|
||||
/// (callbackRequestId), an accepted P7 AI EVENT claim (sourceClaimId), or direct.
|
||||
model IiosMeetingRequest {
|
||||
id String @id @default(cuid())
|
||||
scopeId String
|
||||
interactionId String?
|
||||
requestedByActorId String
|
||||
targetActorId String?
|
||||
requestedWindowJson Json
|
||||
meetingType IiosMeetingType @default(CALLBACK)
|
||||
status IiosMeetingRequestStatus @default(PENDING)
|
||||
resultingMeetingId String?
|
||||
callbackRequestId String?
|
||||
sourceClaimId String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([scopeId, status])
|
||||
}
|
||||
|
||||
/// A meeting: Zoom / phone / in-person / callback / internal. Owns calendar
|
||||
/// semantics; a message is only a related artifact.
|
||||
model IiosMeeting {
|
||||
id String @id @default(cuid())
|
||||
scopeId String
|
||||
interactionId String?
|
||||
calendarEventId String?
|
||||
meetingType IiosMeetingType
|
||||
providerRef String?
|
||||
joinUrlRef String?
|
||||
status IiosMeetingStatus @default(REQUESTED)
|
||||
organizerActorId String
|
||||
threadId String?
|
||||
title String
|
||||
startAt DateTime?
|
||||
endAt DateTime?
|
||||
timezone String @default("UTC")
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
participants IiosMeetingParticipant[]
|
||||
transcripts IiosMeetingTranscript[]
|
||||
summaries IiosMeetingSummary[]
|
||||
actionItems IiosMeetingActionItem[]
|
||||
|
||||
@@index([scopeId, status])
|
||||
}
|
||||
|
||||
/// Attendee with role, attendance, per-attendee recording consent + visibility.
|
||||
/// The consent + visibility model is the P8 safety spine (KG-14 / Scenario 6).
|
||||
model IiosMeetingParticipant {
|
||||
id String @id @default(cuid())
|
||||
meetingId String
|
||||
meeting IiosMeeting @relation(fields: [meetingId], references: [id], onDelete: Cascade)
|
||||
actorRefId String?
|
||||
sourceHandleId String?
|
||||
role IiosParticipantRole @default(REQUIRED)
|
||||
attendanceStatus IiosAttendanceStatus @default(INVITED)
|
||||
recordingConsent IiosConsentStatus @default(UNKNOWN)
|
||||
visibility IiosParticipantVisibility @default(FULL)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([meetingId, actorRefId])
|
||||
@@index([meetingId])
|
||||
}
|
||||
|
||||
/// Transcript artifact metadata. Created only after the consent gate passes;
|
||||
/// otherwise status=BLOCKED with no segments.
|
||||
model IiosMeetingTranscript {
|
||||
id String @id @default(cuid())
|
||||
meetingId String
|
||||
meeting IiosMeeting @relation(fields: [meetingId], references: [id], onDelete: Cascade)
|
||||
sourceType String @default("SIMULATED")
|
||||
transcriptRef String
|
||||
consentRefId String?
|
||||
status IiosTranscriptStatus @default(PENDING)
|
||||
language String @default("en")
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
segments IiosTranscriptSegment[]
|
||||
|
||||
@@index([meetingId])
|
||||
}
|
||||
|
||||
/// Speaker-attributed transcript segment.
|
||||
model IiosTranscriptSegment {
|
||||
id String @id @default(cuid())
|
||||
transcriptId String
|
||||
transcript IiosMeetingTranscript @relation(fields: [transcriptId], references: [id], onDelete: Cascade)
|
||||
segmentNo Int
|
||||
speakerActorId String?
|
||||
startMs Int
|
||||
endMs Int
|
||||
contentRef String
|
||||
confidence Float?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([transcriptId])
|
||||
}
|
||||
|
||||
/// AI or human meeting summary; links to a P7 ai_artifact.
|
||||
model IiosMeetingSummary {
|
||||
id String @id @default(cuid())
|
||||
meetingId String
|
||||
meeting IiosMeeting @relation(fields: [meetingId], references: [id], onDelete: Cascade)
|
||||
aiArtifactId String?
|
||||
summaryType String @default("AI")
|
||||
status IiosSummaryStatus @default(PROPOSED)
|
||||
approvedByActorId String?
|
||||
publishedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([meetingId])
|
||||
}
|
||||
|
||||
/// Generic task/follow-up (Inbox-owned source of truth), derived from meetings,
|
||||
/// support, messages or CRM workflows.
|
||||
model IiosActionItem {
|
||||
id String @id @default(cuid())
|
||||
scopeId String
|
||||
sourceInteractionId String?
|
||||
sourceMessageId String?
|
||||
ownerActorId String?
|
||||
ownerTeamId String?
|
||||
title String
|
||||
status IiosActionItemStatus @default(OPEN)
|
||||
dueAt DateTime?
|
||||
completedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
meetingLinks IiosMeetingActionItem[]
|
||||
|
||||
@@index([scopeId, status])
|
||||
}
|
||||
|
||||
/// Meeting-derived action item linked to a generic action_item.
|
||||
model IiosMeetingActionItem {
|
||||
id String @id @default(cuid())
|
||||
meetingId String
|
||||
meeting IiosMeeting @relation(fields: [meetingId], references: [id], onDelete: Cascade)
|
||||
actionItemId String
|
||||
actionItem IiosActionItem @relation(fields: [actionItemId], references: [id], onDelete: Cascade)
|
||||
ownerActorId String?
|
||||
sourceSegmentId String?
|
||||
status IiosActionItemStatus @default(OPEN)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([meetingId, actionItemId])
|
||||
@@index([meetingId])
|
||||
}
|
||||
|
||||
/// Connected calendar/provider account or service mailbox; stores refs, not secrets.
|
||||
model IiosCalendarProviderAccount {
|
||||
id String @id @default(cuid())
|
||||
scopeId String
|
||||
actorRefId String?
|
||||
providerType IiosCalendarProviderType @default(SIMULATED)
|
||||
accountHandleToken String
|
||||
secretRef String?
|
||||
syncStatus IiosCalendarSyncStatus @default(IDLE)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
events IiosCalendarEvent[]
|
||||
cursors IiosCalendarSyncCursor[]
|
||||
|
||||
@@index([scopeId])
|
||||
}
|
||||
|
||||
/// Imported or created calendar event with policy-scoped metadata.
|
||||
model IiosCalendarEvent {
|
||||
id String @id @default(cuid())
|
||||
scopeId String
|
||||
providerAccountId String?
|
||||
providerAccount IiosCalendarProviderAccount? @relation(fields: [providerAccountId], references: [id], onDelete: Cascade)
|
||||
externalEventId String?
|
||||
title String
|
||||
startAt DateTime
|
||||
endAt DateTime
|
||||
status IiosCalendarEventStatus @default(CONFIRMED)
|
||||
visibilityClass String @default("internal")
|
||||
interactionId String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([providerAccountId, externalEventId])
|
||||
@@index([scopeId])
|
||||
}
|
||||
|
||||
/// Availability / scheduling constraints for an actor or team.
|
||||
model IiosAvailabilityWindow {
|
||||
id String @id @default(cuid())
|
||||
scopeId String
|
||||
actorRefId String?
|
||||
teamProjectionId String?
|
||||
startAt DateTime
|
||||
endAt DateTime
|
||||
source String @default("USER")
|
||||
recurrenceJson Json?
|
||||
status String @default("ACTIVE")
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([scopeId, actorRefId])
|
||||
}
|
||||
|
||||
/// Incremental sync cursor / replay position for a provider calendar.
|
||||
model IiosCalendarSyncCursor {
|
||||
id String @id @default(cuid())
|
||||
providerAccountId String
|
||||
providerAccount IiosCalendarProviderAccount @relation(fields: [providerAccountId], references: [id], onDelete: Cascade)
|
||||
externalCursor String?
|
||||
lastSyncAt DateTime?
|
||||
status IiosCalendarSyncStatus @default(IDLE)
|
||||
errorCode String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([providerAccountId])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user