feat: add blog draft generator and fix broken routes

Blog drafting section (dev-only):
- BlogDraftGenerator gathers project data (gaps, proposals, stats) as
  context and calls Claude to produce Medium-style blog posts
- DB schema: blog_drafts table with title, content, tags, cost tracking
- Web UI: list, generate (async with live preview), detail (rendered +
  source toggle), edit, and export routes
- 6 writing styles: deep-dive, overview, opinion, listicle, comparison,
  series-post
- Nav link added to sidebar under Proposals

Bug fixes found via route testing (scripts/test_all_routes.py):
- /authors/<id>: Draft.status → Draft.states (correct attribute name)
- /false-positives: add missing `import re` in ratings.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 04:39:16 +01:00
parent 2229e70c73
commit d1a20fa02e
13 changed files with 1481 additions and 1 deletions

View File

@@ -136,6 +136,10 @@
<svg class="w-4 h-4 opacity-60" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/></svg>
Proposals
</a>
<a href="/blog" class="sidebar-link flex items-center gap-3 px-5 py-2.5 text-sm text-slate-300 {{ 'active' if active_page == 'blog' }}">
<svg class="w-4 h-4 opacity-60" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z"/></svg>
Blog Drafts
</a>
{% endif %}
<a href="/timeline" class="sidebar-link flex items-center gap-3 px-5 py-2.5 text-sm text-slate-300 {{ 'active' if active_page == 'timeline' }}">
<svg class="w-4 h-4 opacity-60" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>