Add domain CRUD, energy density constraint, LLM status, reset results, score display fixes
Domain management: - Add domain list/detail/form templates and full CRUD routes (domains.py) - Add metric bound add/edit/delete via HTMX partials (_metrics_table.html) Energy density constraint (Rule 6 in ConstraintResolver): - Hard-block combos where power source provides <25% of platform's required Wh/kg - Warn (conditional) when under-density but within 4x - Solar Sail exempt (no stored energy); Airplane requires 400 Wh/kg, Spaceship 2000 Wh/kg - Add energy_density_wh_kg provides to all 8 stored-energy power sources in seed data - 3 new constraint resolver tests LLM-complete status: - Pipeline Pass 4 now sets combo status to llm_reviewed after successful LLM review - update_combination_status guards against downgrading: scored won't overwrite llm_reviewed or reviewed; llm_reviewed won't overwrite reviewed - Add badge-llm_reviewed CSS style (light blue) Reset results: - Repository.reset_domain_results() deletes combination_results, combination_scores, and pipeline_runs for a domain; pipeline re-evaluates on next run - POST /results/<domain>/reset route with flash confirmation - "Reset results" danger button with JS confirm dialog in results list Fix composite score 0 displaying as --- (Jinja2 falsy 0.0 bug): - Change `if r.composite_score` to `if r.composite_score is not none` Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import secrets
|
||||
from pathlib import Path
|
||||
|
||||
from flask import Flask, g
|
||||
@@ -12,6 +13,29 @@ from physcom.db.repository import Repository
|
||||
|
||||
|
||||
DEFAULT_DB = Path("data/physcom.db")
|
||||
_ENV_FILE = Path(".env")
|
||||
|
||||
|
||||
def _load_or_generate_secret_key() -> str:
|
||||
"""Return FLASK_SECRET_KEY from env, .env file, or auto-generate and persist it."""
|
||||
key = os.environ.get("FLASK_SECRET_KEY", "").strip()
|
||||
if key:
|
||||
return key
|
||||
|
||||
# Try to load from .env
|
||||
if _ENV_FILE.exists():
|
||||
for line in _ENV_FILE.read_text().splitlines():
|
||||
line = line.strip()
|
||||
if line.startswith("FLASK_SECRET_KEY="):
|
||||
key = line[len("FLASK_SECRET_KEY="):].strip()
|
||||
if key:
|
||||
return key
|
||||
|
||||
# Generate, persist, and return
|
||||
key = secrets.token_hex(32)
|
||||
with _ENV_FILE.open("a") as f:
|
||||
f.write(f"FLASK_SECRET_KEY={key}\n")
|
||||
return key
|
||||
|
||||
|
||||
def get_repo() -> Repository:
|
||||
@@ -31,7 +55,7 @@ def close_db(exc: BaseException | None = None) -> None:
|
||||
|
||||
def create_app() -> Flask:
|
||||
app = Flask(__name__)
|
||||
app.secret_key = os.environ.get("FLASK_SECRET_KEY", "physcom-dev-key")
|
||||
app.secret_key = _load_or_generate_secret_key()
|
||||
|
||||
app.teardown_appcontext(close_db)
|
||||
|
||||
@@ -57,4 +81,4 @@ def create_app() -> Flask:
|
||||
def run() -> None:
|
||||
"""Entry point for `physcom-web` script."""
|
||||
app = create_app()
|
||||
app.run(debug=True, port=int(os.environ.get("PORT", "5000")))
|
||||
app.run(host="0.0.0.0", debug=True, port=int(os.environ.get("PORT", "5000")))
|
||||
|
||||
Reference in New Issue
Block a user