package models import ( "time" "github.com/google/uuid" ) type AuditAction string const ( AuditActionCreate AuditAction = "create" AuditActionUpdate AuditAction = "update" AuditActionDelete AuditAction = "delete" AuditActionAPICall AuditAction = "api_call" AuditActionExport AuditAction = "export" AuditActionImport AuditAction = "import" AuditActionRevoke AuditAction = "revoke" AuditActionConnect AuditAction = "connect" // Lifecycle / workflow actions AuditActionStart AuditAction = "start" AuditActionStop AuditAction = "stop" AuditActionPause AuditAction = "pause" AuditActionResume AuditAction = "resume" AuditActionSend AuditAction = "send" AuditActionDuplicate AuditAction = "duplicate" AuditActionDisconnect AuditAction = "disconnect" AuditActionRotate AuditAction = "rotate" // Membership / governance actions AuditActionInvite AuditAction = "invite" AuditActionRemove AuditAction = "remove" AuditActionTransfer AuditAction = "transfer" // Worker / fleet operations AuditActionTest AuditAction = "test" AuditActionInstall AuditAction = "install" AuditActionRestart AuditAction = "restart" AuditActionUpgrade AuditAction = "upgrade" AuditActionUninstall AuditAction = "uninstall" AuditActionRotateKeys AuditAction = "rotate_keys" AuditActionApply AuditAction = "apply" AuditActionAssign AuditAction = "assign" AuditActionSystemUpdate AuditAction = "system_update" AuditActionReboot AuditAction = "reboot" AuditActionCheckReleases AuditAction = "check_releases" ) type AuditEntityType string const ( AuditEntityCampaign AuditEntityType = "campaign" // AuditEntityCampaignLead is ONE contact inside ONE campaign: the entity id // is the contact and metadata carries the campaign. Written when a member // pauses or resumes that lead's flow, or changes who it copies. AuditEntityCampaignLead AuditEntityType = "campaign_lead" AuditEntityContact AuditEntityType = "contact" AuditEntityEmailAccount AuditEntityType = "email_account" AuditEntityMailboxImport AuditEntityType = "mailbox_import" AuditEntityMailboxGrant AuditEntityType = "mailbox_grant" AuditEntityMailboxVendor AuditEntityType = "mailbox_vendor" AuditEntityDomainRedirect AuditEntityType = "domain_redirect" AuditEntityAPIKey AuditEntityType = "api_key" AuditEntitySequence AuditEntityType = "step" AuditEntityUser AuditEntityType = "user" AuditEntityOrganization AuditEntityType = "organization" // AuditEntityOrgRisk carries a risk-posture transition. It rides the audit // spine like every other entity, so a change reaches every teammate's // dashboard without a bespoke emit site. AuditEntityOrgRisk AuditEntityType = "org_risk" AuditEntityWorker AuditEntityType = "worker" AuditEntityAWSCredentials AuditEntityType = "aws_credentials" AuditEntityWorkerProfile AuditEntityType = "worker_profile" AuditEntityRelease AuditEntityType = "release" // AuditEntityInstance is the deployment itself: settings and updates. AuditEntityInstance AuditEntityType = "instance" // Org-scoped configuration & governance entities AuditEntityOrganizationMember AuditEntityType = "organization_member" AuditEntityInvitation AuditEntityType = "invitation" AuditEntityTemplate AuditEntityType = "template" // AuditEntityEmailImage is one image in the workspace's library for email // bodies. Audited so a teammate's upload or removal reaches every open // composer through the spine. AuditEntityEmailImage AuditEntityType = "email_image" AuditEntityWebhook AuditEntityType = "webhook" AuditEntityIntegration AuditEntityType = "integration" AuditEntityWarmupRoutingRule AuditEntityType = "warmup_routing_rule" AuditEntityFolder AuditEntityType = "folder" AuditEntityTag AuditEntityType = "tag" AuditEntityCategory AuditEntityType = "category" AuditEntitySegment AuditEntityType = "segment" AuditEntityForm AuditEntityType = "form" AuditEntitySubscription AuditEntityType = "subscription" AuditEntitySettings AuditEntityType = "settings" AuditEntitySuppression AuditEntityType = "suppression" // CRM entities AuditEntityCRMPipeline AuditEntityType = "crm_pipeline" AuditEntityCRMStage AuditEntityType = "crm_stage" AuditEntityCRMDeal AuditEntityType = "crm_deal" AuditEntityCRMTask AuditEntityType = "crm_task" AuditEntityCRMNote AuditEntityType = "crm_note" // Inbox AuditEntityUnibox AuditEntityType = "unibox" // Collaboration / automation surfaces AuditEntityTeam AuditEntityType = "team" AuditEntityAutomation AuditEntityType = "automation" AuditEntityLeadSyncSource AuditEntityType = "lead_sync_source" AuditEntityMeeting AuditEntityType = "meeting" // Workspace archives (export/import for moving between instances). AuditEntityOrgArchive AuditEntityType = "org_archive" AuditEntityRole AuditEntityType = "role" // Referral program. referral = the share code / attribution; referral_credit // = a reward or clawback on the referrer's earnings ledger. AuditEntityReferral AuditEntityType = "referral" AuditEntityReferralCredit AuditEntityType = "referral_credit" // AI credits. credit_purchase = a top-up pack was fulfilled; credit_grant = // the monthly plan allowance was reset/granted. Both change the org's // billing/credits view, so the spine refreshes teammates on either. AuditEntityCreditPurchase AuditEntityType = "credit_purchase" AuditEntityCreditGrant AuditEntityType = "credit_grant" // AI assistant session (per-user dashboard agent conversation). AuditEntityAISession AuditEntityType = "ai_session" // AI skill (org playbook) create/update/delete. AuditEntityAISkill AuditEntityType = "ai_skill" // Workspace "always allow" policy for one assistant tool, set or revoked. AuditEntityAIToolPolicy AuditEntityType = "ai_tool_policy" // Connected MCP server (external tools) connect/update/disconnect. AuditEntityMCPServer AuditEntityType = "mcp_server" // Advisor recommendation: applied, undone, snoozed, dismissed, or a // background evaluation that opened or resolved findings. Rides the audit // spine so every teammate's advisor strips and nav badges stay live. AuditEntityAdvisorFinding AuditEntityType = "advisor_finding" // Pool link: a self-hosted instance linked to this cloud (cloud side) or // this instance's link to the cloud (self-hosted side). Both ride the audit // spine so the settings page and mailbox lists refresh for every member. AuditEntityPoolLink AuditEntityType = "pool_link" AuditEntityCloudLink AuditEntityType = "cloud_link" // Community directory listing of one of the workspace's OAuth apps. AuditEntityAppListing AuditEntityType = "app_listing" // Operator moderation of an OAuth app, and a block on who may register them. AuditEntityOAuthApplication AuditEntityType = "oauth_application" AuditEntityOAuthDeveloperBlock AuditEntityType = "oauth_developer_block" // A member's authorization of an OAuth app, revoked by a workspace admin. AuditEntityOAuthAuthorization AuditEntityType = "oauth_authorization" // Inbox placement: a test or batch started or cancelled, and a campaign's // scheduled test set up, changed or removed. AuditEntityPlacementTest AuditEntityType = "placement_test" AuditEntityPlacementMonitor AuditEntityType = "placement_monitor" AuditEntityPlacementBatch AuditEntityType = "placement_batch" ) // AuditActor is the minimal identity of the member who performed an action, // resolved by joining the users table so the dashboard can render "who" // instead of a bare UUID. Nil when the acting user has since been deleted. type AuditActor struct { ID uuid.UUID `json:"id"` FirstName string `json:"first_name"` LastName string `json:"last_name"` Email string `json:"email"` } type AuditLog struct { ID uuid.UUID `json:"id"` OrgID uuid.UUID `json:"org_id"` UserID uuid.UUID `json:"user_id"` // actor id; kept for backwards-compatible JSON Actor *AuditActor `json:"actor,omitempty"` ActionDate time.Time `json:"action_date"` Action AuditAction `json:"action"` EntityType AuditEntityType `json:"entity_type"` EntityID *uuid.UUID `json:"entity_id,omitempty"` IPAddress string `json:"ip_address"` UserAgent string `json:"user_agent"` Changes map[string]string `json:"changes,omitempty"` Metadata map[string]string `json:"metadata,omitempty"` Timestamp time.Time `json:"timestamp"` } // AuditLogSearch filters an organization's audit trail. OrgID is required and // is always set server-side from the caller's session — never from a // client-supplied value — so one organization can never read another's trail. type AuditLogSearch struct { OrgID *uuid.UUID ActorID *uuid.UUID EntityType *AuditEntityType EntityID *uuid.UUID Action *AuditAction Since *time.Time Until *time.Time Limit int Cursor string } type AuditLogsResult struct { Data []AuditLog `json:"data"` Pagination CPagination `json:"pagination"` } // CreateAuditLog is a helper struct for creating audit logs. type CreateAuditLog struct { OrgID uuid.UUID UserID uuid.UUID // actor id Action AuditAction EntityType AuditEntityType EntityID *uuid.UUID IPAddress string UserAgent string Changes map[string]string Metadata map[string]string }