* add k3s update center
* fix update center status timeouts
* Polish update center settings UI
* Document k3s update center
* Refocus update center docs for users
* Clarify k3s migration path in docs
* feat: Preserve manual models during discovery and refresh, and add Claude configuration files and project documentation.feat: Preserve manual models during discovery and refresh, and add Claude configuration and project documentation files.
* fix: fix Feishu and Larksuite webhook support to the notification service with updated UI and tests.
* feat: 新增路由批量禁用/启用功能
- 后端新增 POST /api/routes/batch 接口,支持批量 enable/disable
- 前端新增批量操作模式,支持 checkbox 选择路由
- 浮动操作栏显示选中数量,支持全选/取消全选
- 批量操作完成后自动退出选择模式并刷新列表
* fix: complete route batch actions on mobile
---------
Co-authored-by: Xiang Li <xiangli>
Co-authored-by: cita-777 <juricek.chen@gmail.com>
* feat: Preserve manual models during discovery and refresh, and add Claude configuration files and project documentation.feat: Preserve manual models during discovery and refresh, and add Claude configuration and project documentation files.
* fix: fix Feishu and Larksuite webhook support to the notification service with updated UI and tests.
---------
Co-authored-by: Xiang Li <xiangli>
- Sync blockedBrands local state after save to prevent stale chips
- Defer getBrandList from blocking Settings bootstrap
- Guard model management UI on brandGroups instead of availableModels
- Deduplicate single-model add in disabled models
- Skip read-only/zero-channel routes in enabledCounts and filter
- Add sequence counter to loadCandidates to prevent force race condition
- Use stableAddChannel for mobile add-channel button
Replace closure-captured editor check with loadingModelsSiteIdRef so the
stale-response guard works correctly across rapid site switches. Also
gate setDisabledModelsLoading(false) behind the same ref check.
- settings.ts: trigger route rebuild after globalBlockedBrands changes in both
import and PUT handler; reject non-array payloads with 400 instead of silently
defaulting to empty array
- sites.ts: trim model names before deduplication so whitespace variants merge
- brandMatcher.ts: align boundary regex with frontend delimiter class [/:_\-\s]
- Settings.tsx: add role="switch" and aria-checked to brand filter chips; make
getBrandList best-effort so its failure doesn't block page load
- Sites.tsx: build brandGroups from union of availableModels and disabledModels
so legacy/removed models remain visible; add stale-response guard and error
logging for disabled/available model fetches
- TokenRoutes.tsx: use baseFilteredRoutes.length for totalRouteCount to keep
enabled/disabled counts in sync with status filter; add candidatesVersionRef
to invalidate lazy caches on payload change; add per-channel in-flight guard
on toggle; invalidate channel cache after rebuild and site-block operations
- Escape modelName/siteName in innerHTML to prevent XSS
- Use content-based routePatternsKey for cache invalidation instead of
length-only keys that miss content changes
- Extract shared baseFilteredRoutes to eliminate duplicated filter logic
between enabledCounts and filteredRoutes
- Add candidatesPromiseRef to deduplicate concurrent loadCandidates calls