@restforgejs/platform 4.1.1 → 4.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SECURITY.md +83 -4
- package/bin/sdf-tools.exe +0 -0
- package/build-info.json +2 -2
- package/cli/consumer-deploy.js +1 -1
- package/cli/consumer.js +1 -1
- package/generators/cli/dashboard/create.js +4 -1
- package/generators/cli/endpoint/create.js +43 -4
- package/generators/cli/key/generate.js +2 -1
- package/generators/cli/key/revoke.js +2 -1
- package/generators/cli/payload/diff.js +3 -2
- package/generators/cli/payload/generate.js +3 -2
- package/generators/cli/payload/sync.js +3 -2
- package/generators/cli/payload/validate.js +3 -2
- package/generators/cli/processor/create.js +14 -3
- package/generators/cli/project/delete.js +2 -1
- package/generators/cli/query/validate.js +3 -2
- package/generators/cli/schema/apply.js +526 -0
- package/generators/cli/schema/describe.js +3 -2
- package/generators/cli/schema/diff.js +322 -0
- package/generators/cli/schema/generate-ddl.js +7 -10
- package/generators/cli/schema/init.js +95 -172
- package/generators/cli/schema/introspect.js +3 -2
- package/generators/cli/schema/list.js +3 -2
- package/generators/cli/schema/migrate.js +13 -18
- package/generators/cli/schema/models.js +8 -12
- package/generators/cli/schema/template.js +222 -0
- package/generators/cli/schema/validate.js +8 -12
- package/generators/cli-entry.js +17 -2
- package/generators/lib/dbschema-kit/apply-engine.js +582 -0
- package/generators/lib/dbschema-kit/diff-engine.js +703 -0
- package/generators/lib/dbschema-kit/diff-reporter.js +272 -0
- package/generators/lib/dbschema-kit/emitters/alter-table.js +275 -0
- package/generators/lib/migration/audit-table-runner.js +213 -215
- package/generators/lib/payload/endpoint-schema-validator.js +171 -0
- package/generators/lib/payload/payload-runner.js +137 -220
- package/generators/lib/payload/schema-diff.js +277 -0
- package/generators/lib/templates/dashboard-catalog.js +1 -437
- package/generators/lib/templates/db-connection-env.js +1 -212
- package/generators/lib/templates/dbschema-catalog.js +1 -489
- package/generators/lib/templates/field-validation-catalog.js +1 -531
- package/generators/lib/templates/mysql-template.js +1 -3863
- package/generators/lib/templates/oracle-template.js +1 -3915
- package/generators/lib/templates/postgres-template.js +1 -5838
- package/generators/lib/templates/query-declarative-catalog.js +1 -199
- package/generators/lib/templates/sqlite-template.js +1 -3440
- package/generators/lib/utils/audit-columns.js +181 -0
- package/generators/lib/utils/cli-output.js +17 -0
- package/generators/lib/utils/database-introspector.js +16 -13
- package/generators/lib/utils/env-manager.js +6 -0
- package/generators/lib/utils/path-validator.js +71 -0
- package/generators/lib/validators/payload-validator.js +1 -2
- package/integrity-manifest.json +28 -10
- package/package.json +11 -3
- package/scripts/verify-integrity.js +1 -1
- package/server.js +1 -1
- package/src/components/handlers/adjust_handler.js +1 -1
- package/src/components/handlers/audit_handler.js +1 -1
- package/src/components/handlers/delete_handler.js +1 -1
- package/src/components/handlers/export_handler.js +1 -1
- package/src/components/handlers/import_handler.js +1 -1
- package/src/components/handlers/insert_handler.js +1 -1
- package/src/components/handlers/update_handler.js +1 -1
- package/src/components/handlers/upload_handler.js +1 -1
- package/src/components/handlers/workflow_handler.js +1 -1
- package/src/components/integrations/webhook.js +1 -1
- package/src/consumers/baseConsumer.js +1 -1
- package/src/consumers/declarativeMapper.js +1 -1
- package/src/consumers/handlers/apiHandler.js +1 -1
- package/src/consumers/handlers/consoleHandler.js +1 -1
- package/src/consumers/handlers/databaseHandler.js +1 -1
- package/src/consumers/handlers/index.js +1 -1
- package/src/consumers/handlers/kafkaHandler.js +1 -1
- package/src/consumers/index.js +1 -1
- package/src/consumers/messageTransformer.js +1 -1
- package/src/consumers/validator.js +1 -1
- package/src/core/db/dialect/base-dialect.js +1 -1
- package/src/core/db/dialect/index.js +1 -1
- package/src/core/db/dialect/mysql-dialect.js +1 -1
- package/src/core/db/dialect/oracle-dialect.js +1 -1
- package/src/core/db/dialect/postgres-dialect.js +1 -1
- package/src/core/db/dialect/sqlite-dialect.js +1 -1
- package/src/core/db/flatten-helper.js +1 -1
- package/src/core/db/query-builder-error.js +1 -1
- package/src/core/db/query-builder.js +1 -1
- package/src/core/db/relation-helper.js +1 -1
- package/src/core/handlers/delete_handler.js +1 -1
- package/src/core/handlers/insert_handler.js +1 -1
- package/src/core/handlers/update_handler.js +1 -1
- package/src/core/models/base-model.js +1 -1
- package/src/core/utils/cache-manager.js +1 -1
- package/src/core/utils/component-engine.js +1 -1
- package/src/core/utils/context-builder.js +1 -1
- package/src/core/utils/datetime-formatter.js +1 -1
- package/src/core/utils/datetime-parser.js +1 -1
- package/src/core/utils/db.js +1 -1
- package/src/core/utils/logger.js +1 -1
- package/src/core/utils/payload-loader.js +1 -1
- package/src/core/utils/security-checks.js +1 -1
- package/src/middleware/body-options.js +1 -1
- package/src/middleware/cors.js +1 -1
- package/src/middleware/idempotency.js +1 -1
- package/src/middleware/rate-limiter.js +1 -1
- package/src/middleware/request-logger.js +1 -1
- package/src/middleware/security-headers.js +1 -1
- package/src/models/base-model-mysql.js +1 -1
- package/src/models/base-model-oracle.js +1 -1
- package/src/models/base-model-sqlite.js +1 -1
- package/src/models/base-model.js +1 -1
- package/src/pro/caching/redis-client.js +1 -1
- package/src/pro/caching/redis-helper.js +1 -1
- package/src/pro/consumers/baseConsumer.js +1 -1
- package/src/pro/consumers/declarativeMapper.js +1 -1
- package/src/pro/consumers/handlers/apiHandler.js +1 -1
- package/src/pro/consumers/handlers/consoleHandler.js +1 -1
- package/src/pro/consumers/handlers/databaseHandler.js +1 -1
- package/src/pro/consumers/handlers/index.js +1 -1
- package/src/pro/consumers/handlers/kafkaHandler.js +1 -1
- package/src/pro/consumers/index.js +1 -1
- package/src/pro/consumers/messageTransformer.js +1 -1
- package/src/pro/consumers/validator.js +1 -1
- package/src/pro/database/base-model-mysql.js +1 -1
- package/src/pro/database/base-model-oracle.js +1 -1
- package/src/pro/database/base-model-sqlite.js +1 -1
- package/src/pro/database/db-mysql.js +1 -1
- package/src/pro/database/db-oracle.js +1 -1
- package/src/pro/database/db-sqlite.js +1 -1
- package/src/pro/excel/excel-generator.js +1 -1
- package/src/pro/excel/excel-parser.js +1 -1
- package/src/pro/excel/export-service.js +1 -1
- package/src/pro/excel/export_handler.js +1 -1
- package/src/pro/excel/import-service.js +1 -1
- package/src/pro/excel/import-validator.js +1 -1
- package/src/pro/excel/import_handler.js +1 -1
- package/src/pro/excel/upsert-builder.js +1 -1
- package/src/pro/idgen/idgen-routes.js +1 -1
- package/src/pro/integrations/lookup-resolver.js +1 -1
- package/src/pro/integrations/upload-handler-v2.js +1 -1
- package/src/pro/integrations/upload-handler.js +1 -1
- package/src/pro/integrations/webhook.js +1 -1
- package/src/pro/locking/lock-routes.js +1 -1
- package/src/pro/locking/resource-lock-manager.js +1 -1
- package/src/pro/messaging/kafkaConsumerService.js +1 -1
- package/src/pro/messaging/kafkaService.js +1 -1
- package/src/pro/messaging/messagehubService.js +1 -1
- package/src/pro/messaging/rabbitmqService.js +1 -1
- package/src/pro/scheduler/job-manager.js +1 -1
- package/src/pro/scheduler/job-routes.js +1 -1
- package/src/pro/scheduler/job-validator.js +1 -1
- package/src/pro/storage/base-storage-provider.js +1 -1
- package/src/pro/storage/file-metadata-helper.js +1 -1
- package/src/pro/storage/index.js +1 -1
- package/src/pro/storage/local-storage-provider.js +1 -1
- package/src/pro/storage/s3-storage-provider.js +1 -1
- package/src/pro/storage/upload-cleanup-job.js +1 -1
- package/src/pro/storage/upload-cleanup-scheduler.js +1 -1
- package/src/pro/storage/upload-pending-tracker.js +1 -1
- package/src/pro/websocket/broadcast-helper.js +1 -1
- package/src/pro/websocket/index.js +1 -1
- package/src/pro/websocket/livesync-server.js +1 -1
- package/src/pro/websocket/ws-broadcaster.js +1 -1
- package/src/services/export-service.js +1 -1
- package/src/services/import-service.js +1 -1
- package/src/services/kafkaConsumerService.js +1 -1
- package/src/services/kafkaService.js +1 -1
- package/src/services/messagehubService.js +1 -1
- package/src/services/rabbitmqService.js +1 -1
- package/src/utils/cache-invalidation-registry.js +1 -1
- package/src/utils/cache-manager.js +1 -1
- package/src/utils/component-engine.js +1 -1
- package/src/utils/config-extractor.js +1 -1
- package/src/utils/consumerLogger.js +1 -1
- package/src/utils/context-builder.js +1 -1
- package/src/utils/dashboard-helpers.js +1 -1
- package/src/utils/dateHelper.js +1 -1
- package/src/utils/datetime-formatter.js +1 -1
- package/src/utils/datetime-parser.js +1 -1
- package/src/utils/db-bootstrap.js +1 -1
- package/src/utils/db-mysql.js +1 -1
- package/src/utils/db-oracle.js +1 -1
- package/src/utils/db-sqlite.js +1 -1
- package/src/utils/db.js +1 -1
- package/src/utils/demo-generator.js +1 -1
- package/src/utils/excel-generator.js +1 -1
- package/src/utils/excel-parser.js +1 -1
- package/src/utils/file-watcher.js +1 -1
- package/src/utils/id-generator.js +1 -1
- package/src/utils/idempotency-manager.js +1 -1
- package/src/utils/import-validator.js +1 -1
- package/src/utils/license-client.js +1 -1
- package/src/utils/lock-manager.js +1 -1
- package/src/utils/logger.js +1 -1
- package/src/utils/lookup-resolver.js +1 -1
- package/src/utils/payload-loader.js +1 -1
- package/src/utils/processor-response.js +1 -1
- package/src/utils/rabbitmq.js +1 -1
- package/src/utils/redis-client.js +1 -1
- package/src/utils/redis-helper.js +1 -1
- package/src/utils/request-scope.js +1 -1
- package/src/utils/security-checks.js +1 -1
- package/src/utils/service-resolver.js +1 -1
- package/src/utils/shutdown-coordinator.js +1 -1
- package/src/utils/trusted-keys.js +1 -1
- package/src/utils/upload-handler.js +1 -1
- package/src/utils/upsert-builder.js +1 -1
- package/src/utils/workflow-hook-executor.js +1 -1
- package/generators/metadata/global.json +0 -58
- package/generators/metadata/test-mysql-workbench.json +0 -118
- package/generators/metadata/test-mysql.json +0 -56
- package/generators/metadata/test-oracle-workbench.json +0 -118
- package/generators/metadata/test-oracle.json +0 -56
- package/generators/metadata/test-pg-workbench.json +0 -118
- package/generators/metadata/test-pg.json +0 -56
- package/generators/scripts/obfuscate-source.js +0 -356
- package/generators/scripts/validate-catalog.js +0 -430
- package/generators/scripts/validate-dbschema-catalog.js +0 -708
- package/generators/tests/baseline/mysql/mini_inventory_item/src/models/mini-inventory/item.js +0 -944
- package/generators/tests/baseline/mysql/mini_inventory_item/src/modules/mini-inventory/item.js +0 -740
- package/generators/tests/baseline/mysql/mini_inventory_item/src/modules/mini-inventory.js +0 -336
- package/generators/tests/baseline/oracle/mini_inventory_item/src/models/mini-inventory/item.js +0 -1002
- package/generators/tests/baseline/oracle/mini_inventory_item/src/modules/mini-inventory/item.js +0 -740
- package/generators/tests/baseline/oracle/mini_inventory_item/src/modules/mini-inventory.js +0 -336
- package/generators/tests/baseline/postgres/mini_inventory_item/src/models/mini-inventory/item.js +0 -1333
- package/generators/tests/baseline/postgres/mini_inventory_item/src/modules/mini-inventory/item.js +0 -1173
- package/generators/tests/baseline/postgres/mini_inventory_item/src/modules/mini-inventory.js +0 -496
- package/generators/tests/fixtures/payloads/custom-sensitive.json +0 -27
- package/generators/tests/fixtures/payloads/dynamic-search-optout.json +0 -23
- package/generators/tests/fixtures/payloads/login-with-password.json +0 -22
- package/generators/tests/fixtures/payloads/order-process.json +0 -52
- package/generators/tests/fixtures/payloads/with-inline-sql.json +0 -26
- package/generators/tests/integration-tahap4b/README.md +0 -145
- package/generators/tests/integration-tahap4b/run-concurrent.js +0 -77
- package/generators/tests/integration-tahap4b/seed.sql +0 -53
- package/generators/tests/integration-tahap4b/verify.sql +0 -110
- package/generators/tests/unit/cli/create-dashboard.test.js +0 -505
- package/generators/tests/unit/cli/create-processor.test.js +0 -319
- package/generators/tests/unit/cli/dispatch-dashboard.test.js +0 -149
- package/generators/tests/unit/lib/dashboard-generator.test.js +0 -895
- package/generators/tests/unit/lib/dashboard-validator.test.js +0 -354
- package/generators/tests/unit/lib/dbschema-kit/apply-executor.test.js +0 -437
- package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-introspect.test.js +0 -393
- package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-kit-generate-ddl.test.js +0 -104
- package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-kit-init.test.js +0 -119
- package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-kit-list.test.js +0 -48
- package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-kit-migrate.test.js +0 -175
- package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-kit-validate.test.js +0 -102
- package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-models.test.js +0 -43
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/all-schemas-listing.js +0 -84
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/connection-error.js +0 -13
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/empty.js +0 -12
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/multi-schema.js +0 -124
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/single-schema-inventory.js +0 -64
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/two-tables.js +0 -66
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/migrate-stubs/connection-error.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/migrate-stubs/partial.js +0 -29
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/migrate-stubs/rollback.js +0 -26
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/migrate-stubs/success.js +0 -43
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/multi-schema/audit/events.js +0 -18
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/multi-schema/inventory/products.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/multi-schema/users.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/connection.test.js +0 -112
- package/generators/tests/unit/lib/dbschema-kit/ddl-generator.test.js +0 -205
- package/generators/tests/unit/lib/dbschema-kit/define-model.test.js +0 -56
- package/generators/tests/unit/lib/dbschema-kit/dialect/index.test.js +0 -46
- package/generators/tests/unit/lib/dbschema-kit/dialect/mysql.test.js +0 -126
- package/generators/tests/unit/lib/dbschema-kit/dialect/oracle.test.js +0 -126
- package/generators/tests/unit/lib/dbschema-kit/dialect/postgres.test.js +0 -131
- package/generators/tests/unit/lib/dbschema-kit/dialect/sqlite.test.js +0 -126
- package/generators/tests/unit/lib/dbschema-kit/driver-loader.test.js +0 -93
- package/generators/tests/unit/lib/dbschema-kit/emitters/create-index.test.js +0 -173
- package/generators/tests/unit/lib/dbschema-kit/emitters/create-table.test.js +0 -376
- package/generators/tests/unit/lib/dbschema-kit/emitters/drop-table.test.js +0 -78
- package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/invalid-dialect.env +0 -6
- package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/missing-dialect.env +0 -5
- package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/missing-host.env +0 -5
- package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/oracle-valid.env +0 -6
- package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/postgres-valid.env +0 -7
- package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/sqlite-valid.env +0 -2
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/category.js +0 -11
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/item_product.js +0 -11
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/stock_inbound.js +0 -24
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/stock_inbound_item.js +0 -28
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/supplier.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/warehouse.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-invalid/orphan.js +0 -17
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/master/category.js +0 -11
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/master/item_product.js +0 -11
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/master/supplier.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/master/warehouse.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/transactions/stock_inbound.js +0 -24
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/transactions/stock_inbound_item.js +0 -28
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/multi-schema/audit/events.js +0 -18
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/multi-schema/inventory/products.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/multi-schema/public/users.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/duplicate-subfolder/extra/category.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/duplicate-subfolder/master/category.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/duplicate-tablename/bar.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/duplicate-tablename/foo.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/empty-folder/README.md +0 -1
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/invalid-export/plain.js +0 -3
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/invalid-schema/bad.js +0 -6
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/legacy-pattern/legacy.js +0 -12
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/multi-schema-distinct/audit/products.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/multi-schema-distinct/inventory/products.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/multi-schema-duplicate/a/products.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/multi-schema-duplicate/b/products.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/nested-deep/a/b/c/deep_table.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/recursive-multi-folder/.hidden/ignored.js +0 -7
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/recursive-multi-folder/master/category.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/recursive-multi-folder/master/supplier.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/recursive-multi-folder/transactions/stock_inbound.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/recursive-multi-folder/transactions/stock_inbound_item.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/valid-multiple/category.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/valid-multiple/item_product.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/valid-single/category.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/integration.test.js +0 -217
- package/generators/tests/unit/lib/dbschema-kit/introspect-mapper.test.js +0 -403
- package/generators/tests/unit/lib/dbschema-kit/ir-builder.test.js +0 -390
- package/generators/tests/unit/lib/dbschema-kit/loader.test.js +0 -128
- package/generators/tests/unit/lib/dbschema-kit/naming.test.js +0 -170
- package/generators/tests/unit/lib/dbschema-kit/parser/shorthand-parser.test.js +0 -237
- package/generators/tests/unit/lib/dbschema-kit/schema-printer.test.js +0 -251
- package/generators/tests/unit/lib/dbschema-kit/statement-modifier.test.js +0 -105
- package/generators/tests/unit/lib/dbschema-kit/statement-splitter.test.js +0 -165
- package/generators/tests/unit/lib/dbschema-kit/topological-sort.test.js +0 -135
- package/generators/tests/unit/lib/dbschema-kit/validator/check-compatibility-validator.test.js +0 -373
- package/generators/tests/unit/lib/dbschema-kit/validator/circular-relation-validator.test.js +0 -454
- package/generators/tests/unit/lib/dbschema-kit/validator/cross-model-validator.test.js +0 -512
- package/generators/tests/unit/lib/dbschema-kit/validator/enhanced-validate-integration.test.js +0 -390
- package/generators/tests/unit/lib/dbschema-kit/validator/naming-convention-validator.test.js +0 -306
- package/generators/tests/unit/lib/dbschema-kit/validator/schema-validator.test.js +0 -443
- package/generators/tests/unit/lib/dbschema-kit/validator/type-compatibility-validator.test.js +0 -440
- package/generators/tests/unit/lib/dbschema-kit/validator/validator-reporter.test.js +0 -172
- package/generators/tests/unit/lib/metadata-manager-dashboard.test.js +0 -256
- package/generators/tests/unit/lib/payload-validator-fieldpolicy.test.js +0 -240
- package/generators/tests/unit/lib/processor-validation-generator.test.js +0 -300
- package/generators/tests/unit/lib/sensitive-field-masker.test.js +0 -170
- package/generators/tests/unit/lib/sql-table-extractor.test.js +0 -119
- package/scripts/generate-integrity-manifest.js +0 -124
- package/scripts/snapshot-cli-contracts.js +0 -194
- package/scripts/verify-publish.js +0 -56
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
# Tahap 4b — Integration Test Concurrent UPDATE Strict (Postgres)
|
|
2
|
-
|
|
3
|
-
Verifikasi runtime path `_updateDataStrict()` di `base-model.js` (PostgreSQL) di bawah beban concurrent: 100 parallel UPDATE pada satu record harus menghasilkan 100 entry audit log dan tidak ada lost update.
|
|
4
|
-
|
|
5
|
-
## Prasyarat
|
|
6
|
-
|
|
7
|
-
| Komponen | Status yang Dibutuhkan |
|
|
8
|
-
|----------|------------------------|
|
|
9
|
-
| PostgreSQL | Running di 127.0.0.1:5432, database `dbinv`, user `postgres`, password `postgres1234` |
|
|
10
|
-
| Redis | Running di localhost:6380 (untuk lockManager — opsional, fallback aman jika down) |
|
|
11
|
-
| restforge runtime | Sudah di-build dan di-install di [restforge-test-pro](../../../../../deployment/restforge-test-pro/) |
|
|
12
|
-
| Module `karyawan-fp` | Sudah di-generate ke restforge-test-pro (lihat setup di bawah) |
|
|
13
|
-
|
|
14
|
-
## Setup (sudah dijalankan saat eksekusi Tahap 4b oleh assistant)
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
# 1. Build runtime restforge dengan modifikasi base-model.js (Tahap 2)
|
|
18
|
-
cd d:/workspace/03_projects/data-connector/source/restforge
|
|
19
|
-
echo y | node build-npm.js --nobump --edition=pro \
|
|
20
|
-
--target="D:\workspace\03_projects\data-connector\deployment\restforge-test-pro"
|
|
21
|
-
|
|
22
|
-
# 2. Reinstall package di restforge-test-pro
|
|
23
|
-
cd d:/workspace/03_projects/data-connector/deployment/restforge-test-pro
|
|
24
|
-
rm -rf node_modules
|
|
25
|
-
npm install restforgejs-2.3.0-beta.9.tgz
|
|
26
|
-
|
|
27
|
-
# 3. Generate module karyawan-fp
|
|
28
|
-
node d:/workspace/03_projects/data-connector/source/restforge-cli/cli/create-module.js \
|
|
29
|
-
--project=mini-inventory --endpoint=karyawan-fp --payload=karyawan_fp \
|
|
30
|
-
--database=postgres --force=true --create-demo=false --no-audit-migration=true
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Workflow Eksekusi Test
|
|
34
|
-
|
|
35
|
-
### Langkah 1 — Seed database
|
|
36
|
-
|
|
37
|
-
Reset state tabel `hr_karyawan` dan `hr_karyawan_audit`:
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
psql -h 127.0.0.1 -U postgres -d dbinv -f seed.sql
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
Output yang diharapkan:
|
|
44
|
-
- Tabel `hr_karyawan` dan `hr_karyawan_audit` di-create
|
|
45
|
-
- 1 record dengan `karyawan_id='test-001'`, `salary=5000000` ter-insert
|
|
46
|
-
- `audit_initial_count = 0`
|
|
47
|
-
|
|
48
|
-
### Langkah 2 — Start server
|
|
49
|
-
|
|
50
|
-
Buka terminal baru:
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
cd d:/workspace/03_projects/data-connector/deployment/restforge-test-pro
|
|
54
|
-
server-start.bat
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Tunggu sampai log menampilkan `Server started on port 3032` (atau serupa).
|
|
58
|
-
|
|
59
|
-
### Langkah 3 — Run concurrent test
|
|
60
|
-
|
|
61
|
-
Di terminal lain:
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
cd d:/workspace/03_projects/data-connector/source/restforge-cli/tests/integration-tahap4b
|
|
65
|
-
node run-concurrent.js
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
Output yang diharapkan:
|
|
69
|
-
```
|
|
70
|
-
[run-concurrent] Endpoint: http://127.0.0.1:3032/api/mini-inventory/karyawan-fp/update
|
|
71
|
-
[run-concurrent] Firing 100 parallel UPDATE requests...
|
|
72
|
-
|
|
73
|
-
=== Summary ===
|
|
74
|
-
Elapsed: XXXX ms
|
|
75
|
-
Success: 100/100
|
|
76
|
-
Failed: 0/100
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
Variasi parameter:
|
|
80
|
-
- `TOTAL=50 node run-concurrent.js` → 50 parallel
|
|
81
|
-
- `RESTFORGE_URL=http://localhost:3032 node run-concurrent.js` → custom URL
|
|
82
|
-
|
|
83
|
-
### Langkah 4 — Verify hasil
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
psql -h 127.0.0.1 -U postgres -d dbinv -f verify.sql
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
Output yang diharapkan (semua section menampilkan verdict `OK`):
|
|
90
|
-
|
|
91
|
-
| Section | Expected |
|
|
92
|
-
|---------|----------|
|
|
93
|
-
| 1. FINAL STATE | `final_salary` antara 5000001-5000100, verdict `OK` |
|
|
94
|
-
| 2. AUDIT ENTRY COUNT | `audit_entry_count = 100`, verdict `OK (100/100)` |
|
|
95
|
-
| 3. AUDIT JSON STRUCTURE | `missing_salary_audit = 0`, verdict `OK` |
|
|
96
|
-
| 4. AUDIT SAMPLE | 5 entry dengan `changed_fields->'salary'` JSON valid `{"old":"...","new":"..."}` |
|
|
97
|
-
| 5. DISTINCT NEW VALUES | `distinct_new_values = 100`, verdict `OK` |
|
|
98
|
-
| 6. FINAL VALUE TRACEABILITY | `final_value_in_audit = true`, verdict `OK` |
|
|
99
|
-
|
|
100
|
-
### Langkah 5 — Stop server
|
|
101
|
-
|
|
102
|
-
Di terminal yang menjalankan server: tekan `Ctrl+C`.
|
|
103
|
-
|
|
104
|
-
## Interpretasi Hasil
|
|
105
|
-
|
|
106
|
-
**Semua verdict OK** → path strict bekerja dengan benar:
|
|
107
|
-
- `SELECT FOR UPDATE` mencegah lost update
|
|
108
|
-
- Audit table tercatat untuk setiap request
|
|
109
|
-
- Atomicity dijamin via transaction wrapping
|
|
110
|
-
|
|
111
|
-
**Failures yang mungkin terjadi**:
|
|
112
|
-
|
|
113
|
-
| Verdict | Kemungkinan Penyebab |
|
|
114
|
-
|---------|---------------------|
|
|
115
|
-
| Section 2 verdict FAIL atau PARTIAL | Strict path tidak ter-trigger (cek log server untuk SELECT FOR UPDATE) — atau audit table mismatched |
|
|
116
|
-
| Section 3 missing_salary_audit > 0 | Bug di `_buildChangedFieldsJSON()` — field salary tidak masuk JSON |
|
|
117
|
-
| Section 6 final_value_in_audit = false | Lost update terjadi — strict path tidak proteksi dengan benar |
|
|
118
|
-
| Section 1 salary out of range | Test config issue, bukan strict path bug |
|
|
119
|
-
|
|
120
|
-
## Cleanup
|
|
121
|
-
|
|
122
|
-
```sql
|
|
123
|
-
-- Optional: drop test tables
|
|
124
|
-
DROP TABLE IF EXISTS hr_karyawan_audit;
|
|
125
|
-
DROP TABLE IF EXISTS hr_karyawan;
|
|
126
|
-
|
|
127
|
-
-- Optional: drop generated module dari project
|
|
128
|
-
-- (tidak otomatis — drop manual via restforge-cli drop atau hapus file)
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## Catatan Teknis
|
|
132
|
-
|
|
133
|
-
**Lock manager via Redis**: `_updateDataStrict` mencoba acquire WRITE lock via Redis. Jika Redis down, lockManager fallback ke disabled mode dan strict path tetap jalan dengan SELECT FOR UPDATE saja. Ini valid — DB-level lock cukup untuk mencegah lost update.
|
|
134
|
-
|
|
135
|
-
**Strict path skip event lifecycle**: per design Tahap 2, `_updateDataStrict` TIDAK memanggil `executeTransactionWithEvents()` (skip onBefore/onAfter hooks). Test ini valid karena payload `karyawan_fp.json` tidak declare `components`.
|
|
136
|
-
|
|
137
|
-
**Concurrent test mungkin lebih lambat dari relaxed path**: SELECT FOR UPDATE serialize concurrent UPDATE pada record yang sama. Total elapsed ~50-200ms untuk 100 request adalah expected.
|
|
138
|
-
|
|
139
|
-
**API auth**: jika test environment require API key (X-Api-Key header), tambah ke `run-concurrent.js`:
|
|
140
|
-
```js
|
|
141
|
-
headers: {
|
|
142
|
-
'Content-Type': 'application/json',
|
|
143
|
-
'X-Api-Key': process.env.RESTFORGE_API_KEY || '...'
|
|
144
|
-
}
|
|
145
|
-
```
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Tahap 4b — Concurrent UPDATE Test
|
|
4
|
-
*
|
|
5
|
-
* Fire N parallel UPDATE pada hr_karyawan/test-001, setiap request set salary
|
|
6
|
-
* ke nilai unique. Verifikasi:
|
|
7
|
-
* - Semua request return 200 (atau lock contention error yang acceptable)
|
|
8
|
-
* - Total elapsed time wajar (path strict harus serialize via SELECT FOR UPDATE)
|
|
9
|
-
*
|
|
10
|
-
* Verifikasi audit log (count = TOTAL, all entries have salary key) dilakukan
|
|
11
|
-
* via verify.sql terpisah.
|
|
12
|
-
*
|
|
13
|
-
* Usage:
|
|
14
|
-
* node run-concurrent.js
|
|
15
|
-
* TOTAL=50 node run-concurrent.js
|
|
16
|
-
* RESTFORGE_URL=http://127.0.0.1:3032 node run-concurrent.js
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
const BASE_URL = process.env.RESTFORGE_URL || 'http://127.0.0.1:3032';
|
|
20
|
-
const ENDPOINT = `${BASE_URL}/api/mini-inventory/karyawan-fp/update`;
|
|
21
|
-
const TOTAL = parseInt(process.env.TOTAL || '100', 10);
|
|
22
|
-
|
|
23
|
-
async function fireUpdate(i) {
|
|
24
|
-
const salary = 5000000 + i;
|
|
25
|
-
try {
|
|
26
|
-
const res = await fetch(ENDPOINT, {
|
|
27
|
-
method: 'POST',
|
|
28
|
-
headers: { 'Content-Type': 'application/json' },
|
|
29
|
-
body: JSON.stringify({ karyawan_id: 'test-001', salary })
|
|
30
|
-
});
|
|
31
|
-
let body = null;
|
|
32
|
-
try { body = await res.json(); } catch (_) {}
|
|
33
|
-
return { i, salary, status: res.status, ok: res.ok, body };
|
|
34
|
-
} catch (err) {
|
|
35
|
-
return { i, salary, status: 0, ok: false, error: err.message };
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
(async () => {
|
|
40
|
-
console.log(`[run-concurrent] Endpoint: ${ENDPOINT}`);
|
|
41
|
-
console.log(`[run-concurrent] Firing ${TOTAL} parallel UPDATE requests...`);
|
|
42
|
-
|
|
43
|
-
const t0 = Date.now();
|
|
44
|
-
const results = await Promise.all(
|
|
45
|
-
Array.from({ length: TOTAL }, (_, i) => fireUpdate(i + 1))
|
|
46
|
-
);
|
|
47
|
-
const elapsed = Date.now() - t0;
|
|
48
|
-
|
|
49
|
-
const ok = results.filter(r => r.status === 200);
|
|
50
|
-
const failed = results.filter(r => r.status !== 200);
|
|
51
|
-
|
|
52
|
-
console.log('');
|
|
53
|
-
console.log('=== Summary ===');
|
|
54
|
-
console.log(`Elapsed: ${elapsed} ms`);
|
|
55
|
-
console.log(`Success: ${ok.length}/${TOTAL}`);
|
|
56
|
-
console.log(`Failed: ${failed.length}/${TOTAL}`);
|
|
57
|
-
|
|
58
|
-
if (failed.length > 0) {
|
|
59
|
-
console.log('');
|
|
60
|
-
console.log('=== First 5 failures ===');
|
|
61
|
-
failed.slice(0, 5).forEach(f => {
|
|
62
|
-
console.log(JSON.stringify({
|
|
63
|
-
i: f.i,
|
|
64
|
-
salary: f.salary,
|
|
65
|
-
status: f.status,
|
|
66
|
-
error: f.error,
|
|
67
|
-
body: f.body ? (typeof f.body === 'object' ? f.body.message || JSON.stringify(f.body).slice(0, 200) : f.body) : null
|
|
68
|
-
}));
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
console.log('');
|
|
73
|
-
console.log('Next: jalankan verify.sql untuk cek audit log');
|
|
74
|
-
console.log(' psql -h 127.0.0.1 -U postgres -d dbinv -f verify.sql');
|
|
75
|
-
|
|
76
|
-
process.exit(failed.length === 0 ? 0 : 1);
|
|
77
|
-
})();
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
-- ============================================================================
|
|
2
|
-
-- Tahap 4b — Integration Test Seed Script
|
|
3
|
-
-- ============================================================================
|
|
4
|
-
-- Membuat tabel hr_karyawan + hr_karyawan_audit dan insert 1 record uji.
|
|
5
|
-
-- Dijalankan SEKALI sebelum run-concurrent.js untuk reset state.
|
|
6
|
-
--
|
|
7
|
-
-- Eksekusi:
|
|
8
|
-
-- psql -h 127.0.0.1 -U postgres -d dbinv -f seed.sql
|
|
9
|
-
-- ============================================================================
|
|
10
|
-
|
|
11
|
-
-- 1. Drop table existing (cascade ke audit jika ada FK — saat ini tidak ada FK)
|
|
12
|
-
DROP TABLE IF EXISTS hr_karyawan_audit;
|
|
13
|
-
DROP TABLE IF EXISTS hr_karyawan;
|
|
14
|
-
|
|
15
|
-
-- 2. Create main table
|
|
16
|
-
CREATE TABLE hr_karyawan (
|
|
17
|
-
karyawan_id VARCHAR(36) PRIMARY KEY,
|
|
18
|
-
nama VARCHAR(128) NOT NULL,
|
|
19
|
-
salary BIGINT NOT NULL DEFAULT 0,
|
|
20
|
-
bonus BIGINT NOT NULL DEFAULT 0,
|
|
21
|
-
is_active VARCHAR(8) NOT NULL DEFAULT 'true',
|
|
22
|
-
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
23
|
-
created_by VARCHAR(64) NOT NULL DEFAULT 'system',
|
|
24
|
-
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
25
|
-
updated_by VARCHAR(64) NOT NULL DEFAULT 'system'
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
-- 3. Create audit table (skema identik dengan output audit-table-generator.js)
|
|
29
|
-
-- audit_id di-supply oleh app layer via uuidv7() — tanpa DB-side default
|
|
30
|
-
-- agar portable ke semua versi PostgreSQL.
|
|
31
|
-
CREATE TABLE hr_karyawan_audit (
|
|
32
|
-
audit_id VARCHAR(36) PRIMARY KEY,
|
|
33
|
-
record_pk TEXT NOT NULL,
|
|
34
|
-
operation VARCHAR(32) NOT NULL,
|
|
35
|
-
changed_fields JSONB NOT NULL,
|
|
36
|
-
metadata JSONB,
|
|
37
|
-
changed_by VARCHAR(128),
|
|
38
|
-
changed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
CREATE INDEX idx_hr_karyawan_audit_record
|
|
42
|
-
ON hr_karyawan_audit (record_pk, changed_at DESC);
|
|
43
|
-
|
|
44
|
-
CREATE INDEX idx_hr_karyawan_audit_changed_at
|
|
45
|
-
ON hr_karyawan_audit (changed_at DESC);
|
|
46
|
-
|
|
47
|
-
-- 4. Insert 1 record uji untuk concurrent UPDATE
|
|
48
|
-
INSERT INTO hr_karyawan (karyawan_id, nama, salary, bonus)
|
|
49
|
-
VALUES ('test-001', 'Concurrent Test User', 5000000, 0);
|
|
50
|
-
|
|
51
|
-
-- 5. Confirm
|
|
52
|
-
SELECT karyawan_id, nama, salary FROM hr_karyawan WHERE karyawan_id = 'test-001';
|
|
53
|
-
SELECT COUNT(*) AS audit_initial_count FROM hr_karyawan_audit;
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
-- ============================================================================
|
|
2
|
-
-- Tahap 4b — Integration Test Verification Script
|
|
3
|
-
-- ============================================================================
|
|
4
|
-
-- Dijalankan SETELAH run-concurrent.js selesai untuk verifikasi:
|
|
5
|
-
-- 1. Final state record konsisten dengan salah satu request (5000001..5000100)
|
|
6
|
-
-- 2. Audit log memuat 100 entry (atau matching dengan jumlah success)
|
|
7
|
-
-- 3. Setiap audit entry punya struktur changed_fields.salary {old, new}
|
|
8
|
-
-- 4. Tidak ada lost update (transition logical: nilai final ada di set request)
|
|
9
|
-
--
|
|
10
|
-
-- Eksekusi:
|
|
11
|
-
-- psql -h 127.0.0.1 -U postgres -d dbinv -f verify.sql
|
|
12
|
-
-- ============================================================================
|
|
13
|
-
|
|
14
|
-
-- ----------------------------------------------------------------------------
|
|
15
|
-
-- 1. Final state hr_karyawan/test-001
|
|
16
|
-
-- ----------------------------------------------------------------------------
|
|
17
|
-
\echo '=== 1. FINAL STATE ==='
|
|
18
|
-
SELECT
|
|
19
|
-
karyawan_id,
|
|
20
|
-
salary AS final_salary,
|
|
21
|
-
updated_at,
|
|
22
|
-
CASE
|
|
23
|
-
WHEN salary BETWEEN 5000001 AND 5000100 THEN 'OK (within expected range)'
|
|
24
|
-
ELSE 'WARN (out of range — possible test config issue)'
|
|
25
|
-
END AS verdict
|
|
26
|
-
FROM hr_karyawan
|
|
27
|
-
WHERE karyawan_id = 'test-001';
|
|
28
|
-
|
|
29
|
-
-- ----------------------------------------------------------------------------
|
|
30
|
-
-- 2. Audit entry count (expected: 100, or matching success count)
|
|
31
|
-
-- ----------------------------------------------------------------------------
|
|
32
|
-
\echo ''
|
|
33
|
-
\echo '=== 2. AUDIT ENTRY COUNT ==='
|
|
34
|
-
SELECT
|
|
35
|
-
COUNT(*) AS audit_entry_count,
|
|
36
|
-
CASE
|
|
37
|
-
WHEN COUNT(*) = 100 THEN 'OK (100/100 — all updates audited)'
|
|
38
|
-
WHEN COUNT(*) > 0 THEN 'PARTIAL (some updates not audited — check failures in run-concurrent output)'
|
|
39
|
-
ELSE 'FAIL (zero audit entries — strict path NOT triggered, or audit table mismatched)'
|
|
40
|
-
END AS verdict
|
|
41
|
-
FROM hr_karyawan_audit
|
|
42
|
-
WHERE record_pk = 'test-001';
|
|
43
|
-
|
|
44
|
-
-- ----------------------------------------------------------------------------
|
|
45
|
-
-- 3. Audit JSON structure check (semua entry harus punya .salary)
|
|
46
|
-
-- ----------------------------------------------------------------------------
|
|
47
|
-
\echo ''
|
|
48
|
-
\echo '=== 3. AUDIT JSON STRUCTURE ==='
|
|
49
|
-
SELECT
|
|
50
|
-
COUNT(*) AS missing_salary_audit,
|
|
51
|
-
CASE
|
|
52
|
-
WHEN COUNT(*) = 0 THEN 'OK (all audit entries have salary key)'
|
|
53
|
-
ELSE 'FAIL (some entries missing salary key — _buildChangedFieldsJSON bug)'
|
|
54
|
-
END AS verdict
|
|
55
|
-
FROM hr_karyawan_audit
|
|
56
|
-
WHERE record_pk = 'test-001'
|
|
57
|
-
AND NOT (changed_fields ? 'salary');
|
|
58
|
-
|
|
59
|
-
-- ----------------------------------------------------------------------------
|
|
60
|
-
-- 4. Sample 5 entry untuk inspeksi manual
|
|
61
|
-
-- ----------------------------------------------------------------------------
|
|
62
|
-
\echo ''
|
|
63
|
-
\echo '=== 4. AUDIT SAMPLE (first 5 by changed_at) ==='
|
|
64
|
-
SELECT
|
|
65
|
-
changed_at,
|
|
66
|
-
operation,
|
|
67
|
-
changed_fields->'salary' AS salary_change,
|
|
68
|
-
changed_by
|
|
69
|
-
FROM hr_karyawan_audit
|
|
70
|
-
WHERE record_pk = 'test-001'
|
|
71
|
-
ORDER BY changed_at ASC
|
|
72
|
-
LIMIT 5;
|
|
73
|
-
|
|
74
|
-
-- ----------------------------------------------------------------------------
|
|
75
|
-
-- 5. Distinct new values di audit — should be ~100 unique (semua request beda)
|
|
76
|
-
-- ----------------------------------------------------------------------------
|
|
77
|
-
\echo ''
|
|
78
|
-
\echo '=== 5. DISTINCT NEW VALUES IN AUDIT ==='
|
|
79
|
-
SELECT
|
|
80
|
-
COUNT(DISTINCT changed_fields->'salary'->>'new') AS distinct_new_values,
|
|
81
|
-
COUNT(*) AS total_entries,
|
|
82
|
-
CASE
|
|
83
|
-
WHEN COUNT(DISTINCT changed_fields->'salary'->>'new') = COUNT(*) THEN 'OK (all updates uniquely audited)'
|
|
84
|
-
ELSE 'INFO (some duplicate new values — bisa terjadi jika ada retry)'
|
|
85
|
-
END AS verdict
|
|
86
|
-
FROM hr_karyawan_audit
|
|
87
|
-
WHERE record_pk = 'test-001';
|
|
88
|
-
|
|
89
|
-
-- ----------------------------------------------------------------------------
|
|
90
|
-
-- 6. Lost update detection — nilai final ada di set audit?
|
|
91
|
-
-- ----------------------------------------------------------------------------
|
|
92
|
-
\echo ''
|
|
93
|
-
\echo '=== 6. FINAL VALUE TRACEABILITY ==='
|
|
94
|
-
WITH final AS (SELECT salary::TEXT AS final_str FROM hr_karyawan WHERE karyawan_id = 'test-001')
|
|
95
|
-
SELECT
|
|
96
|
-
f.final_str AS final_salary,
|
|
97
|
-
EXISTS (
|
|
98
|
-
SELECT 1 FROM hr_karyawan_audit
|
|
99
|
-
WHERE record_pk = 'test-001'
|
|
100
|
-
AND changed_fields->'salary'->>'new' = f.final_str
|
|
101
|
-
) AS final_value_in_audit,
|
|
102
|
-
CASE
|
|
103
|
-
WHEN EXISTS (
|
|
104
|
-
SELECT 1 FROM hr_karyawan_audit
|
|
105
|
-
WHERE record_pk = 'test-001'
|
|
106
|
-
AND changed_fields->'salary'->>'new' = f.final_str
|
|
107
|
-
) THEN 'OK (final value traceable in audit log)'
|
|
108
|
-
ELSE 'FAIL (final value not in audit — atomicity issue!)'
|
|
109
|
-
END AS verdict
|
|
110
|
-
FROM final f;
|