Documentation
¶
Overview ¶
Package models - hooks.go contains GORM lifecycle hooks for validation. These hooks replace PostgreSQL CHECK constraints and triggers to enable consistent validation across all supported databases.
Package models defines GORM models for the TMI database schema.
Package models defines GORM models for the TMI database schema. These models support both PostgreSQL and Oracle databases through GORM's dialect abstraction.
Package models defines GORM models for the TMI database schema. This file contains models for the Survey API feature.
Package models defines GORM models for the TMI database schema.
Package models defines GORM models for the TMI database schema. This file contains models for the Teams and Projects feature.
Index ¶
- Constants
- Variables
- func AllModels() []any
- type Addon
- type AddonInvocationQuota
- type AliasCounter
- type Asset
- type AuditEntry
- type CVSSArray
- type CVSSScore
- type ClientCredential
- type CollaborationSession
- type ContentFeedback
- type DBBool
- type DBBytes
- type DBText
- type DBVarchar
- type Diagram
- type Document
- type ExtractionJob
- type Group
- type GroupMember
- type JSONMap
- type JSONRaw
- type LinkedIdentity
- type Metadata
- type Note
- type NullableDBText
- func (NullableDBText) GormDBDataType(db *gorm.DB, _ *schema.Field) string
- func (t NullableDBText) MarshalJSON() ([]byte, error)
- func (t NullableDBText) Ptr() *string
- func (t *NullableDBText) Scan(value any) error
- func (t *NullableDBText) UnmarshalJSON(data []byte) error
- func (t NullableDBText) Value() (driver.Value, error)
- type NullableDBVarchar
- func (NullableDBVarchar) GormDBDataType(db *gorm.DB, field *schema.Field) string
- func (v NullableDBVarchar) MarshalJSON() ([]byte, error)
- func (v NullableDBVarchar) Ptr() *string
- func (v *NullableDBVarchar) Scan(value any) error
- func (v *NullableDBVarchar) UnmarshalJSON(data []byte) error
- func (v NullableDBVarchar) Value() (driver.Value, error)
- type NullableSSVC
- type OracleBooldeprecated
- type ProjectNoteRecord
- type ProjectRecord
- type ProjectRelationshipRecord
- type ProjectResponsiblePartyRecord
- type RefreshTokenRecord
- type Repository
- type SSVCScore
- type SessionParticipant
- type StringArray
- type SurveyAnswer
- type SurveyResponse
- type SurveyResponseAccess
- type SurveyTemplate
- type SurveyTemplateVersion
- type SystemAuditEntry
- type SystemSetting
- type TeamMemberRecord
- type TeamNoteRecord
- type TeamRecord
- type TeamRelationshipRecord
- type TeamResponsiblePartyRecord
- type Threat
- type ThreatModel
- type ThreatModelAccess
- type TimmyEmbedding
- type TimmyMessage
- type TimmySession
- type TimmyUsage
- type TriageNote
- type UsabilityFeedback
- type User
- type UserAPIQuota
- type UserContentToken
- type UserPreference
- type VersionSnapshot
- type WebhookQuota
- type WebhookSubscription
- type WebhookURLDenyList
Constants ¶
const ( ChangeTypeCreated = "created" ChangeTypeUpdated = "updated" ChangeTypePatched = "patched" ChangeTypeDeleted = "deleted" ChangeTypeRestored = "restored" ChangeTypeRolledBack = "rolled_back" )
Audit change type constants
const ( ObjectTypeThreatModel = "threat_model" ObjectTypeDiagram = "diagram" ObjectTypeThreat = "threat" ObjectTypeAsset = "asset" ObjectTypeDocument = "document" ObjectTypeNote = "note" ObjectTypeRepository = "repository" )
Audit object type constants
const ( SnapshotTypeCheckpoint = "checkpoint" SnapshotTypeDiff = "diff" )
Snapshot type constants
const ( ExtractionStatusQueued = "queued" ExtractionStatusExtracting = "extracting" ExtractionStatusChunkEmbedding = "chunk_embedding" ExtractionStatusCompleted = "completed" ExtractionStatusFailed = "failed" )
Extraction job status values. The monolith actively writes only StatusQueued (at publish time) and the terminal StatusCompleted / StatusFailed (when a result lands). The intermediate values exist for forward-compatibility and are not written in Plan 3.
const ( SystemSettingTypeString = "string" SystemSettingTypeInt = "int" SystemSettingTypeBool = "bool" SystemSettingTypeJSON = "json" // SystemSettingTypeFloat backs observability.sampling_rate, whose config // field is a float64. It was previously declared "string", which made // --export-config emit a quoted value that --import-config could not read // back into the field (#791). SystemSettingTypeFloat = "float" )
SystemSettingType constants for the Type field
const ( // SystemSettingOriginSeeded marks a row inserted by SeedDefaults with a // registry default value — no operator has ever set it. SystemSettingOriginSeeded = "seeded" // SystemSettingOriginExplicit marks a row an operator deliberately set, // via the admin API, SettingsService.Set, or dbtool --import-config. SystemSettingOriginExplicit = "explicit" )
SystemSettingOrigin constants for the Origin field
const CheckpointInterval = 10
CheckpointInterval defines how often a full checkpoint is stored (every Nth version)
Variables ¶
var ErrBuiltInGroupProtected = errors.New("built-in group is protected")
ErrBuiltInGroupProtected is returned by GORM hooks and repositories when an operation would modify or delete a built-in group (everyone, security-reviewers, administrators). Handlers use errors.Is(err, ErrBuiltInGroupProtected) to map these conditions to HTTP 403 responses.
var UseUppercaseTableNames = false
UseUppercaseTableNames controls whether table names should be uppercase. Set to true for Oracle databases where unquoted identifiers are folded to uppercase. This must be set before any GORM operations occur.
Functions ¶
Types ¶
type Addon ¶
type Addon struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
Name DBVarchar `gorm:"size:256;not null"`
WebhookID DBVarchar `gorm:"size:36;not null;index"`
Description NullableDBText `gorm:""`
Icon NullableDBVarchar `gorm:"size:60"`
Objects StringArray `gorm:""`
ThreatModelID NullableDBVarchar `gorm:"size:36;index"`
Parameters JSONRaw `gorm:""`
// Relationships
Webhook WebhookSubscription `gorm:"foreignKey:WebhookID"`
ThreatModel *ThreatModel `gorm:"foreignKey:ThreatModelID"`
}
Addon represents an addon configuration Note: Explicit column tags removed for Oracle compatibility
func (*Addon) BeforeCreate ¶
BeforeCreate generates a UUID if not set
type AddonInvocationQuota ¶
type AddonInvocationQuota struct {
OwnerInternalUUID DBVarchar `gorm:"primaryKey;not null;size:36"`
MaxActiveInvocations int `gorm:"default:3"`
MaxInvocationsPerHour int `gorm:"default:10"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
// Relationships
Owner User `gorm:"foreignKey:OwnerInternalUUID;references:InternalUUID"`
}
AddonInvocationQuota represents per-user addon invocation quotas Note: Explicit column tags removed for Oracle compatibility
func (AddonInvocationQuota) TableName ¶
func (AddonInvocationQuota) TableName() string
TableName specifies the table name for AddonInvocationQuota
type AliasCounter ¶
type AliasCounter struct {
ParentID DBVarchar `gorm:"primaryKey;not null;size:36"`
ObjectType DBVarchar `gorm:"primaryKey;not null;size:16"`
NextAlias int32 `gorm:"not null;default:1"`
}
AliasCounter holds the next-alias value for a given (parent_id, object_type) scope. ThreatModel global counter uses parent_id="__global__"; sub-object counters use the parent threat-model UUID. Allocation is done via SELECT ... FOR UPDATE inside the calling repository's transaction.
func (AliasCounter) TableName ¶
func (AliasCounter) TableName() string
TableName returns the dialect-aware table name.
type Asset ¶
type Asset struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
ThreatModelID DBVarchar `` /* 166-byte string literal not displayed */
Name DBVarchar `gorm:"size:256;not null;index:idx_assets_name"`
Description NullableDBText `gorm:""`
Type DBVarchar `gorm:"size:64;not null;index:idx_assets_type"`
Criticality NullableDBVarchar `gorm:"size:128"`
Classification StringArray `gorm:""`
Sensitivity NullableDBVarchar `gorm:"size:128"`
IncludeInReport DBBool `gorm:"default:1"`
TimmyEnabled DBBool `gorm:"default:1"`
Alias int32 `gorm:"not null;default:0;<-:create;uniqueIndex:uniq_assets_tm_alias,priority:2"` // Server-assigned per-(threat_model_id, type) alias
CreatedAt time.Time `gorm:"not null;autoCreateTime;index:idx_assets_created;index:idx_assets_tm_created,priority:2"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime;index:idx_assets_modified;index:idx_assets_tm_modified,priority:2"`
DeletedAt *time.Time `gorm:"index:idx_assets_deleted_at"`
// Version is incremented on every successful update (T14 / #385).
Version int `gorm:"not null;default:1"`
// Relationships
ThreatModel ThreatModel `gorm:"foreignKey:ThreatModelID"`
}
Asset represents an asset within a threat model Note: Explicit column tags removed for Oracle compatibility
func (*Asset) BeforeCreate ¶
BeforeCreate generates a UUID if not set and validates required fields. Validation is in BeforeCreate (not BeforeSave) because GORM map-based updates trigger BeforeSave on the empty model struct, causing false validation errors.
type AuditEntry ¶
type AuditEntry struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36;index:idx_audit_created_id,priority:2"`
ThreatModelID DBVarchar `gorm:"size:36;not null;index:idx_audit_tm;index:idx_audit_tm_created,priority:1"`
ObjectType DBVarchar `gorm:"size:50;not null;index:idx_audit_object,priority:1;index:idx_audit_object_version,priority:1"`
ObjectID DBVarchar `gorm:"size:36;not null;index:idx_audit_object,priority:2;index:idx_audit_object_version,priority:2"`
Version *int `gorm:"index:idx_audit_object_version,priority:3"` // nullable: NULL means version snapshot has been pruned
ChangeType DBVarchar `gorm:"size:20;not null;index:idx_audit_change_type"`
ActorEmail DBVarchar `gorm:"size:320;not null;index:idx_audit_actor,priority:1"`
ActorProvider DBVarchar `gorm:"size:100;not null"`
ActorProviderID DBVarchar `gorm:"size:500;not null"`
ActorDisplayName DBVarchar `gorm:"size:256;not null"`
ChangeSummary NullableDBText `gorm:""`
// Composite (created_at, id) index serves the unfiltered admin audit keyset
// scans and full-table export in both directions (#473). idx_audit_tm_created
// already covers the filtered-by-threat-model path.
CreatedAt time.Time `` /* 139-byte string literal not displayed */
}
AuditEntry represents an entry in the audit trail. The audit trail tracks who changed what and when for all entity mutations. Actor fields are denormalized (not FKs) so audit entries persist after user deletion. threat_model_id is not a FK so the "threat model deleted" entry persists after TM deletion.
func (*AuditEntry) BeforeCreate ¶
func (a *AuditEntry) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (AuditEntry) TableName ¶
func (AuditEntry) TableName() string
TableName specifies the table name for AuditEntry
type CVSSArray ¶
type CVSSArray []CVSSScore
CVSSArray is a custom type that stores CVSS score arrays as JSON This outputs JSON array format [{"vector":"...","score":9.8}] which works for both PostgreSQL JSONB columns and Oracle JSON columns
func (CVSSArray) GormDBDataType ¶
GormDBDataType implements the GormDBDataTypeInterface to return dialect-specific column types for cross-database compatibility
type ClientCredential ¶
type ClientCredential struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
OwnerUUID DBVarchar `gorm:"size:36;not null;index"`
ClientID DBVarchar `gorm:"size:1000;not null;uniqueIndex"`
ClientSecretHash DBText `gorm:"not null"`
Name DBVarchar `gorm:"size:256;not null"`
Description NullableDBText `gorm:""`
IsActive DBBool `gorm:"default:1"`
// DirectWrite lets this credential's service-account token pass the T18
// subject_authority=invoker gate and be authorized by the owner's normal
// roles (#856). Opt-in; never set on administrator-owned credentials.
DirectWrite DBBool `gorm:"default:0"`
// AddonID links a direct_write credential to the addon whose automation
// uses it, so events caused by its writes are not delivered back to that
// addon's own subscription (#883). Not a FK: deleting the addon must not
// invalidate the credential; a dangling link just stops suppressing.
AddonID NullableDBVarchar `gorm:"size:36"`
LastUsedAt *time.Time
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
ExpiresAt *time.Time
// Relationships
Owner User `gorm:"foreignKey:OwnerUUID;references:InternalUUID"`
}
ClientCredential represents OAuth 2.0 client credentials for machine-to-machine auth Note: Explicit column tags removed for Oracle compatibility
func (*ClientCredential) BeforeCreate ¶
func (c *ClientCredential) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (ClientCredential) TableName ¶
func (ClientCredential) TableName() string
TableName specifies the table name for ClientCredential
type CollaborationSession ¶
type CollaborationSession struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
ThreatModelID DBVarchar `gorm:"size:36;not null;index"`
DiagramID DBVarchar `gorm:"size:36;not null;index"`
WebsocketURL DBText `gorm:"not null"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
ExpiresAt *time.Time
// Relationships
ThreatModel ThreatModel `gorm:"foreignKey:ThreatModelID"`
Diagram Diagram `gorm:"foreignKey:DiagramID"`
Participants []SessionParticipant `gorm:"foreignKey:SessionID"`
}
CollaborationSession represents a real-time collaboration session Note: Explicit column tags removed for Oracle compatibility
func (*CollaborationSession) BeforeCreate ¶
func (c *CollaborationSession) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (*CollaborationSession) BeforeSave ¶
func (c *CollaborationSession) BeforeSave(tx *gorm.DB) error
BeforeSave validates CollaborationSession before create or update
func (CollaborationSession) TableName ¶
func (CollaborationSession) TableName() string
TableName specifies the table name for CollaborationSession
type ContentFeedback ¶
type ContentFeedback struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
ThreatModelID DBVarchar `gorm:"size:36;not null;index:idx_content_feedback_target,priority:1"`
TargetType DBVarchar `gorm:"size:24;not null;index:idx_content_feedback_target,priority:2"`
TargetID DBVarchar `gorm:"size:36;not null;index:idx_content_feedback_target,priority:3"`
TargetField NullableDBVarchar `gorm:"size:64"`
Sentiment DBVarchar `gorm:"size:8;not null;index:idx_content_feedback_sentiment"`
Verbatim NullableDBText `gorm:""`
FalsePositiveReason NullableDBVarchar `gorm:"size:32;index:idx_content_feedback_fp_reason"`
FalsePositiveSubreason NullableDBVarchar `gorm:"size:40"`
ClientID DBVarchar `gorm:"size:32;not null"`
ClientVersion NullableDBVarchar `gorm:"size:32"`
Screenshot NullableDBText `gorm:""`
// CreatedBy is the internal UUID of the authenticated user who submitted
// this feedback (#710: see the identical comment on
// UsabilityFeedback.CreatedBy above -- renamed from CreatedByUUID, and the
// explicit column:created_by tag dropped, so the NamingStrategy-derived
// DBName equals the real column on both dialects).
CreatedBy DBVarchar `gorm:"size:36;not null"`
// Note: autoCreateTime tag removed for Oracle compatibility (#380). The
// repository sets CreatedAt explicitly in Create / CreateWithTargetCheck
// before INSERT, matching the Threat model pattern.
CreatedAt time.Time `gorm:"not null;index:idx_content_feedback_created_at"`
// Relationships. ContentFeedback rows are cleaned up explicitly by
// deleteThreatModelChildren (issue #378), matching every other TM child.
// The CreatedByUser FK is suppressed (constraint:-) so a user with
// outstanding feedback can still be deleted; application-layer integrity
// is sufficient. Named CreatedByUser (not CreatedBy) to avoid colliding
// with the scalar CreatedBy field above.
ThreatModel ThreatModel `gorm:"foreignKey:ThreatModelID"`
CreatedByUser User `gorm:"foreignKey:CreatedBy;references:InternalUUID;constraint:-"`
}
ContentFeedback represents user feedback on AI/automation-generated artifacts (notes, diagrams, threats, threat-classification fields) within a threat model. Issued via POST /threat_models/{id}/feedback by reader+ on the parent TM.
func (*ContentFeedback) BeforeCreate ¶
func (c *ContentFeedback) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set.
func (ContentFeedback) TableName ¶
func (ContentFeedback) TableName() string
TableName returns the dialect-aware table name.
type DBBool ¶
type DBBool bool
DBBool is a cross-database boolean type that handles different database representations of booleans. Oracle uses NUMBER(1), MySQL uses TINYINT(1), SQL Server uses BIT, while PostgreSQL and SQLite have native boolean support. This type implements sql.Scanner and driver.Valuer to handle the conversion for all supported databases.
func (DBBool) GormDBDataType ¶
GormDBDataType implements the GormDBDataTypeInterface to return dialect-specific column types for cross-database compatibility
func (*DBBool) Scan ¶
Scan implements the sql.Scanner interface for DBBool. It handles: - bool (PostgreSQL native boolean) - int64/int/int32 (numeric representation) - godror.Number (Oracle's numeric type, implements fmt.Stringer) - nil (NULL values)
type DBBytes ¶
type DBBytes []byte
DBBytes is a cross-database binary data type. Uses BYTEA on PostgreSQL, BLOB on Oracle, LONGBLOB on MySQL, VARBINARY(MAX) on SQL Server, and BLOB on SQLite.
func (DBBytes) GormDBDataType ¶
GormDBDataType implements the GormDBDataTypeInterface to return dialect-specific column types for cross-database compatibility
type DBText ¶
type DBText string
DBText is a cross-database large text type. Uses TEXT on PostgreSQL, CLOB on Oracle, LONGTEXT on MySQL, NVARCHAR(MAX) on SQL Server, and TEXT on SQLite.
func (DBText) GormDBDataType ¶
GormDBDataType implements the GormDBDataTypeInterface to return dialect-specific column types for cross-database compatibility
type DBVarchar ¶
type DBVarchar string
DBVarchar is a cross-database length-bounded text type with CHAR semantics. Uses varchar(N) on PostgreSQL (already char-counted), varchar2(N CHAR) on Oracle (avoiding default BYTE semantics under AL32UTF8), varchar(N) on MySQL (utf8mb4 is char-counted), nvarchar(N) on SQL Server, varchar(N) on SQLite. The length N is carried by the GORM `size:` tag, not by the Go type.
func (DBVarchar) GormDBDataType ¶
GormDBDataType implements the GormDBDataTypeInterface to return dialect-specific column types for cross-database compatibility The column size is read from field.Size (populated from the `size:` GORM tag). A field.Size of 0 falls back to 255 as a safety default; every usage site should set size: explicitly.
type Diagram ¶
type Diagram struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
ThreatModelID DBVarchar `` /* 129-byte string literal not displayed */
Name DBVarchar `gorm:"size:256;not null"`
Description NullableDBText `gorm:""`
Type NullableDBVarchar `gorm:"size:64;index:idx_diagrams_type;index:idx_diagrams_tm_type,priority:2"`
Content NullableDBText `gorm:""`
Cells JSONRaw `gorm:""`
ColorPalette JSONRaw `gorm:""`
SVGImage NullableDBText `gorm:""`
ImageUpdateVector *int64
UpdateVector int64 `gorm:"default:0"`
IncludeInReport DBBool `gorm:"default:1"`
TimmyEnabled DBBool `gorm:"default:1"`
AutoGenerated DBBool `gorm:"default:0;<-:create" json:"auto_generated"`
Alias int32 `gorm:"not null;default:0;<-:create;uniqueIndex:uniq_diagrams_tm_alias,priority:2"` // Server-assigned per-(threat_model_id, type) alias
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
DeletedAt *time.Time `gorm:"index:idx_diagrams_deleted_at"`
// Version is incremented on every successful update (T14 / #385).
Version int `gorm:"not null;default:1"`
// Relationships
ThreatModel ThreatModel `gorm:"foreignKey:ThreatModelID"`
}
Diagram represents a diagram within a threat model Note: Explicit column tags removed for Oracle compatibility
func (*Diagram) BeforeCreate ¶
BeforeCreate generates a UUID if not set
func (*Diagram) BeforeUpdate ¶
BeforeUpdate validates Diagram before update
type Document ¶
type Document struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
ThreatModelID DBVarchar `` /* 163-byte string literal not displayed */
Name DBVarchar `gorm:"size:256;not null;index:idx_docs_name"`
URI DBText `gorm:"not null"`
Description NullableDBText `gorm:""`
IncludeInReport DBBool `gorm:"default:1"`
TimmyEnabled DBBool `gorm:"default:1"`
AccessStatus NullableDBVarchar `gorm:"size:32;default:unknown"`
ContentSource NullableDBVarchar `gorm:"size:64"`
// Picker registration (all three set together or all null — enforced by application code).
PickerProviderID NullableDBVarchar `gorm:"size:64;index:idx_docs_picker,priority:1"`
PickerFileID NullableDBVarchar `gorm:"size:255;index:idx_docs_picker,priority:2"`
PickerMimeType NullableDBVarchar `gorm:"size:128"`
// Access diagnostics (populated when access_status != accessible/unknown).
AccessReasonCode NullableDBVarchar `gorm:"size:64"`
AccessReasonDetail NullableDBText
AccessStatusUpdatedAt *time.Time
Alias int32 `gorm:"not null;default:0;<-:create;uniqueIndex:uniq_documents_tm_alias,priority:2"` // Server-assigned per-(threat_model_id, type) alias
CreatedAt time.Time `gorm:"not null;autoCreateTime;index:idx_docs_created;index:idx_docs_tm_created,priority:2"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime;index:idx_docs_modified;index:idx_docs_tm_modified,priority:2"`
DeletedAt *time.Time `gorm:"index:idx_docs_deleted_at"`
// Version is incremented on every successful update (T14 / #385).
Version int `gorm:"not null;default:1"`
// Relationships
ThreatModel ThreatModel `gorm:"foreignKey:ThreatModelID"`
}
Document represents a document attached to a threat model Note: Explicit column tags removed for Oracle compatibility
func (*Document) BeforeCreate ¶
BeforeCreate generates a UUID if not set
func (*Document) BeforeSave ¶
BeforeSave validates Document before create or update
type ExtractionJob ¶
type ExtractionJob struct {
JobID DBVarchar `gorm:"primaryKey;not null;size:36"`
// DocumentRef is the document being extracted. NOT NULL with no DB-level FK.
// On the bare-upsert-insert path (a terminal result arriving with no prior
// queued row) the real ref is unknown and the non-empty sentinel
// "__unknown__" (unknownDocumentRef in api/extraction_job_store.go) is
// written instead — an empty string is indistinguishable from NULL on
// Oracle and would violate NOT NULL (ORA-01400). Any query that filters on
// document_ref must exclude the sentinel.
DocumentRef DBVarchar `gorm:"size:36;not null;index:idx_extraction_jobs_doc"`
Status DBVarchar `gorm:"size:32;not null;default:queued"`
ReasonCode NullableDBVarchar `gorm:"size:64"`
Stage NullableDBVarchar `gorm:"size:32"`
Attempts int32 `gorm:"not null;default:0"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
UpdatedAt time.Time `gorm:"not null;autoUpdateTime"`
CompletedAt *time.Time `gorm:""`
}
ExtractionJob is the monolith's internal record of one async extraction job. The result-consumer is the sole writer of terminal states; the publish-side callers only insert the initial queued row (idempotently). Components (workers) never touch this table. document_ref is indexed but has no database-level foreign key, so a document deleted mid-job does not cause a constraint violation; the result-consumer tolerates the missing row.
func (*ExtractionJob) BeforeCreate ¶
func (j *ExtractionJob) BeforeCreate(_ *gorm.DB) error
BeforeCreate is a gorm hook required to satisfy the gorm.DB interface. JobID is always supplied by the caller (it is the envelope job_id) so it is never generated here.
func (ExtractionJob) TableName ¶
func (ExtractionJob) TableName() string
TableName returns the prefixed table name.
type Group ¶
type Group struct {
InternalUUID DBVarchar `gorm:"primaryKey;not null;size:36"`
Provider DBVarchar `gorm:"size:100;not null;index:idx_groups_provider;uniqueIndex:uniq_groups_provider_group_name,priority:1"`
GroupName DBVarchar `gorm:"size:500;not null;index:idx_groups_group_name;uniqueIndex:uniq_groups_provider_group_name,priority:2"`
Name NullableDBVarchar `gorm:"size:256"`
Description NullableDBText `gorm:""`
FirstUsed time.Time `gorm:"not null;autoCreateTime"`
LastUsed time.Time `gorm:"not null;autoUpdateTime;index:idx_groups_last_used"`
UsageCount int `gorm:"default:1"`
}
Group represents an identity provider group Note: Explicit column tags removed for Oracle compatibility
func (*Group) BeforeCreate ¶
BeforeCreate generates a UUID if not set
func (*Group) BeforeDelete ¶
BeforeDelete prevents deletion of built-in groups (everyone, security-reviewers, administrators)
func (*Group) BeforeUpdate ¶
BeforeUpdate prevents renaming or changing the description of built-in groups
type GroupMember ¶
type GroupMember struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
GroupInternalUUID DBVarchar `gorm:"size:36;not null;index;uniqueIndex:idx_gm_group_user_type,priority:1"`
UserInternalUUID NullableDBVarchar `gorm:"size:36;index;uniqueIndex:idx_gm_group_user_type,priority:2"`
MemberGroupInternalUUID NullableDBVarchar `gorm:"size:36;index"`
SubjectType DBVarchar `gorm:"size:10;not null;default:user;uniqueIndex:idx_gm_group_user_type,priority:3"`
AddedByInternalUUID NullableDBVarchar `gorm:"size:36"`
AddedAt time.Time `gorm:"not null;autoCreateTime"`
Notes NullableDBText `gorm:""`
// Relationships
Group Group `gorm:"foreignKey:GroupInternalUUID;references:InternalUUID"`
User *User `gorm:"foreignKey:UserInternalUUID;references:InternalUUID"`
MemberGroup *Group `gorm:"foreignKey:MemberGroupInternalUUID;references:InternalUUID"`
AddedBy *User `gorm:"foreignKey:AddedByInternalUUID;references:InternalUUID;constraint:-"`
}
GroupMember represents a user's or group's membership in a group. Supports one level of group-in-group nesting: an external IdP group can be a member of a built-in group (e.g., Administrators), enabling all members of the external group to inherit the built-in group's privileges. Note: Explicit column tags removed for Oracle compatibility
func (*GroupMember) BeforeCreate ¶
func (g *GroupMember) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (*GroupMember) BeforeSave ¶
func (gm *GroupMember) BeforeSave(tx *gorm.DB) error
BeforeSave validates GroupMember and prevents adding to "everyone" group
func (GroupMember) TableName ¶
func (GroupMember) TableName() string
TableName specifies the table name for GroupMember
type JSONMap ¶
JSONMap is a custom type that stores JSON objects This works across both PostgreSQL JSONB and Oracle JSON
func (JSONMap) GormDBDataType ¶
GormDBDataType implements the GormDBDataTypeInterface to return dialect-specific column types for cross-database compatibility
type JSONRaw ¶
type JSONRaw json.RawMessage
JSONRaw is a custom type for storing raw JSON (like cells in diagrams)
func (JSONRaw) GormDBDataType ¶
GormDBDataType implements the GormDBDataTypeInterface to return dialect-specific column types for cross-database compatibility
func (JSONRaw) MarshalJSON ¶
MarshalJSON implements json.Marshaler
func (*JSONRaw) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler
func (JSONRaw) Value ¶
Value implements the driver.Valuer interface for database writes Returns string (not []byte) for Oracle CLOB compatibility. A zero-length non-nil slice is normalized to nil so that behavior is consistent across PostgreSQL JSONB (which would reject "" as 22P02) and Oracle CLOB (which silently coerces "" to NULL).
type LinkedIdentity ¶
type LinkedIdentity struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
UserInternalUUID DBVarchar `gorm:"size:36;not null;index:idx_linked_user"`
Provider DBVarchar `gorm:"size:100;not null;uniqueIndex:uniq_linked_provider_sub,priority:1"`
ProviderUserID DBVarchar `gorm:"size:500;not null;uniqueIndex:uniq_linked_provider_sub,priority:2"`
Email DBVarchar `gorm:"size:320"`
Name DBVarchar `gorm:"size:256"`
LinkedAt time.Time `gorm:"not null;autoCreateTime"`
LastUsedAt *time.Time
}
LinkedIdentity records an external identity provider credential linked to a TMI user account. Each (provider, provider_user_id) pair is globally unique — a provider sub cannot be linked to more than one TMI user.
Referential integrity to the users table is enforced by application code; no DB-level FK is declared so that users can be deleted without a cascade constraint ordering concern.
func (*LinkedIdentity) BeforeCreate ¶
func (l *LinkedIdentity) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if ID is empty.
func (LinkedIdentity) TableName ¶
func (LinkedIdentity) TableName() string
TableName returns the dialect-aware table name.
type Metadata ¶
type Metadata struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
EntityType DBVarchar `gorm:"size:50;not null;index:idx_metadata_entity_type_id,priority:1;index:idx_metadata_unique,priority:1,unique"`
EntityID DBVarchar `` /* 174-byte string literal not displayed */
Key DBVarchar `gorm:"size:256;not null;index:idx_metadata_key;index:idx_metadata_unique,priority:3;index:idx_metadata_key_value,priority:2"`
Value DBVarchar `gorm:"size:1024;not null;index:idx_metadata_key_value,priority:3"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
}
Metadata represents key-value metadata for entities Note: Explicit column tags removed for Oracle compatibility Note: no index leads with created_at or modified_at (#784): nothing reads metadata by timestamp, and every same-batch row shares one timestamp, so such indexes only concentrated writes on one leaf block (#783).
func (*Metadata) BeforeCreate ¶
BeforeCreate generates a UUID if not set
func (*Metadata) BeforeSave ¶
BeforeSave validates Metadata before create or update
type Note ¶
type Note struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
ThreatModelID DBVarchar `` /* 162-byte string literal not displayed */
Name DBVarchar `gorm:"size:256;not null;index:idx_notes_name"`
Content DBText `gorm:"not null"`
Description NullableDBText `gorm:""`
IncludeInReport DBBool `gorm:"default:1"`
TimmyEnabled DBBool `gorm:"default:1"`
AutoGenerated DBBool `gorm:"default:0;<-:create" json:"auto_generated"`
Alias int32 `gorm:"not null;default:0;<-:create;uniqueIndex:uniq_notes_tm_alias,priority:2"` // Server-assigned per-(threat_model_id, type) alias
CreatedAt time.Time `gorm:"not null;autoCreateTime;index:idx_notes_created;index:idx_notes_tm_created,priority:2"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime;index:idx_notes_modified;index:idx_notes_tm_modified,priority:2"`
DeletedAt *time.Time `gorm:"index:idx_notes_deleted_at"`
// Relationships
ThreatModel ThreatModel `gorm:"foreignKey:ThreatModelID"`
}
Note represents a note attached to a threat model Note: Explicit column tags removed for Oracle compatibility
func (*Note) BeforeCreate ¶
BeforeCreate generates a UUID if not set and validates required fields. Note: Required field validation is intentionally in BeforeCreate (not BeforeSave) because the Update path uses map-based GORM Updates() on an empty model struct. BeforeSave would validate the empty struct's zero-value fields, causing false "cannot be empty" errors. Update-time validation is handled by the API layer.
type NullableDBText ¶
NullableDBText is a nullable cross-database large text type. Wraps a string with a Valid flag for NULL handling. Uses TEXT on PostgreSQL, CLOB on Oracle, LONGTEXT on MySQL, NVARCHAR(MAX) on SQL Server, and TEXT on SQLite.
func NewNullableDBText ¶
func NewNullableDBText(s *string) NullableDBText
NewNullableDBText creates a NullableDBText from a string pointer
func (NullableDBText) GormDBDataType ¶
GormDBDataType implements the GormDBDataTypeInterface to return dialect-specific column types for cross-database compatibility
func (NullableDBText) MarshalJSON ¶
func (t NullableDBText) MarshalJSON() ([]byte, error)
MarshalJSON implements the json.Marshaler interface. A valid NullableDBText marshals as a JSON string; an invalid one marshals as null.
func (NullableDBText) Ptr ¶
func (t NullableDBText) Ptr() *string
Ptr returns a pointer to the string, or nil if not valid
func (*NullableDBText) Scan ¶
func (t *NullableDBText) Scan(value any) error
Scan implements the sql.Scanner interface for database reads
func (*NullableDBText) UnmarshalJSON ¶
func (t *NullableDBText) UnmarshalJSON(data []byte) error
UnmarshalJSON implements the json.Unmarshaler interface. A JSON null sets Valid to false; a JSON string sets Valid to true and String to the value.
func (NullableDBText) Value ¶
func (t NullableDBText) Value() (driver.Value, error)
Value implements the driver.Valuer interface for database writes Empty normalizes to NULL for cross-engine symmetry: Oracle stores the empty string as NULL regardless, so PG must not persist an empty string that Oracle-parity reads (#698) then report as NULL-like (#700). Mirrors JSONRaw.Value.
type NullableDBVarchar ¶
NullableDBVarchar is a nullable cross-database length-bounded text type with CHAR semantics. Wraps a string with a Valid flag for NULL handling. Maps to the same column types as DBVarchar per dialect.
func NewNullableDBVarchar ¶
func NewNullableDBVarchar(s *string) NullableDBVarchar
NewNullableDBVarchar creates a NullableDBVarchar from a string pointer
func (NullableDBVarchar) GormDBDataType ¶
GormDBDataType implements the GormDBDataTypeInterface to return dialect-specific column types for cross-database compatibility
func (NullableDBVarchar) MarshalJSON ¶
func (v NullableDBVarchar) MarshalJSON() ([]byte, error)
MarshalJSON implements the json.Marshaler interface. A valid NullableDBVarchar marshals as a JSON string; an invalid one marshals as null.
func (NullableDBVarchar) Ptr ¶
func (v NullableDBVarchar) Ptr() *string
Ptr returns a pointer to the string, or nil if not valid
func (*NullableDBVarchar) Scan ¶
func (v *NullableDBVarchar) Scan(value any) error
Scan implements the sql.Scanner interface for database reads
func (*NullableDBVarchar) UnmarshalJSON ¶
func (v *NullableDBVarchar) UnmarshalJSON(data []byte) error
UnmarshalJSON implements the json.Unmarshaler interface. A JSON null sets Valid to false; a JSON string sets Valid to true and String to the value.
func (NullableDBVarchar) Value ¶
func (v NullableDBVarchar) Value() (driver.Value, error)
Value implements the driver.Valuer interface for database writes Empty normalizes to NULL for cross-engine symmetry: Oracle stores the empty string as NULL regardless, so PG must not persist an empty string that Oracle-parity reads (#698) then report as NULL-like (#700). Mirrors JSONRaw.Value.
type NullableSSVC ¶
NullableSSVC is a custom type that stores an optional SSVC score as JSON
func (NullableSSVC) GormDBDataType ¶
GormDBDataType implements the GormDBDataTypeInterface
func (NullableSSVC) MarshalJSON ¶
func (s NullableSSVC) MarshalJSON() ([]byte, error)
MarshalJSON implements the json.Marshaler interface. A valid NullableSSVC marshals as the inner SSVCScore JSON object; an invalid one marshals as null. This mirrors the Value/Scan database representation so JSON round-trips (e.g. through a Redis cache) match the on-disk encoding.
func (*NullableSSVC) Scan ¶
func (s *NullableSSVC) Scan(value any) error
Scan implements the sql.Scanner interface for database reads
func (*NullableSSVC) UnmarshalJSON ¶
func (s *NullableSSVC) UnmarshalJSON(data []byte) error
UnmarshalJSON implements the json.Unmarshaler interface. A JSON null sets Valid to false; any other value is unmarshaled into the inner SSVCScore and sets Valid to true.
type OracleBool
deprecated
type OracleBool = DBBool
OracleBool is an alias for DBBool for backward compatibility.
Deprecated: Use DBBool instead.
type ProjectNoteRecord ¶
type ProjectNoteRecord struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
ProjectID DBVarchar `gorm:"size:36;not null;index:idx_pnote_project;index:idx_pnote_project_name,priority:1"`
Name DBVarchar `gorm:"size:256;not null;index:idx_pnote_name;index:idx_pnote_project_name,priority:2"`
Content DBText `gorm:"not null"`
Description NullableDBText `gorm:""`
TimmyEnabled DBBool `gorm:"default:1"`
Sharable DBBool `gorm:"not null"`
CreatedAt time.Time `gorm:"not null;autoCreateTime;index:idx_pnote_created"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
// Relationships
Project ProjectRecord `gorm:"foreignKey:ProjectID;constraint:OnDelete:CASCADE"`
}
ProjectNoteRecord represents a note attached to a project
func (*ProjectNoteRecord) BeforeCreate ¶
func (n *ProjectNoteRecord) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set and validates required fields.
func (ProjectNoteRecord) TableName ¶
func (ProjectNoteRecord) TableName() string
TableName specifies the table name for ProjectNoteRecord
type ProjectRecord ¶
type ProjectRecord struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
Name DBVarchar `gorm:"size:256;not null;index:idx_proj_name"`
Description NullableDBText `gorm:""`
TeamID DBVarchar `gorm:"size:36;not null;index:idx_proj_team"`
URI NullableDBText `gorm:""`
Status NullableDBVarchar `gorm:"size:128;index:idx_proj_status"`
CreatedByInternalUUID DBVarchar `gorm:"size:36;not null"`
ModifiedByInternalUUID NullableDBVarchar `gorm:"size:36"`
ReviewedByInternalUUID NullableDBVarchar `gorm:"size:36"`
ReviewedAt *time.Time `gorm:"index:idx_proj_reviewed_at"`
CreatedAt time.Time `gorm:"not null;autoCreateTime;index:idx_proj_created_at"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
// Version is incremented on every successful update (T14 / #385).
Version int `gorm:"not null;default:1"`
// Relationships
Team TeamRecord `gorm:"foreignKey:TeamID"`
CreatedBy User `gorm:"foreignKey:CreatedByInternalUUID;references:InternalUUID;constraint:-"`
ModifiedBy *User `gorm:"foreignKey:ModifiedByInternalUUID;references:InternalUUID;constraint:-"`
ReviewedBy *User `gorm:"foreignKey:ReviewedByInternalUUID;references:InternalUUID;constraint:-"`
}
ProjectRecord represents a project in the system
func (*ProjectRecord) BeforeCreate ¶
func (p *ProjectRecord) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (ProjectRecord) TableName ¶
func (ProjectRecord) TableName() string
TableName specifies the table name for ProjectRecord
type ProjectRelationshipRecord ¶
type ProjectRelationshipRecord struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
ProjectID DBVarchar `gorm:"size:36;not null;index:idx_prel_project;uniqueIndex:idx_prel_project_related,priority:1"`
RelatedProjectID DBVarchar `gorm:"size:36;not null;index:idx_prel_related;uniqueIndex:idx_prel_project_related,priority:2"`
Relationship DBVarchar `gorm:"size:64;not null"`
CustomRelationship NullableDBVarchar `gorm:"size:128"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
// Relationships
Project ProjectRecord `gorm:"foreignKey:ProjectID"`
RelatedProject ProjectRecord `gorm:"foreignKey:RelatedProjectID"`
}
ProjectRelationshipRecord represents a relationship between two projects
func (*ProjectRelationshipRecord) BeforeCreate ¶
func (p *ProjectRelationshipRecord) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (ProjectRelationshipRecord) TableName ¶
func (ProjectRelationshipRecord) TableName() string
TableName specifies the table name for ProjectRelationshipRecord
type ProjectResponsiblePartyRecord ¶
type ProjectResponsiblePartyRecord struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
ProjectID DBVarchar `gorm:"size:36;not null;index:idx_prp_project;uniqueIndex:idx_prp_project_user,priority:1"`
UserInternalUUID DBVarchar `gorm:"size:36;not null;index:idx_prp_user;uniqueIndex:idx_prp_project_user,priority:2"`
Role DBVarchar `gorm:"size:64;not null"`
CustomRole NullableDBVarchar `gorm:"size:128"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
// Relationships
Project ProjectRecord `gorm:"foreignKey:ProjectID"`
User User `gorm:"foreignKey:UserInternalUUID;references:InternalUUID"`
}
ProjectResponsiblePartyRecord represents a responsible party for a project
func (*ProjectResponsiblePartyRecord) BeforeCreate ¶
func (p *ProjectResponsiblePartyRecord) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (ProjectResponsiblePartyRecord) TableName ¶
func (ProjectResponsiblePartyRecord) TableName() string
TableName specifies the table name for ProjectResponsiblePartyRecord
type RefreshTokenRecord ¶
type RefreshTokenRecord struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
UserInternalUUID DBVarchar `gorm:"size:36;not null;index"`
Token DBVarchar `gorm:"size:4000;not null;uniqueIndex"` // DBVarchar size:4000 for Oracle compatibility (CLOB cannot have unique index)
ExpiresAt time.Time `gorm:"not null"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
// Relationships
User User `gorm:"foreignKey:UserInternalUUID;references:InternalUUID"`
}
RefreshTokenRecord represents a refresh token for a user Note: Explicit column tags removed for Oracle compatibility
func (*RefreshTokenRecord) BeforeCreate ¶
func (r *RefreshTokenRecord) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (RefreshTokenRecord) TableName ¶
func (RefreshTokenRecord) TableName() string
TableName specifies the table name for RefreshTokenRecord
type Repository ¶
type Repository struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
ThreatModelID DBVarchar `` /* 169-byte string literal not displayed */
Name NullableDBVarchar `gorm:"size:256;index:idx_repos_name"`
URI DBText `gorm:"not null"`
Description NullableDBText `gorm:""`
Type NullableDBVarchar `gorm:"size:64;index:idx_repos_type"`
Parameters JSONMap `gorm:""`
IncludeInReport DBBool `gorm:"default:1"`
TimmyEnabled DBBool `gorm:"default:1"`
Alias int32 `gorm:"not null;default:0;<-:create;uniqueIndex:uniq_repositories_tm_alias,priority:2"` // Server-assigned per-(threat_model_id, type) alias
CreatedAt time.Time `gorm:"not null;autoCreateTime;index:idx_repos_created;index:idx_repos_tm_created,priority:2"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime;index:idx_repos_modified;index:idx_repos_tm_modified,priority:2"`
DeletedAt *time.Time `gorm:"index:idx_repos_deleted_at"`
// Relationships
ThreatModel ThreatModel `gorm:"foreignKey:ThreatModelID"`
}
Repository represents a repository attached to a threat model Note: Explicit column tags removed for Oracle compatibility
func (*Repository) BeforeCreate ¶
func (r *Repository) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (*Repository) BeforeSave ¶
func (r *Repository) BeforeSave(tx *gorm.DB) error
BeforeSave validates Repository before create or update
func (Repository) TableName ¶
func (Repository) TableName() string
TableName specifies the table name for Repository
type SSVCScore ¶
type SSVCScore struct {
Vector string `json:"vector"`
Decision string `json:"decision"`
Methodology string `json:"methodology"`
}
SSVCScore represents an SSVC (Stakeholder-Specific Vulnerability Categorization) assessment result
type SessionParticipant ¶
type SessionParticipant struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
SessionID DBVarchar `gorm:"size:36;not null;index"`
UserInternalUUID DBVarchar `gorm:"size:36;not null;index"`
JoinedAt time.Time `gorm:"not null;autoCreateTime"`
LeftAt *time.Time
// Relationships
Session CollaborationSession `gorm:"foreignKey:SessionID"`
User User `gorm:"foreignKey:UserInternalUUID;references:InternalUUID"`
}
SessionParticipant represents a participant in a collaboration session Note: Explicit column tags removed for Oracle compatibility
func (*SessionParticipant) BeforeCreate ¶
func (s *SessionParticipant) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (SessionParticipant) TableName ¶
func (SessionParticipant) TableName() string
TableName specifies the table name for SessionParticipant
type StringArray ¶
type StringArray []string
StringArray is a custom type that stores string arrays as JSON This outputs JSON array format ["val1","val2"] which works for both PostgreSQL JSONB columns and Oracle JSON columns
func (StringArray) GormDBDataType ¶
GormDBDataType implements the GormDBDataTypeInterface to return dialect-specific column types for cross-database compatibility
func (*StringArray) Scan ¶
func (a *StringArray) Scan(value any) error
Scan implements the sql.Scanner interface for database reads
type SurveyAnswer ¶
type SurveyAnswer struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
ResponseID DBVarchar `gorm:"size:36;not null;index:idx_sa_response_id;index:idx_sa_response_mapping"`
QuestionName DBVarchar `gorm:"size:256;not null"`
QuestionType DBVarchar `gorm:"size:64;not null"`
QuestionTitle NullableDBText `gorm:""`
MapsToTmField NullableDBVarchar `gorm:"size:128;index:idx_sa_response_mapping"`
AnswerValue JSONRaw `gorm:""`
ResponseStatus DBVarchar `gorm:"size:30;not null"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
// Relationships
SurveyResponse SurveyResponse `gorm:"foreignKey:ResponseID"`
}
SurveyAnswer represents an extracted answer from a survey response. Rows are fully replaced on every response save for consistency.
func (*SurveyAnswer) BeforeCreate ¶
func (s *SurveyAnswer) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (SurveyAnswer) TableName ¶
func (SurveyAnswer) TableName() string
TableName specifies the table name for SurveyAnswer
type SurveyResponse ¶
type SurveyResponse struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
TemplateID DBVarchar `gorm:"size:36;not null;index:idx_sr_template;index:idx_sr_template_status,priority:1"`
TemplateVersion DBVarchar `gorm:"size:64;not null"` // Captured at creation, immutable
Status DBVarchar `gorm:"size:30;not null;default:draft;index:idx_sr_status;index:idx_sr_template_status,priority:2"`
IsConfidential DBBool `gorm:"default:0"` // If true, Security Reviewers group not auto-added
Answers JSONRaw `gorm:""` // Question answers keyed by question name
UIState JSONRaw `gorm:""` // Client-managed UI state for draft resumption
SurveyJSON JSONRaw `gorm:""` // Snapshot of template survey_json at creation
LinkedThreatModelID NullableDBVarchar `gorm:"size:36;index:idx_sr_linked_tm"`
CreatedThreatModelID NullableDBVarchar `gorm:"size:36;index:idx_sr_created_tm"`
RevisionNotes NullableDBText `gorm:""`
OwnerInternalUUID NullableDBVarchar `gorm:"size:36;index:idx_sr_owner"`
CreatedAt time.Time `gorm:"not null;autoCreateTime;index:idx_sr_created_at"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
SubmittedAt *time.Time `gorm:"index:idx_sr_submitted_at"`
ReviewedAt *time.Time
ReviewedByInternalUUID NullableDBVarchar `gorm:"size:36"`
ProjectID NullableDBVarchar `gorm:"size:36;index:idx_sr_project"`
// Version is incremented on every successful update (T14 / #385).
Version int `gorm:"not null;default:1"`
// Relationships
Template SurveyTemplate `gorm:"foreignKey:TemplateID"`
Owner *User `gorm:"foreignKey:OwnerInternalUUID;references:InternalUUID"`
ReviewedBy *User `gorm:"foreignKey:ReviewedByInternalUUID;references:InternalUUID;constraint:-"`
LinkedThreatModel *ThreatModel `gorm:"foreignKey:LinkedThreatModelID"`
CreatedThreatModel *ThreatModel `gorm:"foreignKey:CreatedThreatModelID"`
Project *ProjectRecord `gorm:"foreignKey:ProjectID"`
}
SurveyResponse represents a user's response to a survey template
func (*SurveyResponse) BeforeCreate ¶
func (s *SurveyResponse) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (SurveyResponse) TableName ¶
func (SurveyResponse) TableName() string
TableName specifies the table name for SurveyResponse
type SurveyResponseAccess ¶
type SurveyResponseAccess struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
SurveyResponseID DBVarchar `gorm:"size:36;not null;index:idx_sra_sr;index:idx_sra_perf,priority:1"`
UserInternalUUID NullableDBVarchar `gorm:"size:36;index:idx_sra_user;index:idx_sra_perf,priority:3"`
GroupInternalUUID NullableDBVarchar `gorm:"size:36;index:idx_sra_group;index:idx_sra_perf,priority:4"`
SubjectType DBVarchar `gorm:"size:10;not null;index:idx_sra_subject_type;index:idx_sra_perf,priority:2"`
Role DBVarchar `gorm:"size:6;not null;index:idx_sra_role"`
GrantedByInternalUUID NullableDBVarchar `gorm:"size:36"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
// Relationships
SurveyResponse SurveyResponse `gorm:"foreignKey:SurveyResponseID"`
User *User `gorm:"foreignKey:UserInternalUUID;references:InternalUUID"`
Group *Group `gorm:"foreignKey:GroupInternalUUID;references:InternalUUID"`
GrantedBy *User `gorm:"foreignKey:GrantedByInternalUUID;references:InternalUUID"`
}
SurveyResponseAccess represents access control for a survey response Mirrors the ThreatModelAccess pattern for consistency
func (*SurveyResponseAccess) BeforeCreate ¶
func (s *SurveyResponseAccess) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (SurveyResponseAccess) TableName ¶
func (SurveyResponseAccess) TableName() string
TableName specifies the table name for SurveyResponseAccess
type SurveyTemplate ¶
type SurveyTemplate struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
Name DBVarchar `gorm:"size:256;not null;index:idx_st_name;uniqueIndex:idx_st_name_version,priority:1"`
Description NullableDBText `gorm:""`
Version DBVarchar `gorm:"size:64;not null;index:idx_st_version;uniqueIndex:idx_st_name_version,priority:2"`
Status DBVarchar `gorm:"size:20;not null;default:inactive;index:idx_st_status"`
SurveyJSON JSONRaw `gorm:""` // Complete SurveyJS JSON definition (opaque blob)
Settings JSONRaw `gorm:""` // Template settings (allow_threat_model_linking, etc.)
CreatedByInternalUUID DBVarchar `gorm:"size:36;not null;index:idx_st_created_by"`
CreatedAt time.Time `gorm:"not null;autoCreateTime;index:idx_st_created_at"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
}
SurveyTemplate represents a survey template for security review intake
func (*SurveyTemplate) BeforeCreate ¶
func (s *SurveyTemplate) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (SurveyTemplate) TableName ¶
func (SurveyTemplate) TableName() string
TableName specifies the table name for SurveyTemplate
type SurveyTemplateVersion ¶
type SurveyTemplateVersion struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
TemplateID DBVarchar `gorm:"size:36;not null;index:idx_stv_template;uniqueIndex:idx_stv_template_version,priority:1"`
Version DBVarchar `gorm:"size:64;not null;uniqueIndex:idx_stv_template_version,priority:2"`
SurveyJSON JSONRaw `gorm:""`
CreatedByInternalUUID DBVarchar `gorm:"size:36;not null"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
// Relationships
Template SurveyTemplate `gorm:"foreignKey:TemplateID"`
}
SurveyTemplateVersion represents a versioned snapshot of a survey template definition
func (*SurveyTemplateVersion) BeforeCreate ¶
func (s *SurveyTemplateVersion) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (SurveyTemplateVersion) TableName ¶
func (SurveyTemplateVersion) TableName() string
TableName specifies the table name for SurveyTemplateVersion
type SystemAuditEntry ¶
type SystemAuditEntry struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36;index:idx_sysaudit_created_id,priority:2"`
// Actor identity (denormalized)
ActorEmail DBVarchar `gorm:"size:320;not null;index:idx_sysaudit_actor,priority:1"`
ActorProvider DBVarchar `gorm:"size:100;not null"`
ActorProviderID DBVarchar `gorm:"size:500;not null"`
ActorDisplayName DBVarchar `gorm:"size:256;not null"`
// Request shape
HTTPMethod DBVarchar `gorm:"size:10;not null"`
HTTPPath DBText `gorm:"not null"`
// Change description
FieldPath DBVarchar `gorm:"size:1024;not null;index:idx_sysaudit_field"`
OldValueRedacted NullableDBText `gorm:""`
NewValueRedacted NullableDBText `gorm:""`
ChangeSummary NullableDBText `gorm:""`
// Composite (created_at, id) index serves the bidirectional keyset scans and
// the unfiltered full-table export in both ASC and DESC directions (#473). It
// also covers single-column created_at lookups by prefix, so the former
// single-column idx_sysaudit_created has been dropped from fresh schemas.
CreatedAt time.Time `gorm:"not null;autoCreateTime;index:idx_sysaudit_actor,priority:2;index:idx_sysaudit_created_id,priority:1"`
}
SystemAuditEntry is a system-level audit row recording a single /admin/* write. Distinct from AuditEntry (which is threat-model-scoped). Append-only; writes only happen on 2xx responses; redaction policy is applied at write time per the deny-list in api/admin_audit_redaction.go (see #355).
Actor fields are denormalized (matches AuditEntry pattern) so audit rows persist after user deletion. No FKs by design — investigators rely on the row content, not on join integrity.
func (*SystemAuditEntry) BeforeCreate ¶
func (s *SystemAuditEntry) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set.
func (SystemAuditEntry) TableName ¶
func (SystemAuditEntry) TableName() string
TableName returns the table name, casing-aware for Oracle compatibility.
type SystemSetting ¶
type SystemSetting struct {
// SettingKey is the unique identifier for this setting (e.g., "websocket.max_participants")
// Named SettingKey instead of Key to avoid Oracle reserved word conflict
SettingKey DBVarchar `gorm:"primaryKey;not null;size:256" json:"key"`
Value DBText `gorm:"not null" json:"value"`
// SettingType stores the value type: "string", "int", "bool", "json", "float"
// Note: default tag removed for Oracle compatibility (unquoted string defaults cause syntax errors)
SettingType DBVarchar `gorm:"size:50;not null" json:"type"`
Description NullableDBText `gorm:"" json:"description,omitempty"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime" json:"modified_at"`
ModifiedBy NullableDBVarchar `gorm:"size:36" json:"modified_by,omitempty"` // User InternalUUID
// Origin records who wrote this row's current value: SystemSettingOriginSeeded
// when SeedDefaults inserted the registry default at first boot, or
// SystemSettingOriginExplicit when an operator deliberately set it (via the
// admin API, SettingsService.Set, or dbtool --import-config).
//
// NULL means SEEDED — the fail-safe direction. Every way an origin value
// can go missing (an empty string bound on Oracle, a future writer that
// forgets the stamp, a stale pre-upgrade Redis entry whose cached JSON has
// no origin key) therefore degrades to "seeded", which makes the config
// layer win. Config is the layer an operator can see and control, so
// losing this value must never hand authority to a database row nobody set
// — that is precisely the 2026-08-20 outage (oracle-db-admin review, #794).
//
// Rows that predate this column are stamped explicit where they show
// operator intent, by BackfillSystemSettingOrigin in internal/dbschema.
// The column itself is added with no `ALTER TABLE ... DEFAULT` (Oracle
// rejects unquoted string defaults — see the SettingType comment above).
// Never write "" here: Oracle binds an
// empty string as NULL, so an empty string and NULL would be
// indistinguishable there. Only NULL, SystemSettingOriginSeeded, or
// SystemSettingOriginExplicit are valid values.
// Exposed read-only as SystemSetting.origin on the admin settings API by
// modelToAPISystemSetting (api/config_handlers.go, #803), which maps NULL
// to "seeded". The tag is a real json name (not "-") because the Redis
// cache tier round-trips a
// SystemSetting through json.Marshal/Unmarshal (setInRedisCache /
// getFromRedisCache) — "-" would silently drop Origin on every Redis
// cache hit and make every setting look explicit after a warm read
// (oracle-db-admin review, #794).
Origin NullableDBVarchar `gorm:"size:16" json:"origin,omitempty"`
// Source indicates where the effective value comes from: "database", "config", "environment", "vault"
// Computed at response time, not stored in the database.
Source string `gorm:"-" json:"source"`
// ReadOnly indicates whether this setting can be modified via the API.
// True when source is not "database". Computed at response time.
ReadOnly bool `gorm:"-" json:"read_only"`
}
SystemSetting represents a system-wide configuration setting stored in the database. These settings can be modified at runtime without requiring server restart. Settings are cached with short TTL for performance.
func DefaultSystemSettings ¶
func DefaultSystemSettings() []SystemSetting
DefaultSystemSettings returns the default system settings that should be seeded when the database is initialized. These provide sensible defaults that can be overridden by administrators.
This is a projection of the internal/config registry (config.SeedableOperationalDefs), not a hand-kept parallel list — a parallel list is what left rate_limit.requests_per_minute and rate_limit.requests_per_hour seeded here with no classification entry anywhere else, so GET/DELETE /admin/settings/{key} 404'd on keys the LIST endpoint showed (#809).
func (*SystemSetting) IsExplicit ¶
func (s *SystemSetting) IsExplicit() bool
IsExplicit reports whether an operator deliberately set this row's value, as opposed to it having been seeded with a registry default at first boot.
Only an explicit "explicit" counts. NULL, "seeded", and any unexpected value all read as NOT explicit, so the database only outranks an explicitly configured env/YAML value when something deliberately said so. See the Origin field's comment for why that polarity is the safe one.
func (SystemSetting) TableName ¶
func (SystemSetting) TableName() string
TableName specifies the table name for SystemSetting
type TeamMemberRecord ¶
type TeamMemberRecord struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
TeamID DBVarchar `gorm:"size:36;not null;index:idx_tmem_team;uniqueIndex:idx_tmem_team_user,priority:1"`
UserInternalUUID DBVarchar `gorm:"size:36;not null;index:idx_tmem_user;uniqueIndex:idx_tmem_team_user,priority:2"`
Role DBVarchar `gorm:"size:64;not null;default:engineer"`
CustomRole NullableDBVarchar `gorm:"size:128"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
// Relationships
Team TeamRecord `gorm:"foreignKey:TeamID"`
User User `gorm:"foreignKey:UserInternalUUID;references:InternalUUID"`
}
TeamMemberRecord represents a user's membership in a team
func (*TeamMemberRecord) BeforeCreate ¶
func (t *TeamMemberRecord) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (TeamMemberRecord) TableName ¶
func (TeamMemberRecord) TableName() string
TableName specifies the table name for TeamMemberRecord
type TeamNoteRecord ¶
type TeamNoteRecord struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
TeamID DBVarchar `gorm:"size:36;not null;index:idx_tnote_team;index:idx_tnote_team_name,priority:1"`
Name DBVarchar `gorm:"size:256;not null;index:idx_tnote_name;index:idx_tnote_team_name,priority:2"`
Content DBText `gorm:"not null"`
Description NullableDBText `gorm:""`
TimmyEnabled DBBool `gorm:"default:1"`
Sharable DBBool `gorm:"not null"`
CreatedAt time.Time `gorm:"not null;autoCreateTime;index:idx_tnote_created"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
// Relationships
Team TeamRecord `gorm:"foreignKey:TeamID;constraint:OnDelete:CASCADE"`
}
TeamNoteRecord represents a note attached to a team
func (*TeamNoteRecord) BeforeCreate ¶
func (n *TeamNoteRecord) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set and validates required fields.
func (TeamNoteRecord) TableName ¶
func (TeamNoteRecord) TableName() string
TableName specifies the table name for TeamNoteRecord
type TeamRecord ¶
type TeamRecord struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
Name DBVarchar `gorm:"size:256;not null;index:idx_team_name"`
Description NullableDBText `gorm:""`
URI NullableDBText `gorm:""`
EmailAddress NullableDBVarchar `gorm:"size:320"`
Status NullableDBVarchar `gorm:"size:128;index:idx_team_status"`
CreatedByInternalUUID DBVarchar `gorm:"size:36;not null"`
ModifiedByInternalUUID NullableDBVarchar `gorm:"size:36"`
ReviewedByInternalUUID NullableDBVarchar `gorm:"size:36"`
ReviewedAt *time.Time `gorm:"index:idx_team_reviewed_at"`
CreatedAt time.Time `gorm:"not null;autoCreateTime;index:idx_team_created_at"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
// Version is incremented on every successful update (T14 / #385).
Version int `gorm:"not null;default:1"`
// Relationships
CreatedBy User `gorm:"foreignKey:CreatedByInternalUUID;references:InternalUUID;constraint:-"`
ModifiedBy *User `gorm:"foreignKey:ModifiedByInternalUUID;references:InternalUUID;constraint:-"`
ReviewedBy *User `gorm:"foreignKey:ReviewedByInternalUUID;references:InternalUUID;constraint:-"`
}
TeamRecord represents a team in the system
func (*TeamRecord) BeforeCreate ¶
func (t *TeamRecord) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (TeamRecord) TableName ¶
func (TeamRecord) TableName() string
TableName specifies the table name for TeamRecord
type TeamRelationshipRecord ¶
type TeamRelationshipRecord struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
TeamID DBVarchar `gorm:"size:36;not null;index:idx_trel_team;uniqueIndex:idx_trel_team_related,priority:1"`
RelatedTeamID DBVarchar `gorm:"size:36;not null;index:idx_trel_related;uniqueIndex:idx_trel_team_related,priority:2"`
Relationship DBVarchar `gorm:"size:64;not null"`
CustomRelationship NullableDBVarchar `gorm:"size:128"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
// Relationships
Team TeamRecord `gorm:"foreignKey:TeamID"`
RelatedTeam TeamRecord `gorm:"foreignKey:RelatedTeamID"`
}
TeamRelationshipRecord represents a relationship between two teams
func (*TeamRelationshipRecord) BeforeCreate ¶
func (t *TeamRelationshipRecord) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (TeamRelationshipRecord) TableName ¶
func (TeamRelationshipRecord) TableName() string
TableName specifies the table name for TeamRelationshipRecord
type TeamResponsiblePartyRecord ¶
type TeamResponsiblePartyRecord struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
TeamID DBVarchar `gorm:"size:36;not null;index:idx_trp_team;uniqueIndex:idx_trp_team_user,priority:1"`
UserInternalUUID DBVarchar `gorm:"size:36;not null;index:idx_trp_user;uniqueIndex:idx_trp_team_user,priority:2"`
Role DBVarchar `gorm:"size:64;not null"`
CustomRole NullableDBVarchar `gorm:"size:128"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
// Relationships
Team TeamRecord `gorm:"foreignKey:TeamID"`
User User `gorm:"foreignKey:UserInternalUUID;references:InternalUUID"`
}
TeamResponsiblePartyRecord represents a responsible party for a team
func (*TeamResponsiblePartyRecord) BeforeCreate ¶
func (t *TeamResponsiblePartyRecord) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (TeamResponsiblePartyRecord) TableName ¶
func (TeamResponsiblePartyRecord) TableName() string
TableName specifies the table name for TeamResponsiblePartyRecord
type Threat ¶
type Threat struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
ThreatModelID DBVarchar `` /* 170-byte string literal not displayed */
DiagramID NullableDBVarchar `gorm:"size:36;index:idx_threats_diagram"`
CellID NullableDBVarchar `gorm:"size:36;index:idx_threats_cell"`
AssetID NullableDBVarchar `gorm:"size:36;index:idx_threats_asset"`
Name DBVarchar `gorm:"size:256;not null;index:idx_threats_name"`
Description NullableDBText `gorm:""`
Severity NullableDBVarchar `gorm:"size:50;index:idx_threats_severity"`
Likelihood NullableDBVarchar `gorm:"size:50"`
RiskLevel NullableDBVarchar `gorm:"size:50;index:idx_threats_risk_level"`
Score *float64 `gorm:"type:decimal(3,1);index:idx_threats_score"`
Priority NullableDBVarchar `gorm:"size:256;index:idx_threats_priority"`
Mitigated DBBool `gorm:"index:idx_threats_mitigated"`
IncludeInReport DBBool `gorm:"default:1"`
TimmyEnabled DBBool `gorm:"default:1"`
AutoGenerated DBBool `gorm:"default:0;<-:create" json:"auto_generated"`
Status NullableDBVarchar `gorm:"size:128;index:idx_threats_status"`
ThreatType StringArray `gorm:"not null"`
CweID StringArray `gorm:""` // CWE identifiers (e.g., CWE-89)
Cvss CVSSArray `gorm:""` // CVSS vector and score pairs
Ssvc NullableSSVC `gorm:""` // SSVC assessment result
Mitigation NullableDBText `gorm:""`
IssueURI NullableDBText `gorm:""`
Alias int32 `gorm:"not null;default:0;<-:create;uniqueIndex:uniq_threats_tm_alias,priority:2"` // Server-assigned per-(threat_model_id, type) alias
// Note: autoCreateTime/autoUpdateTime tags removed for Oracle compatibility.
// Timestamps are set explicitly in the store layer (toGormModelForCreate).
CreatedAt time.Time `gorm:"not null;index:idx_threats_tm_created,priority:2"`
ModifiedAt time.Time `gorm:"not null;index:idx_threats_modified;index:idx_threats_tm_modified,priority:2"`
// DeletedAt is deliberately *time.Time, NOT gorm.DeletedAt (true for every
// tombstoned model in this file): GORM applies no automatic soft-delete
// scoping, so EVERY query on these models must spell out its deleted_at
// intent explicitly. On SELECTs use a plain `deleted_at IS NULL` string
// predicate; on UPDATE/DELETE builds use a map condition
// (Where(map[string]any{"deleted_at": nil})) because gorm-oracle discards
// any clause.Expr containing both "deleted_at" and "null" there (#392).
// See #669 for the audit that established this.
DeletedAt *time.Time `gorm:"index:idx_threats_deleted_at"`
// Version is incremented on every successful update (T14 / #385).
Version int `gorm:"not null;default:1"`
// Relationships
ThreatModel ThreatModel `gorm:"foreignKey:ThreatModelID"`
Diagram *Diagram `gorm:"foreignKey:DiagramID"`
Asset *Asset `gorm:"foreignKey:AssetID"`
}
Threat represents a threat within a threat model Note: Explicit column tags removed for Oracle compatibility
func (*Threat) BeforeCreate ¶
BeforeCreate ensures the ID is set before insert This is required for Oracle compatibility where the driver may not properly handle IDs set after struct initialization
func (*Threat) BeforeSave ¶
BeforeSave validates Threat before create or update
type ThreatModel ¶
type ThreatModel struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
OwnerInternalUUID DBVarchar `gorm:"size:36;not null;index:idx_tm_owner;index:idx_tm_owner_created,priority:1"`
Name DBVarchar `gorm:"size:256;not null"`
Description NullableDBText `gorm:""`
CreatedByInternalUUID DBVarchar `gorm:"size:36;not null;index:idx_tm_created_by"`
ThreatModelFramework DBVarchar `gorm:"size:30;default:STRIDE;index:idx_tm_framework"`
IssueURI NullableDBText `gorm:""`
Status DBVarchar `gorm:"size:128;not null;default:'not_started';index:idx_tm_status"`
StatusUpdated time.Time `gorm:"not null;default:CURRENT_TIMESTAMP;index:idx_tm_status_updated"`
Alias int32 `gorm:"not null;default:0;<-:create;uniqueIndex:uniq_threat_models_alias"` // Server-assigned globally-unique integer alias
IsConfidential DBBool `gorm:"default:0"` // Immutable after creation
SecurityReviewerInternalUUID NullableDBVarchar `gorm:"size:36;index:idx_tm_security_reviewer"`
ProjectID NullableDBVarchar `gorm:"size:36;index:idx_tm_project"`
// Timestamp columns map to precision-6 TIMESTAMP WITH TIME ZONE on both
// PostgreSQL and Oracle (the gorm-oracle dialector emits bare TIMESTAMP WITH
// TIME ZONE = microsecond). The application truncates created_at/modified_at
// to microseconds at generation (see api/store.go UpdateTimestamps and the
// threat-model handlers) so in-memory values match what the DB persists and
// conform to the OpenAPI timestamp schema (max 6 fractional digits). If these
// columns are ever pinned to a different precision, revisit that truncation.
CreatedAt time.Time `gorm:"not null;autoCreateTime;index:idx_tm_owner_created,priority:2"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
DeletedAt *time.Time `gorm:"index:idx_tm_deleted_at"`
LastAccessedAt *time.Time `gorm:"index:idx_tm_last_accessed_at"`
// Version is incremented on every successful update (T14 / #385).
// Clients pass the expected value via If-Match (or version body field) on
// PUT/PATCH; mismatches return 409 Conflict.
Version int `gorm:"not null;default:1"`
// Relationships
Project *ProjectRecord `gorm:"foreignKey:ProjectID"`
Owner User `gorm:"foreignKey:OwnerInternalUUID;references:InternalUUID"`
CreatedBy User `gorm:"foreignKey:CreatedByInternalUUID;references:InternalUUID;constraint:-"`
SecurityReviewer *User `gorm:"foreignKey:SecurityReviewerInternalUUID;references:InternalUUID"`
Diagrams []Diagram `gorm:"foreignKey:ThreatModelID"`
Threats []Threat `gorm:"foreignKey:ThreatModelID"`
Assets []Asset `gorm:"foreignKey:ThreatModelID"`
}
ThreatModel represents a threat model in the system Note: Explicit column tags removed for Oracle compatibility (Oracle stores column names as UPPERCASE, and the Oracle GORM driver doesn't handle case-insensitive matching with explicit column tags)
func (*ThreatModel) BeforeCreate ¶
func (t *ThreatModel) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (*ThreatModel) BeforeUpdate ¶
func (t *ThreatModel) BeforeUpdate(tx *gorm.DB) error
BeforeUpdate validates ThreatModel before update
func (ThreatModel) TableName ¶
func (ThreatModel) TableName() string
TableName specifies the table name for ThreatModel
type ThreatModelAccess ¶
type ThreatModelAccess struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
ThreatModelID DBVarchar `gorm:"size:36;not null;index:idx_tma_tm;index:idx_tma_perf,priority:1"`
UserInternalUUID NullableDBVarchar `gorm:"size:36;index:idx_tma_user;index:idx_tma_perf,priority:3"`
GroupInternalUUID NullableDBVarchar `gorm:"size:36;index:idx_tma_group;index:idx_tma_perf,priority:4"`
SubjectType DBVarchar `gorm:"size:10;not null;index:idx_tma_subject_type;index:idx_tma_perf,priority:2"`
Role DBVarchar `gorm:"size:6;not null;index:idx_tma_role"`
GrantedByInternalUUID NullableDBVarchar `gorm:"size:36"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
// Relationships
ThreatModel ThreatModel `gorm:"foreignKey:ThreatModelID"`
User *User `gorm:"foreignKey:UserInternalUUID;references:InternalUUID"`
Group *Group `gorm:"foreignKey:GroupInternalUUID;references:InternalUUID"`
GrantedBy *User `gorm:"foreignKey:GrantedByInternalUUID;references:InternalUUID;constraint:-"`
}
ThreatModelAccess represents access control for threat models Note: Explicit column tags removed for Oracle compatibility (Oracle stores column names as UPPERCASE, and the Oracle GORM driver doesn't handle case-insensitive matching with explicit column tags)
func (*ThreatModelAccess) BeforeCreate ¶
func (t *ThreatModelAccess) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (*ThreatModelAccess) BeforeSave ¶
func (t *ThreatModelAccess) BeforeSave(tx *gorm.DB) error
BeforeSave validates ThreatModelAccess before create or update
func (ThreatModelAccess) TableName ¶
func (ThreatModelAccess) TableName() string
TableName specifies the table name for ThreatModelAccess
type TimmyEmbedding ¶
type TimmyEmbedding struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
ThreatModelID DBVarchar `gorm:"size:36;not null;index:idx_timmy_embeddings_tm;index:idx_timmy_embeddings_entity,priority:1"`
EntityType DBVarchar `gorm:"size:30;not null;index:idx_timmy_embeddings_entity,priority:2"`
EntityID DBVarchar `gorm:"size:36;not null;index:idx_timmy_embeddings_entity,priority:3"`
ChunkIndex int `gorm:"not null;index:idx_timmy_embeddings_entity,priority:4"`
IndexType DBVarchar `gorm:"size:10;not null;default:text;index:idx_timmy_embeddings_entity,priority:5"`
ContentHash DBVarchar `gorm:"size:64;not null"`
EmbeddingModel DBVarchar `gorm:"size:100;not null"`
EmbeddingDim int `gorm:"not null"`
VectorData DBBytes `gorm:""`
ChunkText DBText `gorm:"not null"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
// Relationships
ThreatModel ThreatModel `gorm:"foreignKey:ThreatModelID"`
}
TimmyEmbedding represents a vector embedding for a chunk of threat model content
func (*TimmyEmbedding) BeforeCreate ¶
func (e *TimmyEmbedding) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (TimmyEmbedding) TableName ¶
func (TimmyEmbedding) TableName() string
TableName specifies the table name for TimmyEmbedding
type TimmyMessage ¶
type TimmyMessage struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
SessionID DBVarchar `gorm:"size:36;not null;index:idx_timmy_messages_session;uniqueIndex:idx_timmy_messages_session_seq,priority:1"`
Role DBVarchar `gorm:"size:20;not null"`
Content DBText `gorm:"not null"`
TokenCount int `gorm:"default:0"`
Sequence int `gorm:"not null;uniqueIndex:idx_timmy_messages_session_seq,priority:2"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
// Relationships
Session TimmySession `gorm:"foreignKey:SessionID"`
}
TimmyMessage represents a single message in a Timmy chat session
func (*TimmyMessage) BeforeCreate ¶
func (m *TimmyMessage) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (TimmyMessage) TableName ¶
func (TimmyMessage) TableName() string
TableName specifies the table name for TimmyMessage
type TimmySession ¶
type TimmySession struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
ThreatModelID DBVarchar `gorm:"size:36;not null;index:idx_timmy_sessions_tm;index:idx_timmy_sessions_tm_user,priority:1"`
UserID DBVarchar `gorm:"size:36;not null;index:idx_timmy_sessions_user;index:idx_timmy_sessions_tm_user,priority:2"`
Title DBVarchar `gorm:"size:256"`
SourceSnapshot JSONRaw `gorm:""`
SystemPromptHash NullableDBVarchar `gorm:"size:64"`
Status DBVarchar `gorm:"size:20;not null;default:active;index:idx_timmy_sessions_status"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
DeletedAt *time.Time `gorm:"index:idx_timmy_sessions_deleted_at"`
// Relationships
ThreatModel ThreatModel `gorm:"foreignKey:ThreatModelID"`
User User `gorm:"foreignKey:UserID;references:InternalUUID"`
}
TimmySession represents a chat session between a user and Timmy for a threat model
func (*TimmySession) BeforeCreate ¶
func (s *TimmySession) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID and sets default status if not set
func (TimmySession) TableName ¶
func (TimmySession) TableName() string
TableName specifies the table name for TimmySession
type TimmyUsage ¶
type TimmyUsage struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
UserID DBVarchar `gorm:"size:36;not null;index:idx_timmy_usage_user"`
SessionID DBVarchar `gorm:"size:36;not null;index:idx_timmy_usage_session"`
ThreatModelID DBVarchar `gorm:"size:36;not null;index:idx_timmy_usage_tm"`
MessageCount int `gorm:"default:0"`
PromptTokens int `gorm:"default:0"`
CompletionTokens int `gorm:"default:0"`
EmbeddingTokens int `gorm:"default:0"`
PeriodStart time.Time `gorm:"not null;index:idx_timmy_usage_period"`
PeriodEnd time.Time `gorm:"not null"`
// Relationships
ThreatModel ThreatModel `gorm:"foreignKey:ThreatModelID"`
User User `gorm:"foreignKey:UserID;references:InternalUUID"`
Session TimmySession `gorm:"foreignKey:SessionID"`
}
TimmyUsage tracks LLM token usage for billing and monitoring
func (*TimmyUsage) BeforeCreate ¶
func (u *TimmyUsage) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (TimmyUsage) TableName ¶
func (TimmyUsage) TableName() string
TableName specifies the table name for TimmyUsage
type TriageNote ¶
type TriageNote struct {
SurveyResponseID DBVarchar `gorm:"primaryKey;not null;size:36;index:idx_tn_sr"`
ID int `gorm:"primaryKey;not null;autoIncrement:false"`
Name DBVarchar `gorm:"size:256;not null"`
Content DBText `gorm:"not null"`
CreatedByInternalUUID NullableDBVarchar `gorm:"size:36"`
ModifiedByInternalUUID NullableDBVarchar `gorm:"size:36"`
CreatedAt time.Time `gorm:"not null;autoCreateTime;index:idx_tn_created"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
// Relationships
SurveyResponse SurveyResponse `gorm:"foreignKey:SurveyResponseID"`
CreatedBy *User `gorm:"foreignKey:CreatedByInternalUUID;references:InternalUUID;constraint:-"`
ModifiedBy *User `gorm:"foreignKey:ModifiedByInternalUUID;references:InternalUUID;constraint:-"`
}
TriageNote represents a triage note attached to a survey response Uses a composite primary key (SurveyResponseID, ID) where ID is a per-response monotonically increasing integer.
func (*TriageNote) BeforeCreate ¶
func (t *TriageNote) BeforeCreate(tx *gorm.DB) error
BeforeCreate assigns the next sequential ID for the survey response. The parent response row is locked first so concurrent notes on one response serialize. The lock is only sufficient at READ COMMITTED, where MAX(id) sees a note committed while this transaction waited; GormTriageNoteStore.Create runs at that level (#911).
func (TriageNote) TableName ¶
func (TriageNote) TableName() string
TableName specifies the table name for TriageNote
type UsabilityFeedback ¶
type UsabilityFeedback struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
Sentiment DBVarchar `gorm:"size:8;not null;index:idx_usability_feedback_sentiment"`
Verbatim NullableDBText `gorm:""`
Surface DBVarchar `gorm:"size:32;not null;index:idx_usability_feedback_surface"`
ClientID DBVarchar `gorm:"size:32;not null"`
ClientVersion NullableDBVarchar `gorm:"size:32"`
ClientBuild NullableDBVarchar `gorm:"size:12"`
UserAgent NullableDBVarchar `gorm:"size:512"`
UserAgentData JSONRaw `gorm:""`
Viewport NullableDBVarchar `gorm:"size:11"`
Screenshot NullableDBText `gorm:""`
// CreatedBy is the internal UUID of the authenticated user who submitted
// this feedback (#710: was named CreatedByUUID with an explicit
// column:created_by tag; the UUID suffix made the NamingStrategy-derived
// DBName "created_by_uuid" diverge from the actual column and, on Oracle,
// silently zero this field on every read via LookUpField. Renamed instead
// of tagged so the derived DBName is "created_by"/"CREATED_BY" on both
// dialects, matching the real column with no tag needed).
CreatedBy DBVarchar `gorm:"size:36;not null;index:idx_usability_feedback_created_by"`
// Note: autoCreateTime tag removed for Oracle compatibility (#380). The
// repository sets CreatedAt explicitly in Create before INSERT, matching
// the Threat model pattern (see api/models/models.go Threat.CreatedAt).
CreatedAt time.Time `gorm:"not null;index:idx_usability_feedback_created_at"`
// Relationships. constraint:- suppresses the DB-level FK so a user with
// outstanding feedback rows can still be deleted without an integrity-
// constraint error. Application-layer integrity (CreatedBy is always
// set from the authenticated user) is sufficient. Named CreatedByUser
// (not CreatedBy) to avoid colliding with the scalar CreatedBy field above.
CreatedByUser User `gorm:"foreignKey:CreatedBy;references:InternalUUID;constraint:-"`
}
UsabilityFeedback represents user feedback about UI usability. Issued via POST /usability_feedback by any authenticated user. Listed via GET /usability_feedback (admin only).
func (*UsabilityFeedback) BeforeCreate ¶
func (u *UsabilityFeedback) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set.
func (UsabilityFeedback) TableName ¶
func (UsabilityFeedback) TableName() string
TableName returns the dialect-aware table name.
type User ¶
type User struct {
InternalUUID DBVarchar `gorm:"primaryKey;not null;size:36"`
Provider DBVarchar `gorm:"size:100;not null;index:idx_users_provider;uniqueIndex:idx_users_provider_lookup,priority:1"`
ProviderUserID NullableDBVarchar `gorm:"size:500;uniqueIndex:idx_users_provider_lookup,priority:2"`
Email DBVarchar `gorm:"size:320;not null;index:idx_users_email"`
Name DBVarchar `gorm:"size:256;not null"`
EmailVerified DBBool `gorm:"default:0"`
AccessToken NullableDBText `gorm:""`
RefreshToken NullableDBText `gorm:""`
TokenExpiry *time.Time
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
LastLogin *time.Time `gorm:"index:idx_users_last_login"`
Automation *bool `gorm:"default:null"`
// ExtractionConcurrencyOverride lets a trusted machine account run more
// concurrent OOXML extractions than the operator default. NULL = use
// default. Hard-capped at maxPerUserConcurrency (16) regardless of value.
ExtractionConcurrencyOverride *int `gorm:""`
}
User represents an authenticated user in the system Note: Column names are intentionally not specified to allow GORM's NamingStrategy to handle database-specific casing (lowercase for PostgreSQL, UPPERCASE for Oracle)
func (*User) BeforeCreate ¶
BeforeCreate generates a UUID if not set
type UserAPIQuota ¶
type UserAPIQuota struct {
UserInternalUUID DBVarchar `gorm:"primaryKey;not null;size:36"`
MaxRequestsPerMinute int `gorm:"default:1000"`
MaxRequestsPerHour *int
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
// Relationships
User User `gorm:"foreignKey:UserInternalUUID;references:InternalUUID"`
}
UserAPIQuota represents per-user API rate limits Note: Explicit column tags removed for Oracle compatibility
func (UserAPIQuota) TableName ¶
func (UserAPIQuota) TableName() string
TableName specifies the table name for UserAPIQuota
type UserContentToken ¶
type UserContentToken struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
UserID DBVarchar `gorm:"size:36;not null;index:idx_uct_user;uniqueIndex:uq_uct_user_provider,priority:1"`
ProviderID DBVarchar `gorm:"size:64;not null;uniqueIndex:uq_uct_user_provider,priority:2"`
AccessToken DBBytes `gorm:"not null"`
RefreshToken DBBytes
Scopes DBText
ExpiresAt *time.Time
Status NullableDBVarchar `gorm:"size:16;default:active;index:idx_uct_status_expires,priority:1"`
LastRefreshAt *time.Time `gorm:"index:idx_uct_status_expires,priority:2"`
LastError NullableDBText
ProviderAccountID NullableDBVarchar `gorm:"size:255"`
ProviderAccountLabel NullableDBVarchar `gorm:"size:255"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
// Owner is the user who owns this token; ON DELETE CASCADE removes the token when the user is deleted.
Owner User `gorm:"foreignKey:UserID;references:InternalUUID;constraint:OnDelete:CASCADE"`
}
UserContentToken is a per-user OAuth token used by delegated content providers. access_token and refresh_token are AES-256-GCM ciphertexts (nonce prepended). DBBytes maps to BYTEA on PostgreSQL and BLOB on Oracle / SQLite (#404).
func (*UserContentToken) BeforeCreate ¶
func (u *UserContentToken) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set.
func (UserContentToken) TableName ¶
func (UserContentToken) TableName() string
TableName specifies the table name for UserContentToken.
type UserPreference ¶
type UserPreference struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
UserInternalUUID DBVarchar `gorm:"size:36;not null;uniqueIndex"`
Preferences JSONRaw `gorm:"not null"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
// Relationships
User User `gorm:"foreignKey:UserInternalUUID;references:InternalUUID"`
}
UserPreference stores user preferences as JSON Preferences are keyed by client application identifier (e.g., "tmi-ux", "tmi-cli") Maximum total size: 1KB, maximum 20 client entries
func (*UserPreference) BeforeCreate ¶
func (u *UserPreference) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (UserPreference) TableName ¶
func (UserPreference) TableName() string
TableName specifies the table name for UserPreference
type VersionSnapshot ¶
type VersionSnapshot struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
AuditEntryID DBVarchar `gorm:"size:36;not null;index:idx_vs_audit_entry"`
ObjectType DBVarchar `gorm:"size:50;not null;index:idx_vs_object,priority:1;index:idx_vs_object_snapshot,priority:1"`
ObjectID DBVarchar `gorm:"size:36;not null;index:idx_vs_object,priority:2;index:idx_vs_object_snapshot,priority:2"`
Version int `gorm:"not null;index:idx_vs_object,priority:3"`
SnapshotType DBVarchar `gorm:"size:20;not null;index:idx_vs_object_snapshot,priority:3"` // "checkpoint" or "diff"
Data NullableDBText `gorm:""` // full JSON snapshot or reverse JSON Patch
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
}
VersionSnapshot stores the data needed for rollback. Each snapshot is either a full JSON checkpoint or a reverse JSON Patch diff (RFC 6902). Checkpoints are stored every 10th version; all others are diffs. Snapshots have their own retention policy and can be pruned independently of audit entries.
func (*VersionSnapshot) BeforeCreate ¶
func (v *VersionSnapshot) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (VersionSnapshot) TableName ¶
func (VersionSnapshot) TableName() string
TableName specifies the table name for VersionSnapshot
type WebhookQuota ¶
type WebhookQuota struct {
OwnerID DBVarchar `gorm:"primaryKey;not null;size:36"`
MaxSubscriptions int `gorm:"default:10"`
MaxEventsPerMinute int `gorm:"default:12"`
MaxSubscriptionRequestsPerMinute int `gorm:"default:10"`
MaxSubscriptionRequestsPerDay int `gorm:"default:20"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
// Relationships
Owner User `gorm:"foreignKey:OwnerID;references:InternalUUID"`
}
WebhookQuota represents per-user webhook quotas Note: Explicit column tags removed for Oracle compatibility
func (WebhookQuota) TableName ¶
func (WebhookQuota) TableName() string
TableName specifies the table name for WebhookQuota
type WebhookSubscription ¶
type WebhookSubscription struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
OwnerInternalUUID DBVarchar `gorm:"size:36;not null;index"`
ThreatModelID NullableDBVarchar `gorm:"size:36;index"`
Name DBVarchar `gorm:"size:256;not null"`
URL DBText `gorm:"not null"`
Events StringArray `gorm:"not null"`
Secret NullableDBVarchar `gorm:"size:128"`
Status DBVarchar `gorm:"size:128;default:pending_verification"`
Challenge NullableDBVarchar `gorm:"size:1000"`
ChallengesSent int `gorm:"default:0"`
TimeoutCount int `gorm:"default:0"`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
ModifiedAt time.Time `gorm:"not null;autoUpdateTime"`
LastSuccessfulUse *time.Time
PublicationFailures int `gorm:"default:0"`
// OperatorPinned marks the subscription as materialized from operator
// config (alerting block, #395). Pinned rows cannot be modified or
// deleted through /admin/webhooks and their URL is redacted in reads.
// DBBool is required for Oracle compatibility (NUMBER(1) column).
OperatorPinned DBBool `gorm:"not null;default:false" json:"operator_pinned"`
// Relationships
Owner User `gorm:"foreignKey:OwnerInternalUUID;references:InternalUUID"`
ThreatModel *ThreatModel `gorm:"foreignKey:ThreatModelID"`
}
WebhookSubscription represents a webhook subscription Note: Explicit column tags removed for Oracle compatibility
func (*WebhookSubscription) BeforeCreate ¶
func (w *WebhookSubscription) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (*WebhookSubscription) BeforeSave ¶
func (w *WebhookSubscription) BeforeSave(tx *gorm.DB) error
BeforeSave validates WebhookSubscription before create or update
func (WebhookSubscription) TableName ¶
func (WebhookSubscription) TableName() string
TableName specifies the table name for WebhookSubscription
type WebhookURLDenyList ¶
type WebhookURLDenyList struct {
ID DBVarchar `gorm:"primaryKey;not null;size:36"`
Pattern DBVarchar `gorm:"size:256;not null;uniqueIndex:idx_webhook_deny_pattern"`
PatternType DBVarchar `gorm:"size:64;not null"`
Description NullableDBText `gorm:""`
CreatedAt time.Time `gorm:"not null;autoCreateTime"`
}
WebhookURLDenyList represents URL patterns blocked for webhooks Note: Explicit column tags removed for Oracle compatibility
func (*WebhookURLDenyList) BeforeCreate ¶
func (w *WebhookURLDenyList) BeforeCreate(tx *gorm.DB) error
BeforeCreate generates a UUID if not set
func (*WebhookURLDenyList) BeforeSave ¶
func (w *WebhookURLDenyList) BeforeSave(tx *gorm.DB) error
BeforeSave validates WebhookURLDenyList before create or update
func (WebhookURLDenyList) TableName ¶
func (WebhookURLDenyList) TableName() string
TableName specifies the table name for WebhookURLDenyList