mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-28 05:46:58 +02:00
A complete UX upgrade for chat sending → receiving → recovering.
* StatusPill replaces the orphan spinner — stage-aware copy
("Reading files · 12s", "Searching the web · 14s", "Typing · 24s"),
shimmer text, monotonic timer, derived effective status, > 60s
warning tone, > 5min cancel button.
* WS writethrough on task:queued / task:dispatch / task:cancelled so
pendingTask cache stays in sync with the daemon state machine without
invalidate-refetch latency. broadcastTaskDispatch now includes
chat_session_id when the task is for a chat session — the existing
payload only carried it on the generic task: events, leaving the pill
stuck at "Queued" until completion.
* Failure fallback — FailTask writes a chat_message tagged with
failure_reason (mirrors the issue path's system comment, gated on
retried==nil). Front-end renders an inline note ("Connection failed",
with a Show details collapsible) instead of the previous black hole.
* Elapsed timing — chat_message.elapsed_ms persists task.completed_at -
task.created_at on success/failure rows. UI shows "Replied in 38s" /
"Failed after 12s" beneath assistant bubbles. Format helper shared
between StatusPill and the persisted caption so the live timer and
final reading never disagree.
* Optimistic burst rebalanced — pendingTask seed + created_at moved
before the HTTP roundtrip so the pill appears the instant the user
hits send; handleStop is fire-and-forget so cancel feels immediate
(server confirmation arrives via task:cancelled WS).
* Presence integration — chat avatars use ActorAvatar (status dot +
hover card); OfflineBanner above the input on offline/unstable;
SessionDropdown shows per-row in-flight/unread pip plus a
cross-session aggregate pip on the closed trigger.
* Editor blur on send so the caret stops competing with the StatusPill
/ streaming reply for the user's attention.
* Chat panel isOpen now persists globally; defaults to OPEN for new
users (storage key absence) so the feature is discoverable. Existing
users' prior choice is respected.
* DB: migrations 062 (failure_reason) + 063 (elapsed_ms), both
ADD COLUMN NULL — fast, non-blocking, backwards compatible.
* WS: task:failed chat path now invalidates chatKeys.messages — fixes
a pre-existing bug where the failure bubble required a page refresh
to appear.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
455 lines
19 KiB
Go
455 lines
19 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.30.0
|
|
|
|
package db
|
|
|
|
import (
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
type ActivityLog struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
IssueID pgtype.UUID `json:"issue_id"`
|
|
ActorType pgtype.Text `json:"actor_type"`
|
|
ActorID pgtype.UUID `json:"actor_id"`
|
|
Action string `json:"action"`
|
|
Details []byte `json:"details"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type Agent struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
Name string `json:"name"`
|
|
AvatarUrl pgtype.Text `json:"avatar_url"`
|
|
RuntimeMode string `json:"runtime_mode"`
|
|
RuntimeConfig []byte `json:"runtime_config"`
|
|
Visibility string `json:"visibility"`
|
|
Status string `json:"status"`
|
|
MaxConcurrentTasks int32 `json:"max_concurrent_tasks"`
|
|
OwnerID pgtype.UUID `json:"owner_id"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
Description string `json:"description"`
|
|
RuntimeID pgtype.UUID `json:"runtime_id"`
|
|
Instructions string `json:"instructions"`
|
|
ArchivedAt pgtype.Timestamptz `json:"archived_at"`
|
|
ArchivedBy pgtype.UUID `json:"archived_by"`
|
|
CustomEnv []byte `json:"custom_env"`
|
|
CustomArgs []byte `json:"custom_args"`
|
|
McpConfig []byte `json:"mcp_config"`
|
|
Model pgtype.Text `json:"model"`
|
|
}
|
|
|
|
type AgentRuntime struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
DaemonID pgtype.Text `json:"daemon_id"`
|
|
Name string `json:"name"`
|
|
RuntimeMode string `json:"runtime_mode"`
|
|
Provider string `json:"provider"`
|
|
Status string `json:"status"`
|
|
DeviceInfo string `json:"device_info"`
|
|
Metadata []byte `json:"metadata"`
|
|
LastSeenAt pgtype.Timestamptz `json:"last_seen_at"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
OwnerID pgtype.UUID `json:"owner_id"`
|
|
LegacyDaemonID pgtype.Text `json:"legacy_daemon_id"`
|
|
}
|
|
|
|
type AgentSkill struct {
|
|
AgentID pgtype.UUID `json:"agent_id"`
|
|
SkillID pgtype.UUID `json:"skill_id"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type AgentTaskQueue struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
AgentID pgtype.UUID `json:"agent_id"`
|
|
IssueID pgtype.UUID `json:"issue_id"`
|
|
Status string `json:"status"`
|
|
Priority int32 `json:"priority"`
|
|
DispatchedAt pgtype.Timestamptz `json:"dispatched_at"`
|
|
StartedAt pgtype.Timestamptz `json:"started_at"`
|
|
CompletedAt pgtype.Timestamptz `json:"completed_at"`
|
|
Result []byte `json:"result"`
|
|
Error pgtype.Text `json:"error"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
Context []byte `json:"context"`
|
|
RuntimeID pgtype.UUID `json:"runtime_id"`
|
|
SessionID pgtype.Text `json:"session_id"`
|
|
WorkDir pgtype.Text `json:"work_dir"`
|
|
TriggerCommentID pgtype.UUID `json:"trigger_comment_id"`
|
|
ChatSessionID pgtype.UUID `json:"chat_session_id"`
|
|
AutopilotRunID pgtype.UUID `json:"autopilot_run_id"`
|
|
Attempt int32 `json:"attempt"`
|
|
MaxAttempts int32 `json:"max_attempts"`
|
|
ParentTaskID pgtype.UUID `json:"parent_task_id"`
|
|
FailureReason pgtype.Text `json:"failure_reason"`
|
|
LastHeartbeatAt pgtype.Timestamptz `json:"last_heartbeat_at"`
|
|
TriggerSummary pgtype.Text `json:"trigger_summary"`
|
|
}
|
|
|
|
type Attachment struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
IssueID pgtype.UUID `json:"issue_id"`
|
|
CommentID pgtype.UUID `json:"comment_id"`
|
|
UploaderType string `json:"uploader_type"`
|
|
UploaderID pgtype.UUID `json:"uploader_id"`
|
|
Filename string `json:"filename"`
|
|
Url string `json:"url"`
|
|
ContentType string `json:"content_type"`
|
|
SizeBytes int64 `json:"size_bytes"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type Autopilot struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
Title string `json:"title"`
|
|
Description pgtype.Text `json:"description"`
|
|
AssigneeID pgtype.UUID `json:"assignee_id"`
|
|
Status string `json:"status"`
|
|
ExecutionMode string `json:"execution_mode"`
|
|
IssueTitleTemplate pgtype.Text `json:"issue_title_template"`
|
|
CreatedByType string `json:"created_by_type"`
|
|
CreatedByID pgtype.UUID `json:"created_by_id"`
|
|
LastRunAt pgtype.Timestamptz `json:"last_run_at"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
}
|
|
|
|
type AutopilotRun struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
AutopilotID pgtype.UUID `json:"autopilot_id"`
|
|
TriggerID pgtype.UUID `json:"trigger_id"`
|
|
Source string `json:"source"`
|
|
Status string `json:"status"`
|
|
IssueID pgtype.UUID `json:"issue_id"`
|
|
TaskID pgtype.UUID `json:"task_id"`
|
|
TriggeredAt pgtype.Timestamptz `json:"triggered_at"`
|
|
CompletedAt pgtype.Timestamptz `json:"completed_at"`
|
|
FailureReason pgtype.Text `json:"failure_reason"`
|
|
TriggerPayload []byte `json:"trigger_payload"`
|
|
Result []byte `json:"result"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type AutopilotTrigger struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
AutopilotID pgtype.UUID `json:"autopilot_id"`
|
|
Kind string `json:"kind"`
|
|
Enabled bool `json:"enabled"`
|
|
CronExpression pgtype.Text `json:"cron_expression"`
|
|
Timezone pgtype.Text `json:"timezone"`
|
|
NextRunAt pgtype.Timestamptz `json:"next_run_at"`
|
|
WebhookToken pgtype.Text `json:"webhook_token"`
|
|
Label pgtype.Text `json:"label"`
|
|
LastFiredAt pgtype.Timestamptz `json:"last_fired_at"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
}
|
|
|
|
type ChatMessage struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
ChatSessionID pgtype.UUID `json:"chat_session_id"`
|
|
Role string `json:"role"`
|
|
Content string `json:"content"`
|
|
TaskID pgtype.UUID `json:"task_id"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
FailureReason pgtype.Text `json:"failure_reason"`
|
|
ElapsedMs pgtype.Int8 `json:"elapsed_ms"`
|
|
}
|
|
|
|
type ChatSession struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
AgentID pgtype.UUID `json:"agent_id"`
|
|
CreatorID pgtype.UUID `json:"creator_id"`
|
|
Title string `json:"title"`
|
|
SessionID pgtype.Text `json:"session_id"`
|
|
WorkDir pgtype.Text `json:"work_dir"`
|
|
Status string `json:"status"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
UnreadSince pgtype.Timestamptz `json:"unread_since"`
|
|
}
|
|
|
|
type Comment struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
IssueID pgtype.UUID `json:"issue_id"`
|
|
AuthorType string `json:"author_type"`
|
|
AuthorID pgtype.UUID `json:"author_id"`
|
|
Content string `json:"content"`
|
|
Type string `json:"type"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
ParentID pgtype.UUID `json:"parent_id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
}
|
|
|
|
type CommentReaction struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
CommentID pgtype.UUID `json:"comment_id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
ActorType string `json:"actor_type"`
|
|
ActorID pgtype.UUID `json:"actor_id"`
|
|
Emoji string `json:"emoji"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type DaemonConnection struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
AgentID pgtype.UUID `json:"agent_id"`
|
|
DaemonID string `json:"daemon_id"`
|
|
Status string `json:"status"`
|
|
LastHeartbeatAt pgtype.Timestamptz `json:"last_heartbeat_at"`
|
|
RuntimeInfo []byte `json:"runtime_info"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
}
|
|
|
|
type DaemonToken struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
TokenHash string `json:"token_hash"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
DaemonID string `json:"daemon_id"`
|
|
ExpiresAt pgtype.Timestamptz `json:"expires_at"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type Feedback struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
UserID pgtype.UUID `json:"user_id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
Message string `json:"message"`
|
|
Metadata []byte `json:"metadata"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type InboxItem struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
RecipientType string `json:"recipient_type"`
|
|
RecipientID pgtype.UUID `json:"recipient_id"`
|
|
Type string `json:"type"`
|
|
Severity string `json:"severity"`
|
|
IssueID pgtype.UUID `json:"issue_id"`
|
|
Title string `json:"title"`
|
|
Body pgtype.Text `json:"body"`
|
|
Read bool `json:"read"`
|
|
Archived bool `json:"archived"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
ActorType pgtype.Text `json:"actor_type"`
|
|
ActorID pgtype.UUID `json:"actor_id"`
|
|
Details []byte `json:"details"`
|
|
}
|
|
|
|
type Issue struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
Title string `json:"title"`
|
|
Description pgtype.Text `json:"description"`
|
|
Status string `json:"status"`
|
|
Priority string `json:"priority"`
|
|
AssigneeType pgtype.Text `json:"assignee_type"`
|
|
AssigneeID pgtype.UUID `json:"assignee_id"`
|
|
CreatorType string `json:"creator_type"`
|
|
CreatorID pgtype.UUID `json:"creator_id"`
|
|
ParentIssueID pgtype.UUID `json:"parent_issue_id"`
|
|
AcceptanceCriteria []byte `json:"acceptance_criteria"`
|
|
ContextRefs []byte `json:"context_refs"`
|
|
Position float64 `json:"position"`
|
|
DueDate pgtype.Timestamptz `json:"due_date"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
Number int32 `json:"number"`
|
|
ProjectID pgtype.UUID `json:"project_id"`
|
|
OriginType pgtype.Text `json:"origin_type"`
|
|
OriginID pgtype.UUID `json:"origin_id"`
|
|
FirstExecutedAt pgtype.Timestamptz `json:"first_executed_at"`
|
|
}
|
|
|
|
type IssueDependency struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
IssueID pgtype.UUID `json:"issue_id"`
|
|
DependsOnIssueID pgtype.UUID `json:"depends_on_issue_id"`
|
|
Type string `json:"type"`
|
|
}
|
|
|
|
type IssueLabel struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
Name string `json:"name"`
|
|
Color string `json:"color"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
}
|
|
|
|
type IssueReaction struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
IssueID pgtype.UUID `json:"issue_id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
ActorType string `json:"actor_type"`
|
|
ActorID pgtype.UUID `json:"actor_id"`
|
|
Emoji string `json:"emoji"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type IssueSubscriber struct {
|
|
IssueID pgtype.UUID `json:"issue_id"`
|
|
UserType string `json:"user_type"`
|
|
UserID pgtype.UUID `json:"user_id"`
|
|
Reason string `json:"reason"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type IssueToLabel struct {
|
|
IssueID pgtype.UUID `json:"issue_id"`
|
|
LabelID pgtype.UUID `json:"label_id"`
|
|
}
|
|
|
|
type Member struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
UserID pgtype.UUID `json:"user_id"`
|
|
Role string `json:"role"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type PersonalAccessToken struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
UserID pgtype.UUID `json:"user_id"`
|
|
Name string `json:"name"`
|
|
TokenHash string `json:"token_hash"`
|
|
TokenPrefix string `json:"token_prefix"`
|
|
ExpiresAt pgtype.Timestamptz `json:"expires_at"`
|
|
LastUsedAt pgtype.Timestamptz `json:"last_used_at"`
|
|
Revoked bool `json:"revoked"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type PinnedItem struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
UserID pgtype.UUID `json:"user_id"`
|
|
ItemType string `json:"item_type"`
|
|
ItemID pgtype.UUID `json:"item_id"`
|
|
Position float64 `json:"position"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type Project struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
Title string `json:"title"`
|
|
Description pgtype.Text `json:"description"`
|
|
Icon pgtype.Text `json:"icon"`
|
|
Status string `json:"status"`
|
|
LeadType pgtype.Text `json:"lead_type"`
|
|
LeadID pgtype.UUID `json:"lead_id"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
Priority string `json:"priority"`
|
|
}
|
|
|
|
type Skill struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
Content string `json:"content"`
|
|
Config []byte `json:"config"`
|
|
CreatedBy pgtype.UUID `json:"created_by"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
}
|
|
|
|
type SkillFile struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
SkillID pgtype.UUID `json:"skill_id"`
|
|
Path string `json:"path"`
|
|
Content string `json:"content"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
}
|
|
|
|
type TaskMessage struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
TaskID pgtype.UUID `json:"task_id"`
|
|
Seq int32 `json:"seq"`
|
|
Type string `json:"type"`
|
|
Tool pgtype.Text `json:"tool"`
|
|
Content pgtype.Text `json:"content"`
|
|
Input []byte `json:"input"`
|
|
Output pgtype.Text `json:"output"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type TaskUsage struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
TaskID pgtype.UUID `json:"task_id"`
|
|
Provider string `json:"provider"`
|
|
Model string `json:"model"`
|
|
InputTokens int64 `json:"input_tokens"`
|
|
OutputTokens int64 `json:"output_tokens"`
|
|
CacheReadTokens int64 `json:"cache_read_tokens"`
|
|
CacheWriteTokens int64 `json:"cache_write_tokens"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type User struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
Name string `json:"name"`
|
|
Email string `json:"email"`
|
|
AvatarUrl pgtype.Text `json:"avatar_url"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
OnboardedAt pgtype.Timestamptz `json:"onboarded_at"`
|
|
OnboardingQuestionnaire []byte `json:"onboarding_questionnaire"`
|
|
CloudWaitlistEmail pgtype.Text `json:"cloud_waitlist_email"`
|
|
CloudWaitlistReason pgtype.Text `json:"cloud_waitlist_reason"`
|
|
StarterContentState pgtype.Text `json:"starter_content_state"`
|
|
}
|
|
|
|
type VerificationCode struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
Email string `json:"email"`
|
|
Code string `json:"code"`
|
|
ExpiresAt pgtype.Timestamptz `json:"expires_at"`
|
|
Used bool `json:"used"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
Attempts int32 `json:"attempts"`
|
|
}
|
|
|
|
type Workspace struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
Name string `json:"name"`
|
|
Slug string `json:"slug"`
|
|
Description pgtype.Text `json:"description"`
|
|
Settings []byte `json:"settings"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
Context pgtype.Text `json:"context"`
|
|
Repos []byte `json:"repos"`
|
|
IssuePrefix string `json:"issue_prefix"`
|
|
IssueCounter int32 `json:"issue_counter"`
|
|
}
|
|
|
|
type WorkspaceInvitation struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
InviterID pgtype.UUID `json:"inviter_id"`
|
|
InviteeEmail string `json:"invitee_email"`
|
|
InviteeUserID pgtype.UUID `json:"invitee_user_id"`
|
|
Role string `json:"role"`
|
|
Status string `json:"status"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
ExpiresAt pgtype.Timestamptz `json:"expires_at"`
|
|
}
|