Scaffold V2 backend foundation

This commit is contained in:
2026-07-06 17:25:06 +08:00
parent 44af745828
commit 17cba7cf61
42 changed files with 1459 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
from __future__ import annotations
from logging.config import fileConfig
from alembic import context
from sqlalchemy import engine_from_config, pool
from app.core.config import get_settings
from app.models import Base
config = context.config
if config.config_file_name is not None:
fileConfig(config.config_file_name)
settings = get_settings()
config.set_main_option("sqlalchemy.url", settings.database_url)
target_metadata = Base.metadata
def run_migrations_offline() -> None:
context.configure(
url=settings.database_url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
compare_type=True,
)
with context.begin_transaction():
context.run_migrations()
def run_migrations_online() -> None:
connectable = engine_from_config(
config.get_section(config.config_ini_section, {}),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
with connectable.connect() as connection:
context.configure(connection=connection, target_metadata=target_metadata, compare_type=True)
with context.begin_transaction():
context.run_migrations()
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,226 @@
from __future__ import annotations
from alembic import op
import sqlalchemy as sa
revision = "0001_initial_schema"
down_revision = None
branch_labels = None
depends_on = None
def upgrade() -> None:
op.create_table(
"sys_user",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("phone", sa.String(length=20), nullable=False),
sa.Column("name", sa.String(length=50), nullable=False),
sa.Column("nickname", sa.String(length=50), nullable=True),
sa.Column("status", sa.Integer(), nullable=False),
sa.Column("daily_chat_limit", sa.Integer(), nullable=False),
sa.Column("daily_chat_used", sa.Integer(), nullable=False),
sa.Column("effective_at", sa.DateTime(), nullable=True),
sa.Column("expired_at", sa.DateTime(), nullable=True),
sa.Column("last_login_at", sa.DateTime(), nullable=True),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.Column("is_deleted", sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
op.create_index("ix_sys_user_phone", "sys_user", ["phone"], unique=True)
op.create_table(
"sys_role",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("code", sa.String(length=50), nullable=False),
sa.Column("name", sa.String(length=50), nullable=False),
sa.Column("remark", sa.String(length=255), nullable=True),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
op.create_index("ix_sys_role_code", "sys_role", ["code"], unique=True)
op.create_table(
"sys_admin",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("username", sa.String(length=50), nullable=False),
sa.Column("password", sa.String(length=255), nullable=False),
sa.Column("name", sa.String(length=50), nullable=False),
sa.Column("role_id", sa.BigInteger(), nullable=True),
sa.Column("status", sa.Integer(), nullable=False),
sa.Column("last_login_at", sa.DateTime(), nullable=True),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.ForeignKeyConstraint(["role_id"], ["sys_role.id"]),
sa.PrimaryKeyConstraint("id"),
)
op.create_index("ix_sys_admin_username", "sys_admin", ["username"], unique=True)
op.create_table(
"sys_knowledge",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("name", sa.String(length=100), nullable=False),
sa.Column("feishu_space_id", sa.String(length=100), nullable=False),
sa.Column("feishu_node_id", sa.String(length=100), nullable=False),
sa.Column("status", sa.Integer(), nullable=False),
sa.Column("remark", sa.String(length=255), nullable=True),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
op.create_table(
"sys_user_kb",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=False),
sa.Column("knowledge_id", sa.BigInteger(), nullable=False),
sa.Column("effective_at", sa.DateTime(), nullable=True),
sa.Column("expired_at", sa.DateTime(), nullable=True),
sa.Column("created_by", sa.BigInteger(), nullable=True),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.ForeignKeyConstraint(["knowledge_id"], ["sys_knowledge.id"]),
sa.ForeignKeyConstraint(["user_id"], ["sys_user.id"]),
sa.PrimaryKeyConstraint("id"),
)
op.create_index("ix_sys_user_kb_user_id", "sys_user_kb", ["user_id"])
op.create_index("ix_sys_user_kb_knowledge_id", "sys_user_kb", ["knowledge_id"])
op.create_table(
"sys_model",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("provider", sa.String(length=50), nullable=False),
sa.Column("model_name", sa.String(length=100), nullable=False),
sa.Column("api_url", sa.String(length=255), nullable=False),
sa.Column("api_key", sa.Text(), nullable=False),
sa.Column("temperature", sa.Numeric(4, 2), nullable=True),
sa.Column("max_token", sa.Integer(), nullable=True),
sa.Column("timeout_second", sa.Integer(), nullable=False),
sa.Column("enabled", sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
op.create_table(
"sys_prompt",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("prompt_content", sa.Text(), nullable=False),
sa.Column("updated_by", sa.BigInteger(), nullable=True),
sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
op.create_table(
"sys_system_config",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("config_key", sa.String(length=100), nullable=False),
sa.Column("config_value", sa.Text(), nullable=False),
sa.Column("description", sa.String(length=255), nullable=True),
sa.Column("updated_by", sa.BigInteger(), nullable=True),
sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
op.create_index("ix_sys_system_config_config_key", "sys_system_config", ["config_key"], unique=True)
op.create_table(
"sys_chat_session",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=False),
sa.Column("title", sa.String(length=100), nullable=False),
sa.Column("message_count", sa.Integer(), nullable=False),
sa.Column("last_message_at", sa.DateTime(), nullable=True),
sa.Column("is_deleted", sa.Integer(), nullable=False),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.ForeignKeyConstraint(["user_id"], ["sys_user.id"]),
sa.PrimaryKeyConstraint("id"),
)
op.create_index("ix_sys_chat_session_user_id", "sys_chat_session", ["user_id"])
op.create_table(
"sys_chat_message",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("session_id", sa.BigInteger(), nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=False),
sa.Column("role", sa.String(length=20), nullable=False),
sa.Column("content", sa.Text(), nullable=False),
sa.Column("message_status", sa.String(length=20), nullable=False),
sa.Column("token_input", sa.Integer(), nullable=True),
sa.Column("token_output", sa.Integer(), nullable=True),
sa.Column("response_time_ms", sa.Integer(), nullable=True),
sa.Column("model_id", sa.BigInteger(), nullable=True),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.ForeignKeyConstraint(["model_id"], ["sys_model.id"]),
sa.ForeignKeyConstraint(["session_id"], ["sys_chat_session.id"]),
sa.ForeignKeyConstraint(["user_id"], ["sys_user.id"]),
sa.PrimaryKeyConstraint("id"),
)
op.create_index("ix_sys_chat_message_session_id", "sys_chat_message", ["session_id"])
op.create_index("ix_sys_chat_message_user_id", "sys_chat_message", ["user_id"])
op.create_table(
"sys_ai_request_log",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("session_id", sa.BigInteger(), nullable=True),
sa.Column("message_id", sa.BigInteger(), nullable=True),
sa.Column("user_id", sa.BigInteger(), nullable=True),
sa.Column("model_name", sa.String(length=100), nullable=True),
sa.Column("prompt", sa.Text(), nullable=True),
sa.Column("knowledge_ids", sa.String(length=500), nullable=True),
sa.Column("retrieve_count", sa.Integer(), nullable=False),
sa.Column("input_token", sa.Integer(), nullable=True),
sa.Column("output_token", sa.Integer(), nullable=True),
sa.Column("total_token", sa.Integer(), nullable=True),
sa.Column("cost_ms", sa.Integer(), nullable=True),
sa.Column("status", sa.String(length=20), nullable=False),
sa.Column("error_message", sa.Text(), nullable=True),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
op.create_index("ix_sys_ai_request_log_session_id", "sys_ai_request_log", ["session_id"])
op.create_index("ix_sys_ai_request_log_message_id", "sys_ai_request_log", ["message_id"])
op.create_index("ix_sys_ai_request_log_user_id", "sys_ai_request_log", ["user_id"])
op.create_table(
"sys_operation_log",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("admin_id", sa.BigInteger(), nullable=True),
sa.Column("module", sa.String(length=50), nullable=False),
sa.Column("action", sa.String(length=50), nullable=False),
sa.Column("target_id", sa.BigInteger(), nullable=True),
sa.Column("before_json", sa.Text(), nullable=True),
sa.Column("after_json", sa.Text(), nullable=True),
sa.Column("ip", sa.String(length=50), nullable=True),
sa.Column("result", sa.String(length=20), nullable=False),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
op.create_index("ix_sys_operation_log_admin_id", "sys_operation_log", ["admin_id"])
def downgrade() -> None:
op.drop_index("ix_sys_operation_log_admin_id", table_name="sys_operation_log")
op.drop_table("sys_operation_log")
op.drop_index("ix_sys_ai_request_log_user_id", table_name="sys_ai_request_log")
op.drop_index("ix_sys_ai_request_log_message_id", table_name="sys_ai_request_log")
op.drop_index("ix_sys_ai_request_log_session_id", table_name="sys_ai_request_log")
op.drop_table("sys_ai_request_log")
op.drop_index("ix_sys_chat_message_user_id", table_name="sys_chat_message")
op.drop_index("ix_sys_chat_message_session_id", table_name="sys_chat_message")
op.drop_table("sys_chat_message")
op.drop_index("ix_sys_chat_session_user_id", table_name="sys_chat_session")
op.drop_table("sys_chat_session")
op.drop_index("ix_sys_system_config_config_key", table_name="sys_system_config")
op.drop_table("sys_system_config")
op.drop_table("sys_prompt")
op.drop_table("sys_model")
op.drop_index("ix_sys_user_kb_knowledge_id", table_name="sys_user_kb")
op.drop_index("ix_sys_user_kb_user_id", table_name="sys_user_kb")
op.drop_table("sys_user_kb")
op.drop_table("sys_knowledge")
op.drop_index("ix_sys_admin_username", table_name="sys_admin")
op.drop_table("sys_admin")
op.drop_index("ix_sys_role_code", table_name="sys_role")
op.drop_table("sys_role")
op.drop_index("ix_sys_user_phone", table_name="sys_user")
op.drop_table("sys_user")