feat: add Admin Panel with JWT auth, DB settings, and integration management
Complete admin backend with login, where all integrations (weather, news, Home Assistant, Vikunja, Unraid, MQTT) can be configured via web UI instead of ENV variables. Two-layer config: ENV seeds DB on first start, then DB is source of truth. Auto-migration system on startup. Backend: db.py shared pool, auth.py JWT, settings_service CRUD, seed_service, admin router (protected), test_connections per integration, config.py rewrite. Frontend: react-router v6, login page, admin layout with sidebar, 8 settings pages (General, Weather, News, HA, Vikunja, Unraid, MQTT, ChangePassword), shared IntegrationForm + TestButton components. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
89ed0c6d0a
commit
f6a42c2dd2
40 changed files with 3487 additions and 311 deletions
|
|
@ -8,7 +8,7 @@ from typing import Any, Dict, List, Optional
|
|||
from fastapi import APIRouter, Query
|
||||
|
||||
from server.cache import cache
|
||||
from server.config import settings
|
||||
from server.config import get_settings
|
||||
from server.services.news_service import get_news, get_news_count
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -50,7 +50,7 @@ async def get_news_articles(
|
|||
total: int = 0
|
||||
|
||||
try:
|
||||
articles = await get_news(limit=limit, offset=offset, category=category, max_age_hours=settings.news_max_age_hours)
|
||||
articles = await get_news(limit=limit, offset=offset, category=category, max_age_hours=get_settings().news_max_age_hours)
|
||||
except Exception as exc:
|
||||
logger.exception("Failed to fetch news articles")
|
||||
return {
|
||||
|
|
@ -63,7 +63,7 @@ async def get_news_articles(
|
|||
}
|
||||
|
||||
try:
|
||||
total = await get_news_count(max_age_hours=settings.news_max_age_hours, category=category)
|
||||
total = await get_news_count(max_age_hours=get_settings().news_max_age_hours, category=category)
|
||||
except Exception as exc:
|
||||
logger.exception("Failed to fetch news count")
|
||||
# We still have articles -- return them with total = len(articles)
|
||||
|
|
@ -76,5 +76,5 @@ async def get_news_articles(
|
|||
"offset": offset,
|
||||
}
|
||||
|
||||
await cache.set(key, payload, settings.news_cache_ttl)
|
||||
await cache.set(key, payload, get_settings().news_cache_ttl)
|
||||
return payload
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue