# Ledger Model Implementation ## Overview This document describes the implementation of the Ledger model for the multi-ledger accounting system feature. ## Feature **Feature:** accounting-feature-upgrade **Task:** 1.1 创建Ledger账本模型和数据库迁移 **Requirements:** 3.1 ## Model Definition ### Ledger Struct ```go type Ledger struct { BaseModel Name string `gorm:"size:100;not null" json:"name"` Theme string `gorm:"size:50" json:"theme"` // pink, beige, brown CoverImage string `gorm:"size:255" json:"cover_image"` IsDefault bool `gorm:"default:false" json:"is_default"` SortOrder int `gorm:"default:0" json:"sort_order"` // Relationships Transactions []Transaction `gorm:"foreignKey:LedgerID" json:"-"` } ``` ### Fields - **ID** (inherited from BaseModel): Primary key, auto-increment - **CreatedAt** (inherited from BaseModel): Timestamp when ledger was created - **UpdatedAt** (inherited from BaseModel): Timestamp when ledger was last updated - **DeletedAt** (inherited from BaseModel): Soft delete timestamp (NULL if not deleted) - **Name**: Ledger name (max 100 characters, required) - **Theme**: Theme color identifier (max 50 characters, optional) - Supported values: "pink", "beige", "brown" - **CoverImage**: Path to cover image (max 255 characters, optional) - **IsDefault**: Whether this is the default ledger (boolean, default: false) - **SortOrder**: Display order for ledgers (integer, default: 0) ### Relationships - **Transactions**: One-to-many relationship with Transaction model - A ledger can have multiple transactions - Foreign key: `LedgerID` in Transaction model ### Constants ```go const MaxLedgersPerUser = 10 ``` Maximum number of ledgers a user can create (Requirement 3.12) ## Database Schema ### Table: ledgers ```sql CREATE TABLE IF NOT EXISTS ledgers ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, created_at DATETIME(3) DEFAULT NULL, updated_at DATETIME(3) DEFAULT NULL, deleted_at DATETIME(3) DEFAULT NULL, name VARCHAR(100) NOT NULL, theme VARCHAR(50) DEFAULT NULL, cover_image VARCHAR(255) DEFAULT NULL, is_default TINYINT(1) DEFAULT 0, sort_order INT DEFAULT 0, PRIMARY KEY (id), INDEX idx_ledgers_deleted_at (deleted_at) ); ``` ### Transaction Model Extension The Transaction model has been extended with a `LedgerID` field: ```go LedgerID *uint `gorm:"index" json:"ledger_id,omitempty"` ``` This creates a foreign key relationship between transactions and ledgers. ## Migration ### Using Go Migration Tool ```bash cd backend go run cmd/migrate/main.go ``` This will automatically create the `ledgers` table and add the `ledger_id` column to the `transactions` table. ### Manual SQL Migration ```bash mysql -u username -p database_name < backend/migrations/001_add_ledger_support.sql ``` ## Testing Unit tests are provided in `ledger_test.go`: ```bash cd backend go test ./internal/models/... -v ``` Tests verify: - Table name is correct ("ledgers") - All model fields work correctly - MaxLedgersPerUser constant has the correct value ## Usage Example ```go // Create a new ledger ledger := models.Ledger{ Name: "Wedding Expenses", Theme: "pink", CoverImage: "/images/wedding-cover.jpg", IsDefault: false, SortOrder: 1, } // Save to database db.Create(&ledger) // Query ledgers var ledgers []models.Ledger db.Where("deleted_at IS NULL").Order("sort_order ASC").Find(&ledgers) // Soft delete a ledger db.Delete(&ledger) // Restore a soft-deleted ledger db.Model(&ledger).Update("deleted_at", nil) ``` ## Next Steps The following tasks will build upon this model: 1. **Task 3.1**: Implement Ledger CRUD API endpoints 2. **Task 3.2**: Implement soft delete and restore functionality 3. **Task 10.1-10.3**: Implement frontend components for ledger management ## Validation Rules When implementing the API layer, ensure: 1. **Name validation**: Required, max 100 characters 2. **Theme validation**: Optional, must be one of: "pink", "beige", "brown" 3. **Ledger count limit**: User cannot create more than 10 ledgers (MaxLedgersPerUser) 4. **Default ledger**: At least one ledger must exist and be marked as default 5. **Soft delete**: Use GORM's soft delete feature (DeletedAt field) ## Design Considerations ### Soft Delete The model uses GORM's soft delete feature (DeletedAt field from BaseModel). This means: - Deleted ledgers are not physically removed from the database - Deleted ledgers are automatically excluded from queries - Historical transaction data is preserved even after ledger deletion - Ledgers can be restored if needed ### Sort Order The `SortOrder` field allows users to customize the display order of their ledgers. Lower values appear first. ### Default Ledger The `IsDefault` field ensures there's always a default ledger for new transactions. Business logic should ensure: - At least one ledger is always marked as default - When the default ledger is deleted, another ledger is automatically promoted to default ## Compliance This implementation satisfies: - **Requirement 3.1**: Ledger data model with all specified fields - **Requirement 3.12**: Maximum 10 ledgers per user (constant defined) - **Design Document**: Ledger model structure matches the design specification