This commit is contained in:
2026-01-25 21:59:00 +08:00
parent 7fd537bef3
commit 4cad3f0250
118 changed files with 30473 additions and 0 deletions

View File

@@ -0,0 +1,188 @@
# 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