* fix(database): prevent empty values from overwriting exchange private keys
Fixes#781
## Problem
- Empty values were overwriting existing private keys during exchange config updates
- INSERT operations were storing plaintext instead of encrypted values
- Caused data loss when users edited exchange configurations via web UI
## Solution
1. **Dynamic UPDATE**: Only update sensitive fields (api_key, secret_key, aster_private_key) when non-empty
2. **Encrypted INSERT**: Use encrypted values for all sensitive fields during INSERT
3. **Comprehensive tests**: Added 9 unit tests with 90.2% coverage
## Changes
- config/database.go (UpdateExchange): Refactored to use dynamic SQL building
- config/database_test.go (new): Added comprehensive test suite
## Test Results
✅ All 9 tests pass
✅ Coverage: 90.2% of UpdateExchange function (100% of normal paths)
✅ Verified empty values no longer overwrite existing keys
✅ Verified INSERT uses encrypted storage
## Impact
- 🔒 Protects user's exchange API keys and private keys from accidental deletion
- 🔒 Ensures all sensitive data is encrypted at rest
- ✅ Backward compatible: non-empty updates work as before
* revert: remove incorrect INSERT encryption fix - out of scope
This commit sets up a minimal, KISS-principle testing infrastructure
for both backend and frontend, and includes the fix for Issue #227.
Backend Changes:
- Add Makefile with test commands (test, test-backend, test-frontend, test-coverage)
- Add example test: config/database_test.go
- Fix Go 1.25 printf format string warnings in trader/auto_trader.go
(Changed log.Printf to log.Print for non-format strings)
- All backend tests pass ✓
Frontend Changes:
- Add Vitest configuration: web/vitest.config.ts (minimal setup)
- Add test utilities: web/src/test/test-utils.tsx
- Add example test: web/src/App.test.tsx
- Add dependencies: vitest, jsdom, @testing-library/react
- All frontend tests pass ✓
Issue #227 Fix:
- Fix AITradersPage to allow editing traders with disabled models/exchanges
- Change validation to use allModels/allExchanges instead of enabledModels/enabledExchanges
- Add comprehensive tests in web/src/components/AITradersPage.test.tsx
- Fixes: https://github.com/tinkle-community/nofx/issues/227
CI/CD:
- Add GitHub Actions workflow: .github/workflows/test.yml
- Non-blocking tests (continue-on-error: true)
- Runs on push/PR to main and dev branches
Test Results:
- Backend: 1 test passing
- Frontend: 5 tests passing (including 4 for Issue #227)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>