package lib import "database/sql" // Entry is the single core data type. One table to rule them all. type Entry struct { EntryID string `json:"entry_id"` ProjectID string `json:"project_id"` ParentID string `json:"parent_id"` Type string `json:"type"` Depth int `json:"depth"` SortOrder int `json:"sort_order"` SearchKey []byte `json:"-"` // blind index (HMAC-SHA256) SearchKey2 []byte `json:"-"` // blind index (HMAC-SHA256) Summary []byte `json:"-"` // packed: zstd + AES-256-GCM Data []byte `json:"-"` // packed: zstd + AES-256-GCM Stage string `json:"stage"` // Workflow routing (plain, indexed) AssigneeID string `json:"assignee_id"` ReturnToID string `json:"return_to_id"` OriginID string `json:"origin_id"` // Optimistic locking Version int `json:"version"` // Soft delete DeletedAt *int64 `json:"deleted_at,omitempty"` DeletedBy *string `json:"deleted_by,omitempty"` // Key rotation KeyVersion int `json:"key_version"` // Timestamps CreatedAt int64 `json:"created_at"` UpdatedAt int64 `json:"updated_at"` CreatedBy string `json:"created_by"` // Unpacked fields (not stored directly, populated by lib) SummaryText string `json:"summary,omitempty"` DataText string `json:"data_text,omitempty"` } // Entry types const ( TypeProject = "project" TypeWorkstream = "workstream" TypeRequestList = "request_list" TypeRequest = "request" TypeAnswer = "answer" TypeSection = "section" TypeComment = "comment" TypeOrganization = "organization" TypeDealOrg = "deal_org" ) // Stages const ( StagePreDataroom = "pre_dataroom" StageDataroom = "dataroom" StageClosed = "closed" ) // OrgData is the JSON structure packed into an organization entry's Data field. type OrgData struct { Name string `json:"name"` Domains []string `json:"domains"` // required, e.g. ["kaseya.com","datto.com"] Role string `json:"role"` // seller | buyer | ib | advisor Website string `json:"website,omitempty"` Description string `json:"description,omitempty"` ContactName string `json:"contact_name,omitempty"` ContactEmail string `json:"contact_email,omitempty"` } // DealOrgData is the JSON structure packed into a deal_org entry's Data field. // A deal_org entry links an organization into a specific deal (project). type DealOrgData struct { OrgID string `json:"org_id"` // entry_id of the organization Role string `json:"role"` // seller | buyer | ib | advisor DomainLock bool `json:"domain_lock"` // if true, enforce domain check on invites } // User represents an account. type User struct { UserID string `json:"user_id"` Email string `json:"email"` Name string `json:"name"` Password string `json:"-"` // bcrypt OrgID string `json:"org_id"` OrgName string `json:"org_name"` MFASecret string `json:"-"` Active bool `json:"active"` CreatedAt int64 `json:"created_at"` UpdatedAt int64 `json:"updated_at"` } // Access is an RBAC grant. type Access struct { ID string `json:"id"` ProjectID string `json:"project_id"` WorkstreamID string `json:"workstream_id,omitempty"` UserID string `json:"user_id"` Role string `json:"role"` Ops string `json:"ops"` CanGrant bool `json:"can_grant"` GrantedBy string `json:"granted_by"` GrantedAt int64 `json:"granted_at"` RevokedAt *int64 `json:"revoked_at,omitempty"` RevokedBy string `json:"revoked_by,omitempty"` } // Roles const ( RoleSuperAdmin = "super_admin" RoleIBAdmin = "ib_admin" RoleIBMember = "ib_member" RoleSellerAdmin = "seller_admin" RoleSellerMember = "seller_member" RoleBuyerAdmin = "buyer_admin" RoleBuyerMember = "buyer_member" RoleObserver = "observer" ) // RoleHierarchy defines privilege levels. Higher = more privileged. var RoleHierarchy = map[string]int{ RoleSuperAdmin: 200, RoleIBAdmin: 100, RoleIBMember: 80, RoleSellerAdmin: 70, RoleSellerMember: 50, RoleBuyerAdmin: 40, RoleBuyerMember: 30, RoleObserver: 10, } // AnswerLink connects answers to requests (many-to-many). type AnswerLink struct { AnswerID string `json:"answer_id"` RequestID string `json:"request_id"` LinkedBy string `json:"linked_by"` LinkedAt int64 `json:"linked_at"` Confirmed bool `json:"confirmed"` AIScore *float64 `json:"ai_score,omitempty"` Status string `json:"status"` ReviewedBy string `json:"reviewed_by,omitempty"` ReviewedAt *int64 `json:"reviewed_at,omitempty"` RejectReason string `json:"reject_reason,omitempty"` } // EntryEvent is a workflow thread item. type EntryEvent struct { ID string `json:"id"` EntryID string `json:"entry_id"` ActorID string `json:"actor_id"` Channel string `json:"channel"` Action []byte `json:"-"` // packed Data []byte `json:"-"` // packed Ts int64 `json:"ts"` ActionText string `json:"action,omitempty"` DataText string `json:"data_text,omitempty"` } // AuditEntry is a security audit log row. type AuditEntry struct { ID string `json:"id"` ProjectID string `json:"project_id"` ActorID string `json:"actor_id"` Action []byte `json:"-"` TargetID string `json:"target_id,omitempty"` Details []byte `json:"-"` IP string `json:"ip,omitempty"` Ts int64 `json:"ts"` ActionText string `json:"action,omitempty"` DetailsText string `json:"details,omitempty"` } // Session tracks active user sessions. type Session struct { ID string `json:"id"` UserID string `json:"user_id"` Fingerprint string `json:"fingerprint"` CreatedAt int64 `json:"created_at"` ExpiresAt int64 `json:"expires_at"` Revoked bool `json:"revoked"` } // Theme is a CSS custom properties bundle. type Theme struct { ID string `json:"id"` Name string `json:"name"` ProjectID string `json:"project_id,omitempty"` Properties string `json:"properties"` // packed CSS vars as JSON } // EntryFilter is used by EntryRead to query entries. type EntryFilter struct { ProjectID string ParentID *string Type string Stage string AssigneeID string SearchKey []byte // blind index to match Limit int Offset int } // DB wraps the database connection. type DB struct { Conn *sql.DB } // Challenge represents an email OTP challenge for passwordless login. type Challenge struct { ChallengeID string `json:"challenge_id"` Email string `json:"email"` Code string `json:"code"` CreatedAt int64 `json:"created_at"` ExpiresAt int64 `json:"expires_at"` Used bool `json:"used"` } // Config holds application configuration. type Config struct { MasterKey []byte DBPath string StorePath string Port string Env string // "development" | "production" JWTSecret []byte Mailer *Mailer BackdoorCode string // OTP backdoor for dev/testing } // RequestData is the JSON structure packed into a request entry's Data field. // Represents a diligence request item imported from CSV/XLSX. type RequestData struct { Title string `json:"title"` // human-readable description ItemNumber string `json:"item_number"` // e.g. "1.3", "A-12" Section string `json:"section"` // e.g. "Financial", "Legal" Description string `json:"description"` // full detail / context Priority string `json:"priority"` // critical | high | medium | low Status string `json:"status"` // open | in_process | partial | complete AssigneeID string `json:"assignee_id,omitempty"` AssigneeName string `json:"assignee_name,omitempty"` ReviewerID string `json:"reviewer_id,omitempty"` DueDate string `json:"due_date,omitempty"` // YYYY-MM-DD CompletedAt string `json:"completed_at,omitempty"` // YYYY-MM-DD BuyerComment string `json:"buyer_comment,omitempty"` SellerComment string `json:"seller_comment,omitempty"` Label string `json:"label,omitempty"` Tags []string `json:"tags,omitempty"` LinkedEntryIDs []string `json:"linked_entry_ids,omitempty"` // linked answer/file entries } // SectionData is the JSON structure packed into a section entry's Data field. type SectionData struct { Name string `json:"name"` } // RequestListData is the JSON structure packed into a request_list entry's Data field. type RequestListData struct { Name string `json:"name"` OrgID string `json:"org_id,omitempty"` // PE firm org entry_id VisibilityOrgID string `json:"visibility_org_id,omitempty"` // restrict visibility to this org (+ IB) } // WorkstreamData is the JSON structure packed into a workstream entry's Data field. type WorkstreamData struct { Name string `json:"name"` Description string `json:"description,omitempty"` } // OAuthClient represents a registered OAuth 2.0 client application. type OAuthClient struct { ClientID string `json:"client_id"` ClientName string `json:"client_name"` RedirectURIs []string `json:"redirect_uris"` CreatedAt int64 `json:"created_at"` } // OAuthCode represents an OAuth 2.0 authorization code. type OAuthCode struct { Code string `json:"code"` ClientID string `json:"client_id"` UserID string `json:"user_id"` RedirectURI string `json:"redirect_uri"` CodeChallenge string `json:"code_challenge"` Scope string `json:"scope"` ExpiresAt int64 `json:"expires_at"` Used bool `json:"used"` } // OAuthToken represents an OAuth 2.0 access token. type OAuthToken struct { Token string `json:"token"` ClientID string `json:"client_id"` UserID string `json:"user_id"` Scope string `json:"scope"` ExpiresAt int64 `json:"expires_at"` Revoked bool `json:"revoked"` CreatedAt int64 `json:"created_at"` }