Run events in the database: Runs page and Agent run card on the Dokploy Portal

Snapshot of D:\Ecw Process 65c92c5 (2026-10-30).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ManikandanandClaude Opus 5.5 committed 2026-10-30 11:28:26 +05:30
1 parent d500f750da
commit 840272032a
9 files changed
+655 -46

No files matched your search

+16 -6
View File
@@ -325,12 +325,15 @@ def create_app(repo, allowed_hosts=ALLOWED_HOSTS, runner=None,
allowed_origins=ALLOWED_ORIGINS, logs_dir=None,
screenshots_root=None, users_store=None,
sessions=None, can_start=True,
secure_cookie=False, ecare=None) -> FastAPI:
secure_cookie=False, ecare=None, events=None) -> FastAPI:
app = FastAPI(title="eCW Charge Validation — Results",
docs_url=None, redoc_url=None, openapi_url=None)
if runner is None:
runner = BotRunner() if can_start else NoRunner()
logs_dir = logs_dir if logs_dir is not None else cfg.LOGS
# Where the Runs page and the last-run banner read Runs from: this PC's
# Logs folder, or (the Portal on Dokploy, 2026-10-30) the database.
events = events if events is not None else run_view.FileEvents(logs_dir)
screenshots_root = (screenshots_root if screenshots_root is not None
else cfg.ROOT / "Screenshots")
# Made per server start and put in the page: a page on another site
@@ -554,7 +557,7 @@ def create_app(repo, allowed_hosts=ALLOWED_HOSTS, runner=None,
"""The latest Run, if it ended badly — the Dashboard's red banner
(EEWA-33). A Run Error, or a Run that ended without a record
(killed); never a Stop, a finished Run or one still going."""
last = run_view.latest_run(logs_dir, _live_run_id())
last = run_view.latest_run(events, _live_run_id())
if last and last["status"] in ("Run Error", "Ended without a record"):
return last
return None
@@ -580,7 +583,7 @@ def create_app(repo, allowed_hosts=ALLOWED_HOSTS, runner=None,
raise BadFilter(f"Not a date: {value}")
if status and status not in run_view.STATUSES:
raise BadFilter(f"Not a result: {status}")
rows = run_view.list_runs(logs_dir, _live_run_id(),
rows = run_view.list_runs(events, _live_run_id(),
day_from=day_from or None,
day_to=day_to or None,
status=status or None)
@@ -592,7 +595,7 @@ def create_app(repo, allowed_hosts=ALLOWED_HOSTS, runner=None,
@app.get("/runs/{run_id}", response_class=HTMLResponse)
def run_page(request: Request, run_id: str):
run = run_view.load_run(logs_dir, run_id, _live_run_id())
run = run_view.load_run(events, run_id, _live_run_id())
if run is None:
return HTMLResponse("<h1>No such run</h1>", status_code=404)
return _page(request, "run.html",
@@ -602,7 +605,7 @@ def create_app(repo, allowed_hosts=ALLOWED_HOSTS, runner=None,
@app.get("/runs/{run_id}/shot/{n}")
def run_shot(run_id: str, n: int):
path = run_view.screenshot_path(logs_dir, run_id, n, screenshots_root)
path = run_view.screenshot_path(events, run_id, n, screenshots_root)
if path is None:
return HTMLResponse("<h1>No such screenshot</h1>",
status_code=404)
@@ -652,6 +655,10 @@ def create_app(repo, allowed_hosts=ALLOWED_HOSTS, runner=None,
@app.get("/api/bot/status")
def bot_status():
# A server Portal cannot see the bot PC's process or log: the
# newest Run in the database instead (2026-10-30).
if isinstance(events, run_view.DbEvents):
return jsonable_encoder(run_view.live_status(events))
return run_status.summarize(runner.status())
# ── Sign-in (Stage 2, EEWA-32) ───────────────────────────────────────
@@ -873,8 +880,11 @@ def _safe_next(target) -> str:
return target
app = create_app(SqlResultsRepo(cfg.RESULTS_DB_CONN),
_repo = SqlResultsRepo(cfg.RESULTS_DB_CONN)
app = create_app(_repo,
users_store=SqlUserStore(cfg.RESULTS_DB_CONN),
# A server Portal has no Logs folder: Runs from the database.
events=run_view.DbEvents(_repo) if cfg.PORTAL_SERVER else None,
ecare=(EcareSignIn(cfg.AUTH_TOKEN_API_URL)
if cfg.AUTH_TOKEN_API_URL else None),
**portal_settings(cfg.PORTAL_URLS, cfg.PORTAL_SERVER))