v2.0.0: Modularize project into single-responsibility packages
Replaced monolithic modules/ package with a clean architecture:
- core/ config.py, utils.py
- ai/ models.py (ResilientModel), setup.py (init_models)
- story/ planner.py, writer.py, editor.py, style_persona.py, bible_tracker.py
- marketing/ cover.py, blurb.py, fonts.py, assets.py
- export/ exporter.py
- web/ app.py (Flask factory), db.py, helpers.py, tasks.py, routes/{auth,project,run,persona,admin}.py
- cli/ engine.py (run_generation), wizard.py (BookWizard)
Flask routes split into 5 Blueprints; all templates updated with blueprint-
prefixed url_for() calls. Dockerfile and docker-compose updated to use
web.app entry point and new package paths.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h2><i class="fas fa-book me-2"></i>Run #{{ run.id }}</h2>
|
||||
<p class="text-muted mb-0">Project: <a href="{{ url_for('view_project', id=run.project_id) }}">{{ run.project.name }}</a></p>
|
||||
<p class="text-muted mb-0">Project: <a href="{{ url_for('project.view_project', id=run.project_id) }}">{{ run.project.name }}</a></p>
|
||||
</div>
|
||||
<div>
|
||||
<button class="btn btn-outline-primary me-2" type="button" data-bs-toggle="collapse" data-bs-target="#bibleCollapse" aria-expanded="false" aria-controls="bibleCollapse">
|
||||
@@ -13,7 +13,7 @@
|
||||
<button class="btn btn-primary me-2" data-bs-toggle="modal" data-bs-target="#modifyRunModal" data-bs-toggle="tooltip" title="Create a new run based on this one, but with different instructions (e.g. 'Make it darker').">
|
||||
<i class="fas fa-pen-fancy me-2"></i>Modify & Re-run
|
||||
</button>
|
||||
<a href="{{ url_for('view_project', id=run.project_id) }}" class="btn btn-outline-secondary">Back to Project</a>
|
||||
<a href="{{ url_for('project.view_project', id=run.project_id) }}" class="btn btn-outline-secondary">Back to Project</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
<div class="col-md-4 mb-3">
|
||||
<div class="text-center">
|
||||
{% if book.cover %}
|
||||
<img src="{{ url_for('download_artifact', run_id=run.id, file=book.cover) }}" class="img-fluid rounded shadow-sm mb-3" alt="Book Cover" style="max-height: 400px;">
|
||||
<img src="{{ url_for('run.download_artifact', run_id=run.id, file=book.cover) }}" class="img-fluid rounded shadow-sm mb-3" alt="Book Cover" style="max-height: 400px;">
|
||||
{% else %}
|
||||
<div class="alert alert-secondary py-5">
|
||||
<i class="fas fa-image fa-3x mb-3"></i><br>No cover.
|
||||
@@ -132,7 +132,7 @@
|
||||
{% endif %}
|
||||
|
||||
{% if loop.first %}
|
||||
<form action="{{ url_for('regenerate_artifacts', run_id=run.id) }}" method="POST" class="mt-2">
|
||||
<form action="{{ url_for('run.regenerate_artifacts', run_id=run.id) }}" method="POST" class="mt-2">
|
||||
<textarea name="feedback" class="form-control mb-2 form-control-sm" rows="1" placeholder="Cover Feedback..."></textarea>
|
||||
<button type="submit" class="btn btn-sm btn-outline-primary w-100">
|
||||
<i class="fas fa-sync me-2"></i>Regenerate All
|
||||
@@ -156,7 +156,7 @@
|
||||
<h6 class="fw-bold">Artifacts</h6>
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
{% for art in book.artifacts %}
|
||||
<a href="{{ url_for('download_artifact', run_id=run.id, file=art.path) }}" class="btn btn-sm btn-outline-success">
|
||||
<a href="{{ url_for('run.download_artifact', run_id=run.id, file=art.path) }}" class="btn btn-sm btn-outline-success">
|
||||
<i class="fas fa-download me-1"></i> {{ art.name }}
|
||||
</a>
|
||||
{% else %}
|
||||
@@ -164,10 +164,10 @@
|
||||
{% endfor %}
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ url_for('read_book', run_id=run.id, book_folder=book.folder) }}" class="btn btn-primary">
|
||||
<a href="{{ url_for('run.read_book', run_id=run.id, book_folder=book.folder) }}" class="btn btn-primary">
|
||||
<i class="fas fa-book-reader me-2"></i>Read & Edit
|
||||
</a>
|
||||
<a href="{{ url_for('check_consistency', run_id=run.id, book_folder=book.folder) }}" class="btn btn-outline-warning ms-2">
|
||||
<a href="{{ url_for('run.check_consistency', run_id=run.id, book_folder=book.folder) }}" class="btn btn-outline-warning ms-2">
|
||||
<i class="fas fa-search me-2"></i>Check Consistency
|
||||
</a>
|
||||
<button class="btn btn-warning ms-2" data-bs-toggle="modal" data-bs-target="#reviseBookModal{{ loop.index }}" title="Regenerate this book with changes, keeping others.">
|
||||
@@ -183,7 +183,7 @@
|
||||
<!-- Revise Book Modal -->
|
||||
<div class="modal fade" id="reviseBookModal{{ loop.index }}" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<form class="modal-content" action="{{ url_for('revise_book', run_id=run.id, book_folder=book.folder) }}" method="POST">
|
||||
<form class="modal-content" action="{{ url_for('project.revise_book', run_id=run.id, book_folder=book.folder) }}" method="POST">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Revise Book</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
|
||||
Reference in New Issue
Block a user