Add run tagging (DB column + migration + route + UI)

- Added tags VARCHAR(300) column to Run model
- Added startup ALTER TABLE migration in app.py
- New POST /run/<id>/set_tags route saves comma-separated tags
- Tag badges + collapsible edit form in run_details.html header area

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-22 10:05:30 -05:00
parent af2050160e
commit 98a330c416
4 changed files with 48 additions and 0 deletions

View File

@@ -116,6 +116,14 @@ with app.app_context():
_log("System: Added 'last_heartbeat' column to Run table.")
except: pass
# Migration: Add 'tags' column if missing
try:
with db.engine.connect() as conn:
conn.execute(text("ALTER TABLE run ADD COLUMN tags VARCHAR(300)"))
conn.commit()
_log("System: Added 'tags' column to Run table.")
except: pass
# Reset all non-terminal runs on startup (running, queued, interrupted)
# The Huey consumer restarts with the app, so any in-flight tasks are gone.
try:

View File

@@ -35,6 +35,8 @@ class Run(db.Model):
progress = db.Column(db.Integer, default=0)
last_heartbeat = db.Column(db.DateTime, nullable=True)
tags = db.Column(db.String(300), nullable=True)
logs = db.relationship('LogEntry', backref='run', lazy=True, cascade="all, delete-orphan")
def duration(self):

View File

@@ -394,6 +394,22 @@ def revise_book(run_id, book_folder):
return redirect(url_for('run.view_run', id=new_run.id))
@run_bp.route('/run/<int:id>/set_tags', methods=['POST'])
@login_required
def set_tags(id):
run = db.session.get(Run, id)
if not run: return "Run not found", 404
if run.project.user_id != current_user.id: return "Unauthorized", 403
raw = request.form.get('tags', '')
tags = [t.strip() for t in raw.split(',') if t.strip()]
run.tags = ','.join(dict.fromkeys(tags))
db.session.commit()
flash("Tags updated.")
return redirect(url_for('run.view_run', id=id))
@run_bp.route('/run/<int:id>/delete', methods=['POST'])
@login_required
def delete_run(id):