162 lines
6.8 KiB
Go
162 lines
6.8 KiB
Go
package localdb
|
|
|
|
import (
|
|
"database/sql/driver"
|
|
"encoding/json"
|
|
"errors"
|
|
"time"
|
|
)
|
|
|
|
// AppSetting stores application settings in local SQLite
|
|
type AppSetting struct {
|
|
Key string `gorm:"primaryKey" json:"key"`
|
|
Value string `gorm:"not null" json:"value"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
func (AppSetting) TableName() string {
|
|
return "app_settings"
|
|
}
|
|
|
|
// LocalConfigItem represents an item in a configuration
|
|
type LocalConfigItem struct {
|
|
LotName string `json:"lot_name"`
|
|
Quantity int `json:"quantity"`
|
|
UnitPrice float64 `json:"unit_price"`
|
|
}
|
|
|
|
// LocalConfigItems is a slice of LocalConfigItem that can be stored as JSON
|
|
type LocalConfigItems []LocalConfigItem
|
|
|
|
func (c LocalConfigItems) Value() (driver.Value, error) {
|
|
return json.Marshal(c)
|
|
}
|
|
|
|
func (c *LocalConfigItems) Scan(value interface{}) error {
|
|
if value == nil {
|
|
*c = make(LocalConfigItems, 0)
|
|
return nil
|
|
}
|
|
var bytes []byte
|
|
switch v := value.(type) {
|
|
case []byte:
|
|
bytes = v
|
|
case string:
|
|
bytes = []byte(v)
|
|
default:
|
|
return errors.New("type assertion failed for LocalConfigItems")
|
|
}
|
|
return json.Unmarshal(bytes, c)
|
|
}
|
|
|
|
func (c LocalConfigItems) Total() float64 {
|
|
var total float64
|
|
for _, item := range c {
|
|
total += item.UnitPrice * float64(item.Quantity)
|
|
}
|
|
return total
|
|
}
|
|
|
|
// LocalConfiguration stores configurations in local SQLite
|
|
type LocalConfiguration struct {
|
|
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
|
UUID string `gorm:"uniqueIndex;not null" json:"uuid"`
|
|
ServerID *uint `json:"server_id"` // ID on MariaDB server, NULL if local only
|
|
CurrentVersionID *string `gorm:"index" json:"current_version_id,omitempty"`
|
|
IsActive bool `gorm:"default:true;index" json:"is_active"`
|
|
Name string `gorm:"not null" json:"name"`
|
|
Items LocalConfigItems `gorm:"type:text" json:"items"` // JSON stored as text in SQLite
|
|
TotalPrice *float64 `json:"total_price"`
|
|
CustomPrice *float64 `json:"custom_price"`
|
|
Notes string `json:"notes"`
|
|
IsTemplate bool `gorm:"default:false" json:"is_template"`
|
|
ServerCount int `gorm:"default:1" json:"server_count"`
|
|
PriceUpdatedAt *time.Time `gorm:"type:timestamp" json:"price_updated_at,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
SyncedAt *time.Time `json:"synced_at"`
|
|
SyncStatus string `gorm:"default:'local'" json:"sync_status"` // 'local', 'synced', 'modified'
|
|
OriginalUserID uint `json:"original_user_id"` // UserID from MariaDB for reference
|
|
OriginalUsername string `gorm:"not null;default:'';index" json:"original_username"`
|
|
CurrentVersion *LocalConfigurationVersion `gorm:"foreignKey:CurrentVersionID;references:ID" json:"current_version,omitempty"`
|
|
Versions []LocalConfigurationVersion `gorm:"foreignKey:ConfigurationUUID;references:UUID" json:"versions,omitempty"`
|
|
}
|
|
|
|
func (LocalConfiguration) TableName() string {
|
|
return "local_configurations"
|
|
}
|
|
|
|
// LocalConfigurationVersion stores immutable full snapshots for each configuration version
|
|
type LocalConfigurationVersion struct {
|
|
ID string `gorm:"primaryKey" json:"id"`
|
|
ConfigurationUUID string `gorm:"not null;index:idx_lcv_config_created,priority:1;index:idx_lcv_config_version,priority:1;uniqueIndex:idx_lcv_config_version_unique,priority:1" json:"configuration_uuid"`
|
|
VersionNo int `gorm:"not null;index:idx_lcv_config_version,sort:desc,priority:2;uniqueIndex:idx_lcv_config_version_unique,priority:2" json:"version_no"`
|
|
Data string `gorm:"type:text;not null" json:"data"`
|
|
ChangeNote *string `json:"change_note,omitempty"`
|
|
CreatedBy *string `json:"created_by,omitempty"`
|
|
AppVersion string `gorm:"size:64" json:"app_version,omitempty"`
|
|
CreatedAt time.Time `gorm:"not null;autoCreateTime;index:idx_lcv_config_created,sort:desc,priority:2" json:"created_at"`
|
|
Configuration *LocalConfiguration `gorm:"foreignKey:ConfigurationUUID;references:UUID" json:"configuration,omitempty"`
|
|
}
|
|
|
|
func (LocalConfigurationVersion) TableName() string {
|
|
return "local_configuration_versions"
|
|
}
|
|
|
|
// LocalPricelist stores cached pricelists from server
|
|
type LocalPricelist struct {
|
|
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
|
ServerID uint `gorm:"not null" json:"server_id"` // ID on MariaDB server
|
|
Version string `gorm:"uniqueIndex;not null" json:"version"`
|
|
Name string `json:"name"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
SyncedAt time.Time `json:"synced_at"`
|
|
IsUsed bool `gorm:"default:false" json:"is_used"` // Used by any local configuration
|
|
}
|
|
|
|
func (LocalPricelist) TableName() string {
|
|
return "local_pricelists"
|
|
}
|
|
|
|
// LocalPricelistItem stores pricelist items
|
|
type LocalPricelistItem struct {
|
|
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
|
|
PricelistID uint `gorm:"not null;index" json:"pricelist_id"`
|
|
LotName string `gorm:"not null" json:"lot_name"`
|
|
Price float64 `gorm:"not null" json:"price"`
|
|
}
|
|
|
|
func (LocalPricelistItem) TableName() string {
|
|
return "local_pricelist_items"
|
|
}
|
|
|
|
// LocalComponent stores cached components for offline search
|
|
type LocalComponent struct {
|
|
LotName string `gorm:"primaryKey" json:"lot_name"`
|
|
LotDescription string `json:"lot_description"`
|
|
Category string `json:"category"`
|
|
Model string `json:"model"`
|
|
CurrentPrice *float64 `json:"current_price"`
|
|
SyncedAt time.Time `json:"synced_at"`
|
|
}
|
|
|
|
func (LocalComponent) TableName() string {
|
|
return "local_components"
|
|
}
|
|
|
|
// PendingChange stores changes that need to be synced to the server
|
|
type PendingChange struct {
|
|
ID int64 `gorm:"primaryKey;autoIncrement" json:"id"`
|
|
EntityType string `gorm:"not null;index" json:"entity_type"` // "configuration", "project", "specification"
|
|
EntityUUID string `gorm:"not null;index" json:"entity_uuid"`
|
|
Operation string `gorm:"not null" json:"operation"` // "create", "update", "rollback", "deactivate", "reactivate", "delete"
|
|
Payload string `gorm:"type:text" json:"payload"` // JSON snapshot of the entity
|
|
CreatedAt time.Time `gorm:"not null" json:"created_at"`
|
|
Attempts int `gorm:"default:0" json:"attempts"` // Retry count for sync
|
|
LastError string `gorm:"type:text" json:"last_error,omitempty"`
|
|
}
|
|
|
|
func (PendingChange) TableName() string {
|
|
return "pending_changes"
|
|
}
|