Files
Novault-backend/internal/models/ACCOUNT_EXTENSION_IMPLEMENTATION.md
2026-01-25 21:59:00 +08:00

190 lines
6.9 KiB
Markdown

# 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