Session 2026-04-21: SEO, Wiki-Anreicherung, Training, Lober
SEO & Crawler:
- robots.txt, llms.txt, sitemap.xml (508 Seiten bei Google)
- SSR-Seiten: /info, /wiki/rassen, /wiki/rasse/{slug}, /knigge
- Open Graph, JSON-LD, Breadcrumbs in index.html
Navigation:
- Training unter "Mein Hund", Wissen collapsible
- Welcome-Seite und Landing-Page auf 5-Gruppen-Struktur
Wiki:
- KI-Anreicherung (Claude API): beschreibung, vorkommen_de, Steckbrief
- "So einen hab ich" / Züchter-Verzeichnis
- Scheduler: 50 Rassen beim Start, 20/Nacht
Training:
- Session-Logging (Erfolgsquote, Stimmung, Zufriedenheit)
- Virtueller KI-Trainer (6h-Cache)
- Trainingskalender (Habit-Tracker)
- Top-Training → automatischer Tagebucheintrag
- Gamification ohne Druck: Badges, Streak, Stats
Fortschritts-Lober:
- Jeden Montag 09:00: Claude schreibt Lob-Text pro Hund
- Push + Karte im Tagebuch
Monitoring:
- 4× täglich Status-Mail mit Scheduler-Status + Wiki-Fortschritt
This commit is contained in:
parent
65d1cf6c7f
commit
180de32e57
22 changed files with 4351 additions and 189 deletions
|
|
@ -86,6 +86,9 @@ class UserPatch(BaseModel):
|
|||
is_banned: Optional[int] = None
|
||||
ban_reason: Optional[str] = None
|
||||
|
||||
class WikiEnrichBody(BaseModel):
|
||||
limit: int = 10
|
||||
|
||||
class ThreadAdminPatch(BaseModel):
|
||||
is_pinned: Optional[int] = None
|
||||
is_locked: Optional[int] = None
|
||||
|
|
@ -550,3 +553,33 @@ async def get_analytics(user=Depends(require_mod)):
|
|||
"pageviews": r_pv.json(),
|
||||
"top_pages": _to_list(r_pages),
|
||||
}
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# POST /api/admin/wiki/enrich — KI-Rassen-Anreicherung anstoßen
|
||||
# ------------------------------------------------------------------
|
||||
@router.post("/wiki/enrich")
|
||||
async def wiki_enrich(data: WikiEnrichBody, user=Depends(require_mod)):
|
||||
from scraper.breed_enricher import enrich_breeds
|
||||
limit = max(1, min(data.limit, 100))
|
||||
enriched = await enrich_breeds(limit)
|
||||
with db() as conn:
|
||||
remaining = conn.execute(
|
||||
"SELECT COUNT(*) FROM wiki_rassen WHERE ki_enriched=0"
|
||||
).fetchone()[0]
|
||||
return {"enriched": enriched, "remaining": remaining}
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# DELETE /api/admin/wiki/zuchter/{id} — Züchter-Eintrag löschen (Admin/Mod)
|
||||
# ------------------------------------------------------------------
|
||||
@router.delete("/wiki/zuchter/{zuchter_id}", status_code=204)
|
||||
async def admin_delete_zuchter(zuchter_id: int, user=Depends(require_mod)):
|
||||
with db() as conn:
|
||||
row = conn.execute(
|
||||
"SELECT id FROM wiki_zuchter WHERE id=?", (zuchter_id,)
|
||||
).fetchone()
|
||||
if not row:
|
||||
raise HTTPException(404, "Züchter nicht gefunden.")
|
||||
conn.execute("DELETE FROM wiki_zuchter WHERE id=?", (zuchter_id,))
|
||||
_audit(conn, user, "wiki_zuchter_delete", f"zuchter:{zuchter_id}")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue