# Scan Settings Migration Plan ## ๐ŸŽฏ Objective Move auto-scan settings from per-user storage to system-wide storage while preserving all existing functionality. ## ๐Ÿ“Š Database Changes ### 1. Add `system_settings` Table ```sql CREATE TABLE system_settings ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), setting_key VARCHAR(100) UNIQUE NOT NULL, setting_value TEXT NOT NULL, description TEXT, updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); ``` ### 2. Add Default Settings Data ```sql INSERT INTO system_settings (setting_key, setting_value, description) VALUES ('scan_frequency_minutes', '60', 'How often to scan all libraries in minutes'), ('auto_scan_enabled', 'true', 'Whether auto-scanning is enabled system-wide'); ``` ### 3. Remove Scan Columns from `users` Table ```sql -- Remove these lines from users table: scan_frequency_minutes INTEGER DEFAULT 60, auto_scan_enabled BOOLEAN DEFAULT true, ``` ## ๐Ÿ— Code Structure Changes ### 1. New File: `internal/handlers/system_settings.go` - Move `UpdateScanSettings` and `GetScanSettings` from `auth.go` - **Remove**: `MustGetAuthenticatedUser(c)` calls - **Remove**: All user ID usage in database operations - **Keep**: All validation, error handling, JSON response logic - **Change**: Database calls to use system_settings queries ### 2. Update Database Queries **Add to `internal/database/queries/queries.sql`:** ```sql -- name: GetSystemSetting :one SELECT setting_value FROM system_settings WHERE setting_key = $1; -- name: UpdateSystemSetting :exec UPDATE system_settings SET setting_value = $2, updated_at = NOW() WHERE setting_key = $1; -- name: GetAllSystemSettings :many SELECT setting_key, setting_value, description FROM system_settings ORDER BY setting_key; ``` **Remove from `internal/database/queries/queries.sql`:** ```sql -- Remove: -- name: UpdateScanSettings :exec -- name: GetScanSettings :one ``` ### 3. Router Changes: `internal/router/library.go` **Add to existing `adminLibrary` group:** ```go // System scan settings (admin-only) adminLibrary.GET("/scan-settings", cfg.SystemSettingsHandler.GetScanSettings) adminLibrary.PUT("/scan-settings", cfg.SystemSettingsHandler.UpdateScanSettings) ``` ## ๐Ÿ”„ Implementation Strategy ### What Stays the Same: - Endpoint paths (`/api/libraries/scan-settings`) - Request/response formats - Validation rules (15-1440 minutes, boolean enabled) - Error handling patterns - Basic handler structure ### What Changes: - Database storage location (users table โ†’ system_settings table) - Access control (per-user โ†’ admin-only) - Handler location (auth.go โ†’ system_settings.go) - Database queries (user-based โ†’ key-value based) ### What Gets Removed: - `MustGetAuthenticatedUser()` calls from scan handlers - User ID usage in scan operations - Scan columns from users table - Per-user scan settings queries ## ๐Ÿงช Testing Requirements ### Modify Existing Tests: - **Update scan settings tests** in `cmd/server/tests/user_test.go:489-563` - **Add admin role verification** to existing tests - **Add database integration** tests - **Update scheduler tests** in `internal/services/scheduler_test.go` ### Create New Tests: - **System settings handler tests** in new file `cmd/server/tests/system_settings_test.go` - **Admin middleware tests** in `internal/middleware/middleware_test.go` - **Integration tests** for cross-component behavior ### Test Success Criteria: - All existing tests still pass - New system settings tests pass - Admin middleware properly tested - Integration tests cover cross-component behavior ## ๐Ÿ“š Documentation Updates ### 1. Create System Settings API Documentation **New File**: `/docs/developer/api/system/settings.md` - Document `GET /api/libraries/scan-settings` - Document `PUT /api/libraries/scan-settings` - Include request/response examples - Include error response codes ### 2. Update Main API Reference **File**: `/docs/developer/api/api-reference.md` - Add "System Management" section - Link to new system settings documentation ### 3. Update Scanner Documentation **File**: `/docs/developer/api/scanner/overview.md` - Add section about system-wide scan settings - Document how scheduler uses system settings ## ๐Ÿ”ง Bruno API Tests ### Create System Settings Bruno Tests **New Directory**: `/bruno/system/` **File**: `/bruno/system/get-scan-settings.bru` ```bru meta { name: Get System Scan Settings type: http seq: 1 } get { url: {{base_url}}/api/libraries/scan-settings auth: inherit } headers { Authorization: Bearer {{adminToken}} Content-Type: application/json } script:post-response { res.status.should.equal(200); res.body.type.should.equal("application/json"); res.body.data.should.have.property('scan_frequency_minutes'); res.body.data.should.have.property('auto_scan_enabled'); } docs { ## Get System Scan Settings Retrieves current system-wide scan settings for all libraries. **Authentication**: Admin token required **Response**: Current scan frequency and auto-scan status } ``` **File**: `/bruno/system/update-scan-settings.bru` ```bru meta { name: Update System Scan Settings type: http seq: 2 } put { url: {{base_url}}/api/libraries/scan-settings body: json auth: inherit } headers { Authorization: Bearer {{adminToken}} Content-Type: application/json } body:json { "scan_frequency_minutes": 30, "auto_scan_enabled": true } script:post-response { res.status.should.equal(200); res.body.type.should.equal("application/json"); res.body.should.have.property('message'); } docs { ## Update System Scan Settings Updates system-wide scan settings that apply to all libraries. **Authentication**: Admin token required **Request**: Scan frequency (15-1440 minutes) and enabled status **Response**: Success message } ``` ## ๐Ÿ“‹ Implementation Order ### Phase 1: Database & Core Implementation 1. **Database schema changes** - Add system_settings table 2. **Database queries** - Add system settings queries 3. **New handler file** - Create system_settings.go 4. **Router registration** - Add routes to adminLibrary group 5. **Update scheduler** - Change to use system settings ### Phase 2: Cleanup & Testing 6. **Remove old handlers** - Delete from auth.go 7. **Remove user table columns** - Clean up schema 8. **Update/create tests** - Comprehensive test coverage 9. **Verify functionality** - Integration testing ### Phase 3: Documentation & API Tests 10. **Create documentation** - API docs and updates 11. **Create Bruno tests** - API test coverage 12. **Final verification** - End-to-end testing ## โœ… Success Criteria ### Functionality: - [ ] All existing API endpoints work with same paths - [ ] Only admin users can access scan settings - [ ] Settings apply system-wide to all libraries - [ ] No per-user scan data remaining in users table - [ ] Scheduler uses system-wide settings correctly ### Testing: - [ ] All existing tests still pass - [ ] New system settings tests pass - [ ] Admin middleware properly tested - [ ] Integration tests verify cross-component behavior ### Documentation: - [ ] API documentation complete and accurate - [ ] Bruno tests cover all scenarios - [ ] Main API reference updated - [ ] Documentation renders correctly ### API Compatibility: - [ ] Existing client code continues to work - [ ] Endpoint paths unchanged - [ ] Request/response formats preserved - [ ] Error handling patterns consistent ## ๐Ÿ”„ Database Migration ### Option 1: Fresh Database (Recommended for Development) ```bash podman compose down -v podman compose up -d ``` ### Option 2: Manual Migration (Preserves Data) ```bash podman exec bookhoard_db psql -U postgres -d bookhoard -c " CREATE TABLE system_settings ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), setting_key VARCHAR(100) UNIQUE NOT NULL, setting_value TEXT NOT NULL, description TEXT, updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); INSERT INTO system_settings (setting_key, setting_value, description) VALUES ('scan_frequency_minutes', '60', 'How often to scan all libraries in minutes'), ('auto_scan_enabled', 'true', 'Whether auto-scanning is enabled system-wide'); ALTER TABLE users DROP COLUMN IF EXISTS scan_frequency_minutes; ALTER TABLE users DROP COLUMN IF EXISTS auto_scan_enabled; " ``` --- **This plan preserves all existing functionality while moving to system-wide scan settings with minimal changes and comprehensive testing/documentation.**