import { type ApplicationType } from '../application/index.js'; import { DeploymentTypeEnum, RegionEnum } from '../common/index.js'; import { RequestSource } from '../user/index.js'; export enum EventEntityType { APPLICATION = 'application', PAGE = 'page', WORKFLOW = 'workflow', SCHEDULED_JOB = 'scheduled_job', DATASOURCE = 'datasource', FOLDER = 'folder', USER = 'user', ORGANIZATION = 'organization', API = 'api', STEP = 'step', AGENT = 'agent', CONTROLLER = 'controller', WORKER = 'worker', SURVEY = 'survey', ACCOUNT = 'account', BILLING = 'billing', BUILDER_LICENSE = 'builder_license', OBSERVABILITY = 'observability', GROUP = 'group', ORGANIZATION_INVITES = 'organization_invites', PROFILE = 'profile', INTEGRATION = 'integration', COMMIT = 'commit', CUSTOM_COMPONENT = 'custom_component', BRANCH = 'branch', ACCESS_TOKEN = 'access_token', PERMISSION = 'permission', ROLE = 'role', APPLICATION_EDITOR = 'application_editor', COMPONENT = 'component', REPOSITORY = 'repository', AI = 'ai', /** App Databases logical DB (one per data tag / database_binding). */ APP_DATABASE = 'app_database' } // This is currently used for application profiles export enum ViewMode { EDITOR = 'editor', PREVIEW = 'preview', DEPLOYED = 'deployed' } export enum ExportViewMode { EXPORT_DEPLOYED = 'export-deployed', EXPORT_LATEST = 'export-latest', EXPORT_LIVE = 'export-live', EXPORT_COMMIT = 'export-commit', EXPORT_DRAFT = 'export-draft', // The live-edit working copy: the application_live_edit row's // directoryContentsHash. Unlike the commit-based views above, this points at // the latest uploaded tree even when no commit was created for it (e.g. // Clark's in-progress `ai:generate:interim` autosaves). A cold/recycled // dev-server pod uses this to restore the actual working copy instead of an // older snapshot. Only the dev-server directory-hash reload path reads it. EXPORT_LIVE_EDIT = 'export-live-edit' } export const CombinedViewMode = { ...ViewMode, ...ExportViewMode }; export type CombinedViewMode = ViewMode | ExportViewMode; export enum EventAction { CREATED = 'created', CLONED = 'cloned', DELETED = 'deleted', SHARED = 'shared', PERMISSION_REMOVED = 'permission_removed', DEPLOYED = 'deployed', UNDEPLOYED = 'undeployed', IMPORTED = 'imported', MIGRATED = 'migrated', EXECUTED = 'executed', EXPORTED = 'exported', VIEWED = 'viewed', STARTED = 'started', FINISHED = 'finished', ADDED = 'added', ASSIGNED = 'assigned', PAUSED = 'paused', RESUMED = 'resumed', UPDATED = 'updated', UNASSIGNED = 'unassigned', PATCHED = 'patched', METADATA_UPDATED = 'metadata_updated', SETTINGS_UPDATED = 'settings_updated', REGISTERED = 'registered', DEREGISTERED = 'deregistered', SUBMITTED = 'submitted', VERIFIED = 'verified', ACCESS_REQUESTED = 'access_requested', ACCESS_ACCEPTED = 'access_accepted', TRIAL_EXTENDED = 'trial_extended', PLAN_UPGRADED = 'plan_upgraded', PLAN_DOWNGRADED = 'plan_downgraded', MEMBER_ADDED = 'member_added', MEMBER_REMOVED = 'member_removed', SENT = 'sent', ACCEPTED = 'accepted', AGENT_TYPE_UPDATED = 'agent_type_updated', COMMITTED = 'committed', BRANCH_CREATED = 'branch_created', RESET = 'reset', PULLED = 'pulled', PUSHED = 'pushed', LOGGED_IN = 'logged_in', SESSION_STARTED = 'session_started', GRANTED = 'granted', DEACTIVATED = 'deactivated', REVOKED = 'revoked', PREVIEWED = 'previewed' } export interface UserEvent { userId?: string; userType?: string; email?: string; organizationId?: string; type: string; entityId?: string; entityType?: EventEntityType; entityName?: string; // properties is a field for event specific fields // eslint-disable-next-line @typescript-eslint/no-explicit-any properties?: Record; createdAt: Date; region?: RegionEnum; deploymentType?: DeploymentTypeEnum; deploymentName?: string; source?: RequestSource; } export interface EventEntity { id: string; name: string | undefined; /** * Product generation (1.0 / 2.0 / 3.0), stamped onto `* application` events. * * Populated only by `applicationEventEntity()`, which classifies from the * application row. No `ApplicationV2` or `ApplicationV2Dto` carries a field of * this name, so passing one of those directly leaves it unset rather than * supplying a value of unknown grain -- but note that is a naming convention, * not something the type system enforces: `newEvent` accepts any `EventEntity`, * so a future field with this name would be picked up structurally. * * Left undefined whenever the caller cannot classify the app (only an id in * hand, or a query that did not project the needed columns). An absent property * beats a guessed one -- a wrong generation is worse for billing than none. */ applicationType?: ApplicationType; } export enum EventSource { SUPERBLOCKS = 'SUPERBLOCKS', SCIM = 'SCIM', JIT = 'JIT', INVITE = 'INVITE' }