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

6.9 KiB

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:

// 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:

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:

ALTER TABLE accounts 
    ADD INDEX idx_accounts_sort_order (sort_order),
    ADD INDEX idx_accounts_account_type (account_type);

Running the Migration

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

mysql -u your_username -p your_database < backend/migrations/004_extend_account_model.sql

Testing

Run the unit tests:

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)
  • 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