Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 使用官方 Python 3.11 slim 镜像作为基础镜像
# 使用官方 Python 3.11 slim 镜像
FROM python:3.11-slim

# 设置工作目录
Expand All @@ -9,12 +9,22 @@ ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PYTHONPATH=/app

# 复制依赖文件(利用 Docker 层缓存)
# 安装系统依赖
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
curl \
&& rm -rf /var/lib/apt/lists/*

# 复制依赖文件
COPY pyproject.toml ./

# 安装 uv 和项目依赖到系统 Python(避免虚拟环境开销)
RUN pip install --no-cache-dir uv && \
uv pip install --no-cache-dir --system -r pyproject.toml
# 安装 uv
RUN pip install --no-cache-dir uv

# 创建虚拟环境并安装所有依赖(内置到镜像)
RUN uv venv && \
. .venv/bin/activate && \
uv pip install -r pyproject.toml

# 复制应用代码
COPY . .
Expand All @@ -25,6 +35,5 @@ RUN chmod +x docker-entrypoint.sh
# 暴露端口
EXPOSE 8000


# 启动命令
ENTRYPOINT ["./docker-entrypoint.sh"]
1 change: 0 additions & 1 deletion backend/alembic.ini
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ path_separator = os
# database URL. This is consumed by the user-maintained env.py script only.
# other means of configuring database URLs may be customized within the env.py
# file.
# ʹ�û��������е����ݿ�URL
sqlalchemy.url = %ENV DATABASE_URL


Expand Down
144 changes: 144 additions & 0 deletions backend/alembic/versions/2952aa9a98f3_initial_migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
"""initial_migration

Revision ID: 2952aa9a98f3
Revises:
Create Date: 2025-10-04 17:23:05.644899

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '2952aa9a98f3'
down_revision: Union[str, Sequence[str], None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('system_config',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('is_allow_register', sa.Boolean(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_system_config_id'), 'system_config', ['id'], unique=False)
op.create_table('users',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('username', sa.String(length=50), nullable=False),
sa.Column('email', sa.String(length=100), nullable=False),
sa.Column('password_hash', sa.String(length=255), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('is_active', sa.Boolean(), nullable=True),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True)
op.create_index(op.f('ix_users_id'), 'users', ['id'], unique=False)
op.create_index(op.f('ix_users_username'), 'users', ['username'], unique=True)
op.create_table('work_flow_states',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('work_id', sa.String(length=50), nullable=False),
sa.Column('current_state', sa.String(length=50), nullable=False),
sa.Column('previous_state', sa.String(length=50), nullable=True),
sa.Column('state_data', sa.JSON(), nullable=True),
sa.Column('transition_reason', sa.Text(), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_work_flow_states_id'), 'work_flow_states', ['id'], unique=False)
op.create_index(op.f('ix_work_flow_states_work_id'), 'work_flow_states', ['work_id'], unique=False)
op.create_table('chat_sessions',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('session_id', sa.String(length=100), nullable=False),
sa.Column('work_id', sa.String(length=50), nullable=False),
sa.Column('system_type', sa.String(length=20), nullable=False),
sa.Column('title', sa.String(length=200), nullable=True),
sa.Column('status', sa.String(length=20), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('created_by', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_chat_sessions_id'), 'chat_sessions', ['id'], unique=False)
op.create_index(op.f('ix_chat_sessions_session_id'), 'chat_sessions', ['session_id'], unique=True)
op.create_index(op.f('ix_chat_sessions_work_id'), 'chat_sessions', ['work_id'], unique=False)
op.create_table('model_configs',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('type', sa.String(length=50), nullable=False),
sa.Column('model_id', sa.String(length=50), nullable=False),
sa.Column('base_url', sa.String(length=100), nullable=False),
sa.Column('api_key', sa.String(length=255), nullable=False),
sa.Column('is_active', sa.Boolean(), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('created_by', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_model_configs_id'), 'model_configs', ['id'], unique=False)
op.create_table('paper_templates',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(length=100), nullable=False),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('category', sa.String(length=50), nullable=True),
sa.Column('file_path', sa.String(length=500), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('is_public', sa.Boolean(), nullable=True),
sa.Column('created_by', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_paper_templates_id'), 'paper_templates', ['id'], unique=False)
op.create_table('works',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('work_id', sa.String(length=50), nullable=False),
sa.Column('title', sa.String(length=200), nullable=False),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('status', sa.String(length=50), nullable=False),
sa.Column('progress', sa.Integer(), nullable=True),
sa.Column('tags', sa.Text(), nullable=True),
sa.Column('template_id', sa.Integer(), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('created_by', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ),
sa.ForeignKeyConstraint(['template_id'], ['paper_templates.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_works_id'), 'works', ['id'], unique=False)
op.create_index(op.f('ix_works_work_id'), 'works', ['work_id'], unique=True)
# ### end Alembic commands ###


def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_works_work_id'), table_name='works')
op.drop_index(op.f('ix_works_id'), table_name='works')
op.drop_table('works')
op.drop_index(op.f('ix_paper_templates_id'), table_name='paper_templates')
op.drop_table('paper_templates')
op.drop_index(op.f('ix_model_configs_id'), table_name='model_configs')
op.drop_table('model_configs')
op.drop_index(op.f('ix_chat_sessions_work_id'), table_name='chat_sessions')
op.drop_index(op.f('ix_chat_sessions_session_id'), table_name='chat_sessions')
op.drop_index(op.f('ix_chat_sessions_id'), table_name='chat_sessions')
op.drop_table('chat_sessions')
op.drop_index(op.f('ix_work_flow_states_work_id'), table_name='work_flow_states')
op.drop_index(op.f('ix_work_flow_states_id'), table_name='work_flow_states')
op.drop_table('work_flow_states')
op.drop_index(op.f('ix_users_username'), table_name='users')
op.drop_index(op.f('ix_users_id'), table_name='users')
op.drop_index(op.f('ix_users_email'), table_name='users')
op.drop_table('users')
op.drop_index(op.f('ix_system_config_id'), table_name='system_config')
op.drop_table('system_config')
# ### end Alembic commands ###
Loading