From 32ef84e187e08bc69c71556e3703e3695f8dd14f Mon Sep 17 00:00:00 2001 From: Daniele Sangalli <196739+daniel78uk@users.noreply.github.com> Date: Fri, 1 Dec 2023 13:35:37 +0000 Subject: [PATCH] feat: adding json schema validator service --- package-lock.json | 224 +++++--- package.json | 2 + server/services/json-schemas/README.md | 3 + .../sirp_json_schema_IF_v0.6.json | 445 ++++++++++++++++ .../sirp_json_schema_OD_v0.3.json | 496 +++++++++++++++++ .../sirp_json_schema_WQ_v0.3.json | 504 ++++++++++++++++++ server/services/schema-validator.service.js | 26 + .../services/schema-validator.service.spec.js | 52 ++ 8 files changed, 1691 insertions(+), 61 deletions(-) create mode 100644 server/services/json-schemas/README.md create mode 100644 server/services/json-schemas/sirp_json_schema_IF_v0.6.json create mode 100644 server/services/json-schemas/sirp_json_schema_OD_v0.3.json create mode 100644 server/services/json-schemas/sirp_json_schema_WQ_v0.3.json create mode 100644 server/services/schema-validator.service.js create mode 100644 tests/unit/services/schema-validator.service.spec.js diff --git a/package-lock.json b/package-lock.json index 6f5fb75c..20c0d98a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,8 @@ "@hapi/inert": "^6.0.5", "@hapi/vision": "^6.1.0", "@hapi/wreck": "^18.0.1", + "ajv": "^8.12.0", + "ajv-formats": "^2.1.1", "applicationinsights": "^2.2.2", "bcrypt": "^5.0.1", "blipp": "^4.0.2", @@ -1048,6 +1050,22 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/@eslint/eslintrc/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1066,6 +1084,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "peer": true + }, "node_modules/@eslint/js": { "version": "8.53.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.53.0.tgz", @@ -2416,13 +2440,13 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dependencies": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" }, "funding": { @@ -2430,6 +2454,22 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -4565,6 +4605,22 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/eslint/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -4611,6 +4667,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "peer": true + }, "node_modules/eslint/node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -7438,9 +7500,9 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -10064,7 +10126,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -10879,6 +10940,22 @@ "node": ">=0.4.0" } }, + "node_modules/standard/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/standard/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -11235,6 +11312,12 @@ "node": ">= 4" } }, + "node_modules/standard/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/standard/node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -11616,28 +11699,6 @@ "node": ">=10.0.0" } }, - "node_modules/table/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/tar": { "version": "6.1.11", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", @@ -13202,6 +13263,18 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "peer": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -13216,6 +13289,12 @@ "requires": { "argparse": "^2.0.1" } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "peer": true } } }, @@ -14387,16 +14466,24 @@ } }, "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "requires": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "requires": { + "ajv": "^8.0.0" + } + }, "ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -15785,6 +15872,18 @@ "text-table": "^0.2.0" }, "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "peer": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -15816,6 +15915,12 @@ "argparse": "^2.0.1" } }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "peer": true + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -18096,9 +18201,9 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -20008,8 +20113,7 @@ "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" }, "requires-port": { "version": "1.0.0", @@ -20601,6 +20705,18 @@ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -20850,6 +20966,12 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -21165,26 +21287,6 @@ "slice-ansi": "^4.0.0", "string-width": "^4.2.3", "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } } }, "tar": { diff --git a/package.json b/package.json index 5c223db3..4d3644e1 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,8 @@ "@hapi/inert": "^6.0.5", "@hapi/vision": "^6.1.0", "@hapi/wreck": "^18.0.1", + "ajv": "^8.12.0", + "ajv-formats": "^2.1.1", "applicationinsights": "^2.2.2", "bcrypt": "^5.0.1", "blipp": "^4.0.2", diff --git a/server/services/json-schemas/README.md b/server/services/json-schemas/README.md new file mode 100644 index 00000000..5e0ef664 --- /dev/null +++ b/server/services/json-schemas/README.md @@ -0,0 +1,3 @@ +# Validation schemas + +In this folder there are schemas used to do a JSON validation before they are sent to Azure service bus. \ No newline at end of file diff --git a/server/services/json-schemas/sirp_json_schema_IF_v0.6.json b/server/services/json-schemas/sirp_json_schema_IF_v0.6.json new file mode 100644 index 00000000..4614a6a0 --- /dev/null +++ b/server/services/json-schemas/sirp_json_schema_IF_v0.6.json @@ -0,0 +1,445 @@ +{ + "$id": "http://example.com/example.json", + "type": "object", + "default": {}, + "title": "Illegal Fishing", + "required": [ + "sirp_incident" + ], + "properties": { + "sirp_incident": { + "type": "object", + "default": {}, + "title": "sirp_incident", + "required": [ + "sirp_incidentid" + ,"sirp_incidentreporttype", "sirp_observeddatetime" + , "sirp_reporteddatetime", "sirp_incidentlocation", "sirp_reporterdetails" + ], + "properties": { + "sirp_incidentid": { + "type": "string", + "format": "uuid", + "default": "", + "title": "sirp_incidentid", + "examples": [ + "9151f21f-43ae-43b4-92f3-f4af67cdf544" + ] + }, + "properties": { + "sirp_incidentreporttype": { + "type": "integer", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, 200, 300, 400 + ], + "meta:enum": { + "100": "Odour", + "200": "Illegal Fishing", + "300": "Water Pollution", + "400": "Flooding" + } + } + }, + "sirp_ObservedDateTime": { + "type": "string", + "format": "date-time", + "default": "", + "title": "sirp_observeddatetime", + "examples": [ + "2023-06-26 23:00:00.0000000" + ] + }, + "sirp_reportedDateTime": { + "type": "string", + "format": "date-time", + "default": "", + "title": "sirp_reportedDateTime", + "examples": [ + "2023-06-27 23:00:00.0000000" + ] + }, + "sirp_illegalfishing": { + "type": "object", + "default": {}, + "title": "sirp_illegalfishing", + "required":["sirp_equipmentillegalfishing", "sirp_howmanyillegalfish" + ,"sirp_peopleillegalfishing","sirp_takenillegalfish","sirp_typeillegalfish" + ,"sirp_whyillegalfishing", "sirp_aretherepeoplefishingstillthere"], + "properties": { + "sirp_equipmentillegalfishing": { + "type": "array", + "description": "Are they using any of the following equipment?", + "uniqueItems": true, + "minItems": 1, + "maxItems": 10, + "items": { + "type": "integer", + "enum": [ + 100, 200, 300, 400, 500 + ], + "meta:enum": { + "100": "Nets", + "200": "Illegal rod or tackle", + "300": "Explosives", + "400": "Spears, crossbows or firearms", + "500": "Poison or Chemicals", + "600": "Electric Stun Devices", + "700": "Something else", + "800": "You don't know" + } + } + }, + "sirp_equipmentillegalfishingother": { + "type": "string", + "description": "(If other else) Please provide a description for the other equipment used", + "default": "", + "title": "sirp_reporteddatetime" + }, + "sirp_howmanyillegalfish": { + "type": "integer", + "title": "sirp_howmanyillegalfish", + "description": "How many fish have you seen being caught or killed?", + "uniqueItems": true, + "minItems": 1, + "maxItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, 200, 300 + ], + "meta:enum": { + "100": "5 or more", + "200": "less than 5", + "300": "You don't know" + } + } + }, + "sirp_peopleillegalfishing": { + "type": "boolean", + "default": "", + "description": "Are there more than 2 people involved?", + "title": "sirp_peopleillegalfishing", + "examples": [ + true, false + ] + }, + "sirp_takenillegalfish": { + "type": "boolean", + "description": "Have you actually seen fish being taken?", + "default": "", + "title": "sirp_takenillegalfish", + "examples": [ + true, false + ] + }, + "sirp_typeillegalfish": { + "type": "array", + "description": "Are they catching any of these types of fish?", + "title": "sirp_typeillegalfish", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, 200, 300, 400, 500, 600 + ], + "meta:enum": { + "100": "Salmon", + "200": "Lamprey eel", + "300": "Sea Trout", + "400": "Coarse fish", + "500": "Other type of fish", + "600": "You don't know" + } + } + }, + "sirp_registrationIllegalFishingDescription": { + "type": "string", + "default": "", + "description": "Registration Illegal Fishing Description", + "title": "sirp_registrationIllegalFishingDescription" + }, + "sirp_typeillegalfishother": { + "type": "string", + "default": "", + "description": "(If other else) Please provide a description for the other illegal fish", + "title": "sirp_typeillegalfishother", + "examples": [ + "" + ] + }, + "sirp_whyillegalfishing": { + "type": "array", + "description": "Why do you think the fishing is illegal?", + "title": "sirp_whyillegalfishing", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, 200, 300, 400, 500 + ], + "meta:enum": { + "100": "Fishing is not allowed here", + "200": "The type of equipment being used", + "300": "Fishing without a licence", + "400": "The type of fish being taken", + "500": "Causing damage or destruction to fish habitats", + "600": "Another reason" + } + } + }, + + "sirp_aretherepeoplefishingstillthere": { + "type": "integer", + "description": "Are there people fishing still there?", + "title": "sirp_aretherepeoplefishingstillthere", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, 200, 300 + ], + "meta:enum": { + "100": "Yes", + "200": "No", + "300": "Dont Know" + } + } + }, + "sirp_whyillegalfishingother": { + "type": "string", + "description": "(If other else) Please provide a description for why illegal fishing is not allowed here", + "default": "", + "title": "sirp_whyillegalfishingother", + "examples": [ + "" + ] + } + } + }, + "sirp_incidentlocation": { + "type": "object", + "default": {}, + "title": "sirp_incidentlocation", + "properties": { + "sirp_bng": { + "type": "string", + "default": "", + "title": "sirp_bng", + "examples": [ + "" + ] + }, + "sirp_eaarea": { + "type": "string", + "default": "", + "title": "sirp_eaarea", + "examples": [ + "" + ] + }, + "sirp_eaoffice": { + "type": "string", + "default": "", + "title": "sirp_eaoffice", + "examples": [ + "" + ] + }, + "sirp_x": { + "type": "number", + "default": "", + "title": "sirp_x" + + }, + "sirp_y": { + "type": "number", + "default": "", + "title": "sirp_y", + "examples": [ + "" + ] + }, + "sirp_address": { + "type": "object", + "default": {}, + "title": "sirp_address", + "properties": { + "sirp_addressline1": { + "type": "string", + "description":"location address line", + "default": "", + "title": "sirp_addressline1", + "examples": [ + "" + ] + }, + "sirp_addressline2": { + "type": "string", + "description":"location addressline2", + "default": "", + "title": "sirp_addressline2", + "examples": [ + "" + ] + }, + "sirp_town": { + "type": "string", + "default": "", + "description":"location town", + "title": "sirp_town", + "examples": [ + "" + ] + }, + "sirp_postcode": { + "type": "string", + "default": "", + "description":"location postcode", + "title": "sirp_postcode", + "examples": [ + "" + ] + } + } + } + } + }, + "sirp_reporterdetails": { + "type": "object", + "default": {}, + "title": "sirp_reporterdetails", + "properties": { + "sirp_consent": { + "type": "boolean", + "description": "Confirm that the reporter is happy for all information they have submitted as part of this report to be used in analysis and reporting for incident response (including photos, videos & supporting documentation ", + "default": "", + "title": "sirp_consent", + "examples": [ + true, false + ] + }, + "sirp_contactable": { + "type": "boolean", + "description": "contactable - Does the reportee wish to be contact by the duty officer", + "default": "", + "title": "sirp_contactable", + "examples": [ + true, false + ] + }, + "sirp_email": { + "type": "string", + "default": "", + "description": "Reporters email address", + "format": "email", + "title": "sirp_email", + "examples": [ + "me@bt.com" + ] + }, + "sirp_feedback": { + "type": "boolean", + "description": "feedback - Would the reporter like to receive any updates on the incident they have reported", + "default": "", + "title": "sirp_feedback", + "examples": [ + true, false + ] + }, + "sirp_homephonenumber": { + "type": "string", + "description":"home number", + "minLength": 10, + "maxLength": 20, + "title": "sirp_homephonenumber" + }, + "sirp_mobilephonenumber": { + "type": "string", + "description":"mobile number", + "minLength": 10, + "maxLength": 20, + "title": "sirp_mobilephonenumber" + }, + "sirp_previouslyreported": { + "type": "boolean", + "description": "Has the reporter previosuly used this digital form to report envrionmental incidents to the EA", + "default": "", + "title": "sirp_previouslyreported", + "examples": [ + true, false + ] + }, + "sirp_reportername": { + "type": "string", + "description": "Name of reporter", + "default": "", + "title": "sirp_reportername", + "examples": [ + "Mark Buttle" + ] + }, + "sirp_address": { + "type": "object", + "default": {}, + "title": "sirp_address", + "properties": { + "sirp_addressline1": { + "type": "string", + "default": "", + "description":"reporter addressline1", + "title": "sirp_addressline1", + "examples": [ + "" + ] + }, + "sirp_addressline2": { + "type": "string", + "description":"reporter addressline2", + "default": "", + "title": "sirp_addressline2", + "examples": [ + "" + ] + }, + "sirp_town": { + "type": "string", + "default": "", + "title": "sirp_town", + "description":"reporter town", + "examples": [ + "" + ] + }, + "sirp_postcode": { + "type": "string", + "default": "", + "description":"reporter postcode", + "title": "sirp_postcode", + "examples": [ + "" + ], + "sirp_Canyougiveusanyotherinformation": { + "type": "string", + "description": "If there is further information about the incident they would like to add, add it here", + "default": "", + "title": "sirp_Canyougiveusanyotherinformation", + "examples": [ + "" + ] + } + } + } + } + } + } + } + } + } +}} \ No newline at end of file diff --git a/server/services/json-schemas/sirp_json_schema_OD_v0.3.json b/server/services/json-schemas/sirp_json_schema_OD_v0.3.json new file mode 100644 index 00000000..5c25e93a --- /dev/null +++ b/server/services/json-schemas/sirp_json_schema_OD_v0.3.json @@ -0,0 +1,496 @@ +{ + "$id": "http://example.com/example.json", + "type": "object", + "default": {}, + "title": "Odour", + "required": [ + "sirp_incident" + ], + "properties": { + "sirp_incident": { + "type": "object", + "default": {}, + "title": "sirp_incident", + "required": [ + "sirp_incidentid", + "sirp_incidentreporttype", + "sirp_observeddatetime", + "sirp_reporteddatetime" + ], + "properties": { + "sirp_incidentid": { + "type": "string", + "format": "uuid", + "default": "", + "title": "sirp_incidentid", + "examples": [ + "9151f21f-43ae-43b4-92f3-f4af67cdf544" + ] + }, + "properties": { + "sirp_incidentreporttype": { + "type": "array", + "description": "Incident Type", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, + 200, + 300, + 400 + ], + "meta:enum": { + "100": "Odour", + "200": "Illegal Fishing", + "300": "Water Pollution", + "400": "Flooding" + } + } + } + }, + "sirp_observeddatetime": { + "type": "string", + "format": "date-time", + "default": "", + "title": "sirp_observeddatetime", + "examples": [ + "2023-07-17T13:59:15" + ] + }, + "sirp_reporteddatetime": { + "type": "string", + "format": "date-time", + "default": "", + "title": "sirp_reporteddatetime", + "examples": [ + "2023-07-17T13:59:15" + ] + }, + "sirp_Odour": { + "type": "object", + "default": {}, + "title": "sirp_Odour", + "properties": { + "sirp_haveyounoticedthesamesmellbefore": { + "type": "array", + "title": "sirp_haveyounoticedthesamesmellbefore", + "description": "Have you noticed the smell this smell before", + "uniqueItems": true, + "minItems": 1, + "maxItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, + 200, + 300 + ], + "meta:enum": { + "100": "Yes, it happens regularly", + "200": "Yes, a few times", + "300": "No, this is the first time" + } + } + }, + "sirp_doyouknowwherethesmelliscomingfrom": { + "type": "boolean", + "description": "Do you know where the smell is coming from", + "default": "", + "title": "sirp_doyouknowwherethesmelliscomingfrom", + "examples": [ + true, + false + ] + }, + "sirp_odourSourceOther": { + "type": "string", + "description": "A description field for when do you know where the smell is coming from?", + "default": "", + "title": "sirp_odourSourceOther", + "examples": [ + "Waste Site which is located down the street" + ] + }, + "sirp_Canyourecognisethesmellonthingslikeyourcl": { + "type": "array", + "description": "Can you smell things on your clothes or hair", + "title": "sirp_Canyourecognisethesmellonthingslikeyourcl", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, + 200, + 300 + ], + "meta:enum": { + "100": "Yes", + "200": "No", + "300": "Dont Know" + } + } + }, + "sirp_Isthesmellstilltherenow": { + "type": "boolean", + "description": "Is the smell stil present", + "default": "", + "title": "sirp_Isthesmellstilltherenow", + "examples": [ + true, + false + ] + }, + "sirp_Hasthesmellstoppedyoufromdoinganyofthefo": { + "type": "array", + "description": "Has the smell stopped any of the following activities", + "title": "sirp_Hasthesmellstoppedyoufromdoinganyofthefo", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, + 200, + 300, + 400, + 500 + ], + "meta:enum": { + "100": "Using parts of your own property, for example sitting in your garden", + "200": "Doing jobs outside, for example hanging washing out or gardening", + "300": "Going to certain places, for example going to the shops", + "400": "Something else", + "500": "None of these" + } + } + }, + "sirp_OdourStoppedActivityOther": { + "type": "string", + "default": "", + "description": "Please provide a description of which activities you can no longer do", + "title": "sirp_OdourStoppedActivity", + "examples": [ + "" + ] + }, + "sirp_hasthesmellcausedanyofthefollowingsymptoms": { + "type": "array", + "default": {}, + "title": "sirp_hasthesmellcausedanyofthefollowingsymptoms", + "description": "Has the smell caused any of the following symptoms?", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, + 200, + 300, + 400, + 500, + 600 + ], + "meta:enum": { + "100": "Headache", + "200": "Watering eyes", + "300": "Sickness or nausea", + "400": "Vomiting", + "500": "Something else", + "600": "None of these" + } + } + }, + "sirp_odourSymptomsOther": { + "type": "string", + "description": "Please provide a description of the symptoms you have", + "default": "", + "title": "sirp_odourSymptomsOther" + }, + "sirp_hownoticeableisthesmellwhenitsthere": { + "type": "array", + "description": "How noticeable is the smell when it's there?", + "title": "sirp_hownoticeableisthesmellwhenitsthere", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, + 200, + 300, + 400, + 500 + ], + "meta:enum": { + "100": "You can smell it all the time when breathing normally", + "200": "You notice it if you breathe in deeply", + "300": "It is quite faint", + "400": "It is very faint, you can only notice it if you try", + "500": "You cannot remember" + } + } + }, + "sirp_hasthesmellmeantyouhavehadtodoanyofthe": { + "type": "array", + "description": "Has the smell meant you have had to do the following?", + "title": "sirp_hasthesmellmeantyouhavehadtodoanyofthe", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, + 200, + 300, + 400, + 500, + 600 + ], + "meta:enum": { + "100": "Cover your face or nose", + "200": "Keep windows and doors closed", + "300": "Leave the area of the smell", + "400": "Leave your home", + "500": "Something else", + "600": "None of these" + } + } + }, + "sirp_odouractionother": { + "type": "string", + "description": "Please provide a description of measures you have had to take", + "default": "", + "title": "sirp_odouractionother", + "examples": [] + } + } + }, + "sirp_incidentlocation": { + "type": "object", + "default": {}, + "title": "sirp_incidentlocation", + "properties": { + "sirp_bng": { + "type": "string", + "default": "", + "title": "sirp_bng", + "examples": [ + "" + ] + }, + "sirp_eaarea": { + "type": "string", + "default": "", + "title": "sirp_eaarea", + "examples": [ + "" + ] + }, + "sirp_eaoffice": { + "type": "string", + "default": "", + "title": "sirp_eaoffice", + "examples": [ + "" + ] + }, + "sirp_x": { + "type": "string", + "default": "", + "title": "sirp_x", + "examples": [ + "" + ] + }, + "sirp_y": { + "type": "string", + "default": "", + "title": "sirp_y", + "examples": [ + "" + ] + }, + "sirp_address": { + "type": "object", + "default": {}, + "title": "sirp_address", + "properties": { + "sirp_addressline1": { + "type": "string", + "description": "Address line 1", + "default": "", + "title": "sirp_addressline1", + "examples": [ + "" + ] + }, + "sirp_addressline2": { + "type": "string", + "description": "Address line 2", + "default": "", + "title": "sirp_addressline2", + "examples": [ + "" + ] + }, + "sirp_town": { + "type": "string", + "description": "Town/City", + "default": "", + "title": "sirp_town", + "examples": [ + "" + ] + }, + "sirp_postcode": { + "type": "string", + "description": "Postcode", + "default": "", + "title": "sirp_postcode", + "examples": [ + "" + ] + }, + "sirp_reporterdetails": { + "type": "object", + "default": {}, + "title": "sirp_reporterdetails", + "properties": { + "sirp_consent": { + "type": "boolean", + "description": "Confirm that the reporter is happy for all information they have submitted as part of this report to be used in analysis and reporting for incident response (including photos, videos & supporting documentation ", + "default": "", + "title": "sirp_consent", + "examples": [ + true, + false + ] + }, + "sirp_contactable": { + "type": "boolean", + "description": "Does the reportee wish to be contact by the duty officer", + "default": "", + "title": "sirp_contactable", + "examples": [ + true, + false + ] + }, + "sirp_email": { + "type": "string", + "default": "", + "description": "Reporters email address", + "format": "email", + "title": "sirp_email", + "examples": [ + "me@bt.com" + ] + }, + "sirp_feedback": { + "type": "boolean", + "description": "Would the reporter like to receive any updates on the incident they have reported", + "default": "", + "title": "sirp_feedback", + "examples": [ + true, + false + ] + }, + "sirp_homephonenumber": { + "type": [ + "string", + "null" + ], + "minLength": 10, + "maxLength": 20, + "title": "The sirp_homephonenumber Schema" + }, + "sirp_mobilephonenumber": { + "type": [ + "string", + "null" + ], + "minLength": 10, + "maxLength": 20, + "title": "The sirp_mobilephonenumber Schema" + }, + "sirp_previouslyreported": { + "type": "boolean", + "description": "Has the reporter previosuly used this digital form to report envrionmental incidents to the EA", + "default": "", + "title": "The sirp_previouslyreported Schema", + "examples": [ + true, + false + ] + }, + "sirp_reportername": { + "type": "string", + "description": "Name of reporter", + "default": "", + "title": "sirp_reportername", + "examples": [ + "Mark Buttle" + ] + }, + "sirp_address": { + "type": "object", + "default": {}, + "title": "The sirp_address Schema", + "properties": { + "sirp_addressline1": { + "type": "string", + "default": "", + "title": "sirp_addressline1", + "examples": [ + "" + ] + }, + "sirp_addressline2": { + "type": "string", + "default": "", + "title": "sirp_addressline2", + "examples": [ + "" + ] + }, + "sirp_town": { + "type": "string", + "default": "", + "title": "sirp_town", + "examples": [ + "" + ] + }, + "sirp_postcode": { + "type": "string", + "default": "", + "title": "sirp_postcode", + "examples": [ + "" + ], + "sirp_Canyougiveusanyotherinformation": { + "type": "string", + "description": "If there is further information about the incident they would like to add, add it here", + "default": "", + "title": "sirp_Canyougiveusanyotherinformation", + "examples": [ + "" + ] + } + } + } + } + } + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/server/services/json-schemas/sirp_json_schema_WQ_v0.3.json b/server/services/json-schemas/sirp_json_schema_WQ_v0.3.json new file mode 100644 index 00000000..e7e63284 --- /dev/null +++ b/server/services/json-schemas/sirp_json_schema_WQ_v0.3.json @@ -0,0 +1,504 @@ +{ + "$id": "http://example.com/example.json", + "type": "object", + "default": {}, + "title": "Water Pollution", + "required": [ + "sirp_incident" + ], + "properties": { + "sirp_incident": { + "type": "object", + "default": {}, + "title": "sirp_incident", + "required": [ + "sirp_incidentid", + "sirp_incidentreporttype", + "sirp_observeddatetime", + "sirp_reporteddatetime" + ], + "properties": { + "sirp_incidentid": { + "type": "string", + "format": "uuid", + "default": "", + "title": "sirp_incidentid", + "examples": [ + "9151f21f-43ae-43b4-92f3-f4af67cdf544" + ] + }, + "properties": { + "sirp_incidentreporttype": { + "type": "integer", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, + 200, + 300, + 400 + ], + "meta:enum": { + "100": "Odour", + "200": "Illegal Fishing", + "300": "Water Pollution", + "400": "Flooding" + } + } + } + }, + "sirp_observeddatetime": { + "type": "string", + "format": "date-time", + "default": "", + "title": "sirp_observeddatetime", + "examples": [ + "2023-07-17T13:59:15" + ] + }, + "sirpreporteddatetime": { + "type": "string", + "format": "date-time", + "default": "", + "title": "sirp_reporteddatetime", + "examples": [ + "2023-07-17T13:59:15" + ] + }, + "sirp_waterquality": { + "type": "object", + "default": {}, + "title": "sirp_waterquality", + "required": [ + "WWhatcanyouseeinoronthewater", + "Inwhatkindofwaterfeaturehaveyouseenpollut", + "Howfaracrossthewaterfeaturecanyouseethe", + "Howfaralongthewaterfeaturedoesthepollutio", + "Doyouthinkyouknowwherethepollutioniscomin", + "Haveyouseendeadfishnearby" + ], + "properties": { + "sirp_Whatcanyouseeinoronthewater": { + "type": "array", + "description": "What can you see on the water?", + "uniqueItems": true, + "minItems": 1, + "maxItems": 10, + "items": { + "type": "integer", + "enum": [ + 100, + 200, + 300, + 400, + 500, + 600, + 700 + ], + "meta:enum": { + "100": "Cloudy or grey water", + "200": "A 'rainbow' film", + "300": "White or brown streaks", + "400": "A foam or scum on top", + "500": "Slime around plants or stones (either under water or along the banks)", + "600": "Recognisable waste or objects, for example toilet paper or containers", + "700": "Something else" + } + } + }, + "sirp_onWaterOther": { + "type": "string", + "description": "On Water Pollution Description", + "default": "", + "title": "sirp_onWaterOther" + }, + "sirp_Inwhatkindofwaterfeaturehaveyouseenpollut": { + "type": "integer", + "title": "sirp_Inwhatkindofwaterfeaturehaveyouseenpollut", + "description": "Describe the water feature", + "uniqueItems": true, + "minItems": 1, + "maxItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, + 200, + 300, + 400, + 500, + 600 + ], + "meta:enum": { + "100": "A River", + "200": "A lake or reservoir", + "300": "The Sea", + "400": "A smaller stream or watercourse", + "500": "Something else ", + "600": "You do not know" + } + } + }, + "sirp_waterFeatureOther": { + "type": "string", + "description": "Description field for water feature", + "default": "", + "title": "sirp_waterFeatureOther" + }, + "sirp_Whatdoyouthinkisinthewater": { + "type": "integer", + "title": "sirp_Whatdoyouthinkisinthewater", + "description": "What is in the water", + "uniqueItems": true, + "minItems": 1, + "maxItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, + 200, + 300, + 400, + 500, + 600 + ], + "meta:enum": { + "100": "Sewage", + "200": "Oil or petrol", + "300": "Agricultural waste, for example from muck spreading", + "400": "Rubbish or refuse", + "500": "Another substance", + "600": "Your're not sure" + } + } + }, + "sirp_inWaterOther": { + "type": "string", + "description": "in Water Description", + "default": "", + "title": "sirp_inWaterOther" + }, + "sirp_Doyouthinkyouknowwherethepollutioniscomin": { + "type": "boolean", + "default": "", + "description": "Do you know where the source of the pollution is?", + "title": "sirp_Doyouthinkyouknowwherethepollutioniscomin", + "examples": [ + true, + false + ] + }, + "sirp_pollutionSourceOther": { + "type": "string", + "description": "Pollution Source Description", + "default": "", + "title": "sirp_pollutionSourceOther" + }, + "sirp_Howfaracrossthewaterfeaturecanyouseethe": { + "type": "array", + "description": "How far across the water feature can you see pollution?", + "title": "sirp_Howfaracrossthewaterfeaturecanyouseethe", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, + 200, + 300, + 400, + 500, + 600 + ], + "meta:enum": { + "100": "Covers it fully (touching both sides)", + "200": "Half of the width or more", + "300": "Less than half the width", + "400": "It's only along one side", + "500": "You're not sure" + } + } + }, + "sirp_Howfaralongthewaterfeaturedoesthepollutio": { + "type": "array", + "description": "How far along the water feature can you see pollution?", + "title": "sirp_Howfaralongthewaterfeaturedoesthepollutio", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, + 200, + 300, + 400, + 500 + ], + "meta:enum": { + "100": "Less than 50 meters", + "200": "50 - 500 metres", + "300": "500 metres - 1 kilometre", + "400": "Greater than 1 kilometre", + "500": "You're not sure" + } + } + }, + "sirp_Howmanydeadfishhaveyouseen": { + "type": "integer", + "description": "How many dead fish are visible", + "title": "sirp_Howmanydeadfishhaveyouseen", + "uniqueItems": true, + "minItems": 1, + "items": { + "type": "integer", + "enum": [ + 100, + 200, + 300, + 400 + ], + "meta:enum": { + "100": "At least 20 or more", + "200": "At least 10 but not as many as 20", + "300": "Less than 10", + "400": "You're not sure" + } + } + }, + "sirp_Haveyouseendeadfishnearby": { + "type": "boolean", + "default": "", + "description": "Have you seen any dead fish nearby", + "title": "sirp_Haveyouseendeadfishnearby", + "examples": [ + true, + false + ] + } + } + }, + "sirp_incidentlocation": { + "type": "object", + "default": {}, + "title": "sirp_incidentlocation", + "properties": { + "sirp_bng": { + "type": "string", + "default": "", + "title": "sirp_bng", + "examples": [ + "" + ] + }, + "sirp_eaarea": { + "type": "string", + "default": "", + "title": "sirp_eaarea", + "examples": [ + "" + ] + }, + "sirp_eaoffice": { + "type": "string", + "default": "", + "title": "sirp_eaoffice", + "examples": [ + "" + ] + }, + "sirp_x": { + "type": "number", + "default": "", + "title": "sirp_x" + }, + "sirp_y": { + "type": "number", + "default": "", + "title": "sirp_y", + "examples": [ + "" + ] + }, + "sirp_address": { + "type": "object", + "default": {}, + "title": "sirp_address", + "properties": { + "sirp_addressline1": { + "type": "string", + "description": "location address line", + "default": "", + "title": "sirp_addressline1", + "examples": [ + "" + ] + }, + "sirp_addressline2": { + "type": "string", + "description": "location addressline2", + "default": "", + "title": "sirp_addressline2", + "examples": [ + "" + ] + }, + "sirp_town": { + "type": "string", + "default": "", + "description": "location town", + "title": "sirp_town", + "examples": [ + "" + ] + }, + "sirp_postcode": { + "type": "string", + "default": "", + "description": "location postcode", + "title": "sirp_postcode", + "examples": [ + "" + ] + } + } + } + } + }, + "sirp_reporterdetails": { + "type": "object", + "default": {}, + "title": "sirp_reporterdetails", + "properties": { + "sirp_consent": { + "type": "boolean", + "description": "Confirm that the reporter is happy for all information they have submitted as part of this report to be used in analysis and reporting for incident response (including photos, videos & supporting documentation ", + "default": "", + "title": "sirp_consent", + "examples": [ + true, + false + ] + }, + "sirp_contactable": { + "type": "boolean", + "description": "contactable - Does the reportee wish to be contact by the duty officer", + "default": "", + "title": "sirp_contactable", + "examples": [ + true, + false + ] + }, + "sirp_email": { + "type": "string", + "default": "", + "description": "Reporters email address", + "format": "email", + "title": "sirp_email", + "examples": [ + "me@bt.com" + ] + }, + "sirp_feedback": { + "type": "boolean", + "description": "feedback - Would the reporter like to receive any updates on the incident they have reported", + "default": "", + "title": "sirp_feedback", + "examples": [ + true, + false + ] + }, + "sirp_homephonenumber": { + "type": "string", + "description": "home number", + "minLength": 10, + "maxLength": 20, + "title": "sirp_homephonenumber" + }, + "sirp_mobilephonenumber": { + "type": "string", + "description": "mobile number", + "minLength": 10, + "maxLength": 20, + "title": "sirp_mobilephonenumber" + }, + "sirp_previouslyreported": { + "type": "boolean", + "description": "Has the reporter previosuly used this digital form to report envrionmental incidents to the EA", + "default": "", + "title": "sirp_previouslyreported", + "examples": [ + true, + false + ] + }, + "sirp_reportername": { + "type": "string", + "description": "Name of reporter", + "default": "", + "title": "sirp_reportername", + "examples": [ + "Mark Buttle" + ] + }, + "sirp_address": { + "type": "object", + "default": {}, + "title": "sirp_address", + "properties": { + "sirp_addressline1": { + "type": "string", + "default": "", + "description": "reporter addressline1", + "title": "sirp_addressline1", + "examples": [ + "" + ] + } + }, + "sirp_addressline2": { + "type": "string", + "description": "reporter addressline2", + "default": "", + "title": "sirp_addressline2", + "examples": [ + "" + ] + }, + "sirp_town": { + "type": "string", + "default": "", + "title": "sirp_town", + "description": "reporter town", + "examples": [ + "" + ] + }, + "sirp_postcode": { + "type": "string", + "default": "", + "description": "reporter postcode", + "title": "sirp_postcode", + "examples": [ + "" + ], + "sirp_Canyougiveusanyotherinformation": { + "type": "string", + "description": "If there is further information about the incident they would like to add, add it here", + "default": "", + "title": "sirp_Canyougiveusanyotherinformation", + "examples": [ + "" + ] + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/server/services/schema-validator.service.js b/server/services/schema-validator.service.js new file mode 100644 index 00000000..6f0fb6c7 --- /dev/null +++ b/server/services/schema-validator.service.js @@ -0,0 +1,26 @@ +const Ajv = require('ajv') +const addFormats = require("ajv-formats") + +const validateDataAgainstSchema = (data, schema,meta) => { + const ajv = new Ajv({ strict: false }) + addFormats(ajv) + + + // Compile the schema + const validate = ajv.compile(schema) + + // Perform validation + const valid = validate(data) + + if (!valid) { + // Log validation errors if validation fails + console.error('Validation errors:', validate.errors) + } + + return valid + +} + +module.exports = { + validateDataAgainstSchema +} diff --git a/tests/unit/services/schema-validator.service.spec.js b/tests/unit/services/schema-validator.service.spec.js new file mode 100644 index 00000000..6d902d49 --- /dev/null +++ b/tests/unit/services/schema-validator.service.spec.js @@ -0,0 +1,52 @@ +const { + validateDataAgainstSchema +} = require('../../../server/services/schema-validator.service.js') + +const wqJsonSchema = require('../../../server/services/json-schemas/sirp_json_schema_WQ_v0.3.json') +const wqSampleResponse = require('../../samples/sample_water_quality_incident.json') + +describe('validateDataAgainstSchema function', () => { + it('should validate correctly against a valid schema', () => { + const schema = { + type: 'object', + properties: { + name: { type: 'string' }, + age: { type: 'number' } + }, + required: ['name', 'age'] + } + + const data = { + name: 'John', + age: 30 + } + + const results = validateDataAgainstSchema(data, schema) + + expect(results).toBe(true) + }) + + it('should return false and log errors for invalid data against schema', () => { + const schema = { + type: 'object', + properties: { + email: { type: 'string', format: 'email' } + }, + required: ['email'] + } + + const data = { + email: 'notAnEmail' + } + + const results = validateDataAgainstSchema(data, schema) + + expect(results).toBe(false) + }) + + it('should compile and validate sample against a given schema', () => { + const results = validateDataAgainstSchema(wqSampleResponse,wqJsonSchema) + + expect(results).toBe(true) + }) +})