Phase 3: VISUAL feed and M-Files drawings in the worker
Migration 0004 (VISUAL and drawing caches, go-live ignored list, resource map, job tables, order-derived columns with provenance; work order key includes the operation sequence). The real worker on APScheduler with settings re-read each fire, pause, run now, advisory locks, job_runs and a heartbeat. The visual-feed job (five VisualKit reads, COPY and MERGE cache, suspect-batch guard, the apply in one transaction: drafts, change orders, retire-moved, work order gone, closed and cancelled observed, projects and units from order links, auto-release) and the fingerprint. The drawing-lookup job (queue, budget, download on version change, sha256 into assets, decision table, staging for rev approval, drawing-origin change orders). Clerical From VISUAL panel, flags, rev approval, hand uploads, change-order review; Admin Feed settings and resource map. Synthetic fixture generator and a fixture-driven worker in CI with a Playwright scenario. Docs updated. Verified: 3249 server tests and 13 Playwright scenarios on the docker-1 CI stack, 76 frontend tests, doctor at 0004; one feed and one drawing run against VISUAL DEV and the vault from the developer machine (counts in the changelog). Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
@@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import contextlib
|
||||
import importlib
|
||||
import logging
|
||||
from collections.abc import AsyncIterator
|
||||
from pathlib import Path
|
||||
@@ -93,13 +94,48 @@ def create_app(
|
||||
app.state.groups_cache = None
|
||||
api_errors.install(app)
|
||||
|
||||
from .api import account, admin, assets, auth, departments, packet_children, packets, projects, units
|
||||
from .api import (
|
||||
account,
|
||||
admin,
|
||||
assets,
|
||||
auth,
|
||||
departments,
|
||||
feed_settings,
|
||||
jobs,
|
||||
packet_children,
|
||||
packets,
|
||||
projects,
|
||||
units,
|
||||
)
|
||||
from .api import events as events_api
|
||||
|
||||
# Routers go in before the static catch-all below, which answers every other GET.
|
||||
for module in (auth, account, admin, departments, events_api, projects, units, packets, packet_children, assets):
|
||||
for module in (
|
||||
auth,
|
||||
account,
|
||||
admin,
|
||||
departments,
|
||||
events_api,
|
||||
projects,
|
||||
units,
|
||||
packets,
|
||||
packet_children,
|
||||
assets,
|
||||
jobs,
|
||||
feed_settings,
|
||||
):
|
||||
app.include_router(module.router)
|
||||
app.include_router(assets.blob_router)
|
||||
for name in ("feed", "packet_visual"):
|
||||
modname = f"{__package__}.api.{name}"
|
||||
try:
|
||||
extra = importlib.import_module(modname)
|
||||
except ModuleNotFoundError as e:
|
||||
if e.name != modname:
|
||||
raise
|
||||
log.warning("router api.%s not there yet; not loaded", name)
|
||||
continue
|
||||
app.include_router(extra.router)
|
||||
|
||||
@app.get("/healthz")
|
||||
def healthz() -> dict[str, Any]:
|
||||
|
||||
Reference in New Issue
Block a user