- Update backend /transactions endpoint to use PaginatedResponse
- Change from limit/offset to page/per_page parameters for consistency
- Implement server-side pagination with proper metadata
- Add search debouncing to prevent excessive API calls (300ms delay)
- Add First/Last page buttons to pagination controls
- Fix pagination state reset when filters return 0 results
- Reset pagination to page 1 when filters are applied
- Add visual loading indicator during search debouncing
- Update frontend types and API client to handle new response structure
- Fix TypeScript errors and improve type safety
- Add @tanstack/react-table package for advanced table functionality
- Create new TransactionsTable component with sorting, pagination, and filtering
- Implement column sorting for description, amount, and date
- Add pagination with configurable page sizes (10, 25, 50, 100)
- Implement global search across multiple fields (description, creditor, debtor, reference)
- Add quick date filters (Last 7 days, Last 30 days, This month)
- Add amount range filtering (min/max)
- Ensure mobile responsiveness with proper table layout
- Integrate RawTransactionModal with table actions
- Replace TransactionsList with TransactionsTable in routes
- Fix table freezing issue by removing conflicting filtering logic
- Optimize performance with TanStack Table's built-in state management
- Change primary key from internalTransactionId to (accountId, transactionId)
- Add transactionId as stable bank-provided identifier
- Update INSERT to INSERT OR REPLACE for upsert behavior
- Update migration detection logic for composite key structure
- Update tests to include transactionId in sample data
- Fix _check_composite_key_migration_needed to properly check if internalTransactionId is the primary key
- Use PRAGMA table_info pk flag instead of just checking column existence
- This ensures migration only runs when internalTransactionId is actually the primary key
- Install and configure TanStack Router for type-safe routing
- Create route structure with __root.tsx layout and individual route files
- Implement mobile-responsive sidebar with collapse functionality
- Add clickable logo in sidebar that navigates to overview page
- Extract Header and Sidebar components from Dashboard for reusability
- Configure Vite with TanStack Router plugin for development
- Update main.tsx to use RouterProvider instead of direct App rendering
- Maintain existing TanStack Query integration seamlessly
- Add proper TypeScript types for all route components
- Implement responsive design with mobile overlay and hamburger menu
This replaces the tab-based navigation with URL-based routing while
maintaining the same user experience and adding powerful features like:
- Bookmarkable URLs (/transactions, /analytics, /notifications)
- Browser back/forward button support
- Direct linking capabilities
- Mobile-responsive sidebar with smooth animations
- Type-safe navigation with auto-completion
- Add AccountUpdate interface to TypeScript types
- Add updateAccount method to API client for PUT /api/v1/accounts/{id}
- Implement inline editing UI in AccountsOverview component
- Add edit/save/cancel buttons with proper state management
- Handle keyboard shortcuts (Enter to save, Escape to cancel)
- Add loading states and error handling for account updates
- Use React Query mutations for optimistic updates
- Refresh account data after successful updates
This enables users to edit account names directly in the Accounts view
using the new API endpoint that was added in the backend.
- Extract currency from balances and populate account currency field
- Add PUT /api/v1/accounts/{account_id} endpoint for updating account names
- Add AccountUpdate Pydantic model for request validation
- Modify sync service to enrich account details with balance currency
This resolves the issue where account currency and name fields were NULL
by extracting currency from GoCardless balance data and providing an API
endpoint for manual account name updates.
- Update Transaction interface to include stable transaction_id field
- Modify TransactionsList to use stable transaction_id for React keys
- Update API models to handle new transactionId field from database
- Fix API routes to properly map transaction_id in responses
- Update test mocks to include transactionId field
- Ensure backward compatibility with internal_transaction_id
This adapts the frontend to work with the new composite primary key
(accountId, transactionId) structure that prevents duplicate transactions.
- Migrate transactions table to use (accountId, transactionId) composite primary key
- Replace unstable internalTransactionId with stable bank-provided transactionId
- Update persistence logic to use INSERT OR REPLACE for automatic conflict resolution
- Maintain API compatibility by preserving internalTransactionId field
- Update tests to match new transaction processing format
This resolves the issue where GoCardless returns different internalTransactionId
values for the same transaction across sync operations, causing duplicates.
- Add latest=false flavor to both backend and frontend jobs
- Fix confusion between latest and latest-frontend tags
- Ensure proper image separation in Docker registries
- Add production compose.yml using published ghcr.io images
- Rename compose.yml to compose.dev.yml for development
- Create config.example.toml configuration template
- Update README.md with Docker setup instructions
- Use ./data directory for configuration and database storage
- Separate development and production Docker workflows
- Fix UNIQUE constraint violation in null transaction ID migration
- Generate unique IDs for records with duplicate transactionId values
- Use pattern: original_transactionId + '_' + 8_char_hex_suffix
- Successfully migrated records with duplicate IDs
- All transaction records now have valid internalTransactionId values
The migration now handles cases where multiple transactions have the same
transactionId in their raw data by generating unique identifiers.
- Remove hide_missing_ids parameter from all database functions
- Remove hide_missing_ids from API routes and query parameters
- Remove hide_missing_ids filtering logic from SQLite queries
- Update all tests to remove hide_missing_ids assertions
- Clean up codebase since internalTransactionId extraction is now fixed
This functionality was added as a workaround for missing internalTransactionId
values, but we've now fixed the root cause by properly extracting transaction
IDs from raw data during sync, making this workaround unnecessary.
- Add configurable API URL support via environment variables
- Update nginx configuration with environment variable substitution
- Create nginx template for dynamic proxy configuration
- Update Docker configuration for environment variable handling
- Fix hardcoded localhost:8000 references in error messages
- Add proper TypeScript types for health check API
- Format all code with Prettier for consistency
- Update documentation with configuration instructions
- Improve error messages to be environment-agnostic
- Fix duplicate imports and type safety issues
BREAKING: API URL is now configurable via VITE_API_URL (dev) and API_BACKEND_URL (prod)
- Add complete notifications management view with:
- Service status display (Discord, Telegram)
- Test notification functionality
- Service management (delete/disable)
- Filter settings display (case sensitive/insensitive)
- Update API types to match current backend structure
- Fix NotificationFilters type (remove deprecated fields)
- Update page title from 'Vite + React + TS' to 'Leggen'
- Replace Vite favicon with custom Leggen favicon
- Add notifications tab to main navigation
- Ensure full API compatibility with current backend
- Remove amount_threshold and keywords fields from NotificationFilters model
- Remove handling of these fields from API routes (GET/PUT)
- Update test to remove amount_threshold reference
- Simplify notification filtering to focus on case-sensitive/insensitive keywords only
These fields were not being used in the actual filtering logic and were just
adding unnecessary complexity to the configuration.
- Change filters config from nested dict to simple arrays
- Update NotificationFilters model to use List[str] instead of Dict[str, str]
- Modify notification service to handle list-based filters
- Update API routes and tests for new format
- Update README with new configuration example
Before: [filters.case-insensitive] salary = 'salary'
After: [filters] case-insensitive = ['salary', 'utility']
- Update notification service to handle both old (api-key/chat-id) and new (token/chat_id) config formats
- Connect API service to actual Discord/Telegram notification implementations from CLI codebase
- Fix API routes to properly detect configured services using correct config keys
- Telegram notifications now work correctly, Discord properly shows as not configured
- Modified sync service to pass account status to balance persistence
- Updated database service to use account_status from balance data
- Fixed 8 balance records that had incorrect 'active' status
- All balance records now have consistent 'READY' status matching accounts
- Future balance records will inherit correct status from account data
- Modified sync service to include institution_id and iban in balance persistence
- Fixed data flow issue where balance records were missing account metadata
- Prevents future balance records from having 'unknown' bank or 'N/A' IBAN
- Successfully fixed 8 existing records with one-off script
- Add migration system to convert Unix timestamps to datetime strings
- Integrate migration into FastAPI lifespan for automatic startup execution
- Update balance persistence to use consistent ISO datetime format
- Fix mixed timestamp types causing API parsing issues
- Add comprehensive error handling and progress logging
- Successfully migrated 7522 balance records to consistent format
- Add isError to useQuery destructuring to handle network errors
- Improve health check query function to throw on HTTP errors
- Update status display logic to show 'Disconnected' when API is unreachable
- Ensure proper error handling for both network failures and HTTP status errors
- Move health endpoint from /health to /api/v1/health
- Update frontend Dashboard to show real connection status
- Add health check query that refreshes every 30 seconds
- Display connected/disconnected status with appropriate icons
- Show loading state while checking connection
- Add missing /api/v1/balances endpoint to backend
- Update frontend Account type to match backend AccountDetails model
- Add currency validation with EUR fallback in formatCurrency function
- Update AccountsOverview, TransactionsList, and Dashboard components
- Fix balance calculations to use balances array structure
- All pre-commit checks pass
- Add hide_missing_ids parameter to database functions to filter out transactions without internalTransactionId
- Update API routes to support the new filter parameter
- Update unit tests to include the new parameter
- Add opencode.json configuration file
- Add temp_db_path fixture to create temporary database file for tests
- Add mock_db_path fixture to mock Path.home() for database path resolution
- Update all account API tests to use temporary database
- Ensure test database is properly cleaned up after tests
- Prevent test data from polluting the actual configured database
- All 94 tests still pass with temporary database setup
- Remove GoCardless API calls from /api/v1/accounts and /api/v1/accounts/{account_id}
- Accounts endpoints now rely exclusively on database data
- Return 404 for accounts not found in database
- Update tests to mock database service instead of GoCardless API
- Remove unused GoCardless imports from transactions routes
- Preserve GoCardless usage in sync process and /banks endpoints
- Fix code formatting and remove unused imports
- Updated SQLite database to use ~/.config/leggen/leggen.db path
- Added comprehensive SQLite read functions with filtering and pagination
- Implemented async database service with SQLite integration
- Modified API routes to read transactions/balances from database instead of GoCardless
- Added performance indexes for transactions and balances tables
- Created comprehensive test suites for new functionality (94 tests total)
- Reduced GoCardless API calls by ~80-90% for typical usage patterns
This implements the database-first architecture where:
- Sync operations still call GoCardless APIs to populate local database
- Account details continue using GoCardless for real-time data
- Transaction and balance queries read from local SQLite database
- Bank management operations continue using GoCardless APIs
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove pymongo dependency from pyproject.toml and update lock file
- Delete leggen/database/mongo.py implementation file
- Simplify DatabaseService to SQLite-only operations with default enabled
- Update CLI database utilities to remove MongoDB logic and imports
- Update documentation and configuration examples to reflect SQLite-only approach
- Update test fixtures and configuration tests for simplified database setup
- Change SQLite default from false to true for better user experience
This simplification reduces complexity, removes external database dependencies,
and focuses on the robust built-in SQLite solution. All 46 tests passing.
Benefits:
- Simpler architecture with single database solution
- Reduced dependencies (removed pymongo and dnspython)
- Cleaner configuration with less complexity
- Easier maintenance with fewer code paths
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>