feat: add A-card operations frontend and backend foundation

This commit is contained in:
郑龙捷
2026-09-02 09:54:03 +08:00
parent 9badd3597f
commit ad71259ba5
106 changed files with 12461 additions and 1796 deletions
+93
View File
@@ -0,0 +1,93 @@
from __future__ import annotations
import asyncio
from logging.config import fileConfig
from typing import Any
from alembic import context
from common.config import settings
from common.db.models.operations import OperationsBase
from sqlalchemy import Connection, pool
from sqlalchemy.ext.asyncio import async_engine_from_config
config = context.config
if config.config_file_name is not None:
fileConfig(config.config_file_name)
target_metadata = OperationsBase.metadata
def database_url() -> str:
value = settings.operations_database_url
if not value:
raise RuntimeError("OPERATIONS_DATABASE_URL is required")
return value
def include_object(
obj: Any,
name: str | None,
type_: str,
reflected: bool,
compare_to: Any,
) -> bool:
"""Protect audited ops tables not yet represented in the P0 ORM subset."""
if type_ == "table" and reflected and compare_to is None:
return False
return type_ != "table" or bool(name and name.startswith("ops_"))
def configure_context(*, connection: Connection | None = None) -> None:
options = {
"target_metadata": target_metadata,
"compare_type": True,
"compare_server_default": True,
"include_object": include_object,
}
if connection is None:
context.configure(
url=database_url(),
literal_binds=True,
dialect_opts={"paramstyle": "named"},
**options,
)
else:
context.configure(connection=connection, **options)
def run_migrations_offline() -> None:
configure_context()
with context.begin_transaction():
context.run_migrations()
def do_run_migrations(connection: Connection) -> None:
configure_context(connection=connection)
with context.begin_transaction():
context.run_migrations()
async def run_async_migrations() -> None:
section = config.get_section(config.config_ini_section, {})
section["sqlalchemy.url"] = database_url()
connectable = async_engine_from_config(
section,
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
try:
async with connectable.connect() as connection:
await connection.run_sync(do_run_migrations)
finally:
await connectable.dispose()
def run_migrations_online() -> None:
asyncio.run(run_async_migrations())
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()