diff --git a/spiffworkflow-backend/migrations/versions/ffef09e6ddf1_.py b/spiffworkflow-backend/migrations/versions/ffef09e6ddf1_.py new file mode 100644 index 000000000..21bb3aae0 --- /dev/null +++ b/spiffworkflow-backend/migrations/versions/ffef09e6ddf1_.py @@ -0,0 +1,34 @@ +"""empty message + +Revision ID: ffef09e6ddf1 +Revises: fc5815a9d482 +Create Date: 2024-06-26 14:22:42.317828 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'ffef09e6ddf1' +down_revision = 'fc5815a9d482' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('process_instance', schema=None) as batch_op: + batch_op.add_column(sa.Column('summary', sa.String(length=255), nullable=True)) + batch_op.create_index(batch_op.f('ix_process_instance_summary'), ['summary'], unique=False) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('process_instance', schema=None) as batch_op: + batch_op.drop_index(batch_op.f('ix_process_instance_summary')) + batch_op.drop_column('summary') + + # ### end Alembic commands ### diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py index 04cc81296..1b633c565 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py @@ -50,6 +50,7 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel): id: int = db.Column(db.Integer, primary_key=True) process_model_identifier: str = db.Column(db.String(255), nullable=False, index=True) process_model_display_name: str = db.Column(db.String(255), nullable=False, index=True) + summary: str | None = db.Column(db.String(255), nullable=True, index=True) process_initiator_id: int = db.Column(ForeignKey(UserModel.id), nullable=False, index=True) # type: ignore bpmn_process_definition_id: int | None = db.Column( ForeignKey(BpmnProcessDefinitionModel.id), # type: ignore @@ -151,6 +152,7 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel): "process_model_identifier": self.process_model_identifier, "start_in_seconds": self.start_in_seconds, "status": self.status, + "summary": self.summary, "task_updated_at_in_seconds": self.task_updated_at_in_seconds, "updated_at_in_seconds": self.updated_at_in_seconds, } diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_processor.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_processor.py index 60daa5169..3714c28ad 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_processor.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_processor.py @@ -972,7 +972,12 @@ class ProcessInstanceProcessor: ) pim.value = str(data_for_key)[0:255] db.session.add(pim) - db.session.commit() + + def update_summary(self) -> None: + current_data = self.get_current_data() + if "spiff_process_instance_summary" in current_data: + summary = current_data["spiff_process_instance_summary"] + self.process_instance_model.summary = summary[:255] @classmethod def _store_bpmn_process_definition( @@ -1119,6 +1124,7 @@ class ProcessInstanceProcessor: ready_or_waiting_tasks = self.get_all_ready_or_waiting_tasks() self.extract_metadata() + self.update_summary() for ready_or_waiting_task in ready_or_waiting_tasks: # filter out non-usertasks diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_report_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_report_service.py index dc40640e9..a79c37b88 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_report_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_report_service.py @@ -255,7 +255,6 @@ class ProcessInstanceReportService: metadata_columns: list[ReportMetadataColumn], ) -> list[dict]: results = [] - cls.non_metadata_columns() for process_instance_row in process_instance_sqlalchemy_rows: process_instance_mapping = process_instance_row._mapping process_instance_dict = process_instance_row[0].serialized() @@ -335,7 +334,7 @@ class ProcessInstanceReportService: @classmethod def non_metadata_columns(cls) -> list[str]: - return cls.process_instance_stock_columns() + ["process_initiator_username", "last_milestone_bpmn_name"] + return cls.process_instance_stock_columns() + ["process_initiator_username", "last_milestone_bpmn_name", "summary"] @classmethod def builtin_column_options(cls) -> list[ReportMetadataColumn]: diff --git a/spiffworkflow-backend/tests/data/script-task-with-instruction/script_task_with_instruction.bpmn b/spiffworkflow-backend/tests/data/script-task-with-instruction/script_task_with_instruction.bpmn index eae149981..9afb4a22b 100644 --- a/spiffworkflow-backend/tests/data/script-task-with-instruction/script_task_with_instruction.bpmn +++ b/spiffworkflow-backend/tests/data/script-task-with-instruction/script_task_with_instruction.bpmn @@ -16,7 +16,8 @@ Flow_0jml23i Flow_0ula2mv - a = 1 + a = 1 +spiff_process_instance_summary = "WE SUMMARIZE" @@ -24,6 +25,8 @@ Flow_0ula2mv Flow_0xzoduo + b = 2 +spiff_process_instance_summary = "WE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAIN" diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_processor.py b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_processor.py index 7bd69ecc2..4a37802e6 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_processor.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_processor.py @@ -1053,3 +1053,26 @@ class TestProcessInstanceProcessor(BaseTest): processor.do_engine_steps(save=True) assert process_instance.status == "complete" + + def test_can_store_summary( + self, + app: Flask, + client: FlaskClient, + with_db_and_bpmn_file_cleanup: None, + ) -> None: + process_model = load_test_spec( + process_model_id="test_group/script_task_with_instruction", + bpmn_file_name="script_task_with_instruction.bpmn", + process_model_source_directory="script-task-with-instruction", + ) + process_instance = self.create_process_instance_from_process_model(process_model=process_model) + + processor = ProcessInstanceProcessor(process_instance) + processor.do_engine_steps(save=True, execution_strategy_name="queue_instructions_for_end_user") + assert process_instance.summary is None + processor.do_engine_steps(save=True, execution_strategy_name="run_current_ready_tasks") + assert process_instance.summary == "WE SUMMARIZE" + processor.do_engine_steps(save=True, execution_strategy_name="greedy") + assert process_instance.summary is not None + # mypy thinks this is unreachable but it is reachable. summary can be str | None + assert len(process_instance.summary) == 255 # type: ignore