diff --git a/.gitignore b/.gitignore index 73f59e5e..f509b359 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ pyrightconfig.json +.idea/ \ No newline at end of file diff --git a/spiffworkflow-backend/migrations/env.py b/spiffworkflow-backend/migrations/env.py index 4bd0316c..68feded2 100644 --- a/spiffworkflow-backend/migrations/env.py +++ b/spiffworkflow-backend/migrations/env.py @@ -1,9 +1,12 @@ +from __future__ import with_statement + import logging from logging.config import fileConfig -from alembic import context from flask import current_app +from alembic import context + # this is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config @@ -11,17 +14,17 @@ config = context.config # Interpret the config file for Python logging. # This line sets up loggers basically. fileConfig(config.config_file_name) -logger = logging.getLogger("alembic.env") +logger = logging.getLogger('alembic.env') # add your model's MetaData object here # for 'autogenerate' support # from myapp import mymodel # target_metadata = mymodel.Base.metadata config.set_main_option( - "sqlalchemy.url", - str(current_app.extensions["migrate"].db.get_engine().url).replace("%", "%%"), -) -target_metadata = current_app.extensions["migrate"].db.metadata + 'sqlalchemy.url', + str(current_app.extensions['migrate'].db.get_engine().url).replace( + '%', '%%')) +target_metadata = current_app.extensions['migrate'].db.metadata # other values from the config, defined by the needs of env.py, # can be acquired: @@ -42,7 +45,9 @@ def run_migrations_offline(): """ url = config.get_main_option("sqlalchemy.url") - context.configure(url=url, target_metadata=target_metadata, literal_binds=True) + context.configure( + url=url, target_metadata=target_metadata, literal_binds=True + ) with context.begin_transaction(): context.run_migrations() @@ -60,20 +65,20 @@ def run_migrations_online(): # when there are no changes to the schema # reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html def process_revision_directives(context, revision, directives): - if getattr(config.cmd_opts, "autogenerate", False): + if getattr(config.cmd_opts, 'autogenerate', False): script = directives[0] if script.upgrade_ops.is_empty(): directives[:] = [] - logger.info("No changes in schema detected.") + logger.info('No changes in schema detected.') - connectable = current_app.extensions["migrate"].db.get_engine() + connectable = current_app.extensions['migrate'].db.get_engine() with connectable.connect() as connection: context.configure( connection=connection, target_metadata=target_metadata, process_revision_directives=process_revision_directives, - **current_app.extensions["migrate"].configure_args + **current_app.extensions['migrate'].configure_args ) with context.begin_transaction(): diff --git a/spiffworkflow-backend/migrations/versions/3e2a826ac720_.py b/spiffworkflow-backend/migrations/versions/3e2a826ac720_.py new file mode 100644 index 00000000..c9e17c1c --- /dev/null +++ b/spiffworkflow-backend/migrations/versions/3e2a826ac720_.py @@ -0,0 +1,318 @@ +"""empty message + +Revision ID: 3e2a826ac720 +Revises: +Create Date: 2022-11-14 14:59:43.265173 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '3e2a826ac720' +down_revision = None +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('group', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', sa.String(length=255), nullable=True), + sa.Column('identifier', sa.String(length=255), nullable=True), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('message_model', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('identifier', sa.String(length=50), nullable=True), + sa.Column('name', sa.String(length=50), nullable=True), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_message_model_identifier'), 'message_model', ['identifier'], unique=True) + op.create_index(op.f('ix_message_model_name'), 'message_model', ['name'], unique=True) + op.create_table('permission_target', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('uri', sa.String(length=255), nullable=False), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('uri') + ) + op.create_table('spec_reference_cache', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('identifier', sa.String(length=255), nullable=True), + sa.Column('display_name', sa.String(length=255), nullable=True), + sa.Column('type', sa.String(length=255), nullable=True), + sa.Column('file_name', sa.String(length=255), nullable=True), + sa.Column('relative_path', sa.String(length=255), nullable=True), + sa.Column('has_lanes', sa.Boolean(), nullable=True), + sa.Column('is_executable', sa.Boolean(), nullable=True), + sa.Column('is_primary', sa.Boolean(), nullable=True), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_spec_reference_cache_display_name'), 'spec_reference_cache', ['display_name'], unique=False) + op.create_index(op.f('ix_spec_reference_cache_identifier'), 'spec_reference_cache', ['identifier'], unique=True) + op.create_index(op.f('ix_spec_reference_cache_type'), 'spec_reference_cache', ['type'], unique=False) + op.create_table('spiff_logging', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('process_instance_id', sa.Integer(), nullable=False), + sa.Column('bpmn_process_identifier', sa.String(length=255), nullable=False), + sa.Column('bpmn_task_identifier', sa.String(length=255), nullable=False), + sa.Column('bpmn_task_name', sa.String(length=255), nullable=True), + sa.Column('bpmn_task_type', sa.String(length=255), nullable=True), + sa.Column('spiff_task_guid', sa.String(length=50), nullable=False), + sa.Column('timestamp', sa.DECIMAL(precision=17, scale=6), nullable=False), + sa.Column('message', sa.String(length=255), nullable=True), + sa.Column('current_user_id', sa.Integer(), nullable=True), + sa.Column('spiff_step', sa.Integer(), nullable=False), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('spiff_step_details', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('process_instance_id', sa.Integer(), nullable=False), + sa.Column('spiff_step', sa.Integer(), nullable=False), + sa.Column('task_json', sa.JSON(), nullable=False), + sa.Column('timestamp', sa.DECIMAL(precision=17, scale=6), nullable=False), + sa.Column('completed_by_user_id', sa.Integer(), nullable=True), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('user', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('username', sa.String(length=255), nullable=False), + sa.Column('uid', sa.String(length=50), nullable=True), + sa.Column('service', sa.String(length=50), nullable=False), + sa.Column('service_id', sa.String(length=255), nullable=False), + sa.Column('name', sa.String(length=255), nullable=True), + sa.Column('email', sa.String(length=255), nullable=True), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('service', 'service_id', name='service_key'), + sa.UniqueConstraint('uid'), + sa.UniqueConstraint('username') + ) + op.create_table('message_correlation_property', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('identifier', sa.String(length=50), nullable=True), + sa.Column('message_model_id', sa.Integer(), nullable=False), + sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True), + sa.Column('created_at_in_seconds', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['message_model_id'], ['message_model.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('identifier', 'message_model_id', name='message_correlation_property_unique') + ) + op.create_index(op.f('ix_message_correlation_property_identifier'), 'message_correlation_property', ['identifier'], unique=False) + op.create_table('message_triggerable_process_model', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('message_model_id', sa.Integer(), nullable=False), + sa.Column('process_model_identifier', sa.String(length=50), nullable=False), + sa.Column('process_group_identifier', sa.String(length=50), nullable=False), + sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True), + sa.Column('created_at_in_seconds', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['message_model_id'], ['message_model.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('message_model_id') + ) + op.create_index(op.f('ix_message_triggerable_process_model_process_group_identifier'), 'message_triggerable_process_model', ['process_group_identifier'], unique=False) + op.create_index(op.f('ix_message_triggerable_process_model_process_model_identifier'), 'message_triggerable_process_model', ['process_model_identifier'], unique=False) + op.create_table('principal', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=True), + sa.Column('group_id', sa.Integer(), nullable=True), + sa.CheckConstraint('NOT(user_id IS NULL AND group_id IS NULL)'), + sa.ForeignKeyConstraint(['group_id'], ['group.id'], ), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('group_id'), + sa.UniqueConstraint('user_id') + ) + op.create_table('process_instance', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('process_model_identifier', sa.String(length=255), nullable=False), + sa.Column('process_group_identifier', sa.String(length=50), nullable=False), + sa.Column('process_initiator_id', sa.Integer(), nullable=False), + sa.Column('bpmn_json', sa.JSON(), nullable=True), + sa.Column('start_in_seconds', sa.Integer(), nullable=True), + sa.Column('end_in_seconds', sa.Integer(), nullable=True), + sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True), + sa.Column('created_at_in_seconds', sa.Integer(), nullable=True), + sa.Column('status', sa.String(length=50), nullable=True), + sa.Column('bpmn_version_control_type', sa.String(length=50), nullable=True), + sa.Column('bpmn_version_control_identifier', sa.String(length=255), nullable=True), + sa.Column('spiff_step', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['process_initiator_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_process_instance_process_group_identifier'), 'process_instance', ['process_group_identifier'], unique=False) + op.create_index(op.f('ix_process_instance_process_model_identifier'), 'process_instance', ['process_model_identifier'], unique=False) + op.create_table('process_instance_report', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('identifier', sa.String(length=50), nullable=False), + sa.Column('report_metadata', sa.JSON(), nullable=True), + sa.Column('created_by_id', sa.Integer(), nullable=False), + sa.Column('created_at_in_seconds', sa.Integer(), nullable=True), + sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('created_by_id', 'identifier', name='process_instance_report_unique') + ) + op.create_index(op.f('ix_process_instance_report_created_by_id'), 'process_instance_report', ['created_by_id'], unique=False) + op.create_index(op.f('ix_process_instance_report_identifier'), 'process_instance_report', ['identifier'], unique=False) + op.create_table('refresh_token', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=False), + sa.Column('token', sa.String(length=1024), nullable=False), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('user_id') + ) + op.create_table('secret', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('key', sa.String(length=50), nullable=False), + sa.Column('value', sa.Text(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=False), + sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True), + sa.Column('created_at_in_seconds', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('key') + ) + op.create_table('user_group_assignment', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=False), + sa.Column('group_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['group_id'], ['group.id'], ), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('user_id', 'group_id', name='user_group_assignment_unique') + ) + op.create_table('active_task', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('process_instance_id', sa.Integer(), nullable=False), + sa.Column('actual_owner_id', sa.Integer(), nullable=True), + sa.Column('lane_assignment_id', sa.Integer(), nullable=True), + sa.Column('form_file_name', sa.String(length=50), nullable=True), + sa.Column('ui_form_file_name', sa.String(length=50), nullable=True), + sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True), + sa.Column('created_at_in_seconds', sa.Integer(), nullable=True), + sa.Column('task_id', sa.String(length=50), nullable=True), + sa.Column('task_name', sa.String(length=50), nullable=True), + sa.Column('task_title', sa.String(length=50), nullable=True), + sa.Column('task_type', sa.String(length=50), nullable=True), + sa.Column('task_status', sa.String(length=50), nullable=True), + sa.Column('process_model_display_name', sa.String(length=255), nullable=True), + sa.ForeignKeyConstraint(['actual_owner_id'], ['user.id'], ), + sa.ForeignKeyConstraint(['lane_assignment_id'], ['group.id'], ), + sa.ForeignKeyConstraint(['process_instance_id'], ['process_instance.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('task_id', 'process_instance_id', name='active_task_unique') + ) + op.create_table('message_correlation', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('process_instance_id', sa.Integer(), nullable=False), + sa.Column('message_correlation_property_id', sa.Integer(), nullable=False), + sa.Column('name', sa.String(length=255), nullable=False), + sa.Column('value', sa.String(length=255), nullable=False), + sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True), + sa.Column('created_at_in_seconds', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['message_correlation_property_id'], ['message_correlation_property.id'], ), + sa.ForeignKeyConstraint(['process_instance_id'], ['process_instance.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('process_instance_id', 'message_correlation_property_id', 'name', name='message_instance_id_name_unique') + ) + op.create_index(op.f('ix_message_correlation_message_correlation_property_id'), 'message_correlation', ['message_correlation_property_id'], unique=False) + op.create_index(op.f('ix_message_correlation_name'), 'message_correlation', ['name'], unique=False) + op.create_index(op.f('ix_message_correlation_process_instance_id'), 'message_correlation', ['process_instance_id'], unique=False) + op.create_index(op.f('ix_message_correlation_value'), 'message_correlation', ['value'], unique=False) + op.create_table('message_instance', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('process_instance_id', sa.Integer(), nullable=False), + sa.Column('message_model_id', sa.Integer(), nullable=False), + sa.Column('message_type', sa.String(length=20), nullable=False), + sa.Column('payload', sa.JSON(), nullable=True), + sa.Column('status', sa.String(length=20), nullable=False), + sa.Column('failure_cause', sa.Text(), nullable=True), + sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True), + sa.Column('created_at_in_seconds', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['message_model_id'], ['message_model.id'], ), + sa.ForeignKeyConstraint(['process_instance_id'], ['process_instance.id'], ), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('permission_assignment', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('principal_id', sa.Integer(), nullable=False), + sa.Column('permission_target_id', sa.Integer(), nullable=False), + sa.Column('grant_type', sa.String(length=50), nullable=False), + sa.Column('permission', sa.String(length=50), nullable=False), + sa.ForeignKeyConstraint(['permission_target_id'], ['permission_target.id'], ), + sa.ForeignKeyConstraint(['principal_id'], ['principal.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('principal_id', 'permission_target_id', 'permission', name='permission_assignment_uniq') + ) + op.create_table('active_task_user', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('active_task_id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['active_task_id'], ['active_task.id'], ), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('active_task_id', 'user_id', name='active_task_user_unique') + ) + op.create_index(op.f('ix_active_task_user_active_task_id'), 'active_task_user', ['active_task_id'], unique=False) + op.create_index(op.f('ix_active_task_user_user_id'), 'active_task_user', ['user_id'], unique=False) + op.create_table('message_correlation_message_instance', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('message_instance_id', sa.Integer(), nullable=False), + sa.Column('message_correlation_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['message_correlation_id'], ['message_correlation.id'], ), + sa.ForeignKeyConstraint(['message_instance_id'], ['message_instance.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('message_instance_id', 'message_correlation_id', name='message_correlation_message_instance_unique') + ) + op.create_index(op.f('ix_message_correlation_message_instance_message_correlation_id'), 'message_correlation_message_instance', ['message_correlation_id'], unique=False) + op.create_index(op.f('ix_message_correlation_message_instance_message_instance_id'), 'message_correlation_message_instance', ['message_instance_id'], unique=False) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index(op.f('ix_message_correlation_message_instance_message_instance_id'), table_name='message_correlation_message_instance') + op.drop_index(op.f('ix_message_correlation_message_instance_message_correlation_id'), table_name='message_correlation_message_instance') + op.drop_table('message_correlation_message_instance') + op.drop_index(op.f('ix_active_task_user_user_id'), table_name='active_task_user') + op.drop_index(op.f('ix_active_task_user_active_task_id'), table_name='active_task_user') + op.drop_table('active_task_user') + op.drop_table('permission_assignment') + op.drop_table('message_instance') + op.drop_index(op.f('ix_message_correlation_value'), table_name='message_correlation') + op.drop_index(op.f('ix_message_correlation_process_instance_id'), table_name='message_correlation') + op.drop_index(op.f('ix_message_correlation_name'), table_name='message_correlation') + op.drop_index(op.f('ix_message_correlation_message_correlation_property_id'), table_name='message_correlation') + op.drop_table('message_correlation') + op.drop_table('active_task') + op.drop_table('user_group_assignment') + op.drop_table('secret') + op.drop_table('refresh_token') + op.drop_index(op.f('ix_process_instance_report_identifier'), table_name='process_instance_report') + op.drop_index(op.f('ix_process_instance_report_created_by_id'), table_name='process_instance_report') + op.drop_table('process_instance_report') + op.drop_index(op.f('ix_process_instance_process_model_identifier'), table_name='process_instance') + op.drop_index(op.f('ix_process_instance_process_group_identifier'), table_name='process_instance') + op.drop_table('process_instance') + op.drop_table('principal') + op.drop_index(op.f('ix_message_triggerable_process_model_process_model_identifier'), table_name='message_triggerable_process_model') + op.drop_index(op.f('ix_message_triggerable_process_model_process_group_identifier'), table_name='message_triggerable_process_model') + op.drop_table('message_triggerable_process_model') + op.drop_index(op.f('ix_message_correlation_property_identifier'), table_name='message_correlation_property') + op.drop_table('message_correlation_property') + op.drop_table('user') + op.drop_table('spiff_step_details') + op.drop_table('spiff_logging') + op.drop_index(op.f('ix_spec_reference_cache_type'), table_name='spec_reference_cache') + op.drop_index(op.f('ix_spec_reference_cache_identifier'), table_name='spec_reference_cache') + op.drop_index(op.f('ix_spec_reference_cache_display_name'), table_name='spec_reference_cache') + op.drop_table('spec_reference_cache') + op.drop_table('permission_target') + op.drop_index(op.f('ix_message_model_name'), table_name='message_model') + op.drop_index(op.f('ix_message_model_identifier'), table_name='message_model') + op.drop_table('message_model') + op.drop_table('group') + # ### end Alembic commands ### diff --git a/spiffworkflow-backend/migrations/versions/fd00c59e1f60_.py b/spiffworkflow-backend/migrations/versions/fd00c59e1f60_.py deleted file mode 100644 index 55f1ca3f..00000000 --- a/spiffworkflow-backend/migrations/versions/fd00c59e1f60_.py +++ /dev/null @@ -1,550 +0,0 @@ -"""empty message - -Revision ID: fd00c59e1f60 -Revises: -Create Date: 2022-11-09 14:04:14.169379 - -""" -import sqlalchemy as sa -from alembic import op - - -# revision identifiers, used by Alembic. -revision = "fd00c59e1f60" -down_revision = None -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.create_table( - "bpmn_process_id_lookup", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("bpmn_process_identifier", sa.String(length=255), nullable=True), - sa.Column("bpmn_file_relative_path", sa.String(length=255), nullable=True), - sa.Column("display_name", sa.String(length=255), nullable=True), - sa.PrimaryKeyConstraint("id"), - ) - op.create_index( - op.f("ix_bpmn_process_id_lookup_bpmn_process_identifier"), - "bpmn_process_id_lookup", - ["bpmn_process_identifier"], - unique=True, - ) - op.create_table( - "group", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("name", sa.String(length=255), nullable=True), - sa.Column("identifier", sa.String(length=255), nullable=True), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "message_model", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("identifier", sa.String(length=50), nullable=True), - sa.Column("name", sa.String(length=50), nullable=True), - sa.PrimaryKeyConstraint("id"), - ) - op.create_index( - op.f("ix_message_model_identifier"), - "message_model", - ["identifier"], - unique=True, - ) - op.create_index( - op.f("ix_message_model_name"), "message_model", ["name"], unique=True - ) - op.create_table( - "permission_target", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("uri", sa.String(length=255), nullable=False), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("uri"), - ) - op.create_table( - "spiff_logging", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("process_instance_id", sa.Integer(), nullable=False), - sa.Column("bpmn_process_identifier", sa.String(length=255), nullable=False), - sa.Column("bpmn_task_identifier", sa.String(length=255), nullable=False), - sa.Column("bpmn_task_name", sa.String(length=255), nullable=True), - sa.Column("bpmn_task_type", sa.String(length=255), nullable=True), - sa.Column("spiff_task_guid", sa.String(length=50), nullable=False), - sa.Column("timestamp", sa.DECIMAL(precision=17, scale=6), nullable=False), - sa.Column("message", sa.String(length=255), nullable=True), - sa.Column("current_user_id", sa.Integer(), nullable=True), - sa.Column("spiff_step", sa.Integer(), nullable=False), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "spiff_step_details", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("process_instance_id", sa.Integer(), nullable=False), - sa.Column("spiff_step", sa.Integer(), nullable=False), - sa.Column("task_json", sa.JSON(), nullable=False), - sa.Column("timestamp", sa.DECIMAL(precision=17, scale=6), nullable=False), - sa.Column("completed_by_user_id", sa.Integer(), nullable=True), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "user", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("username", sa.String(length=255), nullable=False), - sa.Column("uid", sa.String(length=50), nullable=True), - sa.Column("service", sa.String(length=50), nullable=False), - sa.Column("service_id", sa.String(length=255), nullable=False), - sa.Column("name", sa.String(length=255), nullable=True), - sa.Column("email", sa.String(length=255), nullable=True), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("service", "service_id", name="service_key"), - sa.UniqueConstraint("uid"), - sa.UniqueConstraint("username"), - ) - op.create_table( - "message_correlation_property", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("identifier", sa.String(length=50), nullable=True), - sa.Column("message_model_id", sa.Integer(), nullable=False), - sa.Column("updated_at_in_seconds", sa.Integer(), nullable=True), - sa.Column("created_at_in_seconds", sa.Integer(), nullable=True), - sa.ForeignKeyConstraint( - ["message_model_id"], - ["message_model.id"], - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint( - "identifier", "message_model_id", name="message_correlation_property_unique" - ), - ) - op.create_index( - op.f("ix_message_correlation_property_identifier"), - "message_correlation_property", - ["identifier"], - unique=False, - ) - op.create_table( - "message_triggerable_process_model", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("message_model_id", sa.Integer(), nullable=False), - sa.Column("process_model_identifier", sa.String(length=50), nullable=False), - sa.Column("process_group_identifier", sa.String(length=50), nullable=False), - sa.Column("updated_at_in_seconds", sa.Integer(), nullable=True), - sa.Column("created_at_in_seconds", sa.Integer(), nullable=True), - sa.ForeignKeyConstraint( - ["message_model_id"], - ["message_model.id"], - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("message_model_id"), - ) - op.create_index( - op.f("ix_message_triggerable_process_model_process_group_identifier"), - "message_triggerable_process_model", - ["process_group_identifier"], - unique=False, - ) - op.create_index( - op.f("ix_message_triggerable_process_model_process_model_identifier"), - "message_triggerable_process_model", - ["process_model_identifier"], - unique=False, - ) - op.create_table( - "principal", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("user_id", sa.Integer(), nullable=True), - sa.Column("group_id", sa.Integer(), nullable=True), - sa.CheckConstraint("NOT(user_id IS NULL AND group_id IS NULL)"), - sa.ForeignKeyConstraint( - ["group_id"], - ["group.id"], - ), - sa.ForeignKeyConstraint( - ["user_id"], - ["user.id"], - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("group_id"), - sa.UniqueConstraint("user_id"), - ) - op.create_table( - "process_instance", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("process_model_identifier", sa.String(length=255), nullable=False), - sa.Column("process_group_identifier", sa.String(length=50), nullable=False), - sa.Column("process_initiator_id", sa.Integer(), nullable=False), - sa.Column("bpmn_json", sa.JSON(), nullable=True), - sa.Column("start_in_seconds", sa.Integer(), nullable=True), - sa.Column("end_in_seconds", sa.Integer(), nullable=True), - sa.Column("updated_at_in_seconds", sa.Integer(), nullable=True), - sa.Column("created_at_in_seconds", sa.Integer(), nullable=True), - sa.Column("status", sa.String(length=50), nullable=True), - sa.Column("bpmn_version_control_type", sa.String(length=50), nullable=True), - sa.Column( - "bpmn_version_control_identifier", sa.String(length=255), nullable=True - ), - sa.Column("spiff_step", sa.Integer(), nullable=True), - sa.ForeignKeyConstraint( - ["process_initiator_id"], - ["user.id"], - ), - sa.PrimaryKeyConstraint("id"), - ) - op.create_index( - op.f("ix_process_instance_process_group_identifier"), - "process_instance", - ["process_group_identifier"], - unique=False, - ) - op.create_index( - op.f("ix_process_instance_process_model_identifier"), - "process_instance", - ["process_model_identifier"], - unique=False, - ) - op.create_table( - "process_instance_report", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("identifier", sa.String(length=50), nullable=False), - sa.Column("report_metadata", sa.JSON(), nullable=True), - sa.Column("created_by_id", sa.Integer(), nullable=False), - sa.Column("created_at_in_seconds", sa.Integer(), nullable=True), - sa.Column("updated_at_in_seconds", sa.Integer(), nullable=True), - sa.ForeignKeyConstraint( - ["created_by_id"], - ["user.id"], - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint( - "created_by_id", "identifier", name="process_instance_report_unique" - ), - ) - op.create_index( - op.f("ix_process_instance_report_created_by_id"), - "process_instance_report", - ["created_by_id"], - unique=False, - ) - op.create_index( - op.f("ix_process_instance_report_identifier"), - "process_instance_report", - ["identifier"], - unique=False, - ) - op.create_table( - "refresh_token", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("user_id", sa.Integer(), nullable=False), - sa.Column("token", sa.String(length=1024), nullable=False), - sa.ForeignKeyConstraint( - ["user_id"], - ["user.id"], - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("user_id"), - ) - op.create_table( - "secret", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("key", sa.String(length=50), nullable=False), - sa.Column("value", sa.Text(), nullable=False), - sa.Column("user_id", sa.Integer(), nullable=False), - sa.Column("updated_at_in_seconds", sa.Integer(), nullable=True), - sa.Column("created_at_in_seconds", sa.Integer(), nullable=True), - sa.ForeignKeyConstraint( - ["user_id"], - ["user.id"], - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("key"), - ) - op.create_table( - "user_group_assignment", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("user_id", sa.Integer(), nullable=False), - sa.Column("group_id", sa.Integer(), nullable=False), - sa.ForeignKeyConstraint( - ["group_id"], - ["group.id"], - ), - sa.ForeignKeyConstraint( - ["user_id"], - ["user.id"], - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("user_id", "group_id", name="user_group_assignment_unique"), - ) - op.create_table( - "active_task", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("process_instance_id", sa.Integer(), nullable=False), - sa.Column("actual_owner_id", sa.Integer(), nullable=True), - sa.Column("lane_assignment_id", sa.Integer(), nullable=True), - sa.Column("form_file_name", sa.String(length=50), nullable=True), - sa.Column("ui_form_file_name", sa.String(length=50), nullable=True), - sa.Column("updated_at_in_seconds", sa.Integer(), nullable=True), - sa.Column("created_at_in_seconds", sa.Integer(), nullable=True), - sa.Column("task_id", sa.String(length=50), nullable=True), - sa.Column("task_name", sa.String(length=50), nullable=True), - sa.Column("task_title", sa.String(length=50), nullable=True), - sa.Column("task_type", sa.String(length=50), nullable=True), - sa.Column("task_status", sa.String(length=50), nullable=True), - sa.Column("process_model_display_name", sa.String(length=255), nullable=True), - sa.ForeignKeyConstraint( - ["actual_owner_id"], - ["user.id"], - ), - sa.ForeignKeyConstraint( - ["lane_assignment_id"], - ["group.id"], - ), - sa.ForeignKeyConstraint( - ["process_instance_id"], - ["process_instance.id"], - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint( - "task_id", "process_instance_id", name="active_task_unique" - ), - ) - op.create_table( - "message_correlation", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("process_instance_id", sa.Integer(), nullable=False), - sa.Column("message_correlation_property_id", sa.Integer(), nullable=False), - sa.Column("name", sa.String(length=255), nullable=False), - sa.Column("value", sa.String(length=255), nullable=False), - sa.Column("updated_at_in_seconds", sa.Integer(), nullable=True), - sa.Column("created_at_in_seconds", sa.Integer(), nullable=True), - sa.ForeignKeyConstraint( - ["message_correlation_property_id"], - ["message_correlation_property.id"], - ), - sa.ForeignKeyConstraint( - ["process_instance_id"], - ["process_instance.id"], - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint( - "process_instance_id", - "message_correlation_property_id", - "name", - name="message_instance_id_name_unique", - ), - ) - op.create_index( - op.f("ix_message_correlation_message_correlation_property_id"), - "message_correlation", - ["message_correlation_property_id"], - unique=False, - ) - op.create_index( - op.f("ix_message_correlation_name"), - "message_correlation", - ["name"], - unique=False, - ) - op.create_index( - op.f("ix_message_correlation_process_instance_id"), - "message_correlation", - ["process_instance_id"], - unique=False, - ) - op.create_index( - op.f("ix_message_correlation_value"), - "message_correlation", - ["value"], - unique=False, - ) - op.create_table( - "message_instance", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("process_instance_id", sa.Integer(), nullable=False), - sa.Column("message_model_id", sa.Integer(), nullable=False), - sa.Column("message_type", sa.String(length=20), nullable=False), - sa.Column("payload", sa.JSON(), nullable=True), - sa.Column("status", sa.String(length=20), nullable=False), - sa.Column("failure_cause", sa.Text(), nullable=True), - sa.Column("updated_at_in_seconds", sa.Integer(), nullable=True), - sa.Column("created_at_in_seconds", sa.Integer(), nullable=True), - sa.ForeignKeyConstraint( - ["message_model_id"], - ["message_model.id"], - ), - sa.ForeignKeyConstraint( - ["process_instance_id"], - ["process_instance.id"], - ), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "permission_assignment", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("principal_id", sa.Integer(), nullable=False), - sa.Column("permission_target_id", sa.Integer(), nullable=False), - sa.Column("grant_type", sa.String(length=50), nullable=False), - sa.Column("permission", sa.String(length=50), nullable=False), - sa.ForeignKeyConstraint( - ["permission_target_id"], - ["permission_target.id"], - ), - sa.ForeignKeyConstraint( - ["principal_id"], - ["principal.id"], - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint( - "principal_id", - "permission_target_id", - "permission", - name="permission_assignment_uniq", - ), - ) - op.create_table( - "active_task_user", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("active_task_id", sa.Integer(), nullable=False), - sa.Column("user_id", sa.Integer(), nullable=False), - sa.ForeignKeyConstraint( - ["active_task_id"], - ["active_task.id"], - ), - sa.ForeignKeyConstraint( - ["user_id"], - ["user.id"], - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint( - "active_task_id", "user_id", name="active_task_user_unique" - ), - ) - op.create_index( - op.f("ix_active_task_user_active_task_id"), - "active_task_user", - ["active_task_id"], - unique=False, - ) - op.create_index( - op.f("ix_active_task_user_user_id"), - "active_task_user", - ["user_id"], - unique=False, - ) - op.create_table( - "message_correlation_message_instance", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("message_instance_id", sa.Integer(), nullable=False), - sa.Column("message_correlation_id", sa.Integer(), nullable=False), - sa.ForeignKeyConstraint( - ["message_correlation_id"], - ["message_correlation.id"], - ), - sa.ForeignKeyConstraint( - ["message_instance_id"], - ["message_instance.id"], - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint( - "message_instance_id", - "message_correlation_id", - name="message_correlation_message_instance_unique", - ), - ) - op.create_index( - op.f("ix_message_correlation_message_instance_message_correlation_id"), - "message_correlation_message_instance", - ["message_correlation_id"], - unique=False, - ) - op.create_index( - op.f("ix_message_correlation_message_instance_message_instance_id"), - "message_correlation_message_instance", - ["message_instance_id"], - unique=False, - ) - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_index( - op.f("ix_message_correlation_message_instance_message_instance_id"), - table_name="message_correlation_message_instance", - ) - op.drop_index( - op.f("ix_message_correlation_message_instance_message_correlation_id"), - table_name="message_correlation_message_instance", - ) - op.drop_table("message_correlation_message_instance") - op.drop_index(op.f("ix_active_task_user_user_id"), table_name="active_task_user") - op.drop_index( - op.f("ix_active_task_user_active_task_id"), table_name="active_task_user" - ) - op.drop_table("active_task_user") - op.drop_table("permission_assignment") - op.drop_table("message_instance") - op.drop_index( - op.f("ix_message_correlation_value"), table_name="message_correlation" - ) - op.drop_index( - op.f("ix_message_correlation_process_instance_id"), - table_name="message_correlation", - ) - op.drop_index(op.f("ix_message_correlation_name"), table_name="message_correlation") - op.drop_index( - op.f("ix_message_correlation_message_correlation_property_id"), - table_name="message_correlation", - ) - op.drop_table("message_correlation") - op.drop_table("active_task") - op.drop_table("user_group_assignment") - op.drop_table("secret") - op.drop_table("refresh_token") - op.drop_index( - op.f("ix_process_instance_report_identifier"), - table_name="process_instance_report", - ) - op.drop_index( - op.f("ix_process_instance_report_created_by_id"), - table_name="process_instance_report", - ) - op.drop_table("process_instance_report") - op.drop_index( - op.f("ix_process_instance_process_model_identifier"), - table_name="process_instance", - ) - op.drop_index( - op.f("ix_process_instance_process_group_identifier"), - table_name="process_instance", - ) - op.drop_table("process_instance") - op.drop_table("principal") - op.drop_index( - op.f("ix_message_triggerable_process_model_process_model_identifier"), - table_name="message_triggerable_process_model", - ) - op.drop_index( - op.f("ix_message_triggerable_process_model_process_group_identifier"), - table_name="message_triggerable_process_model", - ) - op.drop_table("message_triggerable_process_model") - op.drop_index( - op.f("ix_message_correlation_property_identifier"), - table_name="message_correlation_property", - ) - op.drop_table("message_correlation_property") - op.drop_table("user") - op.drop_table("spiff_step_details") - op.drop_table("spiff_logging") - op.drop_table("permission_target") - op.drop_index(op.f("ix_message_model_name"), table_name="message_model") - op.drop_index(op.f("ix_message_model_identifier"), table_name="message_model") - op.drop_table("message_model") - op.drop_table("group") - op.drop_index( - op.f("ix_bpmn_process_id_lookup_bpmn_process_identifier"), - table_name="bpmn_process_id_lookup", - ) - op.drop_table("bpmn_process_id_lookup") - # ### end Alembic commands ### diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/load_database_models.py b/spiffworkflow-backend/src/spiffworkflow_backend/load_database_models.py index 14dcac0d..97c99000 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/load_database_models.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/load_database_models.py @@ -18,8 +18,8 @@ from spiffworkflow_backend.models.principal import PrincipalModel # noqa: F401 from spiffworkflow_backend.models.active_task import ActiveTaskModel # noqa: F401 -from spiffworkflow_backend.models.bpmn_process_id_lookup import ( - BpmnProcessIdLookup, +from spiffworkflow_backend.models.spec_reference import ( + SpecReferenceCache, ) # noqa: F401 from spiffworkflow_backend.models.message_correlation_property import ( MessageCorrelationPropertyModel, diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/models/bpmn_process_id_lookup.py b/spiffworkflow-backend/src/spiffworkflow_backend/models/bpmn_process_id_lookup.py deleted file mode 100644 index 133901c1..00000000 --- a/spiffworkflow-backend/src/spiffworkflow_backend/models/bpmn_process_id_lookup.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Message_model.""" -from flask_bpmn.models.db import db -from flask_bpmn.models.db import SpiffworkflowBaseDBModel - - -class BpmnProcessIdLookup(SpiffworkflowBaseDBModel): - """BpmnProcessIdLookup.""" - - __tablename__ = "bpmn_process_id_lookup" - - id = db.Column(db.Integer, primary_key=True) - bpmn_process_identifier = db.Column(db.String(255), unique=True, index=True) - display_name = db.Column(db.String(255), unique=True, index=True) - bpmn_file_relative_path = db.Column(db.String(255)) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/models/spec_reference.py b/spiffworkflow-backend/src/spiffworkflow_backend/models/spec_reference.py new file mode 100644 index 00000000..e3fbabe7 --- /dev/null +++ b/spiffworkflow-backend/src/spiffworkflow_backend/models/spec_reference.py @@ -0,0 +1,56 @@ +"""Message_model.""" +from dataclasses import dataclass + +from flask_bpmn.models.db import db +from flask_bpmn.models.db import SpiffworkflowBaseDBModel +from flask_marshmallow import Schema +from marshmallow import INCLUDE + + +@dataclass() +class SpecReference: + """File Reference Information. + + Includes items such as the process id and name for a BPMN, + or the Decision id and Decision name for a DMN file. There may be more than + one reference that points to a particular file - if for instance, there are + three executable processes in a collaboration within a BPMN Diagram. + """ + + identifier: str # The id of the process or decision. "Process_1234" + display_name: str # The name of the process or decision. "Invoice Submission" + type: str # can be 'process' or 'decision' + file_name: str # The name of the file where this process or decision is defined. + relative_path: str # The path to the file. + has_lanes: bool # If this is a process, whether it has lanes or not. + is_executable: bool # Whether this process or decision is designated as executable. + is_primary: bool # Whether this is the primary process of a process model + messages: dict # Any messages defined in the same file where this process is defined. + correlations: dict # Any correlations defined in the same file with this process. + start_messages: list # The names of any messages that would start this process. + + +class SpecReferenceCache(SpiffworkflowBaseDBModel): + """A cache of information about all the Processes and Decisions defined in all files. """ + + __tablename__ = "spec_reference_cache" + + id = db.Column(db.Integer, primary_key=True) + identifier = db.Column(db.String(255), unique=True, index=True) + display_name = db.Column(db.String(255), index=True) + type = db.Column(db.String(255), index=True) # either 'process' or 'decision' + file_name = db.Column(db.String(255)) + relative_path = db.Column(db.String(255)) + has_lanes = db.Column(db.Boolean()) + is_executable = db.Column(db.Boolean()) # either 'process' or 'decision' + is_primary = db.Column(db.Boolean()) + +class SpecReferenceSchema(Schema): + """FileSchema.""" + + class Meta: + """Meta.""" + + model = SpecReference + fields = ["identifier", "display_name", "type"] + unknown = INCLUDE \ No newline at end of file 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 6c472e2a..35bb60f2 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_processor.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_processor.py @@ -68,7 +68,7 @@ from SpiffWorkflow.util.deep_merge import DeepMerge # type: ignore from spiffworkflow_backend.models.active_task import ActiveTaskModel from spiffworkflow_backend.models.active_task_user import ActiveTaskUserModel -from spiffworkflow_backend.models.bpmn_process_id_lookup import BpmnProcessIdLookup +from spiffworkflow_backend.models.spec_reference import SpecReferenceCache from spiffworkflow_backend.models.file import File from spiffworkflow_backend.models.file import FileType from spiffworkflow_backend.models.group import GroupModel @@ -674,9 +674,9 @@ class ProcessInstanceProcessor: return parser @staticmethod - def backfill_missing_bpmn_process_id_lookup_records(bpmn_process_identifier: str) -> Optional[str]: + def backfill_missing_spec_reference_records(bpmn_process_identifier: str) -> Optional[str]: - """Backfill_missing_bpmn_process_id_lookup_records.""" + """Backfill_missing_spec_reference_records.""" process_models = ProcessModelService().get_process_models() for process_model in process_models: refs = SpecFileService.reference_map(SpecFileService.get_references_for_process(process_model)) @@ -698,18 +698,16 @@ class ProcessInstanceProcessor: "bpmn_file_full_path_from_bpmn_process_identifier: bpmn_process_identifier is unexpectedly None" ) - bpmn_process_id_lookup = BpmnProcessIdLookup.query.filter_by( - bpmn_process_identifier=bpmn_process_identifier - ).first() + spec_reference = SpecReferenceCache.query.filter_by(identifier=bpmn_process_identifier).first() bpmn_file_full_path = None - if bpmn_process_id_lookup is None: - bpmn_file_full_path = ProcessInstanceProcessor.backfill_missing_bpmn_process_id_lookup_records( + if spec_reference is None: + bpmn_file_full_path = ProcessInstanceProcessor.backfill_missing_spec_reference_records( bpmn_process_identifier ) else: bpmn_file_full_path = os.path.join( FileSystemService.root_path(), - bpmn_process_id_lookup.bpmn_file_relative_path, + spec_reference.relative_path, ) if bpmn_file_full_path is None: raise ( diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/spec_file_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/spec_file_service.py index a3c44a1e..49c29b36 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/spec_file_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/spec_file_service.py @@ -15,9 +15,9 @@ from lxml.etree import _Element # type: ignore from lxml.etree import Element as EtreeElement from SpiffWorkflow.bpmn.parser.ValidationException import ValidationException # type: ignore -from spiffworkflow_backend.models.bpmn_process_id_lookup import BpmnProcessIdLookup +from spiffworkflow_backend.models.spec_reference import SpecReferenceCache from spiffworkflow_backend.models.file import File -from spiffworkflow_backend.models.file import FileReference +from spiffworkflow_backend.models.file import SpecReference from spiffworkflow_backend.models.file import FileType from spiffworkflow_backend.models.message_correlation_property import ( MessageCorrelationPropertyModel, @@ -61,22 +61,22 @@ class SpecFileService(FileSystemService): return files @staticmethod - def reference_map(references: list[FileReference]) -> dict[str, FileReference]: + def reference_map(references: list[SpecReference]) -> dict[str, SpecReference]: """ Creates a dict with provided references organized by id. """ ref_map = {} for ref in references: - ref_map[ref.id] = ref + ref_map[ref.identifier] = ref return ref_map @staticmethod - def get_references(process_models: List[ProcessModelInfo]) -> list[FileReference]: + def get_references(process_models: List[ProcessModelInfo]) -> list[SpecReference]: """Returns all references -- process_ids, and decision ids, across all process models provided""" references = [] for process_model in process_models: references.extend(SpecFileService.get_references_for_process(process_model)) @staticmethod - def get_references_for_process(process_model_info: ProcessModelInfo) -> list[FileReference]: + def get_references_for_process(process_model_info: ProcessModelInfo) -> list[SpecReference]: files = SpecFileService.get_files(process_model_info) references = [] for file in files: @@ -84,7 +84,7 @@ class SpecFileService(FileSystemService): return references @staticmethod - def get_references_for_file(file: File, process_model_info: ProcessModelInfo) -> list[FileReference]: + def get_references_for_file(file: File, process_model_info: ProcessModelInfo) -> list[SpecReference]: """Uses spiffworkflow to parse BPMN and DMN files to determine how they can be externally referenced. Returns a list of Reference objects that contain the type of reference, the id, the name. @@ -93,14 +93,15 @@ class SpecFileService(FileSystemService): name = {str} 'Level 3' type = {str} 'process' / 'decision' """ - references: list[FileReference] = [] + references: list[SpecReference] = [] full_file_path = SpecFileService.file_path(process_model_info, file.name) file_path = os.path.join(process_model_info.id, file.name) parser = MyCustomParser() parser_type = None sub_parser = None has_lanes = False - executable = True + is_executable = True + is_primary = False messages = {} correlations = {} start_messages = [] @@ -121,10 +122,11 @@ class SpecFileService(FileSystemService): has_lanes = sub_parser.has_lanes() executable = sub_parser.process_executable start_messages = sub_parser.start_messages() - references.append(FileReference( - id=sub_parser.get_id(), name=sub_parser.get_name(), type=parser_type, - file_name=file.name, file_path=file_path, has_lanes=has_lanes, - executable=executable, messages=messages, + is_primary = sub_parser.get_id() == process_model_info.primary_process_id + references.append(SpecReference( + identifier=sub_parser.get_id(), display_name=sub_parser.get_name(), type=parser_type, + file_name=file.name, relative_path=file_path, has_lanes=has_lanes, + is_executable=is_executable, messages=messages, is_primary=is_primary, correlations=correlations, start_messages=start_messages )) return references @@ -162,7 +164,7 @@ class SpecFileService(FileSystemService): if ref.type == "process": ProcessModelService().update_spec( process_model_info, { - "primary_process_id": ref.id, + "primary_process_id": ref.identifier, "primary_file_name": file_name, "is_review": ref.has_lanes, } @@ -231,30 +233,32 @@ class SpecFileService(FileSystemService): @staticmethod - def update_process_cache(ref: FileReference) -> None: - process_id_lookup = BpmnProcessIdLookup.query.filter_by(bpmn_process_identifier=ref.id).first() + def update_process_cache(ref: SpecReference) -> None: + process_id_lookup = SpecReferenceCache.query.filter_by(identifier=ref.identifier).first() if process_id_lookup is None: - process_id_lookup = BpmnProcessIdLookup( - bpmn_process_identifier=ref.id, - display_name=ref.name, - bpmn_file_relative_path=ref.file_path, + process_id_lookup = SpecReferenceCache( + identifier=ref.identifier, + display_name=ref.display_name, + relative_path=ref.relative_path, + type=ref.type, + is_executable=ref.is_executable ) db.session.add(process_id_lookup) else: - if ref.file_path != process_id_lookup.bpmn_file_relative_path: + if ref.relative_path != process_id_lookup.relative_path: full_bpmn_file_path = SpecFileService.full_path_from_relative_path( - process_id_lookup.bpmn_file_relative_path + process_id_lookup.relative_path ) # if the old relative bpmn file no longer exists, then assume things were moved around # on the file system. Otherwise, assume it is a duplicate process id and error. if os.path.isfile(full_bpmn_file_path): raise ValidationException( - f"Process id ({ref.id}) has already been used for " - f"{process_id_lookup.bpmn_file_relative_path}. It cannot be reused." + f"Process id ({ref.identifier}) has already been used for " + f"{process_id_lookup.relative_path}. It cannot be reused." ) else: - process_id_lookup.bpmn_file_relative_path = ( - ref.file_path + process_id_lookup.relative_path = ( + ref.relative_path ) db.session.add(process_id_lookup) db.session.commit() @@ -262,7 +266,7 @@ class SpecFileService(FileSystemService): @staticmethod - def update_message_cache(ref: FileReference) -> None: + def update_message_cache(ref: SpecReference) -> None: """Assure we have a record in the database of all possible message ids and names.""" for message_model_identifier in ref.messages.keys(): message_model = MessageModel.query.filter_by(identifier=message_model_identifier).first() @@ -274,7 +278,7 @@ class SpecFileService(FileSystemService): db.session.commit() @staticmethod - def update_message_trigger_cache(ref: FileReference, process_model_info: ProcessModelInfo) -> None: + def update_message_trigger_cache(ref: SpecReference, process_model_info: ProcessModelInfo) -> None: """assure we know which messages can trigger the start of a process.""" for message_model_identifier in ref.start_messages: message_model = MessageModel.query.filter_by( @@ -313,7 +317,7 @@ class SpecFileService(FileSystemService): ) @staticmethod - def update_correlation_cache(ref: FileReference) -> None: + def update_correlation_cache(ref: SpecReference) -> None: for correlation_identifier in ref.correlations.keys(): correlation_property_retrieval_expressions = \ ref.correlations[correlation_identifier]['retrieval_expressions'] diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/helpers/example_data.py b/spiffworkflow-backend/tests/spiffworkflow_backend/helpers/example_data.py index b5261a26..8a19a4c4 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/helpers/example_data.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/helpers/example_data.py @@ -86,7 +86,7 @@ class ExampleDataLoader: ) if is_primary: references = SpecFileService.get_references_for_file(file_info, spec) - spec.primary_process_id = references[0].id + spec.primary_process_id = references[0].identifier spec.primary_file_name = filename ProcessModelService().save_process_model(spec) finally: diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_model.py b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_model.py index 5b5b9f25..0d093954 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_model.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_model.py @@ -5,7 +5,7 @@ from flask_bpmn.models.db import db from tests.spiffworkflow_backend.helpers.base_test import BaseTest from tests.spiffworkflow_backend.helpers.test_data import load_test_spec -from spiffworkflow_backend.models.bpmn_process_id_lookup import BpmnProcessIdLookup +from spiffworkflow_backend.models.spec_reference import SpecReferenceCache from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.services.process_instance_processor import ( @@ -116,7 +116,7 @@ class TestProcessModel(BaseTest): # delete all of the id lookup items to force to processor to find the correct # process model when running the process - db.session.query(BpmnProcessIdLookup).delete() + db.session.query(SpecReferenceCache).delete() db.session.commit() processor = ProcessInstanceProcessor(process_instance) processor.do_engine_steps(save=True) diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_spec_file_service.py b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_spec_file_service.py index 004d9859..391c86fc 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_spec_file_service.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_spec_file_service.py @@ -10,7 +10,7 @@ from SpiffWorkflow.dmn.parser.BpmnDmnParser import BpmnDmnParser # type: ignore from tests.spiffworkflow_backend.helpers.base_test import BaseTest from tests.spiffworkflow_backend.helpers.test_data import load_test_spec -from spiffworkflow_backend.models.bpmn_process_id_lookup import BpmnProcessIdLookup +from spiffworkflow_backend.models.spec_reference import SpecReferenceCache from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.services.process_model_service import ProcessModelService from spiffworkflow_backend.services.spec_file_service import SpecFileService @@ -45,11 +45,11 @@ class TestSpecFileService(BaseTest): bpmn_file_name=self.bpmn_file_name, bpmn_file_location="call_activity_nested", ) - bpmn_process_id_lookups = BpmnProcessIdLookup.query.all() + bpmn_process_id_lookups = SpecReferenceCache.query.all() assert len(bpmn_process_id_lookups) == 1 - assert bpmn_process_id_lookups[0].bpmn_process_identifier == "Level1" + assert bpmn_process_id_lookups[0].identifier == "Level1" assert ( - bpmn_process_id_lookups[0].bpmn_file_relative_path + bpmn_process_id_lookups[0].relative_path == self.call_activity_nested_relative_file_path ) @@ -70,14 +70,14 @@ class TestSpecFileService(BaseTest): bpmn_file_name=self.bpmn_file_name, bpmn_file_location=self.process_model_id, ) - bpmn_process_id_lookups = BpmnProcessIdLookup.query.all() + bpmn_process_id_lookups = SpecReferenceCache.query.all() assert len(bpmn_process_id_lookups) == 1 assert ( - bpmn_process_id_lookups[0].bpmn_process_identifier + bpmn_process_id_lookups[0].identifier == bpmn_process_identifier ) assert ( - bpmn_process_id_lookups[0].bpmn_file_relative_path + bpmn_process_id_lookups[0].relative_path == self.call_activity_nested_relative_file_path ) with pytest.raises(ValidationException) as exception: @@ -99,9 +99,9 @@ class TestSpecFileService(BaseTest): ) -> None: """Test_updates_relative_file_path_when_appropriate.""" bpmn_process_identifier = "Level1" - process_id_lookup = BpmnProcessIdLookup( - bpmn_process_identifier=bpmn_process_identifier, - bpmn_file_relative_path=self.call_activity_nested_relative_file_path, + process_id_lookup = SpecReferenceCache( + identifier=bpmn_process_identifier, + relative_path=self.call_activity_nested_relative_file_path, ) db.session.add(process_id_lookup) db.session.commit() @@ -115,14 +115,14 @@ class TestSpecFileService(BaseTest): bpmn_file_location=self.process_model_id, ) - bpmn_process_id_lookups = BpmnProcessIdLookup.query.all() + bpmn_process_id_lookups = SpecReferenceCache.query.all() assert len(bpmn_process_id_lookups) == 1 assert ( - bpmn_process_id_lookups[0].bpmn_process_identifier + bpmn_process_id_lookups[0].identifier == bpmn_process_identifier ) assert ( - bpmn_process_id_lookups[0].bpmn_file_relative_path + bpmn_process_id_lookups[0].relative_path == self.call_activity_nested_relative_file_path ) @@ -166,13 +166,13 @@ class TestSpecFileService(BaseTest): file = next(filter(lambda f: f.name == "call_activity_level_3.bpmn", files)) ca_3 = SpecFileService.get_references_for_file(file, process_model_info) assert len(ca_3) == 1 - assert ca_3[0].name == "Level 3" - assert ca_3[0].id == "Level3" + assert ca_3[0].display_name == "Level 3" + assert ca_3[0].identifier == "Level3" assert ca_3[0].type == "process" file = next(filter(lambda f: f.name == "level2c.dmn", files)) dmn1 = SpecFileService.get_references_for_file(file, process_model_info) assert len(dmn1) == 1 - assert dmn1[0].name == "Decision 1" - assert dmn1[0].id == "Decision_0vrtcmk" + assert dmn1[0].display_name == "Decision 1" + assert dmn1[0].identifier == "Decision_0vrtcmk" assert dmn1[0].type == "decision" diff --git a/spiffworkflow-frontend/package-lock.json b/spiffworkflow-frontend/package-lock.json index 79b2bbb5..e890810f 100644 --- a/spiffworkflow-frontend/package-lock.json +++ b/spiffworkflow-frontend/package-lock.json @@ -7485,7 +7485,7 @@ }, "node_modules/bpmn-js-spiffworkflow": { "version": "0.0.8", - "resolved": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#09fa713bb0bb1b9d4f97684afc46bc3711e11770", + "resolved": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#c90359945c98034c76a65fcbe8709f8ddeaf949a", "license": "MIT", "dependencies": { "inherits": "^2.0.4", @@ -35755,7 +35755,7 @@ } }, "bpmn-js-spiffworkflow": { - "version": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#09fa713bb0bb1b9d4f97684afc46bc3711e11770", + "version": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#c90359945c98034c76a65fcbe8709f8ddeaf949a", "from": "bpmn-js-spiffworkflow@sartography/bpmn-js-spiffworkflow#main", "requires": { "inherits": "^2.0.4",