init
This commit is contained in:
189
internal/models/ACCOUNT_EXTENSION_IMPLEMENTATION.md
Normal file
189
internal/models/ACCOUNT_EXTENSION_IMPLEMENTATION.md
Normal file
@@ -0,0 +1,189 @@
|
||||
# Account Model Extension Implementation
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes the implementation of task 1.6: Extending the Account model to support asset management enhancements for the accounting-feature-upgrade specification.
|
||||
|
||||
## Feature
|
||||
|
||||
**Feature:** accounting-feature-upgrade
|
||||
**Task:** 1.6 扩展Account模型
|
||||
**Validates:** Requirements 1.2-1.10
|
||||
|
||||
## Changes Made
|
||||
|
||||
### 1. Model Extension (backend/internal/models/models.go)
|
||||
|
||||
Added the following fields to the `Account` struct:
|
||||
|
||||
```go
|
||||
// Asset management enhancements
|
||||
// Feature: accounting-feature-upgrade
|
||||
// Validates: Requirements 1.2-1.10
|
||||
SortOrder int `gorm:"default:0" json:"sort_order"` // Display order for account list
|
||||
WarningThreshold *float64 `gorm:"type:decimal(15,2)" json:"warning_threshold,omitempty"` // Balance warning threshold
|
||||
LastSyncTime *time.Time `json:"last_sync_time,omitempty"` // Last synchronization time
|
||||
AccountCode string `gorm:"size:50" json:"account_code,omitempty"` // Account identifier (e.g., Alipay, Wechat)
|
||||
AccountType string `gorm:"size:20;default:'asset'" json:"account_type"` // asset or liability
|
||||
```
|
||||
|
||||
### 2. Database Migration (backend/migrations/004_extend_account_model.sql)
|
||||
|
||||
Created a SQL migration file that:
|
||||
- Adds all five new fields to the `accounts` table
|
||||
- Adds indexes for `sort_order` and `account_type` to optimize queries
|
||||
- Includes proper comments for each field
|
||||
- Follows the project's migration file format
|
||||
|
||||
### 3. Unit Tests (backend/internal/models/account_extension_test.go)
|
||||
|
||||
Created comprehensive unit tests covering:
|
||||
|
||||
#### Test Coverage
|
||||
|
||||
1. **TestAccountExtension_SortOrderField** - Verifies the sort_order field works correctly
|
||||
2. **TestAccountExtension_WarningThresholdField** - Tests warning threshold with and without values
|
||||
3. **TestAccountExtension_LastSyncTimeField** - Tests last sync time with and without values
|
||||
4. **TestAccountExtension_AccountCodeField** - Tests various account codes (Alipay, Wechat, etc.)
|
||||
5. **TestAccountExtension_AccountTypeField** - Tests asset and liability account types
|
||||
6. **TestAccountExtension_WarningThresholdLogic** - Tests the warning threshold logic (Validates Requirements 1.5, 1.10)
|
||||
7. **TestAccountExtension_AllFieldsTogether** - Tests all fields working together
|
||||
8. **TestAccountExtension_AssetVsLiability** - Tests asset vs liability distinction (Validates Requirements 1.2)
|
||||
|
||||
#### Test Results
|
||||
|
||||
All tests pass successfully:
|
||||
```
|
||||
PASS: TestAccountExtension_SortOrderField
|
||||
PASS: TestAccountExtension_WarningThresholdField
|
||||
PASS: TestAccountExtension_LastSyncTimeField
|
||||
PASS: TestAccountExtension_AccountCodeField
|
||||
PASS: TestAccountExtension_AccountTypeField
|
||||
PASS: TestAccountExtension_WarningThresholdLogic
|
||||
PASS: TestAccountExtension_AllFieldsTogether
|
||||
PASS: TestAccountExtension_AssetVsLiability
|
||||
```
|
||||
|
||||
## Field Descriptions
|
||||
|
||||
### SortOrder (int)
|
||||
- **Purpose:** Controls the display order of accounts in the account list
|
||||
- **Default:** 0
|
||||
- **Usage:** Allows users to drag and reorder accounts, with the order persisted to the database
|
||||
- **Validates:** Requirements 1.3, 1.4
|
||||
|
||||
### WarningThreshold (*float64)
|
||||
- **Purpose:** Balance threshold below which a warning should be displayed
|
||||
- **Type:** Pointer to allow null values (no warning if not set)
|
||||
- **Usage:** When balance < threshold, display an orange "预警" (warning) badge
|
||||
- **Validates:** Requirements 1.5, 1.7, 1.10
|
||||
|
||||
### LastSyncTime (*time.Time)
|
||||
- **Purpose:** Tracks the last time the account was synchronized
|
||||
- **Type:** Pointer to allow null values
|
||||
- **Format:** Displayed as "MM月DD日 HH:mm" in the UI
|
||||
- **Validates:** Requirements 1.8
|
||||
|
||||
### AccountCode (string)
|
||||
- **Purpose:** Unique identifier for the account (e.g., "Alipay", "Wechat", "ICBC-1234")
|
||||
- **Max Length:** 50 characters
|
||||
- **Usage:** Displayed in account details to help users identify accounts
|
||||
- **Validates:** Requirements 1.9
|
||||
|
||||
### AccountType (string)
|
||||
- **Purpose:** Classifies accounts as either "asset" or "liability"
|
||||
- **Default:** "asset"
|
||||
- **Values:** "asset" (positive balance accounts) or "liability" (negative balance accounts like credit cards)
|
||||
- **Usage:** Used to calculate total assets (only includes asset type accounts)
|
||||
- **Validates:** Requirements 1.2
|
||||
|
||||
## Requirements Validation
|
||||
|
||||
This implementation validates the following requirements from the specification:
|
||||
|
||||
- **1.2** - Total assets calculation only includes asset type accounts
|
||||
- **1.3** - Accounts can be reordered using drag handles
|
||||
- **1.4** - Account order is persisted using sort_order field
|
||||
- **1.5** - Warning badge displayed when balance < threshold
|
||||
- **1.7** - Warning threshold can be set in account details
|
||||
- **1.8** - Last sync time is displayed in account details
|
||||
- **1.9** - Account unique ID (code) is displayed in account details
|
||||
- **1.10** - No warning displayed when threshold is not set (null)
|
||||
|
||||
## Database Schema Changes
|
||||
|
||||
The migration adds the following columns to the `accounts` table:
|
||||
|
||||
```sql
|
||||
ALTER TABLE accounts
|
||||
ADD COLUMN sort_order INT DEFAULT 0,
|
||||
ADD COLUMN warning_threshold DECIMAL(15,2) DEFAULT NULL,
|
||||
ADD COLUMN last_sync_time DATETIME DEFAULT NULL,
|
||||
ADD COLUMN account_code VARCHAR(50) DEFAULT NULL,
|
||||
ADD COLUMN account_type VARCHAR(20) DEFAULT 'asset';
|
||||
```
|
||||
|
||||
With indexes:
|
||||
```sql
|
||||
ALTER TABLE accounts
|
||||
ADD INDEX idx_accounts_sort_order (sort_order),
|
||||
ADD INDEX idx_accounts_account_type (account_type);
|
||||
```
|
||||
|
||||
## Running the Migration
|
||||
|
||||
### Option 1: Using GORM AutoMigrate (Recommended)
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
go run cmd/migrate/main.go
|
||||
```
|
||||
|
||||
GORM will automatically detect the new fields and add them to the database.
|
||||
|
||||
### Option 2: Manual SQL Execution
|
||||
|
||||
```bash
|
||||
mysql -u your_username -p your_database < backend/migrations/004_extend_account_model.sql
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Run the unit tests:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
go test -v ./internal/models -run TestAccountExtension
|
||||
```
|
||||
|
||||
All tests should pass.
|
||||
|
||||
## Next Steps
|
||||
|
||||
After this implementation:
|
||||
|
||||
1. The Account model is ready for use in the asset management page
|
||||
2. Backend API handlers can now use these fields for:
|
||||
- Account reordering (PUT /api/accounts/reorder)
|
||||
- Warning threshold settings
|
||||
- Sync time tracking
|
||||
- Asset vs liability filtering
|
||||
3. Frontend components can display:
|
||||
- Sorted account lists
|
||||
- Warning badges
|
||||
- Sync times
|
||||
- Account codes
|
||||
- Total assets (excluding liabilities)
|
||||
|
||||
## Related Tasks
|
||||
|
||||
- Task 6.1: Implement account reordering API
|
||||
- Task 9.1: Implement AssetSummaryCard component (uses AccountType)
|
||||
- Task 9.2: Implement DraggableAccountList component (uses SortOrder, WarningThreshold, LastSyncTime, AccountCode)
|
||||
|
||||
## Notes
|
||||
|
||||
- All new fields are optional (nullable or have defaults) to maintain backward compatibility
|
||||
- The AccountType field defaults to "asset" for existing accounts
|
||||
- Warning threshold logic: `shouldWarn = threshold != nil && balance < threshold`
|
||||
- The model is already registered in `AllModels()` function, so no additional registration is needed
|
||||
Reference in New Issue
Block a user