From 9575bc5ac17a843bc7bf7dca05ebcccb5270ab9d Mon Sep 17 00:00:00 2001 From: Lloyd Zhou Date: Fri, 29 Dec 2023 13:17:10 +0800 Subject: [PATCH] create database command (#4) * feat: add create command --- pdm.lock | 37 +++++- pyproject.toml | 2 + requirements.txt | 3 + server/model/schema.py | 249 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 281 insertions(+), 10 deletions(-) diff --git a/pdm.lock b/pdm.lock index c1278ab2..8ae18451 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default"] strategy = ["cross_platform"] lock_version = "4.4" -content_hash = "sha256:48cb5d7b587e89f1367467b0d83411c29d3eeb92208ef7e4f520034112de8f8d" +content_hash = "sha256:377060918126987ee7854a1767311674ff9e2710607aaacf0de88245cf78b1cb" [[package]] name = "anyio" @@ -33,6 +33,18 @@ files = [ {file = "blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182"}, ] +[[package]] +name = "bson" +version = "0.5.10" +summary = "BSON codec for Python" +dependencies = [ + "python-dateutil>=2.4.0", + "six>=1.9.0", +] +files = [ + {file = "bson-0.5.10.tar.gz", hash = "sha256:d6511b2ab051139a9123c184de1a04227262173ad593429d21e443d6462d6590"}, +] + [[package]] name = "ca-lark-oauth" version = "0.0.5" @@ -346,6 +358,19 @@ files = [ {file = "PyMySQL-1.1.0.tar.gz", hash = "sha256:4f13a7df8bf36a51e81dd9f3605fede45a4878fe02f9236349fd82a3f0612f96"}, ] +[[package]] +name = "python-dateutil" +version = "2.8.2" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +summary = "Extensions to the standard Python datetime module" +dependencies = [ + "six>=1.5", +] +files = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] + [[package]] name = "python-dotenv" version = "1.0.0" @@ -356,6 +381,16 @@ files = [ {file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, ] +[[package]] +name = "six" +version = "1.16.0" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +summary = "Python 2 and 3 compatibility utilities" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + [[package]] name = "sniffio" version = "1.3.0" diff --git a/pyproject.toml b/pyproject.toml index f8a1c5e5..17b4eef6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,8 @@ dependencies = [ "flask-sqlalchemy>=3.1.1", "flask-cors>=4.0.0", "pymysql>=1.1.0", + "click>=8.1.7", + "bson>=0.5.10", ] requires-python = ">=3.10" readme = "README.md" diff --git a/requirements.txt b/requirements.txt index a53ae4c9..dfc5f3c3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,7 @@ anyio==4.2.0 blinker==1.7.0 +bson==0.5.10 ca-lark-oauth==0.0.5 ca-lark-sdk==0.0.7 ca-lark-webhook==0.0.3 @@ -23,7 +24,9 @@ Jinja2==3.1.2 MarkupSafe==2.1.3 pycryptodome==3.19.1 pymysql==1.1.0 +python-dateutil==2.8.2 python-dotenv==1.0.0 +six==1.16.0 sniffio==1.3.0 sqlalchemy==2.0.23 typing-extensions==4.9.0 diff --git a/server/model/schema.py b/server/model/schema.py index b1298f2d..cf572d93 100644 --- a/server/model/schema.py +++ b/server/model/schema.py @@ -3,8 +3,10 @@ from datetime import datetime import bson -from app import db -from sqlalchemy import BINARY, String, text +import click +from app import app, db +from flask.cli import with_appcontext +from sqlalchemy import BINARY, ForeignKey, String, text class ObjID(BINARY): @@ -71,16 +73,245 @@ def is_valid(value): return False -class User(db.Model): - __tablename__ = "user" +class Base(db.Model): + __abstract__ = True id = db.Column(ObjID(12), primary_key=True) - openid = db.Column(db.String(128), nullable=True, comment="外部用户ID") - name = db.Column(db.String(128), nullable=True, comment="用户名") - extra = db.Column( - JSONStr(1024), nullable=True, server_default=text("'{}'"), comment="用户其他字段" - ) status = db.Column(db.Integer, nullable=True, default=0, server_default=text("0")) created = db.Column(db.TIMESTAMP, nullable=False, default=datetime.utcnow) modified = db.Column( db.TIMESTAMP, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow ) + + +class User(Base): + __tablename__ = "user" + email = db.Column(db.String(128), nullable=True, comment="邮箱,这里考虑一下如何做唯一的用户") + telephone = db.Column(db.String(128), nullable=True, comment="手机号") + name = db.Column(db.String(128), nullable=True, comment="用户名") + avatar = db.Column(db.String(128), nullable=True, comment="头像") + extra = db.Column( + JSONStr(1024), nullable=True, server_default=text("'{}'"), comment="用户其他字段" + ) + + +class Account(User): + passwd = db.Column( + db.String(128), nullable=True, server_default=text("''"), comment="登录密码" + ) + + +class BindUser(Base): + __tablename__ = "bint_user" + user_id = db.Column(ObjID(12), ForeignKey("user.id"), nullable=True, comment="用户ID") + # 这里如果是飞书租户,可能会有不同的name等,但是在github这边不管是哪一个org,都是一样的 + # 这里如何统一? + # 是不是说这里暂时不需要这个platform_id,还是说这个字段为空就好? + platform_id = db.Column( + ObjID(12), ForeignKey("im_platform.id"), nullable=True, comment="平台" + ) + unionid = db.Column(db.String(128), nullable=True, comment="飞书的unionid") + + # 这里还是用platform标记一下 + platform = db.Column(db.String(128), nullable=True, comment="平台:github/lark") + email = db.Column(db.String(128), nullable=True, comment="邮箱") + name = db.Column(db.String(128), nullable=True, comment="用户名") + avatar = db.Column(db.String(128), nullable=True, comment="头像") + extra = db.Column( + JSONStr(1024), nullable=True, server_default=text("'{}'"), comment="用户其他字段" + ) + + +class Team(Base): + __tablename__ = "team" + user_id = db.Column(ObjID(12), ForeignKey("user.id"), nullable=True, comment="用户ID") + code_platform_id = db.Column( + ObjID(12), ForeignKey("code_platform.id"), nullable=True, comment="代码平台" + ) + im_platform_id = db.Column( + ObjID(12), ForeignKey("im_platform.id"), nullable=True, comment="协同平台" + ) + + name = db.Column(db.String(128), nullable=True, comment="名称") + description = db.Column(db.String(1024), nullable=True, comment="描述") + extra = db.Column( + JSONStr(1024), + nullable=True, + server_default=text("'{}'"), + comment="其他字段,可能有一些前期没想好的配置项放这里", + ) + + +class TeamMember(Base): + __tablename__ = "team_member" + team_id = db.Column( + ObjID(12), ForeignKey("team.id"), nullable=True, comment="属于哪一个组" + ) + code_user_id = db.Column( + ObjID(12), + ForeignKey("bind_user.id"), + nullable=True, + comment="从code_platform关联过来的用户", + ) + im_user_id = db.Column( + ObjID(12), + ForeignKey("bind_user.id"), + nullable=True, + comment="从im_platform关联过来的用户", + ) + + +class CodePlatform(Base): + __tablename__ = "code_platform" + name = db.Column(db.String(128), nullable=True, comment="名称") + description = db.Column(db.String(1024), nullable=True, comment="描述") + extra = db.Column( + JSONStr(1024), nullable=True, server_default=text("'{}'"), comment="其他字段" + ) + + +class Repo(Base): + __tablename__ = "repo" + code_platform_id = db.Column( + ObjID(12), ForeignKey("code_platform.id"), nullable=True, comment="属于哪一个org" + ) + application_id = db.Column( + ObjID(12), + ForeignKey("code_application.id"), + nullable=True, + comment="哪一个application_id", + ) + name = db.Column(db.String(128), nullable=True, comment="名称") + description = db.Column(db.String(1024), nullable=True, comment="描述") + extra = db.Column( + JSONStr(1024), nullable=True, server_default=text("'{}'"), comment="其他字段" + ) + + +class RepoUser(Base): + __tablename__ = "repo_user" + code_platform_id = db.Column( + ObjID(12), ForeignKey("code_platform.id"), nullable=True, comment="属于哪一个org" + ) + application_id = db.Column( + ObjID(12), + ForeignKey("code_application.id"), + nullable=True, + comment="哪一个application_id", + ) + bind_user_id = db.Column( + ObjID(12), ForeignKey("bind_user.id"), nullable=True, comment="项目协作者" + ) + + +class IMPlatform(Base): + __tablename__ = "im_platform" + tenant_key = db.Column(db.String(128), nullable=True, comment="飞书租户id") + name = db.Column(db.String(128), nullable=True, comment="名称") + description = db.Column(db.String(1024), nullable=True, comment="描述") + extra = db.Column( + JSONStr(1024), nullable=True, server_default=text("'{}'"), comment="其他字段" + ) + + +class CodeApplication(Base): + __tablename__ = "code_application" + platform_id = db.Column( + ObjID(12), ForeignKey("code_platform.id"), nullable=True, comment="代码平台" + ) + installation_id = db.Column(db.String(128), nullable=True, comment="安装id") + extra = db.Column( + JSONStr(1024), nullable=True, server_default=text("'{}'"), comment="其他字段" + ) + + +class CodeEvent(Base): + __tablename__ = "code_event" + application_id = db.Column( + ObjID(12), ForeignKey("code_application.id"), nullable=True, comment="应用id" + ) + event_id = db.Column(db.String(128), nullable=True, comment="event_id") + event_type = db.Column(db.String(128), nullable=True, comment="event_type") + content = db.Column(db.String(128), nullable=True, comment="主要内容") + extra = db.Column( + JSONStr(1024), nullable=True, server_default=text("'{}'"), comment="其他字段" + ) + + +class CodeAction(Base): + __tablename__ = "code_action" + event_id = db.Column( + ObjID(12), ForeignKey("code_event.id"), nullable=True, comment="事件ID" + ) + action_type = db.Column( + db.String(128), nullable=True, comment="action_type: 主要是飞书那边的消息等" + ) + content = db.Column(db.String(128), nullable=True, comment="主要内容") + extra = db.Column( + JSONStr(1024), nullable=True, server_default=text("'{}'"), comment="其他字段" + ) + + +class IMApplication(Base): + __tablename__ = "im_application" + platform_id = db.Column( + ObjID(12), ForeignKey("code_platform.id"), nullable=True, comment="协同平台" + ) + app_id = db.Column(db.String(128), nullable=True, comment="app_id") + app_secret = db.Column(db.String(128), nullable=True, comment="app_id") + extra = db.Column( + JSONStr(1024), nullable=True, server_default=text("'{}'"), comment="其他字段" + ) + + +class IMEvent(Base): + __tablename__ = "im_event" + application_id = db.Column( + ObjID(12), ForeignKey("im_application.id"), nullable=True, comment="应用id" + ) + event_id = db.Column(db.String(128), nullable=True, comment="event_id") + event_type = db.Column(db.String(128), nullable=True, comment="event_type") + content = db.Column(db.String(128), nullable=True, comment="主要内容") + extra = db.Column( + JSONStr(1024), nullable=True, server_default=text("'{}'"), comment="其他字段" + ) + + +class IMAction(Base): + __tablename__ = "im_action" + event_id = db.Column( + ObjID(12), ForeignKey("im_event.id"), nullable=True, comment="事件ID" + ) + action_type = db.Column( + db.String(128), nullable=True, comment="action_type: 主要是github那边的动作等" + ) + content = db.Column(db.String(128), nullable=True, comment="主要内容") + extra = db.Column( + JSONStr(1024), nullable=True, server_default=text("'{}'"), comment="其他字段" + ) + + +class ChatGroup(Base): + __tablename__ = "chat_group" + repo_id = db.Column( + ObjID(12), ForeignKey("repo.id"), nullable=True, comment="属于哪一个项目" + ) + im_application_id = db.Column( + ObjID(12), ForeignKey("code_application.id"), nullable=True, comment="哪一个项目创建的" + ) + chat_id = db.Column(db.String(128), nullable=True, comment="chat_id") + name = db.Column(db.String(128), nullable=True, comment="群名称") + description = db.Column(db.String(128), nullable=True, comment="群描述") + extra = db.Column( + JSONStr(1024), nullable=True, server_default=text("'{}'"), comment="其他字段" + ) + + +# create command function +@click.command(name="create") +@with_appcontext +def create(): + db.create_all() + + +# add command function to cli commands +app.cli.add_command(create)