Fix 8 bugs from second code review

HIGH:
- Fix JS TypeError on empty API response: validate keys/types are arrays
  before using them; add HTTP status check (resp.ok)
- Fix BEGIN IMMEDIATE conflict: set isolation_level=None (autocommit) on
  SQLite connection so explicit transactions work without implicit ones

MEDIUM:
- Fix import_json_file non-atomic: wrap entire operation in BEGIN/COMMIT
  with ROLLBACK on error — no more partial imports
- Fix crash on non-dict batch_data items: skip non-dict elements
- Fix comma-in-key corruption: store keys/types as JSON arrays in hidden
  widgets instead of comma-delimited strings (backward-compat fallback)
- Fix blocking I/O in API routes: change async def to def so FastAPI
  auto-threads the synchronous SQLite calls

LOW:
- Fix missing ?. on app.graph.setDirtyCanvas in refreshDynamicOutputs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-28 21:32:35 +01:00
parent ba8f104bc1
commit b499eb4dfd
7 changed files with 155 additions and 52 deletions

View File

@@ -35,25 +35,25 @@ def _get_db() -> ProjectDB:
return _db
async def _list_projects() -> dict[str, Any]:
def _list_projects() -> dict[str, Any]:
db = _get_db()
projects = db.list_projects()
return {"projects": [p["name"] for p in projects]}
async def _list_files(name: str) -> dict[str, Any]:
def _list_files(name: str) -> dict[str, Any]:
db = _get_db()
files = db.list_project_files(name)
return {"files": [{"name": f["name"], "data_type": f["data_type"]} for f in files]}
async def _list_sequences(name: str, file_name: str) -> dict[str, Any]:
def _list_sequences(name: str, file_name: str) -> dict[str, Any]:
db = _get_db()
seqs = db.list_project_sequences(name, file_name)
return {"sequences": seqs}
async def _get_data(name: str, file_name: str, seq: int = Query(default=1)) -> dict[str, Any]:
def _get_data(name: str, file_name: str, seq: int = Query(default=1)) -> dict[str, Any]:
db = _get_db()
data = db.query_sequence_data(name, file_name, seq)
if data is None:
@@ -61,7 +61,7 @@ async def _get_data(name: str, file_name: str, seq: int = Query(default=1)) -> d
return data
async def _get_keys(name: str, file_name: str, seq: int = Query(default=1)) -> dict[str, Any]:
def _get_keys(name: str, file_name: str, seq: int = Query(default=1)) -> dict[str, Any]:
db = _get_db()
keys, types = db.query_sequence_keys(name, file_name, seq)
return {"keys": keys, "types": types}