feat: entity relationship refactor — notification trackers, command system, chat actions
Rework entity schema: rename Tracker→NotificationTracker, add CommandConfig/ CommandTracker/CommandTrackerListener entities for decoupled command handling. Commands now resolve through CommandTracker→CommandConfig instead of TelegramBot.commands_config. Smart ref-counted bot polling based on active listeners. Add chat_action to telegram targets. Full frontend CRUD pages for command configs and command trackers. Idempotent SQLite migrations. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -19,11 +19,11 @@ from ..database.engine import get_engine
|
||||
from ..database.models import (
|
||||
EventLog,
|
||||
NotificationTarget,
|
||||
NotificationTracker,
|
||||
NotificationTrackerState,
|
||||
NotificationTrackerTarget,
|
||||
ServiceProvider,
|
||||
TemplateConfig,
|
||||
Tracker,
|
||||
TrackerState,
|
||||
TrackerTarget,
|
||||
TrackingConfig,
|
||||
)
|
||||
|
||||
@@ -89,7 +89,7 @@ async def check_tracker(tracker_id: int) -> dict[str, Any]:
|
||||
|
||||
# Load all DB data eagerly before entering aiohttp context
|
||||
async with AsyncSession(engine) as session:
|
||||
tracker = await session.get(Tracker, tracker_id)
|
||||
tracker = await session.get(NotificationTracker, tracker_id)
|
||||
if not tracker or not tracker.enabled:
|
||||
return {"status": "skipped", "reason": "disabled or not found"}
|
||||
|
||||
@@ -99,7 +99,7 @@ async def check_tracker(tracker_id: int) -> dict[str, Any]:
|
||||
|
||||
# Load tracker state
|
||||
result = await session.exec(
|
||||
select(TrackerState).where(TrackerState.tracker_id == tracker_id)
|
||||
select(NotificationTrackerState).where(NotificationTrackerState.tracker_id == tracker_id)
|
||||
)
|
||||
states = result.all()
|
||||
state_dict: dict[str, Any] = {}
|
||||
@@ -113,7 +113,7 @@ async def check_tracker(tracker_id: int) -> dict[str, Any]:
|
||||
|
||||
# Load tracker-target links (replaces old target_ids JSON array)
|
||||
tt_result = await session.exec(
|
||||
select(TrackerTarget).where(TrackerTarget.tracker_id == tracker_id)
|
||||
select(NotificationTrackerTarget).where(NotificationTrackerTarget.tracker_id == tracker_id)
|
||||
)
|
||||
tracker_targets = tt_result.all()
|
||||
|
||||
@@ -188,7 +188,7 @@ async def check_tracker(tracker_id: int) -> dict[str, Any]:
|
||||
existing.shared = cstate.get("shared", False)
|
||||
session.add(existing)
|
||||
else:
|
||||
new_ts = TrackerState(
|
||||
new_ts = NotificationTrackerState(
|
||||
tracker_id=tracker_id,
|
||||
collection_id=cid,
|
||||
collection_name=cstate.get("name", ""),
|
||||
|
||||
Reference in New Issue
Block a user