feat: sync current progress (P0 hardening + P1 observability + deploy docs/systemd)
This commit is contained in:
20
internal/model/asset.go
Normal file
20
internal/model/asset.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type Asset struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;index:idx_assets_user_status_id,priority:3"`
|
||||
UserID uint `json:"user_id" gorm:"not null;index:idx_assets_user_status_category,priority:1;index:idx_assets_user_status_id,priority:1"`
|
||||
Name string `json:"name" gorm:"size:128;not null"`
|
||||
CategoryID uint `json:"category_id" gorm:"not null;index:idx_assets_user_status_category,priority:3"`
|
||||
Category Category `json:"-"`
|
||||
Quantity float64 `json:"quantity" gorm:"not null"`
|
||||
UnitPrice float64 `json:"unit_price" gorm:"not null"`
|
||||
TotalValue float64 `json:"total_value" gorm:"not null;index"`
|
||||
Currency string `json:"currency" gorm:"size:16;not null"`
|
||||
ExpiryDate *time.Time `json:"expiry_date,omitempty" gorm:"index"`
|
||||
Note string `json:"note" gorm:"type:text"`
|
||||
Status string `json:"status" gorm:"size:16;not null;default:active;check:status IN ('active','inactive');index:idx_assets_user_status_category,priority:2;index:idx_assets_user_status_id,priority:2"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
14
internal/model/audit_log.go
Normal file
14
internal/model/audit_log.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type AuditLog struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
UserID uint `json:"user_id" gorm:"not null;index"`
|
||||
EntityType string `json:"entity_type" gorm:"size:32;not null;index"`
|
||||
EntityID uint `json:"entity_id" gorm:"not null;index"`
|
||||
Action string `json:"action" gorm:"size:16;not null;index"`
|
||||
BeforeJSON string `json:"before_json" gorm:"type:text"`
|
||||
AfterJSON string `json:"after_json" gorm:"type:text"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
13
internal/model/category.go
Normal file
13
internal/model/category.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type Category struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
UserID uint `json:"user_id" gorm:"not null;uniqueIndex:uidx_categories_user_name,priority:1;index"`
|
||||
Name string `json:"name" gorm:"size:128;not null;uniqueIndex:uidx_categories_user_name,priority:2"`
|
||||
Type string `json:"type" gorm:"size:16;not null"`
|
||||
Color string `json:"color" gorm:"size:32"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
14
internal/model/refresh_session.go
Normal file
14
internal/model/refresh_session.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type RefreshSession struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
UserID uint `json:"user_id" gorm:"not null;index"`
|
||||
JTI string `json:"jti" gorm:"size:64;not null;uniqueIndex"`
|
||||
ExpiresAt time.Time `json:"expires_at" gorm:"not null;index"`
|
||||
RevokedAt *time.Time `json:"revoked_at,omitempty" gorm:"index"`
|
||||
ReplacedBy string `json:"replaced_by" gorm:"size:64"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
19
internal/model/reminder.go
Normal file
19
internal/model/reminder.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type Reminder struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
UserID uint `json:"user_id" gorm:"not null;index;uniqueIndex:uq_reminder_identity,priority:1"`
|
||||
AssetID uint `json:"asset_id" gorm:"not null;index;uniqueIndex:uq_reminder_identity,priority:2"`
|
||||
RemindAt time.Time `json:"remind_at" gorm:"not null;index:idx_reminders_status_remind_at,priority:2;uniqueIndex:uq_reminder_identity,priority:3"`
|
||||
Channel string `json:"channel" gorm:"size:32;not null;default:in_app;uniqueIndex:uq_reminder_identity,priority:4"`
|
||||
Status string `json:"status" gorm:"size:16;not null;default:pending;check:status IN ('pending','sending','sent','failed');index:idx_reminders_status_remind_at,priority:1;index:idx_reminders_next_retry_status,priority:2;index:idx_reminders_status_next_retry,priority:1"`
|
||||
DedupeKey string `json:"dedupe_key" gorm:"size:128;not null;uniqueIndex"`
|
||||
RetryCount int `json:"retry_count" gorm:"not null;default:0"`
|
||||
NextRetryAt *time.Time `json:"next_retry_at,omitempty" gorm:"index:idx_reminders_next_retry_status,priority:1;index:idx_reminders_status_next_retry,priority:2"`
|
||||
LastError string `json:"last_error" gorm:"size:500"`
|
||||
SentAt *time.Time `json:"sent_at,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
17
internal/model/reminder_dead_letter.go
Normal file
17
internal/model/reminder_dead_letter.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type ReminderDeadLetter struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
ReminderID uint `json:"reminder_id" gorm:"not null;uniqueIndex"`
|
||||
UserID uint `json:"user_id" gorm:"not null;index"`
|
||||
AssetID uint `json:"asset_id" gorm:"not null;index"`
|
||||
RemindAt time.Time `json:"remind_at" gorm:"not null;index"`
|
||||
Channel string `json:"channel" gorm:"size:32;not null"`
|
||||
Status string `json:"status" gorm:"size:16;not null"`
|
||||
RetryCount int `json:"retry_count" gorm:"not null"`
|
||||
LastError string `json:"last_error" gorm:"size:500"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
12
internal/model/user.go
Normal file
12
internal/model/user.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type User struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
Username string `json:"username" gorm:"size:64;uniqueIndex;not null"`
|
||||
PasswordHash string `json:"-" gorm:"size:255;not null"`
|
||||
Timezone string `json:"timezone" gorm:"size:64;not null;default:UTC"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
Reference in New Issue
Block a user