Squashed 'spiffworkflow-backend/' changes from 1e338f955..153061d41
153061d41 Merge branch 'main' of github.com:sartography/spiffworkflow-backend into main 3724ef7f9 Assure that the Active Task Users table is cleared out before deleting the Active Task Record. We were depending on a cascade here, which seems to fail randomly -- apparently due to some sort of race condition. 137ebbc4b Merge branch 'main' of github.com:sartography/spiffworkflow-backend f8f38f813 pyl - prettier maybe? 02fe90969 Merge branch 'main' into feature/edit-task-data ca7d7d9b3 Merge branch 'main' into feature/edit-task-data c38efe2bd w/Jon Api endpoint to update task data 15b99bf90 mypy git-subtree-dir: spiffworkflow-backend git-subtree-split: 153061d413afc5d7ed0c9cec25b292393585f757
This commit is contained in:
parent
eff49e1ddb
commit
999e0f4d2b
|
@ -469,6 +469,33 @@ paths:
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/Workflow"
|
$ref: "#/components/schemas/Workflow"
|
||||||
|
|
||||||
|
/process-instances/{process_instance_id}/task/{task_id}/update:
|
||||||
|
parameters:
|
||||||
|
- name: process_instance_id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: The unique id of the process instance
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: task_id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: The unique id of the task
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
post:
|
||||||
|
operationId: spiffworkflow_backend.routes.process_api_blueprint.update_task_data
|
||||||
|
summary: Update the task data for requested instance and task
|
||||||
|
tags:
|
||||||
|
- Process Instances
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Task Updated Successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Workflow"
|
||||||
|
|
||||||
/process-models/{process_group_id}/{process_model_id}/script-unit-tests:
|
/process-models/{process_group_id}/{process_model_id}/script-unit-tests:
|
||||||
parameters:
|
parameters:
|
||||||
- name: process_group_id
|
- name: process_group_id
|
||||||
|
|
|
@ -1493,3 +1493,44 @@ def _update_form_schema_with_task_data_as_needed(
|
||||||
for o in value:
|
for o in value:
|
||||||
if isinstance(o, dict):
|
if isinstance(o, dict):
|
||||||
_update_form_schema_with_task_data_as_needed(o, task_data)
|
_update_form_schema_with_task_data_as_needed(o, task_data)
|
||||||
|
|
||||||
|
|
||||||
|
def update_task_data(process_instance_id: str, task_id: str, body: Dict) -> Response:
|
||||||
|
"""Update task data."""
|
||||||
|
process_instance = ProcessInstanceModel.query.filter(
|
||||||
|
ProcessInstanceModel.id == int(process_instance_id)
|
||||||
|
).first()
|
||||||
|
if process_instance:
|
||||||
|
process_instance_bpmn_json_dict = json.loads(process_instance.bpmn_json)
|
||||||
|
if "new_task_data" in body:
|
||||||
|
new_task_data_str: str = body["new_task_data"]
|
||||||
|
new_task_data_dict = json.loads(new_task_data_str)
|
||||||
|
if task_id in process_instance_bpmn_json_dict["tasks"]:
|
||||||
|
process_instance_bpmn_json_dict["tasks"][task_id][
|
||||||
|
"data"
|
||||||
|
] = new_task_data_dict
|
||||||
|
process_instance.bpmn_json = json.dumps(process_instance_bpmn_json_dict)
|
||||||
|
db.session.add(process_instance)
|
||||||
|
try:
|
||||||
|
db.session.commit()
|
||||||
|
except Exception as e:
|
||||||
|
db.session.rollback()
|
||||||
|
raise ApiError(
|
||||||
|
error_code="update_task_data_error",
|
||||||
|
message=f"Could not update the Instance. Original error is {e}",
|
||||||
|
) from e
|
||||||
|
else:
|
||||||
|
raise ApiError(
|
||||||
|
error_code="update_task_data_error",
|
||||||
|
message=f"Could not find Task: {task_id} in Instance: {process_instance_id}.",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise ApiError(
|
||||||
|
error_code="update_task_data_error",
|
||||||
|
message=f"Could not update task data for Instance: {process_instance_id}, and Task: {task_id}.",
|
||||||
|
)
|
||||||
|
return Response(
|
||||||
|
json.dumps(ProcessInstanceModelSchema().dump(process_instance)),
|
||||||
|
status=200,
|
||||||
|
mimetype="application/json",
|
||||||
|
)
|
||||||
|
|
|
@ -522,6 +522,10 @@ class ProcessInstanceProcessor:
|
||||||
).all()
|
).all()
|
||||||
if len(active_tasks) > 0:
|
if len(active_tasks) > 0:
|
||||||
for at in active_tasks:
|
for at in active_tasks:
|
||||||
|
active_task_users = at.active_task_users
|
||||||
|
for atu in active_task_users:
|
||||||
|
# don't trust sqlalchemy to cascade - ran into race condition here.
|
||||||
|
db.session.delete(atu)
|
||||||
db.session.delete(at)
|
db.session.delete(at)
|
||||||
|
|
||||||
db.session.add(self.process_instance_model)
|
db.session.add(self.process_instance_model)
|
||||||
|
|
|
@ -55,7 +55,7 @@ class SecretService:
|
||||||
def get_secret(key: str) -> SecretModel:
|
def get_secret(key: str) -> SecretModel:
|
||||||
"""Get_secret."""
|
"""Get_secret."""
|
||||||
secret = db.session.query(SecretModel).filter(SecretModel.key == key).first()
|
secret = db.session.query(SecretModel).filter(SecretModel.key == key).first()
|
||||||
if secret is not None:
|
if isinstance(secret, SecretModel):
|
||||||
return secret
|
return secret
|
||||||
else:
|
else:
|
||||||
raise ApiError(
|
raise ApiError(
|
||||||
|
|
|
@ -264,7 +264,7 @@ class UserService:
|
||||||
.filter(PrincipalModel.user_id == user_id)
|
.filter(PrincipalModel.user_id == user_id)
|
||||||
.first()
|
.first()
|
||||||
)
|
)
|
||||||
if principal:
|
if isinstance(principal, PrincipalModel):
|
||||||
return principal
|
return principal
|
||||||
raise ApiError(
|
raise ApiError(
|
||||||
error_code="no_principal_found",
|
error_code="no_principal_found",
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
"""Process Model."""
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
|
from flask.app import Flask
|
||||||
|
from flask_bpmn.models.db import db
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.active_task import ActiveTaskModel
|
||||||
|
from spiffworkflow_backend.models.active_task_user import ActiveTaskUserModel
|
||||||
|
from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor
|
||||||
|
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||||
|
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.spiff_logging import SpiffLoggingModel
|
||||||
|
|
||||||
|
|
||||||
|
class TestActiveTask(BaseTest):
|
||||||
|
|
||||||
|
def test_can_create_and_delete_an_active_task (
|
||||||
|
self, app: Flask, with_db_and_bpmn_file_cleanup: None
|
||||||
|
) -> None:
|
||||||
|
process_model = load_test_spec(
|
||||||
|
"call_activity_test",
|
||||||
|
process_model_source_directory="call_activity_same_directory",
|
||||||
|
)
|
||||||
|
|
||||||
|
process_instance = self.create_process_instance_from_process_model(
|
||||||
|
process_model
|
||||||
|
)
|
||||||
|
active_task = ActiveTaskModel(
|
||||||
|
process_instance_id=process_instance.id,
|
||||||
|
process_model_display_name="my shorts",
|
||||||
|
form_file_name="my_file_name",
|
||||||
|
ui_form_file_name="",
|
||||||
|
task_id="1234",
|
||||||
|
task_name="any old thing",
|
||||||
|
task_title="",
|
||||||
|
task_type="test type",
|
||||||
|
task_status="WAITING",
|
||||||
|
lane_assignment_id=None,
|
||||||
|
)
|
||||||
|
initiator_user = self.find_or_create_user("initiator_user")
|
||||||
|
db.session.add(active_task)
|
||||||
|
db.session.commit()
|
||||||
|
active_task_user = ActiveTaskUserModel(active_task_id=active_task.id, user_id=initiator_user.id)
|
||||||
|
db.session.add(active_task_user)
|
||||||
|
db.session.commit()
|
||||||
|
processor = ProcessInstanceProcessor(process_instance)
|
||||||
|
processor.save() # This should clear out all active tasks and active task users.
|
||||||
|
assert(len(db.session.query(ActiveTaskModel).all()) == 0)
|
Loading…
Reference in New Issue