feat(backend): consolidate queue logic for scheduling

This commit is contained in:
2025-08-21 17:17:42 -04:00
parent 8f0dc0d658
commit d0dbba21fb
19 changed files with 1256 additions and 146 deletions

View File

@@ -0,0 +1,49 @@
from __future__ import annotations
from dataclasses import dataclass, asdict, fields
from datetime import date, datetime
from typing import Any, Dict, Tuple, Type, TypeVar, Union
Row = Tuple[Any, ...] | Dict[str, Any] # what sqlite3.Row returns
T = TypeVar("T", bound="BaseModel")
@dataclass()
class BaseModel:
"""A tiny helper that gives every model a common interface."""
@classmethod
def from_row(cls: Type[T], row: Row) -> T:
"""
Build a model instance from a sqlite3.Row (or a dictlike object).
Column names are matched to the dataclass field names.
"""
if isinstance(row, dict):
data = row
else: # sqlite3.Row behaves like a mapping, but we guard for safety
data = dict(row)
# Convert raw strings to proper Python types where we know the annotation
converted: Dict[str, Any] = {}
for f in fields(cls):
value = data.get(f.name)
if value is None:
converted[f.name] = None
continue
# datetime/date handling sqlite returns str in ISO format
if f.type is datetime:
converted[f.name] = datetime.fromisoformat(value)
elif f.type is date:
converted[f.name] = date.fromisoformat(value)
else:
converted[f.name] = value
return cls(**converted) # type: ignore[arg-type]
def to_dict(self) -> Dict[str, Any]:
"""Return a plain dict (useful for INSERT/UPDATE statements)."""
return asdict(self)
def __repr__(self) -> str: # a nicer representation when printing
field_vals = ", ".join(f"{f.name}={getattr(self, f.name)!r}" for f in fields(self))
return f"{self.__class__.__name__}({field_vals})"