From 9b1ae3bb5b60e89b279209c7b7f4c631dfd2c390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=B9=20=E6=9F=8F?= Date: Mon, 9 Dec 2024 13:00:54 +0900 Subject: [PATCH] app history --- backend/app/api/api_v1/routers/platform.py | 34 +++++- backend/app/db/cruddb/dbapp.py | 122 ++++++++++++++------- backend/app/db/schemas.py | 8 +- backend/app/tests/test_user_app.py | 33 ++++-- 4 files changed, 146 insertions(+), 51 deletions(-) diff --git a/backend/app/api/api_v1/routers/platform.py b/backend/app/api/api_v1/routers/platform.py index f871e25..07b538d 100644 --- a/backend/app/api/api_v1/routers/platform.py +++ b/backend/app/api/api_v1/routers/platform.py @@ -77,21 +77,23 @@ async def apps_list( response_model_exclude_none=True) async def apps_update( request: Request, - app: AppVersion, + app: VersionUpdate, user=Depends(get_current_active_user), db=Depends(get_db), ): try: - return ApiReturnModel(data =appService.update_appversion(db, app,user.id)) + domain = domainService.get_default_domain(db, user.id) + if not domain: + return ApiReturnModel(data = None) + return ApiReturnModel(data =appService.update_appversion(db, domain.url,app,user.id)) except Exception as e: raise APIException('platform:apps',request.url._url,f"Error occurred while get create app :",e) -@r.delete( - "/apps/{appid}",tags=["App"], +@r.delete("/apps/{appid}",tags=["App"], response_model=ApiReturnModel[AppList|None], response_model_exclude_none=True ) -async def delete_app( +async def apps_delete( request: Request, appid: str, user=Depends(get_current_active_user), @@ -123,7 +125,27 @@ async def appversions_list( return appService.get_appversions(db,domain.url,appid) except Exception as e: raise APIException('platform:appversions',request.url._url,f"Error occurred while get app({appid}) version :",e) - + +@r.put( + "/appversions/{appid}/{version}",tags=["App"], + response_model=ApiReturnModel[AppList|None], + response_model_exclude_none=True +) +async def appversions_change( + request: Request, + appid: str, + version: int, + user = Depends(get_current_active_user), + db=Depends(get_db), +): + try: + domain = domainService.get_default_domain(db, user.id) #get_activedomain(db, user.id) + if not domain: + ApiReturnModel(data = None) + return ApiReturnModel(data = appService.change_appversion(db, domain.url,appid,version,user.id)) + except Exception as e: + raise APIException('platform:appversions',request.url._url,f"Error occurred while change app version:",e) + @r.get( "/appsettings/{id}", response_model=App, diff --git a/backend/app/db/cruddb/dbapp.py b/backend/app/db/cruddb/dbapp.py index a542260..9d7ac3e 100644 --- a/backend/app/db/cruddb/dbapp.py +++ b/backend/app/db/cruddb/dbapp.py @@ -11,6 +11,16 @@ from app.core.common import ApiReturnPage from app.db import models, schemas from app.core.security import chacha20Decrypt, get_password_hash + +class dbflowhistory(crudbase): + def __init__(self): + super().__init__(model=models.FlowHistory) + + def get_flows_by_appid_version(self,db: Session,domainurl:str,appid:str,version:int): + return db.execute(select(models.FlowHistory).filter(and_(models.FlowHistory.domainurl == domainurl,models.FlowHistory.appid == appid, models.FlowHistory.version == version))).scalars().all() + +dbflowhistory = dbflowhistory() + class dbflow(crudbase): def __init__(self): super().__init__(model=models.Flow) @@ -18,7 +28,7 @@ class dbflow(crudbase): def get_domain_apps(self): return None - def get_domain_app_by_appid(self,db: Session,domainurl:str,appid:str): + def get_flows_by_appid(self,db: Session,domainurl:str,appid:str): return db.execute(select(models.Flow).filter(and_(models.Flow.domainurl == domainurl,models.Flow.appid == appid))).scalars().all() @@ -58,6 +68,16 @@ class dbappversion(crudbase): def get_appversions(self,domainurl:str,appid:str): return super().get_by_conditions({"domainurl":domainurl,"appid":appid}) + + def get_app_by_version(self,db: Session,domainurl:str,appid:str,version:int): + return db.execute(super().get_by_conditions({"domainurl":domainurl,"appid":appid,"version":version})).scalars().first() + + def get_app_latestversion(self,db: Session,domainurl:str,appid:str): + appversion = db.execute(super().get_by_conditions({"domainurl":domainurl,"appid":appid},"version","desc")).scalars().first() + if appversion: + return appversion.version + else: + return 0 dbappversion = dbappversion() @@ -71,49 +91,77 @@ class dbapp(crudbase): def get_apps(self,db: Session,domainurl:str): return db.execute(super().get_by_conditions({"domainurl":domainurl})).scalars().all() - def update_appversion(self,db: Session, appedit: schemas.AppVersion,userid:int): - db_app = db.execute(select(models.App).filter(and_(models.App.domainurl == appedit.domainurl,models.App.appid == appedit.appid))).scalars().first() - if not db_app: - return db_app - - db_app.version = db_app.version + 1 - appversion = models.AppVersion( - domainurl = appedit.domainurl, - appid=appedit.appid, - appname=db_app.appname, - version = db_app.version, - versionname = appedit.versionname, - comment = appedit.comment, - updateuserid = userid, - createuserid = userid - ) - db.add(appversion) - db.add(db_app) - - flows = dbflow.get_domain_app_by_appid(db,appedit.domainurl,appedit.appid) #select(models.Flow).filter(and_(models.Flow.domainurl == appedit.domainurl,models.App.appid == appedit.appid)) - for flow in flows: - db_flowhistory = models.FlowHistory( - flowid = flow.flowid, - appid = flow.appid, - eventid = flow.eventid, - domainurl = flow.domainurl, - name = flow.name, - content = flow.content, - version = db_app.version, - updateuserid = userid, - createuserid = userid + def update_appversion(self,db: Session,domainurl, newversion: schemas.VersionUpdate,userid:int): + db_app = self.get_app(db,domainurl,newversion.appid) + if db_app: + db_app.version = dbappversion.get_app_latestversion(db,domainurl,newversion.appid)+1 + appversion = models.AppVersion( + domainurl = db_app.domainurl, + appid=db_app.appid, + appname=db_app.appname, + version = db_app.version, + versionname = newversion.versionname, + comment = newversion.comment, + updateuserid = userid, + createuserid = userid ) - db.add(db_flowhistory) + db.add(appversion) + db.add(db_app) - db.commit() - db.refresh(db_app) - return db_app + flows = dbflow.get_flows_by_appid(db,domainurl,newversion.appid) + for flow in flows: + db_flowhistory = models.FlowHistory( + flowid = flow.flowid, + appid = flow.appid, + eventid = flow.eventid, + domainurl = flow.domainurl, + name = flow.name, + content = flow.content, + version = db_app.version, + updateuserid = userid, + createuserid = userid + ) + db.add(db_flowhistory) + db.commit() + db.refresh(db_app) + return db_app + return None + + def change_appversion(self,db: Session, domainurl:str,appid:str,version:int,userid:int): + db_app = self.get_app(db,domainurl,appid) + db_appversion = dbappversion.get_app_by_version(db,domainurl,appid,version) + if db_appversion and db_app: + db_app.version = version + db_app.updateuserid = userid + db.add(db_app) + + flows = dbflow.get_flows_by_appid(db,domainurl,appid) #select(models.Flow).filter(and_(models.Flow.domainurl == appedit.domainurl,models.App.appid == appedit.appid)) + for flow in flows: + db.delete(flow) + flows = dbflowhistory.get_flows_by_appid_version(db,domainurl,appid,version) #select(models.Flow).filter(and_(models.Flow.domainurl == appedit.domainurl,models.App.appid == appedit.appid)) + for flow in flows: + db_flow = models.Flow( + flowid = flow.flowid, + appid = flow.appid, + eventid = flow.eventid, + domainurl = flow.domainurl, + name = flow.name, + content = flow.content, + updateuserid = userid, + createuserid = userid + ) + db.add(flow) + + db.commit() + db.refresh(db_app) + return db_app + return None def delete_app(self,db: Session, domainurl: str,appid: str ): db_app =self.get_app(db,domainurl,appid) if db_app: db.delete(db_app) - db_flows = dbflow.get_domain_app_by_appid(db,domainurl,appid) + db_flows = dbflow.get_flows_by_appid(db,domainurl,appid) for flow in db_flows: db.delete(flow) db.commit() diff --git a/backend/app/db/schemas.py b/backend/app/db/schemas.py index 684240f..36f47cf 100644 --- a/backend/app/db/schemas.py +++ b/backend/app/db/schemas.py @@ -91,7 +91,13 @@ class AppVersion(BaseModel): versionname: str comment:str appid:str - + version:t.Optional[int] = None + +class VersionUpdate(BaseModel): + appid:str + versionname: str + comment:str + class TokenData(BaseModel): id:int = 0 diff --git a/backend/app/tests/test_user_app.py b/backend/app/tests/test_user_app.py index 27ad4a4..a42b07a 100644 --- a/backend/app/tests/test_user_app.py +++ b/backend/app/tests/test_user_app.py @@ -20,12 +20,10 @@ def test_create_flow(test_client,test_domain,test_app_id,login_user): assert data["data"]["eventid"] == test_flow["eventid"] assert data["data"]["content"] == test_flow["content"] -def test_apps_update(test_client,test_domain,test_app_id,login_user): +def test_appversions_update(test_client,test_domain,test_app_id,login_user): app_version ={ - "domainurl": test_domain.url, - "appname": "test_app", - "versionname": "testversion", - "comment": "test", + "versionname": "version1", + "comment": "save version1", "appid": test_app_id } response = test_client.post("/api/apps", json=app_version,headers={"Authorization": "Bearer " + login_user}) @@ -34,8 +32,7 @@ def test_apps_update(test_client,test_domain,test_app_id,login_user): assert "data" in data assert data["data"] is not None assert data["data"]["domainurl"] == test_domain.url - assert data["data"]["appname"] == app_version["appname"] - #assert data["data"]["version"] == app_version["versionname"] + assert data["data"]["version"] == 1 assert data["data"]["appid"] == app_version["appid"] def test_apps_list(test_client,login_user): @@ -55,6 +52,28 @@ def test_appversions_list(test_client,test_domain,test_app_id,login_user): assert data["data"] is not None assert len(data["data"]) == 1 +def test_appversions_change(test_client,test_domain,test_app_id,login_user): + app_version ={ + "versionname": "version2", + "comment": "test", + "appid": test_app_id + } + response = test_client.post("/api/apps", json=app_version,headers={"Authorization": "Bearer " + login_user}) + assert response.status_code == 200 + data = response.json() + assert "data" in data + assert data["data"] is not None + assert data["data"]["version"] == 2 + + response = test_client.put("/api/appversions/" + test_app_id +"/1", headers={"Authorization": "Bearer " + login_user}) + assert response.status_code == 200 + data = response.json() + assert "data" in data + assert data["data"] is not None + assert data["data"]["domainurl"] == test_domain.url + assert data["data"]["version"] == 1 + assert data["data"]["appid"] == test_app_id + def test_delete_app(test_client,test_app_id,login_user): response = test_client.delete("/api/apps/"+ test_app_id, headers={"Authorization": "Bearer " + login_user})