diff --git a/.gitignore b/.gitignore index 7c03cc9..1d6139b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,17 @@ coverage/ .tmp/ .cache/ .validate-tmp/ +target/ +*.iml +.vscode/ +.classpath +.project +.settings/ +out/ +hs_err_pid* +replay_pid* +postman/*.postman_environment.json +!postman/*.postman_environment.template.json # Local AI workflow files (not shared via git) sdd/ diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 4eda40e..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/easycode.ignore b/.idea/easycode.ignore deleted file mode 100644 index 04b63e2..0000000 --- a/.idea/easycode.ignore +++ /dev/null @@ -1,13 +0,0 @@ -.idea -.vscode -node_modules/ -dist/ -vendor/ -cache/ -.*/ -*.min.* -*.test.* -*.spec.* -*.bundle.* -*.bundle-min.* -*.log diff --git a/.idea/easycode/codebase-v2.xml b/.idea/easycode/codebase-v2.xml deleted file mode 100644 index 67e8afe..0000000 --- a/.idea/easycode/codebase-v2.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 63e9001..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index 712ab9d..0000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 9dc782b..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/postman/dynapi.postman_collection.json b/postman/dynapi.postman_collection.json new file mode 100644 index 0000000..57a7580 --- /dev/null +++ b/postman/dynapi.postman_collection.json @@ -0,0 +1,1029 @@ +{ + "info": { + "_postman_id": "1f2d43c2-f0c0-4f74-8fef-0adf6073f100", + "name": "Dynapi API", + "description": "Dynapi backend API collection with success and error scenario examples for every active endpoint. Includes app-level error envelopes (400/403/404/500) and endpoint-specific success examples.", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "variable": [ + { + "key": "baseUrl", + "value": "http://localhost:8080/api" + }, + { + "key": "adminToken", + "value": "" + }, + { + "key": "entity", + "value": "tasks" + }, + { + "key": "fieldDefinitionId", + "value": "priority" + }, + { + "key": "fieldGroupId", + "value": "task-form" + }, + { + "key": "groupId", + "value": "task-form" + } + ], + "item": [ + { + "name": "Form API", + "item": [ + { + "name": "POST /form - Submit Form", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"group\": \"task-form\",\n \"data\": {\n \"title\": \"Ship v1\",\n \"priority\": 1\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/form", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "form" + ] + }, + "description": "Submit dynamic payload using a predefined field group." + }, + "response": [ + { + "name": "Success", + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": true,\n \"message\": \"Form submitted successfully\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Validation Error", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Field is required\",\n \"data\": null,\n \"errors\": {\n \"title\": \"Field is required\"\n },\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Group Not Found", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Group not found\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Not Found - Entity (If Raised by Service)", + "status": "Not Found", + "code": 404, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Entity not found\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Internal Server Error", + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Internal server error\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + } + ] + }, + { + "name": "POST /forms/:groupId/submit - Submit Form", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept-Language", + "value": "en-US", + "disabled": true + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"Ship v1\",\n \"priority\": 1\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/forms/{{groupId}}/submit", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "forms", + "{{groupId}}", + "submit" + ] + }, + "description": "Submit dynamic payload using path-based group id. Public endpoint." + }, + "response": [ + { + "name": "Success", + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": true,\n \"message\": \"Form submitted successfully\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Validation Error", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Field is required\",\n \"data\": null,\n \"errors\": {\n \"title\": \"Field is required\"\n },\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Group Not Found", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Group not found\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Not Found - Entity (If Raised by Service)", + "status": "Not Found", + "code": 404, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Entity not found\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Internal Server Error", + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Internal server error\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + } + ] + } + ] + }, + { + "name": "Query API", + "item": [ + { + "name": "POST /query/:entity - Query Records", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"filters\": [\n { \"field\": \"priority\", \"operator\": \"gte\", \"value\": 1 }\n ],\n \"page\": 0,\n \"size\": 10,\n \"sortBy\": \"priority\",\n \"sortDirection\": \"DESC\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/query/{{entity}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "query", + "{{entity}}" + ] + }, + "description": "Query dynamic records with guarded filters, sorting, and pagination." + }, + "response": [ + { + "name": "Success", + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": true,\n \"message\": \"Query successful\",\n \"data\": {\n \"page\": 0,\n \"size\": 10,\n \"totalElements\": 1,\n \"content\": [\n {\n \"id\": \"66f0f4c2d31234ab12345678\",\n \"data\": {\n \"title\": \"Ship v1\",\n \"priority\": 2\n }\n }\n ],\n \"sortBy\": \"priority\",\n \"sortDirection\": \"DESC\"\n },\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Size Exceeds Max", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Size exceeds max page size: 100\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Filter Field Not Allowed", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Filtering by field is not allowed: unknownField\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Operator Not Allowed", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Operator 'regex' is not allowed for field 'priority' of type NUMBER\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Filter Depth Exceeded", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Filter depth exceeds max: 3\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Schema Group Not Found", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Schema group not found for entity: tasks\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Not Found - Entity (If Raised by Service)", + "status": "Not Found", + "code": 404, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Entity not found\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Internal Server Error", + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Internal server error\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + } + ] + } + ] + }, + { + "name": "Schema Admin - Field Definitions", + "item": [ + { + "name": "POST /admin/schema/field-definitions - Create Field Definition", + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{adminToken}}" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"fieldName\": \"priority\",\n \"type\": \"NUMBER\",\n \"required\": false,\n \"min\": 1,\n \"max\": 5,\n \"version\": 1\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/admin/schema/field-definitions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "admin", + "schema", + "field-definitions" + ] + } + }, + "response": [ + { + "name": "Success", + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": true,\n \"message\": \"Created\",\n \"data\": {\n \"fieldName\": \"priority\",\n \"type\": \"NUMBER\",\n \"required\": false,\n \"min\": 1.0,\n \"max\": 5.0,\n \"regex\": null,\n \"enumValues\": null,\n \"requiredIf\": null,\n \"subFields\": null,\n \"version\": 1,\n \"permissions\": null\n },\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Illegal Argument", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Invalid request\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Forbidden - Missing or Non-Admin Token", + "status": "Forbidden", + "code": 403, + "_postman_previewlanguage": "json", + "body": "{\n \"timestamp\": \"2026-02-24T00:00:00.000+00:00\",\n \"status\": 403,\n \"error\": \"Forbidden\",\n \"path\": \"/api/admin/schema/field-definitions\"\n}" + }, + { + "name": "Not Found - Entity (If Raised by Service)", + "status": "Not Found", + "code": 404, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Entity not found\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Internal Server Error", + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": false,\n \"message\": \"Internal server error\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + } + ] + }, + { + "name": "PUT /admin/schema/field-definitions/:id - Update Field Definition", + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{adminToken}}" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"NUMBER\",\n \"required\": true,\n \"min\": 1,\n \"max\": 10\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/admin/schema/field-definitions/{{fieldDefinitionId}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "admin", + "schema", + "field-definitions", + "{{fieldDefinitionId}}" + ] + } + }, + "response": [ + { + "name": "Success", + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": true,\n \"message\": \"Updated\",\n \"data\": {\n \"fieldName\": \"priority\",\n \"type\": \"NUMBER\",\n \"required\": true\n },\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Illegal Argument", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Invalid request\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Forbidden - Missing or Non-Admin Token", + "status": "Forbidden", + "code": 403, + "_postman_previewlanguage": "json", + "body": "{\n \"timestamp\": \"2026-02-24T00:00:00.000+00:00\",\n \"status\": 403,\n \"error\": \"Forbidden\",\n \"path\": \"/api/admin/schema/field-definitions/priority\"\n}" + }, + { + "name": "Not Found - Entity (If Raised by Service)", + "status": "Not Found", + "code": 404, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Entity not found\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Internal Server Error", + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": false,\n \"message\": \"Internal server error\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + } + ] + }, + { + "name": "DELETE /admin/schema/field-definitions/:id - Delete Field Definition", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{adminToken}}" + } + ], + "url": { + "raw": "{{baseUrl}}/admin/schema/field-definitions/{{fieldDefinitionId}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "admin", + "schema", + "field-definitions", + "{{fieldDefinitionId}}" + ] + } + }, + "response": [ + { + "name": "Success", + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": true,\n \"message\": \"Deleted\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Illegal Argument", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Invalid request\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Forbidden - Missing or Non-Admin Token", + "status": "Forbidden", + "code": 403, + "_postman_previewlanguage": "json", + "body": "{\n \"timestamp\": \"2026-02-24T00:00:00.000+00:00\",\n \"status\": 403,\n \"error\": \"Forbidden\",\n \"path\": \"/api/admin/schema/field-definitions/priority\"\n}" + }, + { + "name": "Not Found - Entity (If Raised by Service)", + "status": "Not Found", + "code": 404, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Entity not found\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Internal Server Error", + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": false,\n \"message\": \"Internal server error\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + } + ] + }, + { + "name": "GET /admin/schema/field-definitions - List Field Definitions", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{adminToken}}" + } + ], + "url": { + "raw": "{{baseUrl}}/admin/schema/field-definitions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "admin", + "schema", + "field-definitions" + ] + } + }, + "response": [ + { + "name": "Success", + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": true,\n \"message\": \"Fetched\",\n \"data\": [\n {\n \"fieldName\": \"priority\",\n \"type\": \"NUMBER\"\n }\n ],\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Illegal Argument", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Invalid request\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Forbidden - Missing or Non-Admin Token", + "status": "Forbidden", + "code": 403, + "_postman_previewlanguage": "json", + "body": "{\n \"timestamp\": \"2026-02-24T00:00:00.000+00:00\",\n \"status\": 403,\n \"error\": \"Forbidden\",\n \"path\": \"/api/admin/schema/field-definitions\"\n}" + }, + { + "name": "Not Found - Entity (If Raised by Service)", + "status": "Not Found", + "code": 404, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Entity not found\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Internal Server Error", + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": false,\n \"message\": \"Internal server error\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + } + ] + } + ] + }, + { + "name": "Schema Admin - Field Groups", + "item": [ + { + "name": "POST /admin/schema/field-groups - Create Field Group", + "request": { + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{adminToken}}" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"task-form\",\n \"entity\": \"tasks\",\n \"fieldNames\": [\"title\", \"priority\"],\n \"version\": 1\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/admin/schema/field-groups", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "admin", + "schema", + "field-groups" + ] + } + }, + "response": [ + { + "name": "Success", + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": true,\n \"message\": \"Created\",\n \"data\": {\n \"name\": \"task-form\",\n \"entity\": \"tasks\",\n \"fieldNames\": [\"title\", \"priority\"]\n },\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Illegal Argument", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Invalid request\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Forbidden - Missing or Non-Admin Token", + "status": "Forbidden", + "code": 403, + "_postman_previewlanguage": "json", + "body": "{\n \"timestamp\": \"2026-02-24T00:00:00.000+00:00\",\n \"status\": 403,\n \"error\": \"Forbidden\",\n \"path\": \"/api/admin/schema/field-groups\"\n}" + }, + { + "name": "Not Found - Entity (If Raised by Service)", + "status": "Not Found", + "code": 404, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Entity not found\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Internal Server Error", + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": false,\n \"message\": \"Internal server error\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + } + ] + }, + { + "name": "PUT /admin/schema/field-groups/:id - Update Field Group", + "request": { + "method": "PUT", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{adminToken}}" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"entity\": \"tasks\",\n \"fieldNames\": [\"title\", \"priority\", \"status\"],\n \"version\": 2\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/admin/schema/field-groups/{{fieldGroupId}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "admin", + "schema", + "field-groups", + "{{fieldGroupId}}" + ] + } + }, + "response": [ + { + "name": "Success", + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": true,\n \"message\": \"Updated\",\n \"data\": {\n \"name\": \"task-form\",\n \"entity\": \"tasks\",\n \"fieldNames\": [\"title\", \"priority\", \"status\"]\n },\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Illegal Argument", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Invalid request\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Forbidden - Missing or Non-Admin Token", + "status": "Forbidden", + "code": 403, + "_postman_previewlanguage": "json", + "body": "{\n \"timestamp\": \"2026-02-24T00:00:00.000+00:00\",\n \"status\": 403,\n \"error\": \"Forbidden\",\n \"path\": \"/api/admin/schema/field-groups/task-form\"\n}" + }, + { + "name": "Not Found - Entity (If Raised by Service)", + "status": "Not Found", + "code": 404, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Entity not found\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Internal Server Error", + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": false,\n \"message\": \"Internal server error\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + } + ] + }, + { + "name": "DELETE /admin/schema/field-groups/:id - Delete Field Group", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{adminToken}}" + } + ], + "url": { + "raw": "{{baseUrl}}/admin/schema/field-groups/{{fieldGroupId}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "admin", + "schema", + "field-groups", + "{{fieldGroupId}}" + ] + } + }, + "response": [ + { + "name": "Success", + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": true,\n \"message\": \"Deleted\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Illegal Argument", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Invalid request\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Forbidden - Missing or Non-Admin Token", + "status": "Forbidden", + "code": 403, + "_postman_previewlanguage": "json", + "body": "{\n \"timestamp\": \"2026-02-24T00:00:00.000+00:00\",\n \"status\": 403,\n \"error\": \"Forbidden\",\n \"path\": \"/api/admin/schema/field-groups/task-form\"\n}" + }, + { + "name": "Not Found - Entity (If Raised by Service)", + "status": "Not Found", + "code": 404, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Entity not found\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Internal Server Error", + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": false,\n \"message\": \"Internal server error\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + } + ] + }, + { + "name": "GET /admin/schema/field-groups - List Field Groups", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{adminToken}}" + } + ], + "url": { + "raw": "{{baseUrl}}/admin/schema/field-groups", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "admin", + "schema", + "field-groups" + ] + } + }, + "response": [ + { + "name": "Success", + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": true,\n \"message\": \"Fetched\",\n \"data\": [\n {\n \"name\": \"task-form\",\n \"entity\": \"tasks\",\n \"fieldNames\": [\"title\", \"priority\"]\n }\n ],\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Bad Request - Illegal Argument", + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Invalid request\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Forbidden - Missing or Non-Admin Token", + "status": "Forbidden", + "code": 403, + "_postman_previewlanguage": "json", + "body": "{\n \"timestamp\": \"2026-02-24T00:00:00.000+00:00\",\n \"status\": 403,\n \"error\": \"Forbidden\",\n \"path\": \"/api/admin/schema/field-groups\"\n}" + }, + { + "name": "Not Found - Entity (If Raised by Service)", + "status": "Not Found", + "code": 404, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"success\": false,\n \"message\": \"Entity not found\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + }, + { + "name": "Internal Server Error", + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "body": "{\n \"success\": false,\n \"message\": \"Internal server error\",\n \"data\": null,\n \"errors\": null,\n \"metadata\": null\n}" + } + ] + } + ] + } + ] +} diff --git a/postman/dynapi.postman_environment.template.json b/postman/dynapi.postman_environment.template.json new file mode 100644 index 0000000..91d78e1 --- /dev/null +++ b/postman/dynapi.postman_environment.template.json @@ -0,0 +1,49 @@ +{ + "id": "00000000-0000-0000-0000-000000000000", + "name": "Dynapi Local (Template)", + "values": [ + { + "key": "baseUrl", + "value": "http://localhost:8080/api", + "enabled": true + }, + { + "key": "adminToken", + "value": "", + "enabled": true + }, + { + "key": "entity", + "value": "tasks", + "enabled": true + }, + { + "key": "fieldDefinitionId", + "value": "priority", + "enabled": true + }, + { + "key": "fieldGroupId", + "value": "task-form", + "enabled": true + }, + { + "key": "nonAdminToken", + "value": "", + "enabled": true + }, + { + "key": "invalidToken", + "value": "invalid.jwt.token", + "enabled": true + }, + { + "key": "groupId", + "value": "task-form", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2026-02-23T00:00:00.000Z", + "_postman_exported_using": "Codex GPT-5" +} diff --git a/src/main/java/com/dynapi/config/QueryGuardrailProperties.java b/src/main/java/com/dynapi/config/QueryGuardrailProperties.java new file mode 100644 index 0000000..ba72d1c --- /dev/null +++ b/src/main/java/com/dynapi/config/QueryGuardrailProperties.java @@ -0,0 +1,16 @@ +package com.dynapi.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Getter +@Setter +@Component +@ConfigurationProperties(prefix = "dynapi.query.guardrails") +public class QueryGuardrailProperties { + private int maxPageSize = 100; + private int maxFilterDepth = 3; + private int maxRuleCount = 20; +} diff --git a/src/main/java/com/dynapi/interfaces/rest/FormSubmissionController.java b/src/main/java/com/dynapi/interfaces/rest/FormSubmissionController.java index 2728376..7b609a2 100644 --- a/src/main/java/com/dynapi/interfaces/rest/FormSubmissionController.java +++ b/src/main/java/com/dynapi/interfaces/rest/FormSubmissionController.java @@ -1,25 +1,31 @@ package com.dynapi.interfaces.rest; -import com.dynapi.application.port.input.SubmitFormUseCase; import com.dynapi.dto.ApiResponse; +import com.dynapi.dto.FormSubmissionRequest; +import com.dynapi.service.FormSubmissionService; +import lombok.RequiredArgsConstructor; +import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.web.bind.annotation.*; import java.util.Locale; import java.util.Map; +@RestController @RequestMapping("/forms") +@RequiredArgsConstructor public class FormSubmissionController { - private final SubmitFormUseCase submitFormUseCase; - - public FormSubmissionController(SubmitFormUseCase submitFormUseCase) { - this.submitFormUseCase = submitFormUseCase; - } + private final FormSubmissionService formSubmissionService; @PostMapping("/{groupId}/submit") public ApiResponse submitForm( @PathVariable String groupId, @RequestBody Map formData, @RequestHeader(name = "Accept-Language", required = false) Locale locale) { - submitFormUseCase.submitForm(groupId, formData, locale); + FormSubmissionRequest request = new FormSubmissionRequest(); + request.setGroup(groupId); + request.setData(formData); + + Locale effectiveLocale = locale == null ? LocaleContextHolder.getLocale() : locale; + formSubmissionService.submitForm(request, effectiveLocale); return ApiResponse.success(null, "Form submitted successfully"); } } diff --git a/src/main/java/com/dynapi/repository/FieldGroupRepository.java b/src/main/java/com/dynapi/repository/FieldGroupRepository.java index 9cb0891..534eacf 100644 --- a/src/main/java/com/dynapi/repository/FieldGroupRepository.java +++ b/src/main/java/com/dynapi/repository/FieldGroupRepository.java @@ -3,5 +3,8 @@ import com.dynapi.domain.model.FieldGroup; import org.springframework.data.mongodb.repository.MongoRepository; +import java.util.Optional; + public interface FieldGroupRepository extends MongoRepository { + Optional findByEntity(String entity); } diff --git a/src/main/java/com/dynapi/service/DynamicQueryService.java b/src/main/java/com/dynapi/service/DynamicQueryService.java index ac513ce..738dbc1 100644 --- a/src/main/java/com/dynapi/service/DynamicQueryService.java +++ b/src/main/java/com/dynapi/service/DynamicQueryService.java @@ -1,8 +1,15 @@ package com.dynapi.service; +import com.dynapi.config.QueryGuardrailProperties; +import com.dynapi.domain.model.FieldDefinition; +import com.dynapi.domain.model.FieldGroup; +import com.dynapi.domain.model.FieldType; import com.dynapi.dto.DynamicQueryRequest; +import com.dynapi.dto.FilterRule; import com.dynapi.dto.FormRecordDto; import com.dynapi.dto.PaginatedResponse; +import com.dynapi.repository.FieldDefinitionRepository; +import com.dynapi.repository.FieldGroupRepository; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; @@ -11,88 +18,360 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.stereotype.Service; +import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import java.util.stream.StreamSupport; @Service @RequiredArgsConstructor public class DynamicQueryService { + private static final int DEFAULT_PAGE = 0; + private static final int DEFAULT_SIZE = 10; + + private static final Set COMBINATOR_OPERATORS = Set.of("and", "or", "not"); + private static final Set NUMBER_OPERATORS = Set.of("eq", "ne", "gt", "lt", "gte", "lte", "in"); + private static final Set DATE_OPERATORS = Set.of("eq", "ne", "gt", "lt", "gte", "lte", "in"); + private static final Set STRING_OPERATORS = Set.of("eq", "ne", "in", "regex"); + private static final Set BOOLEAN_OPERATORS = Set.of("eq", "ne", "in"); + private static final Set OBJECT_ARRAY_OPERATORS = Set.of("eq", "ne"); + private final MongoTemplate mongoTemplate; + private final FieldGroupRepository fieldGroupRepository; + private final FieldDefinitionRepository fieldDefinitionRepository; + private final QueryGuardrailProperties guardrailProperties; public PaginatedResponse query(String entity, DynamicQueryRequest request) { + DynamicQueryRequest safeRequest = request == null ? new DynamicQueryRequest() : request; + int page = resolvePage(safeRequest.getPage()); + int size = resolveSize(safeRequest.getSize()); + Map allowedFieldTypes = loadFieldTypesByEntity(entity); + + validateSort(safeRequest.getSortBy(), safeRequest.getSortDirection(), allowedFieldTypes); + validateFilters(safeRequest.getFilters(), allowedFieldTypes); + Query query = new Query(); - // Build advanced filters - if (request.getFilters() != null && !request.getFilters().isEmpty()) { - query.addCriteria(buildCriteria(request.getFilters())); + if (safeRequest.getFilters() != null && !safeRequest.getFilters().isEmpty()) { + query.addCriteria(buildCriteria(safeRequest.getFilters())); } - // Pagination and sorting - int page = request.getPage() != null ? request.getPage() : 0; - int size = request.getSize() != null ? request.getSize() : 10; - if (request.getSortBy() != null && request.getSortDirection() != null) { - Sort.Direction dir = request.getSortDirection().equalsIgnoreCase("DESC") ? Sort.Direction.DESC : Sort.Direction.ASC; - query.with(Sort.by(dir, request.getSortBy())); + + if (safeRequest.getSortBy() != null && !safeRequest.getSortBy().isBlank()) { + Sort.Direction dir = resolveSortDirection(safeRequest.getSortDirection()); + query.with(Sort.by(dir, safeRequest.getSortBy().trim())); } + query.with(PageRequest.of(page, size)); - // Query MongoDB + List results = mongoTemplate.find(query, Map.class, entity); - // Map to FormRecordDto (strip _id, _class) - List content = results.stream().map(map -> { + List content = results.stream().map(result -> { FormRecordDto dto = new FormRecordDto(); - dto.setId(map.get("_id") != null ? map.get("_id").toString() : null); - map.remove("_id"); - map.remove("_class"); - dto.setData(map); + dto.setId(result.get("_id") != null ? result.get("_id").toString() : null); + @SuppressWarnings("unchecked") + Map data = new HashMap<>((Map) result); + data.remove("_id"); + data.remove("_class"); + dto.setData(data); return dto; }).collect(Collectors.toList()); - // Total count + long total = mongoTemplate.count(query.skip(-1).limit(-1), entity); - // Paginated response + PaginatedResponse response = new PaginatedResponse<>(); response.setPage(page); response.setSize(size); response.setTotalElements(total); response.setContent(content); - response.setSortBy(request.getSortBy()); - response.setSortDirection(request.getSortDirection()); + response.setSortBy(safeRequest.getSortBy()); + response.setSortDirection(safeRequest.getSortDirection()); return response; } - // Recursively build Criteria from FilterRule list - private Criteria buildCriteria(List rules) { - if (rules == null || rules.isEmpty()) return new Criteria(); + private int resolvePage(Integer page) { + if (page == null) { + return DEFAULT_PAGE; + } + if (page < 0) { + throw new IllegalArgumentException("Page must be >= 0"); + } + return page; + } + + private int resolveSize(Integer size) { + if (size == null) { + return DEFAULT_SIZE; + } + if (size <= 0) { + throw new IllegalArgumentException("Size must be > 0"); + } + if (size > guardrailProperties.getMaxPageSize()) { + throw new IllegalArgumentException("Size exceeds max page size: " + guardrailProperties.getMaxPageSize()); + } + return size; + } + + private Sort.Direction resolveSortDirection(String sortDirection) { + if (sortDirection == null || sortDirection.isBlank()) { + return Sort.Direction.ASC; + } + + if ("DESC".equalsIgnoreCase(sortDirection)) { + return Sort.Direction.DESC; + } + if ("ASC".equalsIgnoreCase(sortDirection)) { + return Sort.Direction.ASC; + } + throw new IllegalArgumentException("Unsupported sort direction: " + sortDirection); + } + + private Map loadFieldTypesByEntity(String entity) { + FieldGroup fieldGroup = fieldGroupRepository.findByEntity(entity) + .orElseThrow(() -> new IllegalArgumentException("Schema group not found for entity: " + entity)); + + List fieldNames = fieldGroup.getFieldNames(); + if (fieldNames == null || fieldNames.isEmpty()) { + throw new IllegalArgumentException("Field group has no fields for entity: " + entity); + } + + List definitions = StreamSupport + .stream(fieldDefinitionRepository.findAllById(fieldNames).spliterator(), false) + .collect(Collectors.toList()); + + if (definitions.isEmpty()) { + throw new IllegalArgumentException("No field definitions found for entity: " + entity); + } + + Map fieldTypeByPath = new HashMap<>(); + for (FieldDefinition definition : definitions) { + registerFieldPaths(definition, "", fieldTypeByPath); + } + return fieldTypeByPath; + } + + private void registerFieldPaths(FieldDefinition definition, String parentPath, Map fieldTypeByPath) { + String path = parentPath.isEmpty() + ? definition.getFieldName() + : parentPath + "." + definition.getFieldName(); + + fieldTypeByPath.put(path, definition.getType()); + if ((definition.getType() == FieldType.OBJECT || definition.getType() == FieldType.ARRAY) + && definition.getSubFields() != null && !definition.getSubFields().isEmpty()) { + for (FieldDefinition subField : definition.getSubFields()) { + registerFieldPaths(subField, path, fieldTypeByPath); + } + } + } + + private void validateSort(String sortBy, String sortDirection, Map fieldTypes) { + if (sortBy == null || sortBy.isBlank()) { + if (sortDirection != null && !sortDirection.isBlank()) { + throw new IllegalArgumentException("sortDirection requires sortBy"); + } + return; + } + + String normalizedSortBy = sortBy.trim(); + if (!fieldTypes.containsKey(normalizedSortBy)) { + throw new IllegalArgumentException("Sorting by field is not allowed: " + normalizedSortBy); + } + + if (sortDirection != null && !sortDirection.isBlank()) { + resolveSortDirection(sortDirection); + } + } + + private void validateFilters(List filters, Map fieldTypes) { + if (filters == null || filters.isEmpty()) { + return; + } + + AtomicInteger ruleCount = new AtomicInteger(); + for (FilterRule filter : filters) { + validateRule(filter, 1, ruleCount, fieldTypes); + } + } + + private void validateRule( + FilterRule rule, + int depth, + AtomicInteger ruleCount, + Map fieldTypes + ) { + if (rule == null) { + throw new IllegalArgumentException("Filter rule cannot be null"); + } + if (depth > guardrailProperties.getMaxFilterDepth()) { + throw new IllegalArgumentException("Filter depth exceeds max: " + guardrailProperties.getMaxFilterDepth()); + } + if (ruleCount.incrementAndGet() > guardrailProperties.getMaxRuleCount()) { + throw new IllegalArgumentException("Filter rule count exceeds max: " + guardrailProperties.getMaxRuleCount()); + } + + String operator = normalizeOperator(rule.getOperator()); + if (COMBINATOR_OPERATORS.contains(operator)) { + List nestedRules = rule.getRules(); + if (nestedRules == null || nestedRules.isEmpty()) { + throw new IllegalArgumentException("Combinator operator requires nested rules: " + operator); + } + if ("not".equals(operator) && nestedRules.size() != 1) { + throw new IllegalArgumentException("NOT operator requires exactly one nested rule"); + } + for (FilterRule nestedRule : nestedRules) { + validateRule(nestedRule, depth + 1, ruleCount, fieldTypes); + } + return; + } + + if (rule.getRules() != null && !rule.getRules().isEmpty()) { + throw new IllegalArgumentException("Leaf filter operators cannot include nested rules"); + } + + String field = normalizeField(rule.getField()); + if (field == null) { + throw new IllegalArgumentException("Filter field is required"); + } + + FieldType fieldType = fieldTypes.get(field); + if (fieldType == null) { + throw new IllegalArgumentException("Filtering by field is not allowed: " + field); + } + + validateOperatorForType(field, operator, fieldType); + validateOperatorValue(field, operator, fieldType, rule.getValue()); + } + + private void validateOperatorForType(String field, String operator, FieldType fieldType) { + Set allowedOperators = allowedOperatorsFor(fieldType); + if (!allowedOperators.contains(operator)) { + throw new IllegalArgumentException( + "Operator '" + operator + "' is not allowed for field '" + field + "' of type " + fieldType + ); + } + } + + private Set allowedOperatorsFor(FieldType fieldType) { + return switch (fieldType) { + case STRING -> STRING_OPERATORS; + case NUMBER -> NUMBER_OPERATORS; + case BOOLEAN -> BOOLEAN_OPERATORS; + case DATE -> DATE_OPERATORS; + case OBJECT, ARRAY -> OBJECT_ARRAY_OPERATORS; + }; + } + + private void validateOperatorValue(String field, String operator, FieldType fieldType, Object value) { + if ("in".equals(operator)) { + if (!(value instanceof Collection collection)) { + throw new IllegalArgumentException("IN operator requires a list for field: " + field); + } + validateCollectionValues(field, fieldType, collection); + return; + } + + if ("regex".equals(operator)) { + if (!(value instanceof String)) { + throw new IllegalArgumentException("Regex operator requires string value for field: " + field); + } + return; + } + + if (fieldType == FieldType.NUMBER && ("gt".equals(operator) || "lt".equals(operator) || "gte".equals(operator) || "lte".equals(operator))) { + if (!(value instanceof Number)) { + throw new IllegalArgumentException("Operator '" + operator + "' requires numeric value for field: " + field); + } + } + + if (fieldType == FieldType.DATE && ("gt".equals(operator) || "lt".equals(operator) || "gte".equals(operator) || "lte".equals(operator))) { + if (!(value instanceof String)) { + throw new IllegalArgumentException("Operator '" + operator + "' requires date-string value for field: " + field); + } + } + } + + private void validateCollectionValues(String field, FieldType fieldType, Collection collection) { + for (Object item : collection) { + switch (fieldType) { + case NUMBER -> { + if (!(item instanceof Number)) { + throw new IllegalArgumentException("IN operator requires numeric list for field: " + field); + } + } + case BOOLEAN -> { + if (!(item instanceof Boolean)) { + throw new IllegalArgumentException("IN operator requires boolean list for field: " + field); + } + } + case DATE, STRING -> { + if (!(item instanceof String)) { + throw new IllegalArgumentException("IN operator requires string list for field: " + field); + } + } + case OBJECT, ARRAY -> throw new IllegalArgumentException("IN operator is not allowed for field: " + field); + } + } + } + + private String normalizeOperator(String operator) { + if (operator == null || operator.isBlank()) { + return "eq"; + } + return operator.trim().toLowerCase(); + } + + private String normalizeField(String field) { + if (field == null || field.isBlank()) { + return null; + } + return field.trim(); + } + + private Criteria buildCriteria(List rules) { + if (rules == null || rules.isEmpty()) { + return new Criteria(); + } List criteriaList = rules.stream().map(this::buildCriteria).collect(Collectors.toList()); - // Default to AND + if (criteriaList.size() == 1) { + return criteriaList.get(0); + } return new Criteria().andOperator(criteriaList.toArray(new Criteria[0])); } - private Criteria buildCriteria(com.dynapi.dto.FilterRule rule) { - if (rule.getOperator() == null || rule.getOperator().equalsIgnoreCase("eq")) { - return Criteria.where(rule.getField()).is(rule.getValue()); + private Criteria buildCriteria(FilterRule rule) { + String operator = normalizeOperator(rule.getOperator()); + if (COMBINATOR_OPERATORS.contains(operator)) { + List nested = rule.getRules().stream().map(this::buildCriteria).collect(Collectors.toList()); + return switch (operator) { + case "and" -> new Criteria().andOperator(nested.toArray(new Criteria[0])); + case "or" -> new Criteria().orOperator(nested.toArray(new Criteria[0])); + case "not" -> new Criteria().norOperator(nested.get(0)); + default -> new Criteria(); + }; } - switch (rule.getOperator().toLowerCase()) { + + String field = normalizeField(rule.getField()); + Object value = rule.getValue(); + switch (operator) { + case "eq": + return Criteria.where(field).is(value); case "ne": - return Criteria.where(rule.getField()).ne(rule.getValue()); + return Criteria.where(field).ne(value); case "gt": - return Criteria.where(rule.getField()).gt(rule.getValue()); + return Criteria.where(field).gt(value); case "lt": - return Criteria.where(rule.getField()).lt(rule.getValue()); + return Criteria.where(field).lt(value); case "gte": - return Criteria.where(rule.getField()).gte(rule.getValue()); + return Criteria.where(field).gte(value); case "lte": - return Criteria.where(rule.getField()).lte(rule.getValue()); + return Criteria.where(field).lte(value); case "in": - return Criteria.where(rule.getField()).in((List) rule.getValue()); + return Criteria.where(field).in((Collection) value); case "regex": - return Criteria.where(rule.getField()).regex(rule.getValue().toString()); - case "and": - return new Criteria().andOperator(rule.getRules().stream().map(this::buildCriteria).toArray(Criteria[]::new)); - case "or": - return new Criteria().orOperator(rule.getRules().stream().map(this::buildCriteria).toArray(Criteria[]::new)); - case "not": - return new Criteria().not().elemMatch(buildCriteria(rule.getRules().get(0))); + return Criteria.where(field).regex((String) value); default: - return Criteria.where(rule.getField()).is(rule.getValue()); + return Criteria.where(field).is(value); } } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 92e59c2..79edbcf 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -25,6 +25,13 @@ security: jwt: secret: ZHluYXBpLWRldi1zZWNyZXQta2V5LWNoYW5nZS1tZS0xMjM0NTY3ODkw +dynapi: + query: + guardrails: + max-page-size: 100 + max-filter-depth: 3 + max-rule-count: 20 + springdoc: api-docs: path: /api-docs diff --git a/src/test/java/com/dynapi/integration/FormControllerIntegrationTest.java b/src/test/java/com/dynapi/integration/FormControllerIntegrationTest.java index 952a815..d704479 100644 --- a/src/test/java/com/dynapi/integration/FormControllerIntegrationTest.java +++ b/src/test/java/com/dynapi/integration/FormControllerIntegrationTest.java @@ -22,6 +22,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.verify; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -87,6 +88,28 @@ void submitForm_returnsBadRequestWhenServiceThrowsIllegalArgument() throws Excep .andExpect(jsonPath("$.message").value("Group not found")); } + @Test + void submitFormByGroup_returnsSuccessEnvelope() throws Exception { + String requestBody = """ + { + "name": "Alice" + } + """; + + mockMvc.perform(post("/api/forms/profile/submit") + .contextPath("/api") + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.message").value("Form submitted successfully")); + + var requestCaptor = org.mockito.ArgumentCaptor.forClass(FormSubmissionRequest.class); + verify(formSubmissionService).submitForm(requestCaptor.capture(), any(Locale.class)); + assertThat(requestCaptor.getValue().getGroup()).isEqualTo("profile"); + assertThat(requestCaptor.getValue().getData()).containsEntry("name", "Alice"); + } + @TestConfiguration static class FormControllerTestConfig { @Bean diff --git a/src/test/java/com/dynapi/service/DynamicQueryServiceTest.java b/src/test/java/com/dynapi/service/DynamicQueryServiceTest.java new file mode 100644 index 0000000..b8808a2 --- /dev/null +++ b/src/test/java/com/dynapi/service/DynamicQueryServiceTest.java @@ -0,0 +1,218 @@ +package com.dynapi.service; + +import com.dynapi.config.QueryGuardrailProperties; +import com.dynapi.domain.model.FieldDefinition; +import com.dynapi.domain.model.FieldGroup; +import com.dynapi.domain.model.FieldType; +import com.dynapi.dto.DynamicQueryRequest; +import com.dynapi.dto.FilterRule; +import com.dynapi.dto.FormRecordDto; +import com.dynapi.dto.PaginatedResponse; +import com.dynapi.repository.FieldDefinitionRepository; +import com.dynapi.repository.FieldGroupRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.mongodb.core.MongoTemplate; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class DynamicQueryServiceTest { + + @Mock + private MongoTemplate mongoTemplate; + + @Mock + private FieldGroupRepository fieldGroupRepository; + + @Mock + private FieldDefinitionRepository fieldDefinitionRepository; + + private DynamicQueryService dynamicQueryService; + + @BeforeEach + void setUp() { + QueryGuardrailProperties guardrails = new QueryGuardrailProperties(); + guardrails.setMaxPageSize(100); + guardrails.setMaxFilterDepth(3); + guardrails.setMaxRuleCount(20); + + dynamicQueryService = new DynamicQueryService( + mongoTemplate, + fieldGroupRepository, + fieldDefinitionRepository, + guardrails + ); + + FieldGroup group = new FieldGroup(); + group.setName("task-group"); + group.setEntity("tasks"); + group.setFieldNames(List.of("title", "priority", "profile")); + lenient().when(fieldGroupRepository.findByEntity("tasks")).thenReturn(Optional.of(group)); + + FieldDefinition title = field("title", FieldType.STRING); + FieldDefinition priority = field("priority", FieldType.NUMBER); + FieldDefinition profile = field("profile", FieldType.OBJECT); + FieldDefinition age = field("age", FieldType.NUMBER); + profile.setSubFields(List.of(age)); + lenient().when(fieldDefinitionRepository.findAllById(group.getFieldNames())) + .thenReturn(List.of(title, priority, profile)); + } + + @Test + void query_rejectsSizeAboveMax() { + DynamicQueryRequest request = new DynamicQueryRequest(); + request.setSize(101); + + IllegalArgumentException ex = assertThrows( + IllegalArgumentException.class, + () -> dynamicQueryService.query("tasks", request) + ); + + assertTrue(ex.getMessage().contains("max page size")); + } + + @Test + void query_rejectsUnknownSortField() { + DynamicQueryRequest request = new DynamicQueryRequest(); + request.setSortBy("unknownField"); + request.setSortDirection("ASC"); + + IllegalArgumentException ex = assertThrows( + IllegalArgumentException.class, + () -> dynamicQueryService.query("tasks", request) + ); + + assertTrue(ex.getMessage().contains("Sorting by field is not allowed")); + } + + @Test + void query_rejectsUnknownFilterField() { + DynamicQueryRequest request = new DynamicQueryRequest(); + request.setFilters(List.of(filter("unknown", "eq", "x"))); + + IllegalArgumentException ex = assertThrows( + IllegalArgumentException.class, + () -> dynamicQueryService.query("tasks", request) + ); + + assertTrue(ex.getMessage().contains("Filtering by field is not allowed")); + } + + @Test + void query_rejectsUnsupportedOperatorForFieldType() { + DynamicQueryRequest request = new DynamicQueryRequest(); + request.setFilters(List.of(filter("priority", "regex", "^1$"))); + + IllegalArgumentException ex = assertThrows( + IllegalArgumentException.class, + () -> dynamicQueryService.query("tasks", request) + ); + + assertTrue(ex.getMessage().contains("not allowed")); + } + + @Test + void query_rejectsFilterDepthExceeded() { + DynamicQueryRequest request = new DynamicQueryRequest(); + request.setFilters(List.of(nestedAnd(4, filter("title", "eq", "A")))); + + IllegalArgumentException ex = assertThrows( + IllegalArgumentException.class, + () -> dynamicQueryService.query("tasks", request) + ); + + assertTrue(ex.getMessage().contains("Filter depth exceeds max")); + } + + @Test + void query_rejectsFilterRuleCountExceeded() { + List tooManyRules = new ArrayList<>(); + for (int i = 0; i < 21; i++) { + tooManyRules.add(filter("title", "eq", "task-" + i)); + } + + DynamicQueryRequest request = new DynamicQueryRequest(); + request.setFilters(tooManyRules); + + IllegalArgumentException ex = assertThrows( + IllegalArgumentException.class, + () -> dynamicQueryService.query("tasks", request) + ); + + assertTrue(ex.getMessage().contains("Filter rule count exceeds max")); + } + + @Test + void query_allowsValidGuardedQuery() { + DynamicQueryRequest request = new DynamicQueryRequest(); + request.setPage(0); + request.setSize(10); + request.setSortBy("priority"); + request.setSortDirection("DESC"); + request.setFilters(List.of( + filter("priority", "gte", 1), + filter("profile.age", "lt", 65) + )); + + when(mongoTemplate.find(any(), eq(Map.class), eq("tasks"))) + .thenReturn(List.of(Map.of( + "_id", "id-1", + "title", "Task", + "priority", 2 + ))); + when(mongoTemplate.count(any(), eq("tasks"))).thenReturn(1L); + + PaginatedResponse response = dynamicQueryService.query("tasks", request); + + assertEquals(0, response.getPage()); + assertEquals(10, response.getSize()); + assertEquals(1L, response.getTotalElements()); + assertEquals(1, response.getContent().size()); + assertEquals("id-1", response.getContent().get(0).getId()); + assertEquals(2, response.getContent().get(0).getData().get("priority")); + + verify(mongoTemplate).find(any(), eq(Map.class), eq("tasks")); + verify(mongoTemplate).count(any(), eq("tasks")); + } + + private FieldDefinition field(String name, FieldType type) { + FieldDefinition definition = new FieldDefinition(); + definition.setFieldName(name); + definition.setType(type); + return definition; + } + + private FilterRule filter(String field, String operator, Object value) { + FilterRule rule = new FilterRule(); + rule.setField(field); + rule.setOperator(operator); + rule.setValue(value); + return rule; + } + + private FilterRule nestedAnd(int depth, FilterRule leaf) { + if (depth <= 1) { + return leaf; + } + FilterRule parent = new FilterRule(); + parent.setOperator("and"); + parent.setRules(List.of(nestedAnd(depth - 1, leaf))); + return parent; + } +} diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml index 3eb2fa2..1e7ae5c 100644 --- a/src/test/resources/application-test.yml +++ b/src/test/resources/application-test.yml @@ -21,3 +21,10 @@ server: security: jwt: secret: ZHluYXBpLWRldi1zZWNyZXQta2V5LWNoYW5nZS1tZS0xMjM0NTY3ODkw + +dynapi: + query: + guardrails: + max-page-size: 100 + max-filter-depth: 3 + max-rule-count: 20 diff --git a/target/classes/application.properties b/target/classes/application.properties deleted file mode 100644 index 41f9679..0000000 --- a/target/classes/application.properties +++ /dev/null @@ -1,2 +0,0 @@ -# MongoDB connection example -# spring.data.mongodb.uri=mongodb://localhost:27017/dynapi diff --git a/target/classes/application.yml b/target/classes/application.yml deleted file mode 100644 index 92e59c2..0000000 --- a/target/classes/application.yml +++ /dev/null @@ -1,39 +0,0 @@ -spring: - data: - mongodb: - host: localhost - port: 27017 - database: dynapi - - kafka: - bootstrap-servers: localhost:9092 - producer: - key-serializer: org.apache.kafka.common.serialization.StringSerializer - value-serializer: org.springframework.kafka.support.serializer.JsonSerializer - - messages: - basename: messages - encoding: UTF-8 - fallback-to-system-locale: false - -server: - port: 8080 - servlet: - context-path: /api - -security: - jwt: - secret: ZHluYXBpLWRldi1zZWNyZXQta2V5LWNoYW5nZS1tZS0xMjM0NTY3ODkw - -springdoc: - api-docs: - path: /api-docs - swagger-ui: - path: /swagger-ui.html - operationsSorter: method - -logging: - level: - com.dynapi: DEBUG - org.springframework.data.mongodb: INFO - org.springframework.kafka: INFO diff --git a/target/classes/com/dynapi/DynapiApplication.class b/target/classes/com/dynapi/DynapiApplication.class deleted file mode 100644 index f1b0b39..0000000 Binary files a/target/classes/com/dynapi/DynapiApplication.class and /dev/null differ diff --git a/target/classes/com/dynapi/application/port/AuditPublisher.class b/target/classes/com/dynapi/application/port/AuditPublisher.class deleted file mode 100644 index e13a711..0000000 Binary files a/target/classes/com/dynapi/application/port/AuditPublisher.class and /dev/null differ diff --git a/target/classes/com/dynapi/application/port/FormSubmissionPersistencePort.class b/target/classes/com/dynapi/application/port/FormSubmissionPersistencePort.class deleted file mode 100644 index 04b1b97..0000000 Binary files a/target/classes/com/dynapi/application/port/FormSubmissionPersistencePort.class and /dev/null differ diff --git a/target/classes/com/dynapi/application/port/input/SubmitFormUseCase.class b/target/classes/com/dynapi/application/port/input/SubmitFormUseCase.class deleted file mode 100644 index b0e7bdb..0000000 Binary files a/target/classes/com/dynapi/application/port/input/SubmitFormUseCase.class and /dev/null differ diff --git a/target/classes/com/dynapi/application/port/output/FormSubmissionPersistencePort.class b/target/classes/com/dynapi/application/port/output/FormSubmissionPersistencePort.class deleted file mode 100644 index cccb405..0000000 Binary files a/target/classes/com/dynapi/application/port/output/FormSubmissionPersistencePort.class and /dev/null differ diff --git a/target/classes/com/dynapi/application/query/DynamicQueryService.class b/target/classes/com/dynapi/application/query/DynamicQueryService.class deleted file mode 100644 index a540a47..0000000 Binary files a/target/classes/com/dynapi/application/query/DynamicQueryService.class and /dev/null differ diff --git a/target/classes/com/dynapi/application/service/DynamicValidatorImpl.class b/target/classes/com/dynapi/application/service/DynamicValidatorImpl.class deleted file mode 100644 index fae7d7a..0000000 Binary files a/target/classes/com/dynapi/application/service/DynamicValidatorImpl.class and /dev/null differ diff --git a/target/classes/com/dynapi/application/service/FormSubmissionApplicationService.class b/target/classes/com/dynapi/application/service/FormSubmissionApplicationService.class deleted file mode 100644 index 654e572..0000000 Binary files a/target/classes/com/dynapi/application/service/FormSubmissionApplicationService.class and /dev/null differ diff --git a/target/classes/com/dynapi/audit/AuditEvent.class b/target/classes/com/dynapi/audit/AuditEvent.class deleted file mode 100644 index 2bf8f02..0000000 Binary files a/target/classes/com/dynapi/audit/AuditEvent.class and /dev/null differ diff --git a/target/classes/com/dynapi/audit/AuditEventListener$AuditLog.class b/target/classes/com/dynapi/audit/AuditEventListener$AuditLog.class deleted file mode 100644 index 212221a..0000000 Binary files a/target/classes/com/dynapi/audit/AuditEventListener$AuditLog.class and /dev/null differ diff --git a/target/classes/com/dynapi/audit/AuditEventListener.class b/target/classes/com/dynapi/audit/AuditEventListener.class deleted file mode 100644 index f0be8cb..0000000 Binary files a/target/classes/com/dynapi/audit/AuditEventListener.class and /dev/null differ diff --git a/target/classes/com/dynapi/audit/AuditPublisher.class b/target/classes/com/dynapi/audit/AuditPublisher.class deleted file mode 100644 index 3108d47..0000000 Binary files a/target/classes/com/dynapi/audit/AuditPublisher.class and /dev/null differ diff --git a/target/classes/com/dynapi/config/OpenApiConfig.class b/target/classes/com/dynapi/config/OpenApiConfig.class deleted file mode 100644 index bc8d70d..0000000 Binary files a/target/classes/com/dynapi/config/OpenApiConfig.class and /dev/null differ diff --git a/target/classes/com/dynapi/controller/FormController.class b/target/classes/com/dynapi/controller/FormController.class deleted file mode 100644 index ed0d383..0000000 Binary files a/target/classes/com/dynapi/controller/FormController.class and /dev/null differ diff --git a/target/classes/com/dynapi/controller/QueryController.class b/target/classes/com/dynapi/controller/QueryController.class deleted file mode 100644 index a787b3e..0000000 Binary files a/target/classes/com/dynapi/controller/QueryController.class and /dev/null differ diff --git a/target/classes/com/dynapi/controller/SchemaAdminController.class b/target/classes/com/dynapi/controller/SchemaAdminController.class deleted file mode 100644 index cfdb658..0000000 Binary files a/target/classes/com/dynapi/controller/SchemaAdminController.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/event/AuditPublisher.class b/target/classes/com/dynapi/domain/event/AuditPublisher.class deleted file mode 100644 index b11520d..0000000 Binary files a/target/classes/com/dynapi/domain/event/AuditPublisher.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/event/DomainEvent.class b/target/classes/com/dynapi/domain/event/DomainEvent.class deleted file mode 100644 index 7bb6940..0000000 Binary files a/target/classes/com/dynapi/domain/event/DomainEvent.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/exception/EntityNotFoundException.class b/target/classes/com/dynapi/domain/exception/EntityNotFoundException.class deleted file mode 100644 index 63b28f0..0000000 Binary files a/target/classes/com/dynapi/domain/exception/EntityNotFoundException.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/exception/ValidationException.class b/target/classes/com/dynapi/domain/exception/ValidationException.class deleted file mode 100644 index 28ddacb..0000000 Binary files a/target/classes/com/dynapi/domain/exception/ValidationException.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/model/DynamicQuery$QueryFilter.class b/target/classes/com/dynapi/domain/model/DynamicQuery$QueryFilter.class deleted file mode 100644 index e4ec909..0000000 Binary files a/target/classes/com/dynapi/domain/model/DynamicQuery$QueryFilter.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/model/DynamicQuery.class b/target/classes/com/dynapi/domain/model/DynamicQuery.class deleted file mode 100644 index d7b2db1..0000000 Binary files a/target/classes/com/dynapi/domain/model/DynamicQuery.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/model/FieldDefinition$RequiredIfRule.class b/target/classes/com/dynapi/domain/model/FieldDefinition$RequiredIfRule.class deleted file mode 100644 index cd6931b..0000000 Binary files a/target/classes/com/dynapi/domain/model/FieldDefinition$RequiredIfRule.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/model/FieldDefinition.class b/target/classes/com/dynapi/domain/model/FieldDefinition.class deleted file mode 100644 index eb49647..0000000 Binary files a/target/classes/com/dynapi/domain/model/FieldDefinition.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/model/FieldGroup.class b/target/classes/com/dynapi/domain/model/FieldGroup.class deleted file mode 100644 index 7e7ea67..0000000 Binary files a/target/classes/com/dynapi/domain/model/FieldGroup.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/model/FieldPermission.class b/target/classes/com/dynapi/domain/model/FieldPermission.class deleted file mode 100644 index d880be1..0000000 Binary files a/target/classes/com/dynapi/domain/model/FieldPermission.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/model/FieldType.class b/target/classes/com/dynapi/domain/model/FieldType.class deleted file mode 100644 index b84983f..0000000 Binary files a/target/classes/com/dynapi/domain/model/FieldType.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/model/FormSubmission.class b/target/classes/com/dynapi/domain/model/FormSubmission.class deleted file mode 100644 index c2ae556..0000000 Binary files a/target/classes/com/dynapi/domain/model/FormSubmission.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/model/SchemaVersion.class b/target/classes/com/dynapi/domain/model/SchemaVersion.class deleted file mode 100644 index a57c72c..0000000 Binary files a/target/classes/com/dynapi/domain/model/SchemaVersion.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/repository/FieldDefinitionRepository.class b/target/classes/com/dynapi/domain/repository/FieldDefinitionRepository.class deleted file mode 100644 index 0bd62e9..0000000 Binary files a/target/classes/com/dynapi/domain/repository/FieldDefinitionRepository.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/repository/FieldGroupRepository.class b/target/classes/com/dynapi/domain/repository/FieldGroupRepository.class deleted file mode 100644 index 9f61fb1..0000000 Binary files a/target/classes/com/dynapi/domain/repository/FieldGroupRepository.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/repository/FormSubmissionRepository.class b/target/classes/com/dynapi/domain/repository/FormSubmissionRepository.class deleted file mode 100644 index 1a71ee9..0000000 Binary files a/target/classes/com/dynapi/domain/repository/FormSubmissionRepository.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/service/DynamicValidator.class b/target/classes/com/dynapi/domain/service/DynamicValidator.class deleted file mode 100644 index aaf3707..0000000 Binary files a/target/classes/com/dynapi/domain/service/DynamicValidator.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/service/FieldPermissionService.class b/target/classes/com/dynapi/domain/service/FieldPermissionService.class deleted file mode 100644 index 9902db3..0000000 Binary files a/target/classes/com/dynapi/domain/service/FieldPermissionService.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/service/FormSubmissionDomainService.class b/target/classes/com/dynapi/domain/service/FormSubmissionDomainService.class deleted file mode 100644 index e70ba67..0000000 Binary files a/target/classes/com/dynapi/domain/service/FormSubmissionDomainService.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/service/FormSubmissionDomainServiceImpl.class b/target/classes/com/dynapi/domain/service/FormSubmissionDomainServiceImpl.class deleted file mode 100644 index 47fa1e2..0000000 Binary files a/target/classes/com/dynapi/domain/service/FormSubmissionDomainServiceImpl.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/service/SchemaVersionService.class b/target/classes/com/dynapi/domain/service/SchemaVersionService.class deleted file mode 100644 index 348dc42..0000000 Binary files a/target/classes/com/dynapi/domain/service/SchemaVersionService.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/service/impl/FieldPermissionServiceImpl.class b/target/classes/com/dynapi/domain/service/impl/FieldPermissionServiceImpl.class deleted file mode 100644 index ccee4d8..0000000 Binary files a/target/classes/com/dynapi/domain/service/impl/FieldPermissionServiceImpl.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/service/impl/SchemaVersionServiceImpl.class b/target/classes/com/dynapi/domain/service/impl/SchemaVersionServiceImpl.class deleted file mode 100644 index b0ecac9..0000000 Binary files a/target/classes/com/dynapi/domain/service/impl/SchemaVersionServiceImpl.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/validation/DynamicValidator$1.class b/target/classes/com/dynapi/domain/validation/DynamicValidator$1.class deleted file mode 100644 index ef31edb..0000000 Binary files a/target/classes/com/dynapi/domain/validation/DynamicValidator$1.class and /dev/null differ diff --git a/target/classes/com/dynapi/domain/validation/DynamicValidator.class b/target/classes/com/dynapi/domain/validation/DynamicValidator.class deleted file mode 100644 index f43fc8a..0000000 Binary files a/target/classes/com/dynapi/domain/validation/DynamicValidator.class and /dev/null differ diff --git a/target/classes/com/dynapi/dto/ApiResponse$Metadata.class b/target/classes/com/dynapi/dto/ApiResponse$Metadata.class deleted file mode 100644 index b745ecc..0000000 Binary files a/target/classes/com/dynapi/dto/ApiResponse$Metadata.class and /dev/null differ diff --git a/target/classes/com/dynapi/dto/ApiResponse.class b/target/classes/com/dynapi/dto/ApiResponse.class deleted file mode 100644 index 80aea29..0000000 Binary files a/target/classes/com/dynapi/dto/ApiResponse.class and /dev/null differ diff --git a/target/classes/com/dynapi/dto/DynamicQueryRequest.class b/target/classes/com/dynapi/dto/DynamicQueryRequest.class deleted file mode 100644 index 9276bda..0000000 Binary files a/target/classes/com/dynapi/dto/DynamicQueryRequest.class and /dev/null differ diff --git a/target/classes/com/dynapi/dto/FilterRule.class b/target/classes/com/dynapi/dto/FilterRule.class deleted file mode 100644 index f6c61e8..0000000 Binary files a/target/classes/com/dynapi/dto/FilterRule.class and /dev/null differ diff --git a/target/classes/com/dynapi/dto/FormRecordDto.class b/target/classes/com/dynapi/dto/FormRecordDto.class deleted file mode 100644 index 1c67a61..0000000 Binary files a/target/classes/com/dynapi/dto/FormRecordDto.class and /dev/null differ diff --git a/target/classes/com/dynapi/dto/FormSubmissionRequest.class b/target/classes/com/dynapi/dto/FormSubmissionRequest.class deleted file mode 100644 index 0f0aff5..0000000 Binary files a/target/classes/com/dynapi/dto/FormSubmissionRequest.class and /dev/null differ diff --git a/target/classes/com/dynapi/dto/PaginatedResponse.class b/target/classes/com/dynapi/dto/PaginatedResponse.class deleted file mode 100644 index cf01275..0000000 Binary files a/target/classes/com/dynapi/dto/PaginatedResponse.class and /dev/null differ diff --git a/target/classes/com/dynapi/exception/GlobalExceptionHandler.class b/target/classes/com/dynapi/exception/GlobalExceptionHandler.class deleted file mode 100644 index 61baeb2..0000000 Binary files a/target/classes/com/dynapi/exception/GlobalExceptionHandler.class and /dev/null differ diff --git a/target/classes/com/dynapi/infrastructure/audit/LoggingAuditPublisher.class b/target/classes/com/dynapi/infrastructure/audit/LoggingAuditPublisher.class deleted file mode 100644 index 3ec8190..0000000 Binary files a/target/classes/com/dynapi/infrastructure/audit/LoggingAuditPublisher.class and /dev/null differ diff --git a/target/classes/com/dynapi/infrastructure/messaging/EventPublisher.class b/target/classes/com/dynapi/infrastructure/messaging/EventPublisher.class deleted file mode 100644 index 7e1e3e5..0000000 Binary files a/target/classes/com/dynapi/infrastructure/messaging/EventPublisher.class and /dev/null differ diff --git a/target/classes/com/dynapi/infrastructure/messaging/KafkaConfig.class b/target/classes/com/dynapi/infrastructure/messaging/KafkaConfig.class deleted file mode 100644 index dc93e8d..0000000 Binary files a/target/classes/com/dynapi/infrastructure/messaging/KafkaConfig.class and /dev/null differ diff --git a/target/classes/com/dynapi/infrastructure/persistence/MongoDynamicQueryService.class b/target/classes/com/dynapi/infrastructure/persistence/MongoDynamicQueryService.class deleted file mode 100644 index 5783995..0000000 Binary files a/target/classes/com/dynapi/infrastructure/persistence/MongoDynamicQueryService.class and /dev/null differ diff --git a/target/classes/com/dynapi/infrastructure/persistence/MongoFormSubmissionAdapter.class b/target/classes/com/dynapi/infrastructure/persistence/MongoFormSubmissionAdapter.class deleted file mode 100644 index 693d80b..0000000 Binary files a/target/classes/com/dynapi/infrastructure/persistence/MongoFormSubmissionAdapter.class and /dev/null differ diff --git a/target/classes/com/dynapi/interfaces/rest/FormSubmissionController.class b/target/classes/com/dynapi/interfaces/rest/FormSubmissionController.class deleted file mode 100644 index 0dc8e2a..0000000 Binary files a/target/classes/com/dynapi/interfaces/rest/FormSubmissionController.class and /dev/null differ diff --git a/target/classes/com/dynapi/interfaces/rest/dto/FormSubmissionRequest.class b/target/classes/com/dynapi/interfaces/rest/dto/FormSubmissionRequest.class deleted file mode 100644 index dd67225..0000000 Binary files a/target/classes/com/dynapi/interfaces/rest/dto/FormSubmissionRequest.class and /dev/null differ diff --git a/target/classes/com/dynapi/repository/FieldDefinitionRepository.class b/target/classes/com/dynapi/repository/FieldDefinitionRepository.class deleted file mode 100644 index 3c2799a..0000000 Binary files a/target/classes/com/dynapi/repository/FieldDefinitionRepository.class and /dev/null differ diff --git a/target/classes/com/dynapi/repository/FieldGroupRepository.class b/target/classes/com/dynapi/repository/FieldGroupRepository.class deleted file mode 100644 index eaf2bee..0000000 Binary files a/target/classes/com/dynapi/repository/FieldGroupRepository.class and /dev/null differ diff --git a/target/classes/com/dynapi/security/JwtAuthenticationFilter.class b/target/classes/com/dynapi/security/JwtAuthenticationFilter.class deleted file mode 100644 index 0326249..0000000 Binary files a/target/classes/com/dynapi/security/JwtAuthenticationFilter.class and /dev/null differ diff --git a/target/classes/com/dynapi/security/JwtProperties.class b/target/classes/com/dynapi/security/JwtProperties.class deleted file mode 100644 index d7f0d76..0000000 Binary files a/target/classes/com/dynapi/security/JwtProperties.class and /dev/null differ diff --git a/target/classes/com/dynapi/security/JwtTokenService.class b/target/classes/com/dynapi/security/JwtTokenService.class deleted file mode 100644 index 30c31d4..0000000 Binary files a/target/classes/com/dynapi/security/JwtTokenService.class and /dev/null differ diff --git a/target/classes/com/dynapi/security/SecurityConfig.class b/target/classes/com/dynapi/security/SecurityConfig.class deleted file mode 100644 index 0bc5283..0000000 Binary files a/target/classes/com/dynapi/security/SecurityConfig.class and /dev/null differ diff --git a/target/classes/com/dynapi/service/DynamicQueryService.class b/target/classes/com/dynapi/service/DynamicQueryService.class deleted file mode 100644 index 25c020e..0000000 Binary files a/target/classes/com/dynapi/service/DynamicQueryService.class and /dev/null differ diff --git a/target/classes/com/dynapi/service/FormSubmissionService.class b/target/classes/com/dynapi/service/FormSubmissionService.class deleted file mode 100644 index 0a4bcf4..0000000 Binary files a/target/classes/com/dynapi/service/FormSubmissionService.class and /dev/null differ diff --git a/target/classes/com/dynapi/validation/DynamicValidator$1.class b/target/classes/com/dynapi/validation/DynamicValidator$1.class deleted file mode 100644 index 948f373..0000000 Binary files a/target/classes/com/dynapi/validation/DynamicValidator$1.class and /dev/null differ diff --git a/target/classes/com/dynapi/validation/DynamicValidator.class b/target/classes/com/dynapi/validation/DynamicValidator.class deleted file mode 100644 index 1635f05..0000000 Binary files a/target/classes/com/dynapi/validation/DynamicValidator.class and /dev/null differ diff --git a/target/classes/messages.properties b/target/classes/messages.properties deleted file mode 100644 index 3139606..0000000 --- a/target/classes/messages.properties +++ /dev/null @@ -1,12 +0,0 @@ -# messages.properties -error.internal=Internal server error -error.validation=Validation failed -error.notfound=Resource not found -error.group.notfound=Field group not found -error.field.notfound=Field definition not found -success.created=Created successfully -success.updated=Updated successfully -success.deleted=Deleted successfully -success.fetched=Fetched successfully -success.submitted=Form submitted successfully -success.query=Query successful diff --git a/target/classes/messages_tr.properties b/target/classes/messages_tr.properties deleted file mode 100644 index 7eb23c3..0000000 --- a/target/classes/messages_tr.properties +++ /dev/null @@ -1,12 +0,0 @@ -# messages_tr.properties -error.internal=Sunucu hatası -error.validation=Doğrulama başarısız -error.notfound=Kaynak bulunamadı -error.group.notfound=Alan grubu bulunamadı -error.field.notfound=Alan tanımı bulunamadı -success.created=Başarıyla oluşturuldu -success.updated=Başarıyla güncellendi -success.deleted=Başarıyla silindi -success.fetched=Başarıyla getirildi -success.submitted=Form başarıyla gönderildi -success.query=Sorgu başarılı diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst deleted file mode 100644 index 855846a..0000000 --- a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +++ /dev/null @@ -1,66 +0,0 @@ -com/dynapi/security/SecurityConfig.class -com/dynapi/DynapiApplication.class -com/dynapi/domain/exception/EntityNotFoundException.class -com/dynapi/domain/model/FieldGroup.class -com/dynapi/infrastructure/messaging/KafkaConfig.class -com/dynapi/infrastructure/persistence/MongoDynamicQueryService.class -com/dynapi/domain/model/SchemaVersion.class -com/dynapi/domain/model/FieldType.class -com/dynapi/config/OpenApiConfig.class -com/dynapi/domain/exception/ValidationException.class -com/dynapi/security/JwtTokenService.class -com/dynapi/dto/ApiResponse.class -com/dynapi/infrastructure/persistence/MongoFormSubmissionAdapter.class -com/dynapi/domain/event/AuditPublisher.class -com/dynapi/domain/repository/FieldDefinitionRepository.class -com/dynapi/application/service/FormSubmissionApplicationService.class -com/dynapi/application/port/AuditPublisher.class -com/dynapi/repository/FieldDefinitionRepository.class -com/dynapi/application/port/input/SubmitFormUseCase.class -com/dynapi/validation/DynamicValidator$1.class -com/dynapi/domain/repository/FieldGroupRepository.class -com/dynapi/domain/model/FieldPermission.class -com/dynapi/audit/AuditEventListener$AuditLog.class -com/dynapi/domain/repository/FormSubmissionRepository.class -com/dynapi/domain/model/FieldDefinition.class -com/dynapi/dto/FilterRule.class -com/dynapi/controller/QueryController.class -com/dynapi/service/DynamicQueryService.class -com/dynapi/interfaces/rest/dto/FormSubmissionRequest.class -com/dynapi/dto/FormRecordDto.class -com/dynapi/domain/model/FormSubmission.class -com/dynapi/dto/PaginatedResponse.class -com/dynapi/domain/service/FieldPermissionService.class -com/dynapi/controller/SchemaAdminController.class -com/dynapi/domain/service/impl/SchemaVersionServiceImpl.class -com/dynapi/audit/AuditEvent.class -com/dynapi/dto/FormSubmissionRequest.class -com/dynapi/application/service/DynamicValidatorImpl.class -com/dynapi/domain/service/impl/FieldPermissionServiceImpl.class -com/dynapi/dto/DynamicQueryRequest.class -com/dynapi/infrastructure/messaging/EventPublisher.class -com/dynapi/domain/service/SchemaVersionService.class -com/dynapi/infrastructure/audit/LoggingAuditPublisher.class -com/dynapi/security/JwtProperties.class -com/dynapi/controller/FormController.class -com/dynapi/audit/AuditPublisher.class -com/dynapi/application/port/output/FormSubmissionPersistencePort.class -com/dynapi/domain/event/DomainEvent.class -com/dynapi/service/FormSubmissionService.class -com/dynapi/domain/validation/DynamicValidator.class -com/dynapi/dto/ApiResponse$Metadata.class -com/dynapi/domain/model/FieldDefinition$RequiredIfRule.class -com/dynapi/interfaces/rest/FormSubmissionController.class -com/dynapi/domain/service/FormSubmissionDomainServiceImpl.class -com/dynapi/domain/model/DynamicQuery.class -com/dynapi/application/port/FormSubmissionPersistencePort.class -com/dynapi/exception/GlobalExceptionHandler.class -com/dynapi/repository/FieldGroupRepository.class -com/dynapi/domain/service/DynamicValidator.class -com/dynapi/domain/model/DynamicQuery$QueryFilter.class -com/dynapi/domain/service/FormSubmissionDomainService.class -com/dynapi/security/JwtAuthenticationFilter.class -com/dynapi/audit/AuditEventListener.class -com/dynapi/validation/DynamicValidator.class -com/dynapi/domain/validation/DynamicValidator$1.class -com/dynapi/application/query/DynamicQueryService.class diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst deleted file mode 100644 index 15d90a1..0000000 --- a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ /dev/null @@ -1,60 +0,0 @@ -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/DynapiApplication.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/application/port/AuditPublisher.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/application/port/FormSubmissionPersistencePort.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/application/port/input/SubmitFormUseCase.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/application/port/output/FormSubmissionPersistencePort.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/application/query/DynamicQueryService.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/application/service/DynamicValidatorImpl.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/application/service/FormSubmissionApplicationService.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/audit/AuditEvent.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/audit/AuditEventListener.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/audit/AuditPublisher.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/config/OpenApiConfig.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/controller/FormController.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/controller/QueryController.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/controller/SchemaAdminController.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/event/AuditPublisher.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/event/DomainEvent.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/exception/EntityNotFoundException.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/exception/ValidationException.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/model/DynamicQuery.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/model/FieldDefinition.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/model/FieldGroup.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/model/FieldPermission.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/model/FieldType.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/model/FormSubmission.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/model/SchemaVersion.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/repository/FieldDefinitionRepository.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/repository/FieldGroupRepository.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/repository/FormSubmissionRepository.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/service/DynamicValidator.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/service/FieldPermissionService.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/service/FormSubmissionDomainService.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/service/FormSubmissionDomainServiceImpl.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/service/SchemaVersionService.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/service/impl/FieldPermissionServiceImpl.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/service/impl/SchemaVersionServiceImpl.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/domain/validation/DynamicValidator.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/dto/ApiResponse.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/dto/DynamicQueryRequest.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/dto/FilterRule.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/dto/FormRecordDto.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/dto/FormSubmissionRequest.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/dto/PaginatedResponse.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/exception/GlobalExceptionHandler.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/infrastructure/audit/LoggingAuditPublisher.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/infrastructure/messaging/EventPublisher.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/infrastructure/messaging/KafkaConfig.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/infrastructure/persistence/MongoDynamicQueryService.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/infrastructure/persistence/MongoFormSubmissionAdapter.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/interfaces/rest/FormSubmissionController.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/interfaces/rest/dto/FormSubmissionRequest.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/repository/FieldDefinitionRepository.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/repository/FieldGroupRepository.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/security/JwtAuthenticationFilter.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/security/JwtProperties.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/security/JwtTokenService.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/security/SecurityConfig.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/service/DynamicQueryService.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/service/FormSubmissionService.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/main/java/com/dynapi/validation/DynamicValidator.java diff --git a/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst deleted file mode 100644 index 09864b3..0000000 --- a/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst +++ /dev/null @@ -1,8 +0,0 @@ -com/dynapi/domain/validation/DynamicValidatorTest.class -com/dynapi/integration/FormControllerIntegrationTest$FormControllerTestConfig.class -com/dynapi/integration/QueryControllerIntegrationTest$QueryControllerTestConfig.class -com/dynapi/integration/QueryControllerIntegrationTest.class -com/dynapi/DynapiApplicationTests.class -com/dynapi/integration/SchemaAdminControllerSecurityIntegrationTest.class -com/dynapi/integration/FormControllerIntegrationTest.class -com/dynapi/integration/SchemaAdminControllerSecurityIntegrationTest$SchemaAdminControllerTestConfig.class diff --git a/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst deleted file mode 100644 index 06dd48a..0000000 --- a/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst +++ /dev/null @@ -1,5 +0,0 @@ -/Users/yunus.akin/Documents/projects/Java/dynapi/src/test/java/com/dynapi/DynapiApplicationTests.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/test/java/com/dynapi/domain/validation/DynamicValidatorTest.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/test/java/com/dynapi/integration/FormControllerIntegrationTest.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/test/java/com/dynapi/integration/QueryControllerIntegrationTest.java -/Users/yunus.akin/Documents/projects/Java/dynapi/src/test/java/com/dynapi/integration/SchemaAdminControllerSecurityIntegrationTest.java diff --git a/target/surefire-reports/TEST-com.dynapi.DynapiApplicationTests.xml b/target/surefire-reports/TEST-com.dynapi.DynapiApplicationTests.xml deleted file mode 100644 index 592354c..0000000 --- a/target/surefire-reports/TEST-com.dynapi.DynapiApplicationTests.xml +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/target/surefire-reports/TEST-com.dynapi.domain.validation.DynamicValidatorTest.xml b/target/surefire-reports/TEST-com.dynapi.domain.validation.DynamicValidatorTest.xml deleted file mode 100644 index 4c161b6..0000000 --- a/target/surefire-reports/TEST-com.dynapi.domain.validation.DynamicValidatorTest.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/target/surefire-reports/TEST-com.dynapi.integration.FormControllerIntegrationTest.xml b/target/surefire-reports/TEST-com.dynapi.integration.FormControllerIntegrationTest.xml deleted file mode 100644 index f1e79c5..0000000 --- a/target/surefire-reports/TEST-com.dynapi.integration.FormControllerIntegrationTest.xml +++ /dev/null @@ -1,180 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/target/surefire-reports/TEST-com.dynapi.integration.QueryControllerIntegrationTest.xml b/target/surefire-reports/TEST-com.dynapi.integration.QueryControllerIntegrationTest.xml deleted file mode 100644 index b6a1d3a..0000000 --- a/target/surefire-reports/TEST-com.dynapi.integration.QueryControllerIntegrationTest.xml +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/target/surefire-reports/TEST-com.dynapi.integration.SchemaAdminControllerSecurityIntegrationTest.xml b/target/surefire-reports/TEST-com.dynapi.integration.SchemaAdminControllerSecurityIntegrationTest.xml deleted file mode 100644 index f2f8c87..0000000 --- a/target/surefire-reports/TEST-com.dynapi.integration.SchemaAdminControllerSecurityIntegrationTest.xml +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/target/surefire-reports/com.dynapi.DynapiApplicationTests.txt b/target/surefire-reports/com.dynapi.DynapiApplicationTests.txt deleted file mode 100644 index de08e77..0000000 --- a/target/surefire-reports/com.dynapi.DynapiApplicationTests.txt +++ /dev/null @@ -1,4 +0,0 @@ -------------------------------------------------------------------------------- -Test set: com.dynapi.DynapiApplicationTests -------------------------------------------------------------------------------- -Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 7.082 s -- in com.dynapi.DynapiApplicationTests diff --git a/target/surefire-reports/com.dynapi.domain.validation.DynamicValidatorTest.txt b/target/surefire-reports/com.dynapi.domain.validation.DynamicValidatorTest.txt deleted file mode 100644 index 27113a0..0000000 --- a/target/surefire-reports/com.dynapi.domain.validation.DynamicValidatorTest.txt +++ /dev/null @@ -1,4 +0,0 @@ -------------------------------------------------------------------------------- -Test set: com.dynapi.domain.validation.DynamicValidatorTest -------------------------------------------------------------------------------- -Tests run: 6, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.077 s -- in com.dynapi.domain.validation.DynamicValidatorTest diff --git a/target/surefire-reports/com.dynapi.integration.FormControllerIntegrationTest.txt b/target/surefire-reports/com.dynapi.integration.FormControllerIntegrationTest.txt deleted file mode 100644 index b1308f0..0000000 --- a/target/surefire-reports/com.dynapi.integration.FormControllerIntegrationTest.txt +++ /dev/null @@ -1,4 +0,0 @@ -------------------------------------------------------------------------------- -Test set: com.dynapi.integration.FormControllerIntegrationTest -------------------------------------------------------------------------------- -Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.224 s -- in com.dynapi.integration.FormControllerIntegrationTest diff --git a/target/surefire-reports/com.dynapi.integration.QueryControllerIntegrationTest.txt b/target/surefire-reports/com.dynapi.integration.QueryControllerIntegrationTest.txt deleted file mode 100644 index fcb6d29..0000000 --- a/target/surefire-reports/com.dynapi.integration.QueryControllerIntegrationTest.txt +++ /dev/null @@ -1,4 +0,0 @@ -------------------------------------------------------------------------------- -Test set: com.dynapi.integration.QueryControllerIntegrationTest -------------------------------------------------------------------------------- -Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.599 s -- in com.dynapi.integration.QueryControllerIntegrationTest diff --git a/target/surefire-reports/com.dynapi.integration.SchemaAdminControllerSecurityIntegrationTest.txt b/target/surefire-reports/com.dynapi.integration.SchemaAdminControllerSecurityIntegrationTest.txt deleted file mode 100644 index 98d52e4..0000000 --- a/target/surefire-reports/com.dynapi.integration.SchemaAdminControllerSecurityIntegrationTest.txt +++ /dev/null @@ -1,4 +0,0 @@ -------------------------------------------------------------------------------- -Test set: com.dynapi.integration.SchemaAdminControllerSecurityIntegrationTest -------------------------------------------------------------------------------- -Tests run: 16, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.137 s -- in com.dynapi.integration.SchemaAdminControllerSecurityIntegrationTest diff --git a/target/test-classes/application-test.yml b/target/test-classes/application-test.yml deleted file mode 100644 index 3eb2fa2..0000000 --- a/target/test-classes/application-test.yml +++ /dev/null @@ -1,23 +0,0 @@ -spring: - data: - mongodb: - host: localhost - port: 27017 - database: dynapi-test - - kafka: - bootstrap-servers: localhost:9092 - producer: - key-serializer: org.apache.kafka.common.serialization.StringSerializer - value-serializer: org.springframework.kafka.support.serializer.JsonSerializer - - messages: - basename: messages - encoding: UTF-8 - -server: - port: 0 # Random port for testing - -security: - jwt: - secret: ZHluYXBpLWRldi1zZWNyZXQta2V5LWNoYW5nZS1tZS0xMjM0NTY3ODkw diff --git a/target/test-classes/com/dynapi/DynapiApplicationTests.class b/target/test-classes/com/dynapi/DynapiApplicationTests.class deleted file mode 100644 index f7fb091..0000000 Binary files a/target/test-classes/com/dynapi/DynapiApplicationTests.class and /dev/null differ diff --git a/target/test-classes/com/dynapi/domain/validation/DynamicValidatorTest.class b/target/test-classes/com/dynapi/domain/validation/DynamicValidatorTest.class deleted file mode 100644 index 711b8d7..0000000 Binary files a/target/test-classes/com/dynapi/domain/validation/DynamicValidatorTest.class and /dev/null differ diff --git a/target/test-classes/com/dynapi/integration/FormControllerIntegrationTest$FormControllerTestConfig.class b/target/test-classes/com/dynapi/integration/FormControllerIntegrationTest$FormControllerTestConfig.class deleted file mode 100644 index 290d20d..0000000 Binary files a/target/test-classes/com/dynapi/integration/FormControllerIntegrationTest$FormControllerTestConfig.class and /dev/null differ diff --git a/target/test-classes/com/dynapi/integration/FormControllerIntegrationTest.class b/target/test-classes/com/dynapi/integration/FormControllerIntegrationTest.class deleted file mode 100644 index 535670c..0000000 Binary files a/target/test-classes/com/dynapi/integration/FormControllerIntegrationTest.class and /dev/null differ diff --git a/target/test-classes/com/dynapi/integration/QueryControllerIntegrationTest$QueryControllerTestConfig.class b/target/test-classes/com/dynapi/integration/QueryControllerIntegrationTest$QueryControllerTestConfig.class deleted file mode 100644 index b1c489c..0000000 Binary files a/target/test-classes/com/dynapi/integration/QueryControllerIntegrationTest$QueryControllerTestConfig.class and /dev/null differ diff --git a/target/test-classes/com/dynapi/integration/QueryControllerIntegrationTest.class b/target/test-classes/com/dynapi/integration/QueryControllerIntegrationTest.class deleted file mode 100644 index 2b91bea..0000000 Binary files a/target/test-classes/com/dynapi/integration/QueryControllerIntegrationTest.class and /dev/null differ diff --git a/target/test-classes/com/dynapi/integration/SchemaAdminControllerSecurityIntegrationTest$SchemaAdminControllerTestConfig.class b/target/test-classes/com/dynapi/integration/SchemaAdminControllerSecurityIntegrationTest$SchemaAdminControllerTestConfig.class deleted file mode 100644 index 57d6140..0000000 Binary files a/target/test-classes/com/dynapi/integration/SchemaAdminControllerSecurityIntegrationTest$SchemaAdminControllerTestConfig.class and /dev/null differ diff --git a/target/test-classes/com/dynapi/integration/SchemaAdminControllerSecurityIntegrationTest.class b/target/test-classes/com/dynapi/integration/SchemaAdminControllerSecurityIntegrationTest.class deleted file mode 100644 index 0b854f6..0000000 Binary files a/target/test-classes/com/dynapi/integration/SchemaAdminControllerSecurityIntegrationTest.class and /dev/null differ