5.2 KiB
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
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:
LedgerIDin Transaction model
Constants
const MaxLedgersPerUser = 10
Maximum number of ledgers a user can create (Requirement 3.12)
Database Schema
Table: ledgers
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:
LedgerID *uint `gorm:"index" json:"ledger_id,omitempty"`
This creates a foreign key relationship between transactions and ledgers.
Migration
Using Go Migration Tool
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
mysql -u username -p database_name < backend/migrations/001_add_ledger_support.sql
Testing
Unit tests are provided in ledger_test.go:
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
// 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:
- Task 3.1: Implement Ledger CRUD API endpoints
- Task 3.2: Implement soft delete and restore functionality
- Task 10.1-10.3: Implement frontend components for ledger management
Validation Rules
When implementing the API layer, ensure:
- Name validation: Required, max 100 characters
- Theme validation: Optional, must be one of: "pink", "beige", "brown"
- Ledger count limit: User cannot create more than 10 ledgers (MaxLedgersPerUser)
- Default ledger: At least one ledger must exist and be marked as default
- 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