Per-User Domain-Ausschlüsse + Grundquellen-Schutz
- Neue Tabelle user_excluded_domains für benutzerspezifische Ausschlüsse - Domain-Ausschlüsse wirken nur für den jeweiligen User, nicht org-weit - user_id wird durch die gesamte Pipeline geschleust (Orchestrator → Researcher → RSS-Parser) - Grundquellen (is_global) können nicht mehr bearbeitet/gelöscht werden im Frontend - Grundquelle-Badge bei globalen Quellen statt Edit/Delete-Buttons - Filter Von mir ausgeschlossen im Quellen-Modal Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dieser Commit ist enthalten in:
@@ -332,7 +332,7 @@ class AgentOrchestrator:
|
||||
self._running = False
|
||||
logger.info("Agenten-Orchestrator gestoppt")
|
||||
|
||||
async def enqueue_refresh(self, incident_id: int, trigger_type: str = "manual") -> bool:
|
||||
async def enqueue_refresh(self, incident_id: int, trigger_type: str = "manual", user_id: int = None) -> bool:
|
||||
"""Refresh-Auftrag in die Queue stellen. Gibt False zurueck wenn bereits in Queue/aktiv."""
|
||||
if incident_id in self._queued_ids or self._current_task == incident_id:
|
||||
logger.info(f"Refresh fuer Lage {incident_id} uebersprungen: bereits aktiv/in Queue")
|
||||
@@ -341,7 +341,7 @@ class AgentOrchestrator:
|
||||
visibility, created_by, tenant_id = await self._get_incident_visibility(incident_id)
|
||||
|
||||
self._queued_ids.add(incident_id)
|
||||
await self._queue.put((incident_id, trigger_type))
|
||||
await self._queue.put((incident_id, trigger_type, user_id))
|
||||
queue_size = self._queue.qsize()
|
||||
logger.info(f"Refresh fuer Lage {incident_id} eingereiht (Queue: {queue_size}, Trigger: {trigger_type})")
|
||||
|
||||
@@ -386,7 +386,11 @@ class AgentOrchestrator:
|
||||
except asyncio.TimeoutError:
|
||||
continue
|
||||
|
||||
incident_id, trigger_type = item
|
||||
if len(item) == 3:
|
||||
incident_id, trigger_type, user_id = item
|
||||
else:
|
||||
incident_id, trigger_type = item
|
||||
user_id = None
|
||||
self._queued_ids.discard(incident_id)
|
||||
self._current_task = incident_id
|
||||
logger.info(f"Starte Refresh für Lage {incident_id} (Trigger: {trigger_type})")
|
||||
@@ -398,7 +402,7 @@ class AgentOrchestrator:
|
||||
try:
|
||||
for attempt in range(3):
|
||||
try:
|
||||
await self._run_refresh(incident_id, trigger_type=trigger_type, retry_count=attempt)
|
||||
await self._run_refresh(incident_id, trigger_type=trigger_type, retry_count=attempt, user_id=user_id)
|
||||
last_error = None
|
||||
break # Erfolg
|
||||
except asyncio.CancelledError:
|
||||
@@ -509,7 +513,7 @@ class AgentOrchestrator:
|
||||
await db.close()
|
||||
return visibility, created_by, tenant_id
|
||||
|
||||
async def _run_refresh(self, incident_id: int, trigger_type: str = "manual", retry_count: int = 0):
|
||||
async def _run_refresh(self, incident_id: int, trigger_type: str = "manual", retry_count: int = 0, user_id: int = None):
|
||||
"""Führt einen kompletten Refresh-Zyklus durch."""
|
||||
import aiosqlite
|
||||
from database import get_db
|
||||
@@ -604,7 +608,7 @@ class AgentOrchestrator:
|
||||
keywords = feed_sel_keywords
|
||||
articles = await rss_parser.search_feeds_selective(title, selected_feeds, keywords=keywords)
|
||||
else:
|
||||
articles = await rss_parser.search_feeds(title, international=international, tenant_id=tenant_id, keywords=keywords)
|
||||
articles = await rss_parser.search_feeds(title, international=international, tenant_id=tenant_id, keywords=keywords, user_id=user_id)
|
||||
|
||||
logger.info(f"RSS: {len(articles)} relevante Artikel gefunden (international={international})")
|
||||
return articles, feed_usage
|
||||
@@ -612,7 +616,7 @@ class AgentOrchestrator:
|
||||
async def _web_search_pipeline():
|
||||
"""Claude WebSearch-Recherche."""
|
||||
researcher = ResearcherAgent()
|
||||
results, usage = await researcher.search(title, description, incident_type, international=international)
|
||||
results, usage = await researcher.search(title, description, incident_type, international=international, user_id=user_id)
|
||||
logger.info(f"Claude-Recherche: {len(results)} Ergebnisse")
|
||||
return results, usage
|
||||
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren