Initial commit: Open sourcing all of the Maple Open Technologies code.
This commit is contained in:
commit
755d54a99d
2010 changed files with 448675 additions and 0 deletions
|
|
@ -0,0 +1,225 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/domain/user"
|
||||
)
|
||||
|
||||
// UserByDate represents the users_by_date table
|
||||
// Query pattern: List users sorted by creation date
|
||||
// Primary key: ((tenant_id, created_date), id) - composite partition key + clustering
|
||||
type UserByDate struct {
|
||||
TenantID string `db:"tenant_id"` // Multi-tenant isolation (partition key part 1)
|
||||
CreatedDate string `db:"created_date"` // Format: YYYY-MM-DD (partition key part 2)
|
||||
ID string `db:"id"` // Clustering column
|
||||
Email string `db:"email"`
|
||||
FirstName string `db:"first_name"`
|
||||
LastName string `db:"last_name"`
|
||||
Name string `db:"name"`
|
||||
LexicalName string `db:"lexical_name"`
|
||||
Timezone string `db:"timezone"`
|
||||
Role int `db:"role"`
|
||||
Status int `db:"status"`
|
||||
|
||||
// Profile data fields (flattened)
|
||||
Phone string `db:"phone"`
|
||||
Country string `db:"country"`
|
||||
Region string `db:"region"`
|
||||
City string `db:"city"`
|
||||
PostalCode string `db:"postal_code"`
|
||||
AddressLine1 string `db:"address_line1"`
|
||||
AddressLine2 string `db:"address_line2"`
|
||||
HasShippingAddress bool `db:"has_shipping_address"`
|
||||
ShippingName string `db:"shipping_name"`
|
||||
ShippingPhone string `db:"shipping_phone"`
|
||||
ShippingCountry string `db:"shipping_country"`
|
||||
ShippingRegion string `db:"shipping_region"`
|
||||
ShippingCity string `db:"shipping_city"`
|
||||
ShippingPostalCode string `db:"shipping_postal_code"`
|
||||
ShippingAddressLine1 string `db:"shipping_address_line1"`
|
||||
ShippingAddressLine2 string `db:"shipping_address_line2"`
|
||||
ProfileTimezone string `db:"profile_timezone"`
|
||||
AgreeTermsOfService bool `db:"agree_terms_of_service"`
|
||||
AgreePromotions bool `db:"agree_promotions"`
|
||||
AgreeToTrackingAcrossThirdPartyAppsAndServices bool `db:"agree_to_tracking_across_third_party_apps_and_services"`
|
||||
|
||||
// Security data fields (flattened)
|
||||
PasswordHashAlgorithm string `db:"password_hash_algorithm"`
|
||||
PasswordHash string `db:"password_hash"`
|
||||
WasEmailVerified bool `db:"was_email_verified"`
|
||||
Code string `db:"code"`
|
||||
CodeType string `db:"code_type"`
|
||||
CodeExpiry time.Time `db:"code_expiry"`
|
||||
OTPEnabled bool `db:"otp_enabled"`
|
||||
OTPVerified bool `db:"otp_verified"`
|
||||
OTPValidated bool `db:"otp_validated"`
|
||||
OTPSecret string `db:"otp_secret"`
|
||||
OTPAuthURL string `db:"otp_auth_url"`
|
||||
OTPBackupCodeHash string `db:"otp_backup_code_hash"`
|
||||
OTPBackupCodeHashAlgorithm string `db:"otp_backup_code_hash_algorithm"`
|
||||
|
||||
// Metadata fields (flattened)
|
||||
// CWE-359: Encrypted IP addresses for GDPR compliance
|
||||
CreatedFromIPAddress string `db:"created_from_ip_address"` // Encrypted with go-ipcrypt
|
||||
CreatedFromIPTimestamp time.Time `db:"created_from_ip_timestamp"` // For 90-day expiration tracking
|
||||
CreatedByUserID string `db:"created_by_user_id"`
|
||||
CreatedByName string `db:"created_by_name"`
|
||||
ModifiedFromIPAddress string `db:"modified_from_ip_address"` // Encrypted with go-ipcrypt
|
||||
ModifiedFromIPTimestamp time.Time `db:"modified_from_ip_timestamp"` // For 90-day expiration tracking
|
||||
ModifiedByUserID string `db:"modified_by_user_id"`
|
||||
ModifiedAt time.Time `db:"modified_at"`
|
||||
ModifiedByName string `db:"modified_by_name"`
|
||||
LastLoginAt time.Time `db:"last_login_at"`
|
||||
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
// ToUser converts table model to domain entity
|
||||
func (u *UserByDate) ToUser() *user.User {
|
||||
return &user.User{
|
||||
ID: u.ID,
|
||||
Email: u.Email,
|
||||
FirstName: u.FirstName,
|
||||
LastName: u.LastName,
|
||||
Name: u.Name,
|
||||
LexicalName: u.LexicalName,
|
||||
Timezone: u.Timezone,
|
||||
Role: u.Role,
|
||||
Status: u.Status,
|
||||
|
||||
ProfileData: &user.UserProfileData{
|
||||
Phone: u.Phone,
|
||||
Country: u.Country,
|
||||
Region: u.Region,
|
||||
City: u.City,
|
||||
PostalCode: u.PostalCode,
|
||||
AddressLine1: u.AddressLine1,
|
||||
AddressLine2: u.AddressLine2,
|
||||
HasShippingAddress: u.HasShippingAddress,
|
||||
ShippingName: u.ShippingName,
|
||||
ShippingPhone: u.ShippingPhone,
|
||||
ShippingCountry: u.ShippingCountry,
|
||||
ShippingRegion: u.ShippingRegion,
|
||||
ShippingCity: u.ShippingCity,
|
||||
ShippingPostalCode: u.ShippingPostalCode,
|
||||
ShippingAddressLine1: u.ShippingAddressLine1,
|
||||
ShippingAddressLine2: u.ShippingAddressLine2,
|
||||
Timezone: u.ProfileTimezone,
|
||||
AgreeTermsOfService: u.AgreeTermsOfService,
|
||||
AgreePromotions: u.AgreePromotions,
|
||||
AgreeToTrackingAcrossThirdPartyAppsAndServices: u.AgreeToTrackingAcrossThirdPartyAppsAndServices,
|
||||
},
|
||||
|
||||
SecurityData: &user.UserSecurityData{
|
||||
PasswordHashAlgorithm: u.PasswordHashAlgorithm,
|
||||
PasswordHash: u.PasswordHash,
|
||||
WasEmailVerified: u.WasEmailVerified,
|
||||
Code: u.Code,
|
||||
CodeType: u.CodeType,
|
||||
CodeExpiry: u.CodeExpiry,
|
||||
OTPEnabled: u.OTPEnabled,
|
||||
OTPVerified: u.OTPVerified,
|
||||
OTPValidated: u.OTPValidated,
|
||||
OTPSecret: u.OTPSecret,
|
||||
OTPAuthURL: u.OTPAuthURL,
|
||||
OTPBackupCodeHash: u.OTPBackupCodeHash,
|
||||
OTPBackupCodeHashAlgorithm: u.OTPBackupCodeHashAlgorithm,
|
||||
},
|
||||
|
||||
Metadata: &user.UserMetadata{
|
||||
CreatedFromIPAddress: u.CreatedFromIPAddress,
|
||||
CreatedFromIPTimestamp: u.CreatedFromIPTimestamp,
|
||||
CreatedByUserID: u.CreatedByUserID,
|
||||
CreatedAt: u.CreatedAt,
|
||||
CreatedByName: u.CreatedByName,
|
||||
ModifiedFromIPAddress: u.ModifiedFromIPAddress,
|
||||
ModifiedFromIPTimestamp: u.ModifiedFromIPTimestamp,
|
||||
ModifiedByUserID: u.ModifiedByUserID,
|
||||
ModifiedAt: u.ModifiedAt,
|
||||
ModifiedByName: u.ModifiedByName,
|
||||
LastLoginAt: u.LastLoginAt,
|
||||
},
|
||||
|
||||
TenantID: u.TenantID,
|
||||
CreatedAt: u.CreatedAt,
|
||||
UpdatedAt: u.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
// FromUserByDate converts domain entity to table model
|
||||
func FromUserByDate(tenantID string, u *user.User) *UserByDate {
|
||||
userByDate := &UserByDate{
|
||||
TenantID: tenantID,
|
||||
CreatedDate: u.CreatedAt.Format("2006-01-02"),
|
||||
ID: u.ID,
|
||||
Email: u.Email,
|
||||
FirstName: u.FirstName,
|
||||
LastName: u.LastName,
|
||||
Name: u.Name,
|
||||
LexicalName: u.LexicalName,
|
||||
Timezone: u.Timezone,
|
||||
Role: u.Role,
|
||||
Status: u.Status,
|
||||
CreatedAt: u.CreatedAt,
|
||||
UpdatedAt: u.UpdatedAt,
|
||||
}
|
||||
|
||||
// Map ProfileData if present
|
||||
if u.ProfileData != nil {
|
||||
userByDate.Phone = u.ProfileData.Phone
|
||||
userByDate.Country = u.ProfileData.Country
|
||||
userByDate.Region = u.ProfileData.Region
|
||||
userByDate.City = u.ProfileData.City
|
||||
userByDate.PostalCode = u.ProfileData.PostalCode
|
||||
userByDate.AddressLine1 = u.ProfileData.AddressLine1
|
||||
userByDate.AddressLine2 = u.ProfileData.AddressLine2
|
||||
userByDate.HasShippingAddress = u.ProfileData.HasShippingAddress
|
||||
userByDate.ShippingName = u.ProfileData.ShippingName
|
||||
userByDate.ShippingPhone = u.ProfileData.ShippingPhone
|
||||
userByDate.ShippingCountry = u.ProfileData.ShippingCountry
|
||||
userByDate.ShippingRegion = u.ProfileData.ShippingRegion
|
||||
userByDate.ShippingCity = u.ProfileData.ShippingCity
|
||||
userByDate.ShippingPostalCode = u.ProfileData.ShippingPostalCode
|
||||
userByDate.ShippingAddressLine1 = u.ProfileData.ShippingAddressLine1
|
||||
userByDate.ShippingAddressLine2 = u.ProfileData.ShippingAddressLine2
|
||||
userByDate.ProfileTimezone = u.ProfileData.Timezone
|
||||
userByDate.AgreeTermsOfService = u.ProfileData.AgreeTermsOfService
|
||||
userByDate.AgreePromotions = u.ProfileData.AgreePromotions
|
||||
userByDate.AgreeToTrackingAcrossThirdPartyAppsAndServices = u.ProfileData.AgreeToTrackingAcrossThirdPartyAppsAndServices
|
||||
}
|
||||
|
||||
// Map SecurityData if present
|
||||
if u.SecurityData != nil {
|
||||
userByDate.PasswordHashAlgorithm = u.SecurityData.PasswordHashAlgorithm
|
||||
userByDate.PasswordHash = u.SecurityData.PasswordHash
|
||||
userByDate.WasEmailVerified = u.SecurityData.WasEmailVerified
|
||||
userByDate.Code = u.SecurityData.Code
|
||||
userByDate.CodeType = u.SecurityData.CodeType
|
||||
userByDate.CodeExpiry = u.SecurityData.CodeExpiry
|
||||
userByDate.OTPEnabled = u.SecurityData.OTPEnabled
|
||||
userByDate.OTPVerified = u.SecurityData.OTPVerified
|
||||
userByDate.OTPValidated = u.SecurityData.OTPValidated
|
||||
userByDate.OTPSecret = u.SecurityData.OTPSecret
|
||||
userByDate.OTPAuthURL = u.SecurityData.OTPAuthURL
|
||||
userByDate.OTPBackupCodeHash = u.SecurityData.OTPBackupCodeHash
|
||||
userByDate.OTPBackupCodeHashAlgorithm = u.SecurityData.OTPBackupCodeHashAlgorithm
|
||||
}
|
||||
|
||||
// Map Metadata if present
|
||||
if u.Metadata != nil {
|
||||
userByDate.CreatedFromIPAddress = u.Metadata.CreatedFromIPAddress
|
||||
userByDate.CreatedFromIPTimestamp = u.Metadata.CreatedFromIPTimestamp
|
||||
userByDate.CreatedByUserID = u.Metadata.CreatedByUserID
|
||||
userByDate.CreatedByName = u.Metadata.CreatedByName
|
||||
userByDate.ModifiedFromIPAddress = u.Metadata.ModifiedFromIPAddress
|
||||
userByDate.ModifiedFromIPTimestamp = u.Metadata.ModifiedFromIPTimestamp
|
||||
userByDate.ModifiedByUserID = u.Metadata.ModifiedByUserID
|
||||
userByDate.ModifiedAt = u.Metadata.ModifiedAt
|
||||
userByDate.ModifiedByName = u.Metadata.ModifiedByName
|
||||
userByDate.LastLoginAt = u.Metadata.LastLoginAt
|
||||
}
|
||||
|
||||
return userByDate
|
||||
}
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/domain/user"
|
||||
)
|
||||
|
||||
// UserByEmail represents the users_by_email table
|
||||
// Query pattern: Get user by email (for login, uniqueness checks)
|
||||
// Primary key: (tenant_id, email) - composite partition key for multi-tenancy
|
||||
type UserByEmail struct {
|
||||
TenantID string `db:"tenant_id"` // Multi-tenant isolation
|
||||
Email string `db:"email"`
|
||||
ID string `db:"id"`
|
||||
FirstName string `db:"first_name"`
|
||||
LastName string `db:"last_name"`
|
||||
Name string `db:"name"`
|
||||
LexicalName string `db:"lexical_name"`
|
||||
Timezone string `db:"timezone"`
|
||||
Role int `db:"role"`
|
||||
Status int `db:"status"`
|
||||
|
||||
// Profile data fields (flattened)
|
||||
Phone string `db:"phone"`
|
||||
Country string `db:"country"`
|
||||
Region string `db:"region"`
|
||||
City string `db:"city"`
|
||||
PostalCode string `db:"postal_code"`
|
||||
AddressLine1 string `db:"address_line1"`
|
||||
AddressLine2 string `db:"address_line2"`
|
||||
HasShippingAddress bool `db:"has_shipping_address"`
|
||||
ShippingName string `db:"shipping_name"`
|
||||
ShippingPhone string `db:"shipping_phone"`
|
||||
ShippingCountry string `db:"shipping_country"`
|
||||
ShippingRegion string `db:"shipping_region"`
|
||||
ShippingCity string `db:"shipping_city"`
|
||||
ShippingPostalCode string `db:"shipping_postal_code"`
|
||||
ShippingAddressLine1 string `db:"shipping_address_line1"`
|
||||
ShippingAddressLine2 string `db:"shipping_address_line2"`
|
||||
ProfileTimezone string `db:"profile_timezone"`
|
||||
AgreeTermsOfService bool `db:"agree_terms_of_service"`
|
||||
AgreePromotions bool `db:"agree_promotions"`
|
||||
AgreeToTrackingAcrossThirdPartyAppsAndServices bool `db:"agree_to_tracking_across_third_party_apps_and_services"`
|
||||
|
||||
// Security data fields (flattened)
|
||||
PasswordHashAlgorithm string `db:"password_hash_algorithm"`
|
||||
PasswordHash string `db:"password_hash"`
|
||||
WasEmailVerified bool `db:"was_email_verified"`
|
||||
Code string `db:"code"`
|
||||
CodeType string `db:"code_type"`
|
||||
CodeExpiry time.Time `db:"code_expiry"`
|
||||
OTPEnabled bool `db:"otp_enabled"`
|
||||
OTPVerified bool `db:"otp_verified"`
|
||||
OTPValidated bool `db:"otp_validated"`
|
||||
OTPSecret string `db:"otp_secret"`
|
||||
OTPAuthURL string `db:"otp_auth_url"`
|
||||
OTPBackupCodeHash string `db:"otp_backup_code_hash"`
|
||||
OTPBackupCodeHashAlgorithm string `db:"otp_backup_code_hash_algorithm"`
|
||||
|
||||
// Metadata fields (flattened)
|
||||
// CWE-359: Encrypted IP addresses for GDPR compliance
|
||||
CreatedFromIPAddress string `db:"created_from_ip_address"` // Encrypted with go-ipcrypt
|
||||
CreatedFromIPTimestamp time.Time `db:"created_from_ip_timestamp"` // For 90-day expiration tracking
|
||||
CreatedByUserID string `db:"created_by_user_id"`
|
||||
CreatedByName string `db:"created_by_name"`
|
||||
ModifiedFromIPAddress string `db:"modified_from_ip_address"` // Encrypted with go-ipcrypt
|
||||
ModifiedFromIPTimestamp time.Time `db:"modified_from_ip_timestamp"` // For 90-day expiration tracking
|
||||
ModifiedByUserID string `db:"modified_by_user_id"`
|
||||
ModifiedAt time.Time `db:"modified_at"`
|
||||
ModifiedByName string `db:"modified_by_name"`
|
||||
LastLoginAt time.Time `db:"last_login_at"`
|
||||
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
// ToUser converts table model to domain entity
|
||||
func (u *UserByEmail) ToUser() *user.User {
|
||||
return &user.User{
|
||||
ID: u.ID,
|
||||
Email: u.Email,
|
||||
FirstName: u.FirstName,
|
||||
LastName: u.LastName,
|
||||
Name: u.Name,
|
||||
LexicalName: u.LexicalName,
|
||||
Timezone: u.Timezone,
|
||||
Role: u.Role,
|
||||
Status: u.Status,
|
||||
|
||||
ProfileData: &user.UserProfileData{
|
||||
Phone: u.Phone,
|
||||
Country: u.Country,
|
||||
Region: u.Region,
|
||||
City: u.City,
|
||||
PostalCode: u.PostalCode,
|
||||
AddressLine1: u.AddressLine1,
|
||||
AddressLine2: u.AddressLine2,
|
||||
HasShippingAddress: u.HasShippingAddress,
|
||||
ShippingName: u.ShippingName,
|
||||
ShippingPhone: u.ShippingPhone,
|
||||
ShippingCountry: u.ShippingCountry,
|
||||
ShippingRegion: u.ShippingRegion,
|
||||
ShippingCity: u.ShippingCity,
|
||||
ShippingPostalCode: u.ShippingPostalCode,
|
||||
ShippingAddressLine1: u.ShippingAddressLine1,
|
||||
ShippingAddressLine2: u.ShippingAddressLine2,
|
||||
Timezone: u.ProfileTimezone,
|
||||
AgreeTermsOfService: u.AgreeTermsOfService,
|
||||
AgreePromotions: u.AgreePromotions,
|
||||
AgreeToTrackingAcrossThirdPartyAppsAndServices: u.AgreeToTrackingAcrossThirdPartyAppsAndServices,
|
||||
},
|
||||
|
||||
SecurityData: &user.UserSecurityData{
|
||||
PasswordHashAlgorithm: u.PasswordHashAlgorithm,
|
||||
PasswordHash: u.PasswordHash,
|
||||
WasEmailVerified: u.WasEmailVerified,
|
||||
Code: u.Code,
|
||||
CodeType: u.CodeType,
|
||||
CodeExpiry: u.CodeExpiry,
|
||||
OTPEnabled: u.OTPEnabled,
|
||||
OTPVerified: u.OTPVerified,
|
||||
OTPValidated: u.OTPValidated,
|
||||
OTPSecret: u.OTPSecret,
|
||||
OTPAuthURL: u.OTPAuthURL,
|
||||
OTPBackupCodeHash: u.OTPBackupCodeHash,
|
||||
OTPBackupCodeHashAlgorithm: u.OTPBackupCodeHashAlgorithm,
|
||||
},
|
||||
|
||||
Metadata: &user.UserMetadata{
|
||||
CreatedFromIPAddress: u.CreatedFromIPAddress,
|
||||
CreatedFromIPTimestamp: u.CreatedFromIPTimestamp,
|
||||
CreatedByUserID: u.CreatedByUserID,
|
||||
CreatedAt: u.CreatedAt,
|
||||
CreatedByName: u.CreatedByName,
|
||||
ModifiedFromIPAddress: u.ModifiedFromIPAddress,
|
||||
ModifiedFromIPTimestamp: u.ModifiedFromIPTimestamp,
|
||||
ModifiedByUserID: u.ModifiedByUserID,
|
||||
ModifiedAt: u.ModifiedAt,
|
||||
ModifiedByName: u.ModifiedByName,
|
||||
LastLoginAt: u.LastLoginAt,
|
||||
},
|
||||
|
||||
TenantID: u.TenantID,
|
||||
CreatedAt: u.CreatedAt,
|
||||
UpdatedAt: u.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
// FromUserByEmail converts domain entity to table model
|
||||
func FromUserByEmail(tenantID string, u *user.User) *UserByEmail {
|
||||
userByEmail := &UserByEmail{
|
||||
TenantID: tenantID,
|
||||
Email: u.Email,
|
||||
ID: u.ID,
|
||||
FirstName: u.FirstName,
|
||||
LastName: u.LastName,
|
||||
Name: u.Name,
|
||||
LexicalName: u.LexicalName,
|
||||
Timezone: u.Timezone,
|
||||
Role: u.Role,
|
||||
Status: u.Status,
|
||||
CreatedAt: u.CreatedAt,
|
||||
UpdatedAt: u.UpdatedAt,
|
||||
}
|
||||
|
||||
// Map ProfileData if present
|
||||
if u.ProfileData != nil {
|
||||
userByEmail.Phone = u.ProfileData.Phone
|
||||
userByEmail.Country = u.ProfileData.Country
|
||||
userByEmail.Region = u.ProfileData.Region
|
||||
userByEmail.City = u.ProfileData.City
|
||||
userByEmail.PostalCode = u.ProfileData.PostalCode
|
||||
userByEmail.AddressLine1 = u.ProfileData.AddressLine1
|
||||
userByEmail.AddressLine2 = u.ProfileData.AddressLine2
|
||||
userByEmail.HasShippingAddress = u.ProfileData.HasShippingAddress
|
||||
userByEmail.ShippingName = u.ProfileData.ShippingName
|
||||
userByEmail.ShippingPhone = u.ProfileData.ShippingPhone
|
||||
userByEmail.ShippingCountry = u.ProfileData.ShippingCountry
|
||||
userByEmail.ShippingRegion = u.ProfileData.ShippingRegion
|
||||
userByEmail.ShippingCity = u.ProfileData.ShippingCity
|
||||
userByEmail.ShippingPostalCode = u.ProfileData.ShippingPostalCode
|
||||
userByEmail.ShippingAddressLine1 = u.ProfileData.ShippingAddressLine1
|
||||
userByEmail.ShippingAddressLine2 = u.ProfileData.ShippingAddressLine2
|
||||
userByEmail.ProfileTimezone = u.ProfileData.Timezone
|
||||
userByEmail.AgreeTermsOfService = u.ProfileData.AgreeTermsOfService
|
||||
userByEmail.AgreePromotions = u.ProfileData.AgreePromotions
|
||||
userByEmail.AgreeToTrackingAcrossThirdPartyAppsAndServices = u.ProfileData.AgreeToTrackingAcrossThirdPartyAppsAndServices
|
||||
}
|
||||
|
||||
// Map SecurityData if present
|
||||
if u.SecurityData != nil {
|
||||
userByEmail.PasswordHashAlgorithm = u.SecurityData.PasswordHashAlgorithm
|
||||
userByEmail.PasswordHash = u.SecurityData.PasswordHash
|
||||
userByEmail.WasEmailVerified = u.SecurityData.WasEmailVerified
|
||||
userByEmail.Code = u.SecurityData.Code
|
||||
userByEmail.CodeType = u.SecurityData.CodeType
|
||||
userByEmail.CodeExpiry = u.SecurityData.CodeExpiry
|
||||
userByEmail.OTPEnabled = u.SecurityData.OTPEnabled
|
||||
userByEmail.OTPVerified = u.SecurityData.OTPVerified
|
||||
userByEmail.OTPValidated = u.SecurityData.OTPValidated
|
||||
userByEmail.OTPSecret = u.SecurityData.OTPSecret
|
||||
userByEmail.OTPAuthURL = u.SecurityData.OTPAuthURL
|
||||
userByEmail.OTPBackupCodeHash = u.SecurityData.OTPBackupCodeHash
|
||||
userByEmail.OTPBackupCodeHashAlgorithm = u.SecurityData.OTPBackupCodeHashAlgorithm
|
||||
}
|
||||
|
||||
// Map Metadata if present
|
||||
if u.Metadata != nil {
|
||||
userByEmail.CreatedFromIPAddress = u.Metadata.CreatedFromIPAddress
|
||||
userByEmail.CreatedFromIPTimestamp = u.Metadata.CreatedFromIPTimestamp
|
||||
userByEmail.CreatedByUserID = u.Metadata.CreatedByUserID
|
||||
userByEmail.CreatedByName = u.Metadata.CreatedByName
|
||||
userByEmail.ModifiedFromIPAddress = u.Metadata.ModifiedFromIPAddress
|
||||
userByEmail.ModifiedFromIPTimestamp = u.Metadata.ModifiedFromIPTimestamp
|
||||
userByEmail.ModifiedByUserID = u.Metadata.ModifiedByUserID
|
||||
userByEmail.ModifiedAt = u.Metadata.ModifiedAt
|
||||
userByEmail.ModifiedByName = u.Metadata.ModifiedByName
|
||||
userByEmail.LastLoginAt = u.Metadata.LastLoginAt
|
||||
}
|
||||
|
||||
return userByEmail
|
||||
}
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/domain/user"
|
||||
)
|
||||
|
||||
// UserByID represents the users_by_id table
|
||||
// Query pattern: Get user by ID
|
||||
// Primary key: (tenant_id, id) - composite partition key for multi-tenancy
|
||||
type UserByID struct {
|
||||
TenantID string `db:"tenant_id"` // Multi-tenant isolation
|
||||
ID string `db:"id"`
|
||||
Email string `db:"email"`
|
||||
FirstName string `db:"first_name"`
|
||||
LastName string `db:"last_name"`
|
||||
Name string `db:"name"`
|
||||
LexicalName string `db:"lexical_name"`
|
||||
Timezone string `db:"timezone"`
|
||||
Role int `db:"role"`
|
||||
Status int `db:"status"`
|
||||
|
||||
// Profile data fields (flattened)
|
||||
Phone string `db:"phone"`
|
||||
Country string `db:"country"`
|
||||
Region string `db:"region"`
|
||||
City string `db:"city"`
|
||||
PostalCode string `db:"postal_code"`
|
||||
AddressLine1 string `db:"address_line1"`
|
||||
AddressLine2 string `db:"address_line2"`
|
||||
HasShippingAddress bool `db:"has_shipping_address"`
|
||||
ShippingName string `db:"shipping_name"`
|
||||
ShippingPhone string `db:"shipping_phone"`
|
||||
ShippingCountry string `db:"shipping_country"`
|
||||
ShippingRegion string `db:"shipping_region"`
|
||||
ShippingCity string `db:"shipping_city"`
|
||||
ShippingPostalCode string `db:"shipping_postal_code"`
|
||||
ShippingAddressLine1 string `db:"shipping_address_line1"`
|
||||
ShippingAddressLine2 string `db:"shipping_address_line2"`
|
||||
ProfileTimezone string `db:"profile_timezone"`
|
||||
AgreeTermsOfService bool `db:"agree_terms_of_service"`
|
||||
AgreePromotions bool `db:"agree_promotions"`
|
||||
AgreeToTrackingAcrossThirdPartyAppsAndServices bool `db:"agree_to_tracking_across_third_party_apps_and_services"`
|
||||
|
||||
// Security data fields (flattened)
|
||||
PasswordHashAlgorithm string `db:"password_hash_algorithm"`
|
||||
PasswordHash string `db:"password_hash"`
|
||||
WasEmailVerified bool `db:"was_email_verified"`
|
||||
Code string `db:"code"`
|
||||
CodeType string `db:"code_type"`
|
||||
CodeExpiry time.Time `db:"code_expiry"`
|
||||
OTPEnabled bool `db:"otp_enabled"`
|
||||
OTPVerified bool `db:"otp_verified"`
|
||||
OTPValidated bool `db:"otp_validated"`
|
||||
OTPSecret string `db:"otp_secret"`
|
||||
OTPAuthURL string `db:"otp_auth_url"`
|
||||
OTPBackupCodeHash string `db:"otp_backup_code_hash"`
|
||||
OTPBackupCodeHashAlgorithm string `db:"otp_backup_code_hash_algorithm"`
|
||||
|
||||
// Metadata fields (flattened)
|
||||
// CWE-359: Encrypted IP addresses for GDPR compliance
|
||||
CreatedFromIPAddress string `db:"created_from_ip_address"` // Encrypted with go-ipcrypt
|
||||
CreatedFromIPTimestamp time.Time `db:"created_from_ip_timestamp"` // For 90-day expiration tracking
|
||||
CreatedByUserID string `db:"created_by_user_id"`
|
||||
CreatedByName string `db:"created_by_name"`
|
||||
ModifiedFromIPAddress string `db:"modified_from_ip_address"` // Encrypted with go-ipcrypt
|
||||
ModifiedFromIPTimestamp time.Time `db:"modified_from_ip_timestamp"` // For 90-day expiration tracking
|
||||
ModifiedByUserID string `db:"modified_by_user_id"`
|
||||
ModifiedAt time.Time `db:"modified_at"`
|
||||
ModifiedByName string `db:"modified_by_name"`
|
||||
LastLoginAt time.Time `db:"last_login_at"`
|
||||
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
// ToUser converts table model to domain entity
|
||||
func (u *UserByID) ToUser() *user.User {
|
||||
return &user.User{
|
||||
ID: u.ID,
|
||||
Email: u.Email,
|
||||
FirstName: u.FirstName,
|
||||
LastName: u.LastName,
|
||||
Name: u.Name,
|
||||
LexicalName: u.LexicalName,
|
||||
Timezone: u.Timezone,
|
||||
Role: u.Role,
|
||||
Status: u.Status,
|
||||
|
||||
ProfileData: &user.UserProfileData{
|
||||
Phone: u.Phone,
|
||||
Country: u.Country,
|
||||
Region: u.Region,
|
||||
City: u.City,
|
||||
PostalCode: u.PostalCode,
|
||||
AddressLine1: u.AddressLine1,
|
||||
AddressLine2: u.AddressLine2,
|
||||
HasShippingAddress: u.HasShippingAddress,
|
||||
ShippingName: u.ShippingName,
|
||||
ShippingPhone: u.ShippingPhone,
|
||||
ShippingCountry: u.ShippingCountry,
|
||||
ShippingRegion: u.ShippingRegion,
|
||||
ShippingCity: u.ShippingCity,
|
||||
ShippingPostalCode: u.ShippingPostalCode,
|
||||
ShippingAddressLine1: u.ShippingAddressLine1,
|
||||
ShippingAddressLine2: u.ShippingAddressLine2,
|
||||
Timezone: u.ProfileTimezone,
|
||||
AgreeTermsOfService: u.AgreeTermsOfService,
|
||||
AgreePromotions: u.AgreePromotions,
|
||||
AgreeToTrackingAcrossThirdPartyAppsAndServices: u.AgreeToTrackingAcrossThirdPartyAppsAndServices,
|
||||
},
|
||||
|
||||
SecurityData: &user.UserSecurityData{
|
||||
PasswordHashAlgorithm: u.PasswordHashAlgorithm,
|
||||
PasswordHash: u.PasswordHash,
|
||||
WasEmailVerified: u.WasEmailVerified,
|
||||
Code: u.Code,
|
||||
CodeType: u.CodeType,
|
||||
CodeExpiry: u.CodeExpiry,
|
||||
OTPEnabled: u.OTPEnabled,
|
||||
OTPVerified: u.OTPVerified,
|
||||
OTPValidated: u.OTPValidated,
|
||||
OTPSecret: u.OTPSecret,
|
||||
OTPAuthURL: u.OTPAuthURL,
|
||||
OTPBackupCodeHash: u.OTPBackupCodeHash,
|
||||
OTPBackupCodeHashAlgorithm: u.OTPBackupCodeHashAlgorithm,
|
||||
},
|
||||
|
||||
Metadata: &user.UserMetadata{
|
||||
CreatedFromIPAddress: u.CreatedFromIPAddress,
|
||||
CreatedFromIPTimestamp: u.CreatedFromIPTimestamp,
|
||||
CreatedByUserID: u.CreatedByUserID,
|
||||
CreatedAt: u.CreatedAt,
|
||||
CreatedByName: u.CreatedByName,
|
||||
ModifiedFromIPAddress: u.ModifiedFromIPAddress,
|
||||
ModifiedFromIPTimestamp: u.ModifiedFromIPTimestamp,
|
||||
ModifiedByUserID: u.ModifiedByUserID,
|
||||
ModifiedAt: u.ModifiedAt,
|
||||
ModifiedByName: u.ModifiedByName,
|
||||
LastLoginAt: u.LastLoginAt,
|
||||
},
|
||||
|
||||
TenantID: u.TenantID,
|
||||
CreatedAt: u.CreatedAt,
|
||||
UpdatedAt: u.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
// FromUser converts domain entity to table model
|
||||
func FromUser(tenantID string, u *user.User) *UserByID {
|
||||
userByID := &UserByID{
|
||||
TenantID: tenantID,
|
||||
ID: u.ID,
|
||||
Email: u.Email,
|
||||
FirstName: u.FirstName,
|
||||
LastName: u.LastName,
|
||||
Name: u.Name,
|
||||
LexicalName: u.LexicalName,
|
||||
Timezone: u.Timezone,
|
||||
Role: u.Role,
|
||||
Status: u.Status,
|
||||
CreatedAt: u.CreatedAt,
|
||||
UpdatedAt: u.UpdatedAt,
|
||||
}
|
||||
|
||||
// Map ProfileData if present
|
||||
if u.ProfileData != nil {
|
||||
userByID.Phone = u.ProfileData.Phone
|
||||
userByID.Country = u.ProfileData.Country
|
||||
userByID.Region = u.ProfileData.Region
|
||||
userByID.City = u.ProfileData.City
|
||||
userByID.PostalCode = u.ProfileData.PostalCode
|
||||
userByID.AddressLine1 = u.ProfileData.AddressLine1
|
||||
userByID.AddressLine2 = u.ProfileData.AddressLine2
|
||||
userByID.HasShippingAddress = u.ProfileData.HasShippingAddress
|
||||
userByID.ShippingName = u.ProfileData.ShippingName
|
||||
userByID.ShippingPhone = u.ProfileData.ShippingPhone
|
||||
userByID.ShippingCountry = u.ProfileData.ShippingCountry
|
||||
userByID.ShippingRegion = u.ProfileData.ShippingRegion
|
||||
userByID.ShippingCity = u.ProfileData.ShippingCity
|
||||
userByID.ShippingPostalCode = u.ProfileData.ShippingPostalCode
|
||||
userByID.ShippingAddressLine1 = u.ProfileData.ShippingAddressLine1
|
||||
userByID.ShippingAddressLine2 = u.ProfileData.ShippingAddressLine2
|
||||
userByID.ProfileTimezone = u.ProfileData.Timezone
|
||||
userByID.AgreeTermsOfService = u.ProfileData.AgreeTermsOfService
|
||||
userByID.AgreePromotions = u.ProfileData.AgreePromotions
|
||||
userByID.AgreeToTrackingAcrossThirdPartyAppsAndServices = u.ProfileData.AgreeToTrackingAcrossThirdPartyAppsAndServices
|
||||
}
|
||||
|
||||
// Map SecurityData if present
|
||||
if u.SecurityData != nil {
|
||||
userByID.PasswordHashAlgorithm = u.SecurityData.PasswordHashAlgorithm
|
||||
userByID.PasswordHash = u.SecurityData.PasswordHash
|
||||
userByID.WasEmailVerified = u.SecurityData.WasEmailVerified
|
||||
userByID.Code = u.SecurityData.Code
|
||||
userByID.CodeType = u.SecurityData.CodeType
|
||||
userByID.CodeExpiry = u.SecurityData.CodeExpiry
|
||||
userByID.OTPEnabled = u.SecurityData.OTPEnabled
|
||||
userByID.OTPVerified = u.SecurityData.OTPVerified
|
||||
userByID.OTPValidated = u.SecurityData.OTPValidated
|
||||
userByID.OTPSecret = u.SecurityData.OTPSecret
|
||||
userByID.OTPAuthURL = u.SecurityData.OTPAuthURL
|
||||
userByID.OTPBackupCodeHash = u.SecurityData.OTPBackupCodeHash
|
||||
userByID.OTPBackupCodeHashAlgorithm = u.SecurityData.OTPBackupCodeHashAlgorithm
|
||||
}
|
||||
|
||||
// Map Metadata if present
|
||||
if u.Metadata != nil {
|
||||
userByID.CreatedFromIPAddress = u.Metadata.CreatedFromIPAddress
|
||||
userByID.CreatedFromIPTimestamp = u.Metadata.CreatedFromIPTimestamp
|
||||
userByID.CreatedByUserID = u.Metadata.CreatedByUserID
|
||||
userByID.CreatedByName = u.Metadata.CreatedByName
|
||||
userByID.ModifiedFromIPAddress = u.Metadata.ModifiedFromIPAddress
|
||||
userByID.ModifiedFromIPTimestamp = u.Metadata.ModifiedFromIPTimestamp
|
||||
userByID.ModifiedByUserID = u.Metadata.ModifiedByUserID
|
||||
userByID.ModifiedAt = u.Metadata.ModifiedAt
|
||||
userByID.ModifiedByName = u.Metadata.ModifiedByName
|
||||
userByID.LastLoginAt = u.Metadata.LastLoginAt
|
||||
}
|
||||
|
||||
return userByID
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue