- save_admin_config_handler now creates parent directory if it doesn't exist
- Prevents 500 error when config/ directory is missing
- Enables first-time config save without manual directory creation
- saveConfig no longer throws error when current config returns 404
- Creates new config file with current values if none exists
- User can save config for the first time without errors
- loadConfig now uses default values when config file doesn't exist (404)
- No error shown to user when config file is missing
- Config tab loads with empty defaults instead of error message
- loadMbeModels no longer logs console.error for 404 (endpoint may not exist)
- loadUsers removed from onMounted - only called after admin login
- Prevents 401 errors on page load before user has authenticated
- Users tab now only loads data after successful login
- saveUploadPath now validates path via POST /api/v2/settings/validate
- Shows clear error message if path doesn't exist or isn't writable
- Only saves if validation passes (valid: true)
- 5 validation checks: format, existence, type, read/write permissions
- Added useAdminAuth composable for login/logout/token management
- Admin Users tab now requires login before showing users
- loadUsers/loadShares now use direct fetch with Bearer token
- Added login form with username/password fields
- Token stored in localStorage with expiry check
- Default credentials: demo/demo123
- Replaced deprecated /api/v2/config with new /api/v2/settings
- loadSettings() now uses GET /api/v2/settings (structured JSON)
- saveUploadPath() now uses POST /api/v2/settings
- Removed PostgreSQL migration error handling (no longer needed)
- Settings page now works correctly with SQLite-only MarkBase
- Created MARKBASE_API_REQUIREMENTS.md with detailed API specs
- Requests GET/POST /api/v2/settings endpoints from MarkBase team
- Documents current issues with /api/v2/config returning 500
- Defines required fields, error handling, and priority levels
- loadSettings now shows detailed error from MarkBase response body
- MarkBase /api/v2/config returns 500 when config file is incomplete
- Error message now includes actual error details instead of just HTTP status
- Previously proxy accessed llama-server /health endpoint directly
- Now forwards /api/v1/mbe/health to Core API (3002) which has full health check
- Returns complete health info: status, model, uptime
- Fixes frontend not showing 'online' status in Admin Settings
- Vite now forwards /health to Rust proxy (port 8888)
- Required for Admin Panel proxy health check to work in dev mode
- External Caddy reverse proxy may also need /health forwarding rule
- loadServiceUrls: use window.location.origin for remote access, localhost for local dev
- testCoreApi: use /api/v1/health for remote, /health for localhost
- testProxy: health check path works for both
- testMbe: already uses getApiBase() which handles both cases
This fixes the issue where Admin Panel showed offline when accessed via
https://nextorage.momentry.ddns.net because localhost health checks
point to user's machine, not the server.
- useVLMScenes(fileUuid): load scenes for a specific file with thumbnails
- useVLMSearch(): search VLM scenes and traces with bilingual support
- useSceneThumbnail(fileUuid, sceneIndex): load scene thumbnail URLs
- TypeScript interfaces: VLMTag, VLMScene, VLMTrace, FileScene
- Uses direct HTTP calls via getApiBase() (no Tauri IPC needed)
- Follows Vue 3 composable best practices (ref, loading, error states)
- Core API now returns both vlm_description (EN) and vlm_description_localized (JA)
- Removed duplicate API calls (was fetching EN + JA separately)
- Single API call with output_language param, uses both fields from response
- Load More also updated to use results array and correct field names
- Format: 【JA】localized text...【English】english text...
- Bilingual format: 【JA】... then 【English】...
- Summary uses localized language (vlm_description_lang) as primary
- Load More function now also supports bilingual format
- Fallback: only vlm_description shows single language without labels
- Removed isLocalhost checks from loadServiceUrls()
- All services now default to http://localhost:XXXX
- Health check URLs always use direct paths (/health)
- Fixes Core API and Proxy showing offline from external URL
- Backend already polls 60s for MBE port readiness
- Frontend no longer polls 30s after backend returns
- Total wait time: ~60s instead of ~90s
- Start timeout set to 60s for MBE
- Added /api/v1/mbe/health proxy endpoint
- Frontend uses proxy for MBE health check (works on localhost and external)
- Accepts 'healthy' status from MBE response
- Shows model info (MBE e4b) in Admin UI
- Added /api/v1/mbe/health proxy in Studio proxy (port 8888)
- Frontend now uses proxy endpoint instead of direct mbeUrl
- Works for both localhost and external access (once proxy is deployed)
- MBE health response: {status: 'healthy', model: 'e4b', layers: 42}
- Updated testMbe() to accept status='healthy' from MarkBaseServer
- Added model and layers info to mbeInfo display
- MBE now shows 'MBE (e4b)' instead of generic 'MarkBaseEngine'
- Fixed testMbe() to always use /health instead of /v1/health
- Added model selection dropdown for MarkBaseEngine
- Modified startService('mbe') to pass model and port parameters
- Added loadMbeModels() to fetch available models on mount
- Added getApiBase import
- Clear all marks (not just face marks)
- Reset playMode to 'continuous' to disable trace/segment limits
- Reset currentTraceIdx and currentSegmentIdx to 0
- Reset seekFrame to 0
- This ensures full file plays from start to end without restrictions
- File name in header is now clickable
- Click reloads video with full file range (startFrame=0, endFrame=999999)
- Added play icon and hover effect for visual feedback
- Use endFrame=999999 for full file playback (backend clips correctly)
- Add z-index:10 to card-file-info to prevent being obscured
- Full file now plays complete duration
- Add card-file-info bar at top of search result cards
- Click file name to play full file (startFrame: 0, endFrame: 0)
- Show video/document icon based on file extension
- Display file UUID badge
- Remove duplicate card-file section from bottom of card
- Save messages to localStorage when leaving search page
- Restore messages when returning to search page
- Clear session on newChat()
- Session includes: messages, conversationId, fileUuidCache, mode
- Filter history to show only items from last 2 hours
- Pinned items are always kept regardless of age
- Auto-cleanup old unpinned items from database
- Increased fetch limit to 50 to ensure enough items for filtering
- Database was corrupted (WAL file had uncommitted data)
- Recovered 101 search history records from WAL
- Cleaned up test data with empty ID
- Proxy now returns 30 records correctly
Root cause: finally block called loadFiles() which cleared the cache
and reloaded from server, overwriting the manual 'scanning' status.
Server videos.status may not be synced yet by PostgreSQL trigger.
Fix: Remove loadFiles() from finally block. Keep manual status update.
Polling mechanism will sync status from server automatically.
- Added Rescan button for paused files in context menu
- Re-scan now removes file from paused set
- Paused files can be re-scanned directly without resuming first
- Added pausedCount computed property
- Added ⏸ Paused N to status bar between Scanning and Completed
- Paused count displayed in warning color (yellow) to distinguish from Scanning
- Deep Scan button hidden when status is 'paused'
- Resume button shows when status is 'paused'
- Pause button shows when status is 'scanning'
- Simplified conditions: no longer need isFilePaused check in template
Core Team implemented PostgreSQL trigger (sync_video_status) that automatically
syncs videos.status when monitor_jobs.status changes. Removed frontend workaround
that manually updated filesCache/fileStatusCache.
Now ctxPause/batchPause call loadFiles() + loadPausedFiles() after success
to get the properly synced status from backend.
Root cause: backend pause updates monitor_jobs table, but frontend
displays status from videos table (via get_files API). These are separate.
Fix:
- ctxPause: manually sets file.status = 'paused' in filesCache + fileStatusCache
- batchPause: same manual cache update for each file
- ctxResume/batchResume: calls loadFiles() to refresh from backend
- Added console.log debug for troubleshooting
- Fixed i18n: removed duplicate emoji from translation strings
- ctxPause and ctxResume now call loadFiles() + loadPausedFiles()
- batchPause and batchResume also reload after completion
- Use new Set() for proper Vue reactivity
- Fixes status badge not updating after pause
- Add pause/resume buttons to file context menu (right-click)
- Add batch pause/resume buttons to section titles
- Support concurrent pause/resume with pLimit(3)
- Add paused status badge (⏸) with warning color
- Integrate with Core API /api/v1/jobs/:uuid/pause|resume
- Track paused files via Redis jobs:paused set
- Add i18n translations (zh-TW, en)