From 48838e4bff909d46198ce6cd81009ed8c16ae728 Mon Sep 17 00:00:00 2001 From: Kuan Fan Date: Tue, 30 Jul 2024 16:35:30 -0700 Subject: [PATCH 01/14] add prettier --- .github/workflows/prettier-test.yaml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/prettier-test.yaml diff --git a/.github/workflows/prettier-test.yaml b/.github/workflows/prettier-test.yaml new file mode 100644 index 00000000..babac64e --- /dev/null +++ b/.github/workflows/prettier-test.yaml @@ -0,0 +1,25 @@ +name: CTHUB prettier test + +on: + push: + branches: [ prettier-0.3.0 ] + workflow_dispatch: + +jobs: + + test-prettier: + + name: prettier + runs-on: ubuntu-latest + + steps: + + - name: Check out repository + uses: actions/checkout@v4.1.1 + with: + ref: ${{ github.head_ref }} + + - name: Prettify code + uses: creyD/prettier_action@v4.3 + with: + prettier_options: --write **/*.{js,md,py} \ No newline at end of file From 272dd7bac8d256b55f2a2469666c9df3aa444db9 Mon Sep 17 00:00:00 2001 From: Kuan Fan Date: Wed, 31 Jul 2024 11:54:45 -0700 Subject: [PATCH 02/14] test yarn --- .github/workflows/prettier-test.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/prettier-test.yaml b/.github/workflows/prettier-test.yaml index babac64e..a71552ee 100644 --- a/.github/workflows/prettier-test.yaml +++ b/.github/workflows/prettier-test.yaml @@ -19,6 +19,10 @@ jobs: with: ref: ${{ github.head_ref }} + - name: Test yarn + run: | + yarn --version + - name: Prettify code uses: creyD/prettier_action@v4.3 with: From 52d9ca951a99b2e824273ebafa78acb88df50cc5 Mon Sep 17 00:00:00 2001 From: Kuan Fan Date: Wed, 31 Jul 2024 12:01:12 -0700 Subject: [PATCH 03/14] yarn add py plugin --- .github/workflows/prettier-test.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/prettier-test.yaml b/.github/workflows/prettier-test.yaml index a71552ee..6b5d5ca8 100644 --- a/.github/workflows/prettier-test.yaml +++ b/.github/workflows/prettier-test.yaml @@ -22,6 +22,7 @@ jobs: - name: Test yarn run: | yarn --version + yarn add --exact prettier @prettier/plugin-python - name: Prettify code uses: creyD/prettier_action@v4.3 From f4929d88a9ae9c7e1342fb1bd9e20bd5b3a1e8d9 Mon Sep 17 00:00:00 2001 From: Kuan Fan Date: Wed, 31 Jul 2024 12:09:21 -0700 Subject: [PATCH 04/14] user action-py-black-formatter --- .github/workflows/prettier-test.yaml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/prettier-test.yaml b/.github/workflows/prettier-test.yaml index 6b5d5ca8..01042b8e 100644 --- a/.github/workflows/prettier-test.yaml +++ b/.github/workflows/prettier-test.yaml @@ -19,12 +19,14 @@ jobs: with: ref: ${{ github.head_ref }} - - name: Test yarn - run: | - yarn --version - yarn add --exact prettier @prettier/plugin-python - - name: Prettify code uses: creyD/prettier_action@v4.3 with: - prettier_options: --write **/*.{js,md,py} \ No newline at end of file + prettier_options: --write **/*.{js,md} + + + - name: Run python black code formatter + uses: DataDog/action-py-black-formatter@v2.5 + with: + check_mode: "true" + \ No newline at end of file From d8820d7ce751b7047d419b3f375d57223e1f8160 Mon Sep 17 00:00:00 2001 From: kuanfandevops Date: Wed, 31 Jul 2024 19:10:00 +0000 Subject: [PATCH 05/14] Prettified Code! --- .github/ISSUE_TEMPLATE/bug.md | 6 +- .github/ISSUE_TEMPLATE/spike.md | 15 +- .github/ISSUE_TEMPLATE/task.md | 7 +- .github/ISSUE_TEMPLATE/user-story.md | 7 +- .pipeline/build-metabase.js | 8 +- .pipeline/build-patroni.js | 8 +- .pipeline/build.js | 8 +- .pipeline/clean-tools.js | 8 +- .pipeline/clean.js | 8 +- .pipeline/deploy-knp.js | 8 +- .pipeline/deploy-metabase.js | 8 +- .pipeline/deploy-patroni.js | 8 +- .pipeline/deploy-unittest.js | 8 +- .pipeline/deploy.js | 8 +- .pipeline/lib/build-metabase.js | 17 +- .pipeline/lib/build-patroni.js | 17 +- .pipeline/lib/build.js | 56 ++-- .pipeline/lib/clean-tools.js | 14 +- .pipeline/lib/clean.js | 77 +++--- .pipeline/lib/config.js | 259 ++++++++++++++---- .pipeline/lib/deploy-knp.js | 47 ++-- .pipeline/lib/deploy-metabase.js | 55 ++-- .pipeline/lib/deploy-patroni.js | 72 +++-- .pipeline/lib/deploy-unittest.js | 105 ++++--- .pipeline/lib/deploy.js | 102 ++++--- .pipeline/lib/keycloak.js | 234 ++++++++-------- README.md | 71 ++--- charts/cthub-spilo/Readme.md | 130 +++++---- charts/spilo/docs/restore.md | 23 +- django/README.md | 24 +- frontend/src/uploads/UploadContainer.js | 124 ++++----- .../uploads/components/UploadIssuesDetail.js | 4 +- frontend/src/users/UsersContainer.js | 2 +- frontend/src/users/components/UsersPage.js | 2 +- openshift/README.md | 12 +- openshift/templates/backend/README.md | 1 + .../openshift/README.md | 69 ++--- .../backup-container-2.6.1/cronjob.md | 5 +- openshift/templates/crunchydb/readme.md | 19 +- openshift/templates/keycloak/README.md | 6 +- .../templates/metabase-postgresql/README.md | 18 +- openshift/templates/metabase/README.md | 9 +- openshift/templates/minio/README.md | 8 +- openshift/templates/patroni-2.1.1/README.md | 16 +- openshift/templates/redis/readme.md | 8 +- openshift/templates/superset/readme.md | 10 +- superset/README.md | 4 +- 47 files changed, 1031 insertions(+), 704 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index afa680ef..7bc2d2d6 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -2,9 +2,8 @@ name: Bug about: An undesirable behaviour that needs correction title: Bug -labels: '' -assignees: '' - +labels: "" +assignees: "" --- **Describe the Bug** @@ -22,6 +21,7 @@ A clear and concise description of any implications. **Steps To Reproduce** Steps to reproduce the behaviour: User/Role: + 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' diff --git a/.github/ISSUE_TEMPLATE/spike.md b/.github/ISSUE_TEMPLATE/spike.md index f5917b39..9665cd41 100644 --- a/.github/ISSUE_TEMPLATE/spike.md +++ b/.github/ISSUE_TEMPLATE/spike.md @@ -2,25 +2,28 @@ name: Spike about: Research options prior to development work title: Spike -labels: '' -assignees: '' - +labels: "" +assignees: "" --- -**Problem Description** +**Problem Description** **In order to** (achieve some goal), (a system or persona) **needs to** (some action). **Solution Needs** + - Enter the non-negotiables of the solution (what are the needs vs. what are the wants) **Timebox** + - How much effort are we committing to this research? **Outcome** -Details describing the outcome of the research -- Was it successful? What direction should the work go? +Details describing the outcome of the research + +- Was it successful? What direction should the work go? - Was it unsuccessful? Discuss next steps with team **Additional Context** + - enter text here - enter text here diff --git a/.github/ISSUE_TEMPLATE/task.md b/.github/ISSUE_TEMPLATE/task.md index e0f7fcd1..2a9a9adb 100644 --- a/.github/ISSUE_TEMPLATE/task.md +++ b/.github/ISSUE_TEMPLATE/task.md @@ -2,9 +2,8 @@ name: Task about: Any work that does not directly impact the user title: Task -labels: '' -assignees: '' - +labels: "" +assignees: "" --- **Describe the task** @@ -14,10 +13,12 @@ A clear and concise description of what the task is. The reason why this task is needed and/or what value it adds. **Acceptance Criteria** + - [ ] first - [ ] second - [ ] third **Additional context** + - Add any other context about the task here. - Or here diff --git a/.github/ISSUE_TEMPLATE/user-story.md b/.github/ISSUE_TEMPLATE/user-story.md index 91938c94..0f4dfcf3 100644 --- a/.github/ISSUE_TEMPLATE/user-story.md +++ b/.github/ISSUE_TEMPLATE/user-story.md @@ -2,14 +2,14 @@ name: User Story about: This template is to be used when describing a feature from the user's perspective title: User Story -labels: '' -assignees: '' - +labels: "" +assignees: "" --- **Title:** **Description:** + - [ ] "As a [type of user]" "I want [an action or feature]" "So that [benefit or value]" - **Wireframe:** @@ -22,6 +22,7 @@ assignees: '' - [ ] Given I am a , When I am , then **Development Checklist:** + - [ ] A - [ ] B - [ ] C diff --git a/.pipeline/build-metabase.js b/.pipeline/build-metabase.js index 35935c29..f56e6412 100755 --- a/.pipeline/build-metabase.js +++ b/.pipeline/build-metabase.js @@ -1,5 +1,5 @@ -'use strict'; -const task = require('./lib/build-metabase.js') -const settings = require('./lib/config.js') +"use strict"; +const task = require("./lib/build-metabase.js"); +const settings = require("./lib/config.js"); -task(Object.assign(settings, { phase: 'build'})) +task(Object.assign(settings, { phase: "build" })); diff --git a/.pipeline/build-patroni.js b/.pipeline/build-patroni.js index f9dbb87d..993e6e72 100755 --- a/.pipeline/build-patroni.js +++ b/.pipeline/build-patroni.js @@ -1,5 +1,5 @@ -'use strict'; -const task = require('./lib/build-patroni.js') -const settings = require('./lib/config.js') +"use strict"; +const task = require("./lib/build-patroni.js"); +const settings = require("./lib/config.js"); -task(Object.assign(settings, { phase: 'build'})) +task(Object.assign(settings, { phase: "build" })); diff --git a/.pipeline/build.js b/.pipeline/build.js index 3ac899f8..e73ecef3 100755 --- a/.pipeline/build.js +++ b/.pipeline/build.js @@ -1,5 +1,5 @@ -'use strict'; -const task = require('./lib/build.js') -const settings = require('./lib/config.js') +"use strict"; +const task = require("./lib/build.js"); +const settings = require("./lib/config.js"); -task(Object.assign(settings, { phase: 'build'})) +task(Object.assign(settings, { phase: "build" })); diff --git a/.pipeline/clean-tools.js b/.pipeline/clean-tools.js index 42f4c43e..7d120617 100755 --- a/.pipeline/clean-tools.js +++ b/.pipeline/clean-tools.js @@ -1,5 +1,5 @@ -'use strict'; -const settings = require('./lib/config.js') -const task = require('./lib/clean-tools.js') +"use strict"; +const settings = require("./lib/config.js"); +const task = require("./lib/clean-tools.js"); -task(Object.assign(settings, { phase: settings.options.env})); +task(Object.assign(settings, { phase: settings.options.env })); diff --git a/.pipeline/clean.js b/.pipeline/clean.js index 42231d7f..c4fa6f72 100755 --- a/.pipeline/clean.js +++ b/.pipeline/clean.js @@ -1,5 +1,5 @@ -'use strict'; -const settings = require('./lib/config.js') -const task = require('./lib/clean.js') +"use strict"; +const settings = require("./lib/config.js"); +const task = require("./lib/clean.js"); -task(Object.assign(settings, { phase: settings.options.env})); +task(Object.assign(settings, { phase: settings.options.env })); diff --git a/.pipeline/deploy-knp.js b/.pipeline/deploy-knp.js index ccbc4048..f425f68f 100755 --- a/.pipeline/deploy-knp.js +++ b/.pipeline/deploy-knp.js @@ -1,5 +1,5 @@ -'use strict'; -const settings = require('./lib/config.js') -const task = require('./lib/deploy-knp.js') +"use strict"; +const settings = require("./lib/config.js"); +const task = require("./lib/deploy-knp.js"); -task(Object.assign(settings, { phase: settings.options.env})); +task(Object.assign(settings, { phase: settings.options.env })); diff --git a/.pipeline/deploy-metabase.js b/.pipeline/deploy-metabase.js index 02d551f0..e169e82f 100755 --- a/.pipeline/deploy-metabase.js +++ b/.pipeline/deploy-metabase.js @@ -1,5 +1,5 @@ -'use strict'; -const settings = require('./lib/config.js') -const task = require('./lib/deploy-metabase.js') +"use strict"; +const settings = require("./lib/config.js"); +const task = require("./lib/deploy-metabase.js"); -task(Object.assign(settings, { phase: settings.options.env})); +task(Object.assign(settings, { phase: settings.options.env })); diff --git a/.pipeline/deploy-patroni.js b/.pipeline/deploy-patroni.js index 348313cd..df570f23 100755 --- a/.pipeline/deploy-patroni.js +++ b/.pipeline/deploy-patroni.js @@ -1,5 +1,5 @@ -'use strict'; -const settings = require('./lib/config.js') -const task = require('./lib/deploy-patroni.js') +"use strict"; +const settings = require("./lib/config.js"); +const task = require("./lib/deploy-patroni.js"); -task(Object.assign(settings, { phase: settings.options.env})); +task(Object.assign(settings, { phase: settings.options.env })); diff --git a/.pipeline/deploy-unittest.js b/.pipeline/deploy-unittest.js index c6c95ded..c59c63bf 100644 --- a/.pipeline/deploy-unittest.js +++ b/.pipeline/deploy-unittest.js @@ -1,5 +1,5 @@ -'use strict'; -const settings = require('./lib/config.js') -const task = require('./lib/deploy-unittest.js') +"use strict"; +const settings = require("./lib/config.js"); +const task = require("./lib/deploy-unittest.js"); -task(Object.assign(settings, { phase: settings.options.env})); +task(Object.assign(settings, { phase: settings.options.env })); diff --git a/.pipeline/deploy.js b/.pipeline/deploy.js index 59550945..d0eea0ee 100755 --- a/.pipeline/deploy.js +++ b/.pipeline/deploy.js @@ -1,5 +1,5 @@ -'use strict'; -const settings = require('./lib/config.js') -const task = require('./lib/deploy.js') +"use strict"; +const settings = require("./lib/config.js"); +const task = require("./lib/deploy.js"); -task(Object.assign(settings, { phase: settings.options.env})); +task(Object.assign(settings, { phase: settings.options.env })); diff --git a/.pipeline/lib/build-metabase.js b/.pipeline/lib/build-metabase.js index 6ac832d9..0b03c67d 100755 --- a/.pipeline/lib/build-metabase.js +++ b/.pipeline/lib/build-metabase.js @@ -2,16 +2,25 @@ const { OpenShiftClientX } = require("@bcgov/pipeline-cli"); const path = require("path"); -module.exports = settings => { +module.exports = (settings) => { const phases = settings.phases; const options = settings.options; - const oc = new OpenShiftClientX(Object.assign({ namespace: phases.build.namespace }, options)); + const oc = new OpenShiftClientX( + Object.assign({ namespace: phases.build.namespace }, options), + ); const phase = "build"; let objects = []; - const templatesLocalBaseUrl = oc.toFileUrl(path.resolve(__dirname, "../../openshift")); + const templatesLocalBaseUrl = oc.toFileUrl( + path.resolve(__dirname, "../../openshift"), + ); // The building of your cool app goes here ▼▼▼ - objects = objects.concat(oc.processDeploymentTemplate(`${templatesLocalBaseUrl}/templates/metabase/metabase-bc.yaml`, {})); + objects = objects.concat( + oc.processDeploymentTemplate( + `${templatesLocalBaseUrl}/templates/metabase/metabase-bc.yaml`, + {}, + ), + ); oc.applyRecommendedLabels( objects, diff --git a/.pipeline/lib/build-patroni.js b/.pipeline/lib/build-patroni.js index 5ea254bf..052dd1ba 100755 --- a/.pipeline/lib/build-patroni.js +++ b/.pipeline/lib/build-patroni.js @@ -2,16 +2,25 @@ const { OpenShiftClientX } = require("@bcgov/pipeline-cli"); const path = require("path"); -module.exports = settings => { +module.exports = (settings) => { const phases = settings.phases; const options = settings.options; - const oc = new OpenShiftClientX(Object.assign({ namespace: phases.build.namespace }, options)); + const oc = new OpenShiftClientX( + Object.assign({ namespace: phases.build.namespace }, options), + ); const phase = "build"; let objects = []; - const templatesLocalBaseUrl = oc.toFileUrl(path.resolve(__dirname, "../../openshift")); + const templatesLocalBaseUrl = oc.toFileUrl( + path.resolve(__dirname, "../../openshift"), + ); // The building of your cool app goes here ▼▼▼ - objects = objects.concat(oc.processDeploymentTemplate(`${templatesLocalBaseUrl}/templates/patroni-2.1.1/templates/build.yaml`, {})); + objects = objects.concat( + oc.processDeploymentTemplate( + `${templatesLocalBaseUrl}/templates/patroni-2.1.1/templates/build.yaml`, + {}, + ), + ); oc.applyRecommendedLabels( objects, diff --git a/.pipeline/lib/build.js b/.pipeline/lib/build.js index c9fe35d1..ae7ea643 100755 --- a/.pipeline/lib/build.js +++ b/.pipeline/lib/build.js @@ -2,37 +2,51 @@ const { OpenShiftClientX } = require("@bcgov/pipeline-cli"); const path = require("path"); -module.exports = settings => { +module.exports = (settings) => { const phases = settings.phases; const options = settings.options; - const oc = new OpenShiftClientX(Object.assign({ namespace: phases.build.namespace }, options)); + const oc = new OpenShiftClientX( + Object.assign({ namespace: phases.build.namespace }, options), + ); const phase = "build"; let objects = []; - const templatesLocalBaseUrl = oc.toFileUrl(path.resolve(__dirname, "../../openshift")); + const templatesLocalBaseUrl = oc.toFileUrl( + path.resolve(__dirname, "../../openshift"), + ); // The building of your cool app goes here ▼▼▼ // build frontend - objects = objects.concat(oc.processDeploymentTemplate(`${templatesLocalBaseUrl}/templates/frontend/frontend-bc.yaml`, { - 'param':{ - 'NAME': phases[phase].name, - 'SUFFIX': phases[phase].suffix, - 'VERSION': phases[phase].tag, - 'GIT_URL': oc.git.http_url, - 'GIT_REF': oc.git.ref - } - })) + objects = objects.concat( + oc.processDeploymentTemplate( + `${templatesLocalBaseUrl}/templates/frontend/frontend-bc.yaml`, + { + param: { + NAME: phases[phase].name, + SUFFIX: phases[phase].suffix, + VERSION: phases[phase].tag, + GIT_URL: oc.git.http_url, + GIT_REF: oc.git.ref, + }, + }, + ), + ); //build backend - objects = objects.concat(oc.processDeploymentTemplate(`${templatesLocalBaseUrl}/templates/backend/backend-bc.yaml`, { - 'param':{ - 'NAME': phases[phase].name, - 'SUFFIX': phases[phase].suffix, - 'VERSION': phases[phase].tag, - 'GIT_URL': oc.git.http_url, - 'GIT_REF': oc.git.ref - } - })) + objects = objects.concat( + oc.processDeploymentTemplate( + `${templatesLocalBaseUrl}/templates/backend/backend-bc.yaml`, + { + param: { + NAME: phases[phase].name, + SUFFIX: phases[phase].suffix, + VERSION: phases[phase].tag, + GIT_URL: oc.git.http_url, + GIT_REF: oc.git.ref, + }, + }, + ), + ); oc.applyRecommendedLabels( objects, diff --git a/.pipeline/lib/clean-tools.js b/.pipeline/lib/clean-tools.js index 0521bd6f..1b953d55 100755 --- a/.pipeline/lib/clean-tools.js +++ b/.pipeline/lib/clean-tools.js @@ -27,15 +27,16 @@ const getTargetPhases = (env, phases) => { return target_phase; }; -module.exports = settings => { +module.exports = (settings) => { const phases = settings.phases; const options = settings.options; - const oc = new OpenShiftClientX(Object.assign({ namespace: phases.build.namespace }, options)); + const oc = new OpenShiftClientX( + Object.assign({ namespace: phases.build.namespace }, options), + ); const target_phases = getTargetPhases(options.env, phases); - target_phases.forEach(k => { + target_phases.forEach((k) => { if (phases.hasOwnProperty(k)) { - const phase = phases[k]; oc.namespace(phase.namespace); @@ -44,7 +45,7 @@ module.exports = settings => { namespace: phase.namespace, }); - buildConfigs.forEach(bc => { + buildConfigs.forEach((bc) => { if (bc.spec.output.to.kind == "ImageStreamTag") { oc.delete([`ImageStreamTag/${bc.spec.output.to.name}`], { "ignore-not-found": "true", @@ -56,9 +57,8 @@ module.exports = settings => { "ignore-not-found": "true", wait: "true", namespace: phase.namespace, - }); + }); }); - } }); }; diff --git a/.pipeline/lib/clean.js b/.pipeline/lib/clean.js index 7ec61c13..fdfa3d7f 100755 --- a/.pipeline/lib/clean.js +++ b/.pipeline/lib/clean.js @@ -27,17 +27,17 @@ const getTargetPhases = (env, phases) => { return target_phase; }; -module.exports = settings => { +module.exports = (settings) => { const phases = settings.phases; const options = settings.options; - const oc = new OpenShiftClientX(Object.assign({ namespace: phases.build.namespace }, options)); + const oc = new OpenShiftClientX( + Object.assign({ namespace: phases.build.namespace }, options), + ); const target_phases = getTargetPhases(options.env, phases); - target_phases.forEach(k => { - + target_phases.forEach((k) => { //k is dve, test or prod if (phases.hasOwnProperty(k)) { - const phase = phases[k]; oc.namespace(phase.namespace); @@ -45,17 +45,20 @@ module.exports = settings => { selector: `app=${phase.instance},env-id=${phase.changeId},env-name=${k},!shared,github-repo=${oc.git.repository},github-owner=${oc.git.owner}`, namespace: phase.namespace, }); - deploymentConfigs.forEach(dc => { - dc.spec.triggers.forEach(trigger => { + deploymentConfigs.forEach((dc) => { + dc.spec.triggers.forEach((trigger) => { if ( - trigger.type == "ImageChange" && - trigger.imageChangeParams.from.kind == "ImageStreamTag" + trigger.type == "ImageChange" && + trigger.imageChangeParams.from.kind == "ImageStreamTag" ) { - oc.delete([`ImageStreamTag/${trigger.imageChangeParams.from.name}`], { - "ignore-not-found": "true", - wait: "true", - namespace: phase.namespace, - }); + oc.delete( + [`ImageStreamTag/${trigger.imageChangeParams.from.name}`], + { + "ignore-not-found": "true", + wait: "true", + namespace: phase.namespace, + }, + ); } }); oc.delete([`DeploymentConfig/${dc.metadata.name}`], { @@ -66,44 +69,42 @@ module.exports = settings => { }); oc.raw( "delete", - ["Secret,configmap,endpoints,RoleBinding,role,ServiceAccount,Endpoints,service,route"], + [ + "Secret,configmap,endpoints,RoleBinding,role,ServiceAccount,Endpoints,service,route", + ], { selector: `app=${phase.instance},env-id=${phase.changeId},!shared,github-repo=${oc.git.repository},github-owner=${oc.git.owner}`, wait: "true", namespace: phase.namespace, - } + }, ); //get all statefulsets before they are deleted const statefulsets = oc.get("statefulset", { selector: `app=${phase.instance},env-id=${phase.changeId},!shared,github-repo=${oc.git.repository},github-owner=${oc.git.owner}`, namespace: phase.namespace, - }); + }); //remove all the PVCs associated with each statefulset, after they get deleted by above delete all operation - statefulsets.forEach(statefulset => { + statefulsets.forEach((statefulset) => { //delete StatefulSet oc.delete([`StatefulSet/${statefulset.metadata.name}`], { "ignore-not-found": "true", wait: "true", namespace: phase.namespace, - }); + }); //delete configmaps create by patroni let patroniConfigmaps = oc.get("configmap", { selector: `app.kubernetes.io/name=patroni,cluster-name=${statefulset.metadata.name}`, namespace: phase.namespace, }); - if(Object.entries(patroniConfigmaps).length > 0) { - oc.raw( - "delete", - ["configmap"], - { - selector: `app.kubernetes.io/name=patroni,cluster-name=${statefulset.metadata.name}`, - wait: "true", - "ignore-not-found": "true", - namespace: phase.namespace, - }, - ); - }; + if (Object.entries(patroniConfigmaps).length > 0) { + oc.raw("delete", ["configmap"], { + selector: `app.kubernetes.io/name=patroni,cluster-name=${statefulset.metadata.name}`, + wait: "true", + "ignore-not-found": "true", + namespace: phase.namespace, + }); + } //delete PVCs mounted for statfulset oc.raw("delete", ["pvc"], { selector: `app=${phase.instance},statefulset=${statefulset.metadata.name},!shared,github-repo=${oc.git.repository},github-owner=${oc.git.owner}`, @@ -111,22 +112,20 @@ module.exports = settings => { wait: "true", namespace: phase.namespace, }); - }); //remove all PR's network policies const knps = oc.get("networkpolicies", { selector: `app=${phase.instance},env-id=${phase.changeId},env-name=${k},!shared,github-repo=${oc.git.repository},github-owner=${oc.git.owner}`, namespace: phase.namespace, - }); - knps.forEach(knp => { + }); + knps.forEach((knp) => { oc.delete([`networkpolicy/${knp.metadata.name}`], { - "ignore-not-found": "true", - wait: "true", - namespace: phase.namespace, - }); + "ignore-not-found": "true", + wait: "true", + namespace: phase.namespace, + }); }); - } }); }; diff --git a/.pipeline/lib/config.js b/.pipeline/lib/config.js index b03f1886..f02bae89 100644 --- a/.pipeline/lib/config.js +++ b/.pipeline/lib/config.js @@ -1,9 +1,9 @@ -'use strict'; -const options= require('@bcgov/pipeline-cli').Util.parseArguments() -const changeId = options.pr //aka pull-request -const version = '0.2.0' -const name = 'cthub' -const ocpName = 'apps.silver.devops' +"use strict"; +const options = require("@bcgov/pipeline-cli").Util.parseArguments(); +const changeId = options.pr; //aka pull-request +const version = "0.2.0"; +const name = "cthub"; +const ocpName = "apps.silver.devops"; //if work directly on bcgov repo, the value is bcgov //if work on forked developer repo, the value is the developer's GitHub Id @@ -26,57 +26,220 @@ Set the cpu usage 20m as the lowest Set the limit as two times of request */ -options.git.owner='bcgov' -options.git.repository='cthub' +options.git.owner = "bcgov"; +options.git.repository = "cthub"; const phases = { + build: { + namespace: "30b186-tools", + transient: true, + name: `${name}`, + phase: "build", + changeId: `${changeId}`, + suffix: `-build-${changeId}`, + instance: `${name}-build-${changeId}`, + version: `${version}-${changeId}`, + tag: `build-${version}-${changeId}`, + ocpName: `${ocpName}`, + }, - build: {namespace:'30b186-tools' , transient:true, name: `${name}`, phase: 'build', - changeId:`${changeId}`, suffix: `-build-${changeId}` , instance: `${name}-build-${changeId}`, - version:`${version}-${changeId}`, tag:`build-${version}-${changeId}`, ocpName: `${ocpName}`}, + dev: { + namespace: "30b186-dev", + transient: true, + name: `${name}`, + ssoSuffix: "-dev", + ssoName: "dev.oidc.gov.bc.ca", + phase: "dev", + changeId: `${changeId}`, + suffix: "-dev", + instance: `${name}-dev`, + version: `${version}`, + tag: `dev-${version}`, + host: `cthub-dev.${ocpName}.gov.bc.ca`, + djangoDebug: "True", + logoutHostName: "logontest7.gov.bc.ca", + dbHost: "cthub-crunchy-dev-pgbouncer", + metabaseCpuRequest: "200m", + metabaseCpuLimit: "300m", + metabaseMemoryRequest: "500Mi", + metabaseMemoryLimit: "2Gi", + metabaseReplicas: 1, + frontendCpuRequest: "400m", + frontendCpuLimit: "800m", + frontendMemoryRequest: "600Mi", + frontendMemoryLimit: "1200Mi", + frontendReplicas: 1, + backendCpuRequest: "50m", + backendCpuLimit: "100m", + backendMemoryRequest: "520Mi", + backendMemoryLimit: "1Gi", + backendHealthCheckDelay: 30, + backendHost: `cthub-backend-dev.${ocpName}.gov.bc.ca`, + backendReplicas: 1, + minioCpuRequest: "30m", + minioCpuLimit: "100m", + minioMemoryRequest: "150Mi", + minioMemoryLimit: "300Mi", + minioPvcSize: "3Gi", + minioBucketName: "zevadv", + schemaspyCpuRequest: "50m", + schemaspyCpuLimit: "200m", + schemaspyMemoryRequest: "150M", + schemaspyMemoryLimit: "300M", + schemaspyHealthCheckDelay: 160, + rabbitmqCpuRequest: "250m", + rabbitmqCpuLimit: "700m", + rabbitmqMemoryRequest: "500M", + rabbitmqMemoryLimit: "1G", + rabbitmqPvcSize: "1G", + rabbitmqReplica: 1, + rabbitmqPostStartSleep: 120, + storageClass: "netapp-block-standard", + patroniCpuRequest: "200m", + patroniCpuLimit: "400m", + patroniMemoryRequest: "250Mi", + patroniMemoryLimit: "500Mi", + patroniPvcSize: "2G", + patroniReplica: 2, + storageClass: "netapp-block-standard", + ocpName: `${ocpName}`, + }, - dev: {namespace:'30b186-dev', transient:true, name: `${name}`, ssoSuffix:'-dev', - ssoName:'dev.oidc.gov.bc.ca', phase: 'dev' , changeId:`${changeId}`, suffix: '-dev', - instance: `${name}-dev` , version:`${version}`, tag:`dev-${version}`, - host: `cthub-dev.${ocpName}.gov.bc.ca`, djangoDebug: 'True', logoutHostName: 'logontest7.gov.bc.ca', dbHost: 'cthub-crunchy-dev-pgbouncer', - metabaseCpuRequest: '200m', metabaseCpuLimit: '300m', metabaseMemoryRequest: '500Mi', metabaseMemoryLimit: '2Gi', metabaseReplicas: 1, - frontendCpuRequest: '400m', frontendCpuLimit: '800m', frontendMemoryRequest: '600Mi', frontendMemoryLimit: '1200Mi', frontendReplicas: 1, - backendCpuRequest: '50m', backendCpuLimit: '100m', backendMemoryRequest: '520Mi', backendMemoryLimit: '1Gi', backendHealthCheckDelay: 30, backendHost: `cthub-backend-dev.${ocpName}.gov.bc.ca`, backendReplicas: 1, - minioCpuRequest: '30m', minioCpuLimit: '100m', minioMemoryRequest: '150Mi', minioMemoryLimit: '300Mi', minioPvcSize: '3Gi', minioBucketName: 'zevadv', - schemaspyCpuRequest: '50m', schemaspyCpuLimit: '200m', schemaspyMemoryRequest: '150M', schemaspyMemoryLimit: '300M', schemaspyHealthCheckDelay: 160, - rabbitmqCpuRequest: '250m', rabbitmqCpuLimit: '700m', rabbitmqMemoryRequest: '500M', rabbitmqMemoryLimit: '1G', rabbitmqPvcSize: '1G', rabbitmqReplica: 1, rabbitmqPostStartSleep: 120, storageClass: 'netapp-block-standard', - patroniCpuRequest: '200m', patroniCpuLimit: '400m', patroniMemoryRequest: '250Mi', patroniMemoryLimit: '500Mi', patroniPvcSize: '2G', patroniReplica: 2, storageClass: 'netapp-block-standard', ocpName: `${ocpName}`}, - - test: {namespace:'30b186-test', name: `${name}`, ssoSuffix:'-test', - ssoName:'test.oidc.gov.bc.ca', phase: 'test' , changeId:`${changeId}`, suffix: `-test`, - instance: `${name}-test`, version:`${version}`, tag:`test-${version}`, - host: `cthub-test.${ocpName}.gov.bc.ca`, djangoDebug: 'False', logoutHostName: 'logontest7.gov.bc.ca', dbHost: 'cthub-crunchy-test-pgbouncer', - metabaseCpuRequest: '200m', metabaseCpuLimit: '300m', metabaseMemoryRequest: '500Mi', metabaseMemoryLimit: '2Gi', metabaseReplicas: 1, - frontendCpuRequest: '400m', frontendCpuLimit: '800m', frontendMemoryRequest: '600Mi', frontendMemoryLimit: '1200Mi', frontendReplicas: 1, frontendMinReplicas: 1, frontendMaxReplicas: 3, - backendCpuRequest: '50m', backendCpuLimit: '100m', backendMemoryRequest: '520Mi', backendMemoryLimit: '1Gi', backendHealthCheckDelay: 30, backendReplicas: 1, backendMinReplicas: 1, backendMaxReplicas: 3, backendHost: `cthub-backend-test.${ocpName}.gov.bc.ca`, - minioCpuRequest: '30m', minioCpuLimit: '100m', minioMemoryRequest: '150Mi', minioMemoryLimit: '300Mi', minioPvcSize: '3G', minioBucketName: 'zevats', - schemaspyCpuRequest: '20m', schemaspyCpuLimit: '200m', schemaspyMemoryRequest: '150M', schemaspyMemoryLimit: '300M', schemaspyHealthCheckDelay: 160, - rabbitmqCpuRequest: '250m', rabbitmqCpuLimit: '700m', rabbitmqMemoryRequest: '500M', rabbitmqMemoryLimit: '700M', rabbitmqPvcSize: '1G', rabbitmqReplica: 2, rabbitmqPostStartSleep: 120, storageClass: 'netapp-block-standard', - patroniCpuRequest: '200m', patroniCpuLimit: '400m', patroniMemoryRequest: '250Mi', patroniMemoryLimit: '500Mi', patroniPvcSize: '5G', patroniReplica: 2, storageClass: 'netapp-block-standard', ocpName: `${ocpName}`}, - - prod: {namespace:'30b186-prod', name: `${name}`, ssoSuffix:'', - ssoName:'oidc.gov.bc.ca', phase: 'prod' , changeId:`${changeId}`, suffix: `-prod`, - instance: `${name}-prod`, version:`${version}`, tag:`prod-${version}`, - metabaseCpuRequest: '200m', metabaseCpuLimit: '300m', metabaseMemoryRequest: '500Mi', metabaseMemoryLimit: '2Gi', metabaseReplicas: 1, - host: `cthub-prod.${ocpName}.gov.bc.ca`, djangoDebug: 'False', logoutHostName: 'logon7.gov.bc.ca', dbHost: 'patroni-master-prod', - frontendCpuRequest: '400m', frontendCpuLimit: '800m', frontendMemoryRequest: '600Mi', frontendMemoryLimit: '1200Mi', frontendReplicas: 1, frontendMinReplicas: 1, frontendMaxReplicas: 3, - backendCpuRequest: '50m', backendCpuLimit: '100m', backendMemoryRequest: '520Mi', backendMemoryLimit: '1Gi', backendHealthCheckDelay: 30, backendReplicas: 1, backendMinReplicas: 1, backendMaxReplicas: 3, backendHost: `cthub-backend-prod.${ocpName}.gov.bc.ca`, - minioCpuRequest: '30m', minioCpuLimit: '100m', minioMemoryRequest: '150Mi', minioMemoryLimit: '300Mi', minioPvcSize: '3G', minioBucketName: 'zevapr', - schemaspyCpuRequest: '50m', schemaspyCpuLimit: '400m', schemaspyMemoryRequest: '150M', schemaspyMemoryLimit: '300M', schemaspyHealthCheckDelay: 160, - rabbitmqCpuRequest: '250m', rabbitmqCpuLimit: '700m', rabbitmqMemoryRequest: '500M', rabbitmqMemoryLimit: '1G', rabbitmqPvcSize: '5G', rabbitmqReplica: 2, rabbitmqPostStartSleep: 120, storageClass: 'netapp-block-standard', - patroniCpuRequest: '200m', patroniCpuLimit: '400m', patroniMemoryRequest: '250Mi', patroniMemoryLimit: '500Mi', patroniPvcSize: '8G', patroniReplica: 3, storageClass: 'netapp-block-standard', ocpName: `${ocpName}`} + test: { + namespace: "30b186-test", + name: `${name}`, + ssoSuffix: "-test", + ssoName: "test.oidc.gov.bc.ca", + phase: "test", + changeId: `${changeId}`, + suffix: `-test`, + instance: `${name}-test`, + version: `${version}`, + tag: `test-${version}`, + host: `cthub-test.${ocpName}.gov.bc.ca`, + djangoDebug: "False", + logoutHostName: "logontest7.gov.bc.ca", + dbHost: "cthub-crunchy-test-pgbouncer", + metabaseCpuRequest: "200m", + metabaseCpuLimit: "300m", + metabaseMemoryRequest: "500Mi", + metabaseMemoryLimit: "2Gi", + metabaseReplicas: 1, + frontendCpuRequest: "400m", + frontendCpuLimit: "800m", + frontendMemoryRequest: "600Mi", + frontendMemoryLimit: "1200Mi", + frontendReplicas: 1, + frontendMinReplicas: 1, + frontendMaxReplicas: 3, + backendCpuRequest: "50m", + backendCpuLimit: "100m", + backendMemoryRequest: "520Mi", + backendMemoryLimit: "1Gi", + backendHealthCheckDelay: 30, + backendReplicas: 1, + backendMinReplicas: 1, + backendMaxReplicas: 3, + backendHost: `cthub-backend-test.${ocpName}.gov.bc.ca`, + minioCpuRequest: "30m", + minioCpuLimit: "100m", + minioMemoryRequest: "150Mi", + minioMemoryLimit: "300Mi", + minioPvcSize: "3G", + minioBucketName: "zevats", + schemaspyCpuRequest: "20m", + schemaspyCpuLimit: "200m", + schemaspyMemoryRequest: "150M", + schemaspyMemoryLimit: "300M", + schemaspyHealthCheckDelay: 160, + rabbitmqCpuRequest: "250m", + rabbitmqCpuLimit: "700m", + rabbitmqMemoryRequest: "500M", + rabbitmqMemoryLimit: "700M", + rabbitmqPvcSize: "1G", + rabbitmqReplica: 2, + rabbitmqPostStartSleep: 120, + storageClass: "netapp-block-standard", + patroniCpuRequest: "200m", + patroniCpuLimit: "400m", + patroniMemoryRequest: "250Mi", + patroniMemoryLimit: "500Mi", + patroniPvcSize: "5G", + patroniReplica: 2, + storageClass: "netapp-block-standard", + ocpName: `${ocpName}`, + }, + prod: { + namespace: "30b186-prod", + name: `${name}`, + ssoSuffix: "", + ssoName: "oidc.gov.bc.ca", + phase: "prod", + changeId: `${changeId}`, + suffix: `-prod`, + instance: `${name}-prod`, + version: `${version}`, + tag: `prod-${version}`, + metabaseCpuRequest: "200m", + metabaseCpuLimit: "300m", + metabaseMemoryRequest: "500Mi", + metabaseMemoryLimit: "2Gi", + metabaseReplicas: 1, + host: `cthub-prod.${ocpName}.gov.bc.ca`, + djangoDebug: "False", + logoutHostName: "logon7.gov.bc.ca", + dbHost: "patroni-master-prod", + frontendCpuRequest: "400m", + frontendCpuLimit: "800m", + frontendMemoryRequest: "600Mi", + frontendMemoryLimit: "1200Mi", + frontendReplicas: 1, + frontendMinReplicas: 1, + frontendMaxReplicas: 3, + backendCpuRequest: "50m", + backendCpuLimit: "100m", + backendMemoryRequest: "520Mi", + backendMemoryLimit: "1Gi", + backendHealthCheckDelay: 30, + backendReplicas: 1, + backendMinReplicas: 1, + backendMaxReplicas: 3, + backendHost: `cthub-backend-prod.${ocpName}.gov.bc.ca`, + minioCpuRequest: "30m", + minioCpuLimit: "100m", + minioMemoryRequest: "150Mi", + minioMemoryLimit: "300Mi", + minioPvcSize: "3G", + minioBucketName: "zevapr", + schemaspyCpuRequest: "50m", + schemaspyCpuLimit: "400m", + schemaspyMemoryRequest: "150M", + schemaspyMemoryLimit: "300M", + schemaspyHealthCheckDelay: 160, + rabbitmqCpuRequest: "250m", + rabbitmqCpuLimit: "700m", + rabbitmqMemoryRequest: "500M", + rabbitmqMemoryLimit: "1G", + rabbitmqPvcSize: "5G", + rabbitmqReplica: 2, + rabbitmqPostStartSleep: 120, + storageClass: "netapp-block-standard", + patroniCpuRequest: "200m", + patroniCpuLimit: "400m", + patroniMemoryRequest: "250Mi", + patroniMemoryLimit: "500Mi", + patroniPvcSize: "8G", + patroniReplica: 3, + storageClass: "netapp-block-standard", + ocpName: `${ocpName}`, + }, }; // This callback forces the node process to exit as failure. -process.on('unhandledRejection', (reason) => { +process.on("unhandledRejection", (reason) => { console.log(reason); process.exit(1); }); -module.exports = exports = {phases, options}; +module.exports = exports = { phases, options }; diff --git a/.pipeline/lib/deploy-knp.js b/.pipeline/lib/deploy-knp.js index 6458596c..7fbeef2a 100755 --- a/.pipeline/lib/deploy-knp.js +++ b/.pipeline/lib/deploy-knp.js @@ -2,33 +2,46 @@ const { OpenShiftClientX } = require("@bcgov/pipeline-cli"); const path = require("path"); -module.exports = settings => { +module.exports = (settings) => { const phases = settings.phases; const options = settings.options; const phase = options.env; const changeId = phases[phase].changeId; - const oc = new OpenShiftClientX(Object.assign({namespace: phases[phase].namespace}, options)); + const oc = new OpenShiftClientX( + Object.assign({ namespace: phases[phase].namespace }, options), + ); //add Valid Redirect URIs for the pull request to keycloak - const templatesLocalBaseUrl = oc.toFileUrl(path.resolve(__dirname, "../../openshift")); + const templatesLocalBaseUrl = oc.toFileUrl( + path.resolve(__dirname, "../../openshift"), + ); var objects = []; // The deployment of your cool app goes here ▼▼▼ - objects = objects.concat(oc.processDeploymentTemplate(`${templatesLocalBaseUrl}/templates/knp/knp-env-pr.yaml`, { - 'param': { - 'SUFFIX': phases[phase].suffix, - 'ENVIRONMENT': phases[phase].phase - } - })) - + objects = objects.concat( + oc.processDeploymentTemplate( + `${templatesLocalBaseUrl}/templates/knp/knp-env-pr.yaml`, + { + param: { + SUFFIX: phases[phase].suffix, + ENVIRONMENT: phases[phase].phase, + }, + }, + ), + ); + oc.applyRecommendedLabels( - objects, - phases[phase].name, - phase, - `${changeId}`, - phases[phase].instance, + objects, + phases[phase].name, + phase, + `${changeId}`, + phases[phase].instance, + ); + oc.importImageStreams( + objects, + phases[phase].tag, + phases.build.namespace, + phases.build.tag, ); - oc.importImageStreams(objects, phases[phase].tag, phases.build.namespace, phases.build.tag); oc.applyAndDeploy(objects, phases[phase].instance); - }; diff --git a/.pipeline/lib/deploy-metabase.js b/.pipeline/lib/deploy-metabase.js index 16a5c424..e775b9d7 100755 --- a/.pipeline/lib/deploy-metabase.js +++ b/.pipeline/lib/deploy-metabase.js @@ -3,37 +3,50 @@ const { OpenShiftClientX } = require("@bcgov/pipeline-cli"); const path = require("path"); //const KeyCloakClient = require('./keycloak'); -module.exports = settings => { +module.exports = (settings) => { const phases = settings.phases; const options = settings.options; const phase = options.env; const changeId = phases[phase].changeId; - const oc = new OpenShiftClientX(Object.assign({namespace: phases[phase].namespace}, options)); + const oc = new OpenShiftClientX( + Object.assign({ namespace: phases[phase].namespace }, options), + ); - const templatesLocalBaseUrl = oc.toFileUrl(path.resolve(__dirname, "../../openshift")); + const templatesLocalBaseUrl = oc.toFileUrl( + path.resolve(__dirname, "../../openshift"), + ); var objects = []; // The deployment of your cool app goes here ▼▼▼ - objects = objects.concat(oc.processDeploymentTemplate(`${templatesLocalBaseUrl}/templates/metabase-postgresql/metabase-dc.yaml`, { - 'param': { - 'ENV_NAME': phases[phase].phase, - 'SUFFIX': phases[phase].suffix, - 'CPU_REQUEST': phases[phase].metabaseCpuRequest, - 'CPU_LIMIT': phases[phase].metabaseCpuLimit, - 'MEMORY_REQUEST': phases[phase].metabaseMemoryRequest, - 'MEMORY_LIMIT': phases[phase].metabaseMemoryLimit, - 'REPLICAS': phases[phase].metabaseReplicas, - } - })) + objects = objects.concat( + oc.processDeploymentTemplate( + `${templatesLocalBaseUrl}/templates/metabase-postgresql/metabase-dc.yaml`, + { + param: { + ENV_NAME: phases[phase].phase, + SUFFIX: phases[phase].suffix, + CPU_REQUEST: phases[phase].metabaseCpuRequest, + CPU_LIMIT: phases[phase].metabaseCpuLimit, + MEMORY_REQUEST: phases[phase].metabaseMemoryRequest, + MEMORY_LIMIT: phases[phase].metabaseMemoryLimit, + REPLICAS: phases[phase].metabaseReplicas, + }, + }, + ), + ); oc.applyRecommendedLabels( - objects, - phases[phase].name, - phase, - `${changeId}`, - phases[phase].instance, + objects, + phases[phase].name, + phase, + `${changeId}`, + phases[phase].instance, + ); + oc.importImageStreams( + objects, + phases[phase].tag, + phases.build.namespace, + phases.build.tag, ); - oc.importImageStreams(objects, phases[phase].tag, phases.build.namespace, phases.build.tag); oc.applyAndDeploy(objects, phases[phase].instance); - }; diff --git a/.pipeline/lib/deploy-patroni.js b/.pipeline/lib/deploy-patroni.js index e7eb5f97..42494d70 100755 --- a/.pipeline/lib/deploy-patroni.js +++ b/.pipeline/lib/deploy-patroni.js @@ -3,12 +3,14 @@ const { OpenShiftClientX } = require("@bcgov/pipeline-cli"); const path = require("path"); //const KeyCloakClient = require('./keycloak'); -module.exports = settings => { +module.exports = (settings) => { const phases = settings.phases; const options = settings.options; const phase = options.env; const changeId = phases[phase].changeId; - const oc = new OpenShiftClientX(Object.assign({namespace: phases[phase].namespace}, options)); + const oc = new OpenShiftClientX( + Object.assign({ namespace: phases[phase].namespace }, options), + ); //add Valid Redirect URIs for the pull request to keycloak /************ @@ -18,37 +20,53 @@ module.exports = settings => { } *************/ - const templatesLocalBaseUrl = oc.toFileUrl(path.resolve(__dirname, "../../openshift")); + const templatesLocalBaseUrl = oc.toFileUrl( + path.resolve(__dirname, "../../openshift"), + ); var objects = []; // The deployment of your cool app goes here ▼▼▼ - objects = objects.concat(oc.processDeploymentTemplate(`${templatesLocalBaseUrl}/templates/patroni-2.1.1/templates/prerequisite.yaml`, { - 'param': { - 'SUFFIX': phases[phase].suffix - } - })) + objects = objects.concat( + oc.processDeploymentTemplate( + `${templatesLocalBaseUrl}/templates/patroni-2.1.1/templates/prerequisite.yaml`, + { + param: { + SUFFIX: phases[phase].suffix, + }, + }, + ), + ); - objects = objects.concat(oc.processDeploymentTemplate(`${templatesLocalBaseUrl}/templates/patroni-2.1.1/templates/deploy.yaml`, { - 'param': { - 'SUFFIX': phases[phase].suffix, - 'CPU_REQUEST': phases[phase].patroniCpuRequest, - 'CPU_LIMIT': phases[phase].patroniCpuLimit, - 'MEMORY_REQUEST': phases[phase].patroniMemoryRequest, - 'MEMORY_LIMIT': phases[phase].patroniMemoryLimit, - 'REPLICAS': phases[phase].patroniReplica, - 'PVC_SIZE': phases[phase].patroniPvcSize, - 'STORAGE_CLASS': phases[phase].storageClass - } - })) + objects = objects.concat( + oc.processDeploymentTemplate( + `${templatesLocalBaseUrl}/templates/patroni-2.1.1/templates/deploy.yaml`, + { + param: { + SUFFIX: phases[phase].suffix, + CPU_REQUEST: phases[phase].patroniCpuRequest, + CPU_LIMIT: phases[phase].patroniCpuLimit, + MEMORY_REQUEST: phases[phase].patroniMemoryRequest, + MEMORY_LIMIT: phases[phase].patroniMemoryLimit, + REPLICAS: phases[phase].patroniReplica, + PVC_SIZE: phases[phase].patroniPvcSize, + STORAGE_CLASS: phases[phase].storageClass, + }, + }, + ), + ); oc.applyRecommendedLabels( - objects, - phases[phase].name, - phase, - `${changeId}`, - phases[phase].instance, + objects, + phases[phase].name, + phase, + `${changeId}`, + phases[phase].instance, + ); + oc.importImageStreams( + objects, + phases[phase].tag, + phases.build.namespace, + phases.build.tag, ); - oc.importImageStreams(objects, phases[phase].tag, phases.build.namespace, phases.build.tag); oc.applyAndDeploy(objects, phases[phase].instance); - }; diff --git a/.pipeline/lib/deploy-unittest.js b/.pipeline/lib/deploy-unittest.js index 93e01e50..a5ec5f5c 100644 --- a/.pipeline/lib/deploy-unittest.js +++ b/.pipeline/lib/deploy-unittest.js @@ -2,66 +2,87 @@ const { OpenShiftClientX } = require("@bcgov/pipeline-cli"); const path = require("path"); -module.exports = settings => { +module.exports = (settings) => { const phases = settings.phases; const options = settings.options; const phase = options.env; const changeId = phases[phase].changeId; - const oc = new OpenShiftClientX(Object.assign({namespace: phases[phase].namespace}, options)); + const oc = new OpenShiftClientX( + Object.assign({ namespace: phases[phase].namespace }, options), + ); - const templatesLocalBaseUrl = oc.toFileUrl(path.resolve(__dirname, "../../openshift")); + const templatesLocalBaseUrl = oc.toFileUrl( + path.resolve(__dirname, "../../openshift"), + ); var objects = []; // The deployment of your cool app goes here ▼▼▼ //deploy separate database and backend pod for unit test - if( phase === 'dev' ) { - + if (phase === "dev") { //create unit test database init scripts - objects = objects.concat(oc.processDeploymentTemplate(`${templatesLocalBaseUrl}/templates/unittest/zeva-postgresql-init.yaml`, { - 'param': { - 'NAME': phases[phase].name, - 'SUFFIX': phases[phase].suffix - } - })) + objects = objects.concat( + oc.processDeploymentTemplate( + `${templatesLocalBaseUrl}/templates/unittest/zeva-postgresql-init.yaml`, + { + param: { + NAME: phases[phase].name, + SUFFIX: phases[phase].suffix, + }, + }, + ), + ); //deploy postgresql unit test - objects = objects.concat(oc.processDeploymentTemplate(`${templatesLocalBaseUrl}/templates/unittest/postgresql-dc-unittest.yaml`, { - 'param': { - 'NAME': phases[phase].name, - 'SUFFIX': phases[phase].suffix, - 'ENV_NAME': phases[phase].phase - } - })) + objects = objects.concat( + oc.processDeploymentTemplate( + `${templatesLocalBaseUrl}/templates/unittest/postgresql-dc-unittest.yaml`, + { + param: { + NAME: phases[phase].name, + SUFFIX: phases[phase].suffix, + ENV_NAME: phases[phase].phase, + }, + }, + ), + ); //deploy backend unit test - objects = objects.concat(oc.processDeploymentTemplate(`${templatesLocalBaseUrl}/templates/unittest/backend-dc-unittest.yaml`, { - 'param': { - 'NAME': phases[phase].name, - 'SUFFIX': phases[phase].suffix, - 'VERSION': phases[phase].tag, - 'ENV_NAME': phases[phase].phase, - 'BACKEND_HOST_NAME': phases[phase].backendHost, - 'RABBITMQ_CLUSTER_NAME': 'rabbitmq-cluster', - 'CPU_REQUEST': phases[phase].backendCpuRequest, - 'CPU_LIMIT': '700m', - 'MEMORY_REQUEST': phases[phase].backendMemoryRequest, - 'MEMORY_LIMIT': phases[phase].backendMemoryLimit, - 'HEALTH_CHECK_DELAY': phases[phase].backendHealthCheckDelay, - 'REPLICAS': phases[phase].backendReplicas - } - })) - + objects = objects.concat( + oc.processDeploymentTemplate( + `${templatesLocalBaseUrl}/templates/unittest/backend-dc-unittest.yaml`, + { + param: { + NAME: phases[phase].name, + SUFFIX: phases[phase].suffix, + VERSION: phases[phase].tag, + ENV_NAME: phases[phase].phase, + BACKEND_HOST_NAME: phases[phase].backendHost, + RABBITMQ_CLUSTER_NAME: "rabbitmq-cluster", + CPU_REQUEST: phases[phase].backendCpuRequest, + CPU_LIMIT: "700m", + MEMORY_REQUEST: phases[phase].backendMemoryRequest, + MEMORY_LIMIT: phases[phase].backendMemoryLimit, + HEALTH_CHECK_DELAY: phases[phase].backendHealthCheckDelay, + REPLICAS: phases[phase].backendReplicas, + }, + }, + ), + ); } oc.applyRecommendedLabels( - objects, - phases[phase].name, - phase, - `${changeId}`, - phases[phase].instance, + objects, + phases[phase].name, + phase, + `${changeId}`, + phases[phase].instance, + ); + oc.importImageStreams( + objects, + phases[phase].tag, + phases.build.namespace, + phases.build.tag, ); - oc.importImageStreams(objects, phases[phase].tag, phases.build.namespace, phases.build.tag); oc.applyAndDeploy(objects, phases[phase].instance); - }; diff --git a/.pipeline/lib/deploy.js b/.pipeline/lib/deploy.js index 8b5b0f54..7575410e 100755 --- a/.pipeline/lib/deploy.js +++ b/.pipeline/lib/deploy.js @@ -3,12 +3,14 @@ const { OpenShiftClientX } = require("@bcgov/pipeline-cli"); const path = require("path"); //const KeyCloakClient = require('./keycloak'); -module.exports = settings => { +module.exports = (settings) => { const phases = settings.phases; const options = settings.options; const phase = options.env; const changeId = phases[phase].changeId; - const oc = new OpenShiftClientX(Object.assign({namespace: phases[phase].namespace}, options)); + const oc = new OpenShiftClientX( + Object.assign({ namespace: phases[phase].namespace }, options), + ); //add Valid Redirect URIs for the pull request to keycloak /************ @@ -18,52 +20,68 @@ module.exports = settings => { } *************/ - const templatesLocalBaseUrl = oc.toFileUrl(path.resolve(__dirname, "../../openshift")); + const templatesLocalBaseUrl = oc.toFileUrl( + path.resolve(__dirname, "../../openshift"), + ); var objects = []; // The deployment of your cool app goes here ▼▼▼ - objects = objects.concat(oc.processDeploymentTemplate(`${templatesLocalBaseUrl}/templates/frontend/frontend-dc.yaml`, { - 'param': { - 'NAME': phases[phase].name, - 'SUFFIX': phases[phase].suffix, - 'VERSION': phases[phase].tag, - 'ENV_NAME': phases[phase].phase, - 'HOST_NAME': phases[phase].host, - 'CPU_REQUEST': phases[phase].frontendCpuRequest, - 'CPU_LIMIT': phases[phase].frontendCpuLimit, - 'MEMORY_REQUEST': phases[phase].frontendMemoryRequest, - 'MEMORY_LIMIT': phases[phase].frontendMemoryLimit, - 'REPLICAS': phases[phase].frontendReplicas - } - })) - - objects = objects.concat(oc.processDeploymentTemplate(`${templatesLocalBaseUrl}/templates/backend/backend-dc.yaml`, { - 'param': { - 'NAME': phases[phase].name, - 'SUFFIX': phases[phase].suffix, - 'VERSION': phases[phase].tag, - 'ENV_NAME': phases[phase].phase, - 'BACKEND_HOST_NAME': phases[phase].backendHost, - 'CPU_REQUEST': phases[phase].backendCpuRequest, - 'CPU_LIMIT': phases[phase].backendCpuLimit, - 'MEMORY_REQUEST': phases[phase].backendMemoryRequest, - 'MEMORY_LIMIT': phases[phase].backendMemoryLimit, - 'HEALTH_CHECK_DELAY': phases[phase].backendHealthCheckDelay, - 'REPLICAS': phases[phase].backendReplicas, - 'DB_HOST': phases[phase].dbHost, - 'MINIO_BUCKET_NAME': phases[phase].minioBucketName - } - })) + objects = objects.concat( + oc.processDeploymentTemplate( + `${templatesLocalBaseUrl}/templates/frontend/frontend-dc.yaml`, + { + param: { + NAME: phases[phase].name, + SUFFIX: phases[phase].suffix, + VERSION: phases[phase].tag, + ENV_NAME: phases[phase].phase, + HOST_NAME: phases[phase].host, + CPU_REQUEST: phases[phase].frontendCpuRequest, + CPU_LIMIT: phases[phase].frontendCpuLimit, + MEMORY_REQUEST: phases[phase].frontendMemoryRequest, + MEMORY_LIMIT: phases[phase].frontendMemoryLimit, + REPLICAS: phases[phase].frontendReplicas, + }, + }, + ), + ); + + objects = objects.concat( + oc.processDeploymentTemplate( + `${templatesLocalBaseUrl}/templates/backend/backend-dc.yaml`, + { + param: { + NAME: phases[phase].name, + SUFFIX: phases[phase].suffix, + VERSION: phases[phase].tag, + ENV_NAME: phases[phase].phase, + BACKEND_HOST_NAME: phases[phase].backendHost, + CPU_REQUEST: phases[phase].backendCpuRequest, + CPU_LIMIT: phases[phase].backendCpuLimit, + MEMORY_REQUEST: phases[phase].backendMemoryRequest, + MEMORY_LIMIT: phases[phase].backendMemoryLimit, + HEALTH_CHECK_DELAY: phases[phase].backendHealthCheckDelay, + REPLICAS: phases[phase].backendReplicas, + DB_HOST: phases[phase].dbHost, + MINIO_BUCKET_NAME: phases[phase].minioBucketName, + }, + }, + ), + ); oc.applyRecommendedLabels( - objects, - phases[phase].name, - phase, - `${changeId}`, - phases[phase].instance, + objects, + phases[phase].name, + phase, + `${changeId}`, + phases[phase].instance, + ); + oc.importImageStreams( + objects, + phases[phase].tag, + phases.build.namespace, + phases.build.tag, ); - oc.importImageStreams(objects, phases[phase].tag, phases.build.namespace, phases.build.tag); oc.applyAndDeploy(objects, phases[phase].instance); - }; diff --git a/.pipeline/lib/keycloak.js b/.pipeline/lib/keycloak.js index 5310a10b..122eb75a 100644 --- a/.pipeline/lib/keycloak.js +++ b/.pipeline/lib/keycloak.js @@ -3,135 +3,131 @@ const axios = require("axios"); const _ = require("lodash"); //code reference https://github.com/bcgov/HMCR/blob/0.7/.pipeline/lib/keycloak.js module.exports = class KeyCloakClient { - constructor(settings, oc) { - this.phases = settings.phases; - this.options = settings.options; - this.oc = oc; - this.zevaHost = this.phases.dev.host; + constructor(settings, oc) { + this.phases = settings.phases; + this.options = settings.options; + this.oc = oc; + this.zevaHost = this.phases.dev.host; + } + + async init() { + this.getSecrets(); + + this.apiTokenPath = `/auth/realms/${this.realmId}/protocol/openid-connect/token`; + this.zevaPublicClientPath = `auth/admin/realms/${this.realmId}/clients/${this.zevaClientId}`; + + this.api = axios.create({ + baseURL: `https://${this.ssoHost}`, + }); + + const token = await this.getAccessToken(); + + this.api.defaults.headers.common = { + Authorization: `Bearer ${token}`, + }; + } + + getSecrets() { + const keycloakSecret = this.oc.raw("get", [ + "secret", + "zeva-keycloak", + "-o", + "json", + ]); + const secret = JSON.parse(keycloakSecret.stdout).data; + + this.clientId = Buffer.from(secret.clientId, "base64").toString(); + this.clientSecret = Buffer.from(secret.clientSecret, "base64").toString(); + this.zevaClientId = Buffer.from(secret.zevaPublic, "base64").toString(); + this.realmId = Buffer.from(secret.realmId, "base64").toString(); + this.ssoHost = Buffer.from(secret.host, "base64").toString(); + + if (!this.clientId || !this.clientSecret || !this.zevaClientId) + throw new Error( + "Unable to retrieve Keycloak service account info from OpenShift", + ); + } + + getAccessToken() { + return this.api + .post(this.apiTokenPath, "grant_type=client_credentials", { + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + auth: { + username: this.clientId, + password: this.clientSecret, + }, + }) + .then(function (response) { + if (!response.data.access_token) + throw new Error( + "Unable to retrieve Keycloak service account access token", + ); + + return Promise.resolve(response.data.access_token); + }); + } + + async getUris() { + const response = await this.api.get(this.zevaPublicClientPath); + + const data = { ...response.data }; + const redirectUris = data.redirectUris; + + return { data, redirectUris }; + } + + async addUris() { + await this.init(); + + console.log("Attempting to add RedirectUri and WebOrigins"); + + const { data, redirectUris } = await this.getUris(); + + const putData = { id: data.id, clientId: data.clientId }; + + const hasRedirectUris = redirectUris.find((item) => + item.includes(this.zevaHost), + ); + + if (!hasRedirectUris) { + redirectUris.push(`https://${this.zevaHost}/*`); + putData.redirectUris = redirectUris; } - async init() { - - this.getSecrets(); - - this.apiTokenPath = `/auth/realms/${this.realmId}/protocol/openid-connect/token`; - this.zevaPublicClientPath = `auth/admin/realms/${this.realmId}/clients/${this.zevaClientId}`; - - this.api = axios.create({ - baseURL: `https://${this.ssoHost}` - }); - - const token = await this.getAccessToken(); - - this.api.defaults.headers.common = { - Authorization: `Bearer ${token}` - }; - } - - getSecrets() { - const keycloakSecret = this.oc.raw("get", [ - "secret", - "zeva-keycloak", - "-o", - "json" - ]); - const secret = JSON.parse(keycloakSecret.stdout).data; - - this.clientId = Buffer.from(secret.clientId, "base64").toString(); - this.clientSecret = Buffer.from(secret.clientSecret, "base64").toString(); - this.zevaClientId = Buffer.from(secret.zevaPublic, "base64").toString(); - this.realmId = Buffer.from(secret.realmId, "base64").toString(); - this.ssoHost = Buffer.from(secret.host, "base64").toString(); - - if (!this.clientId || !this.clientSecret || !this.zevaClientId) - throw new Error( - "Unable to retrieve Keycloak service account info from OpenShift" - ); - } - - getAccessToken() { - - return this.api - .post(this.apiTokenPath, "grant_type=client_credentials", { - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - auth: { - username: this.clientId, - password: this.clientSecret - } - }) - .then(function(response) { - if (!response.data.access_token) - throw new Error( - "Unable to retrieve Keycloak service account access token" - ); - - return Promise.resolve(response.data.access_token); - }); - } - - async getUris() { - - const response = await this.api.get(this.zevaPublicClientPath); - - const data = { ...response.data }; - const redirectUris = data.redirectUris; - - return { data, redirectUris }; + if (!hasRedirectUris) { + this.api + .put(this.zevaPublicClientPath, putData) + .then(() => console.log("RedirectUri and WebOrigins added.")); + } else { + console.log("RedirectUri and WebOrigins add skipped."); } + } - async addUris() { - await this.init(); + async removeUris() { + await this.init(); - console.log("Attempting to add RedirectUri and WebOrigins"); + console.log("Attempting to remove RedirectUri and WebOrigins"); - const { data, redirectUris} = await this.getUris(); + const { data, redirectUris } = await this.getUris(); - const putData = { id: data.id, clientId: data.clientId }; + const putData = { id: data.id, clientId: data.clientId }; - const hasRedirectUris = redirectUris.find(item => - item.includes(this.zevaHost) - ); + const hasRedirectUris = redirectUris.find((item) => + item.includes(this.zevaHost), + ); - if (!hasRedirectUris) { - redirectUris.push(`https://${this.zevaHost}/*`); - putData.redirectUris = redirectUris; - } - - if (!(hasRedirectUris)) { - this.api - .put(this.zevaPublicClientPath, putData) - .then(() => console.log("RedirectUri and WebOrigins added.")); - } else { - console.log("RedirectUri and WebOrigins add skipped."); - } + if (hasRedirectUris) { + putData.redirectUris = redirectUris.filter( + (item) => !item.includes(this.zevaHost), + ); } - async removeUris() { - await this.init(); - - console.log("Attempting to remove RedirectUri and WebOrigins"); - - const { data, redirectUris } = await this.getUris(); - - const putData = { id: data.id, clientId: data.clientId }; - - const hasRedirectUris = redirectUris.find(item => - item.includes(this.zevaHost) - ); - - if (hasRedirectUris) { - putData.redirectUris = redirectUris.filter( - item => !item.includes(this.zevaHost) - ); - } - - if (hasRedirectUris) { - this.api - .put(this.zevaPublicClientPath, putData) - .then(() => console.log("RedirectUri and WebOrigins removed.")); - } else { - console.log("RedirectUri and WebOrigins remove skipped."); - } - + if (hasRedirectUris) { + this.api + .put(this.zevaPublicClientPath, putData) + .then(() => console.log("RedirectUri and WebOrigins removed.")); + } else { + console.log("RedirectUri and WebOrigins remove skipped."); } + } }; diff --git a/README.md b/README.md index 7b1a67cf..1bee4d3e 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,48 @@ # CTHUB + The Clean Transportation Data Hub provides an evidence base for the Clean Transportation Branch through data storage, analysis and visualization, that improves decision making to increase energy efficiency and de-carbonise the transportation system. It aims to be the most comprehensive, reliable and accessible data management system for clean transportation in the world. # Docker Instructions + - Make sure Docker is installed and running -- In your terminal, go to your project folder and execute the following: - - ```docker-compose up``` +- In your terminal, go to your project folder and execute the following: + - `docker-compose up` ## Useful Docker Commands - To access postgres: + - Go to your project folder in your terminal - Execute the following: - - ```docker-compose exec db psql -U postgres``` + - `docker-compose exec db psql -U postgres` - Some notes about the structure of the command - docker-compose exec - this is your standard command to execute something within the context of the docker-compose yml file - db - this is the service you want to execute your command in - psql -U postgres - execute psql with a the default user of postgres - To access the backend: (to do migrations and other stuff with the backend) + - Go to your project folder in your terminal - Execute the following: - - ```docker-compose exec api bash``` + - `docker-compose exec api bash` - Here you can do your standard django stuff like: - - ```python manage.py makemigrations``` - - ```python manage.py migrate``` + - `python manage.py makemigrations` + - `python manage.py migrate` - To access the frontend: (to install/update a package, etc) + - Go to your project folder in your terminal - Execute the following: - - ```docker-compose exec web bash``` + + - `docker-compose exec web bash` - This is where you can make changes to your package.json - You can technically make changes to your packages without going into your container, but you'll need npm installed into your system - - To run in testing mode - if you don't have docker-compose-local-dev.yml locally, create a new file and - add the contents from docker-compose plus a line for: - - KEYCLOAK_TESTING=True - in api environment - + if you don't have docker-compose-local-dev.yml locally, create a new file and + add the contents from docker-compose plus a line for: - KEYCLOAK_TESTING=True + in api environment + to run using this docker file: docker-compose -f docker-compose-local-dev.yml up @@ -46,26 +50,29 @@ The Clean Transportation Data Hub provides an evidence base for the Clean Transp and uses the user table to get permissions # Rebasing Guide + - To rebase your branch onto the latest release branch: - - ```git fetch upstream``` - - ```git checkout your_branch``` - - ```git rebase --onto A B``` - - Where `upstream` is the remote containing the release branch, and `A` is the hash of the latest commit to the release branch, and `B` is the hash of the commit in `your_branch` such that every commit after `B` ought to be rebased onto the release branch. - - If you run into conflicts while rebasing, you can resolve them in your IDE, and `git add` the resolved changes before finishing the rebase (committing). - - The rebased commits will have different hashes than the old ones, so if you previously pushed `your_branch` to a remote you will have to `git push --force` in order not to end up with additional commits in your remote branch. - - On Github, you can modify the base branch of a PR if you're rebasing from a branch based on a previous release branch to the latest release branch. +- `git fetch upstream` +- `git checkout your_branch` +- `git rebase --onto A B` +- Where `upstream` is the remote containing the release branch, and `A` is the hash of the latest commit to the release branch, and `B` is the hash of the commit in `your_branch` such that every commit after `B` ought to be rebased onto the release branch. +- If you run into conflicts while rebasing, you can resolve them in your IDE, and `git add` the resolved changes before finishing the rebase (committing). +- The rebased commits will have different hashes than the old ones, so if you previously pushed `your_branch` to a remote you will have to `git push --force` in order not to end up with additional commits in your remote branch. +- On Github, you can modify the base branch of a PR if you're rebasing from a branch based on a previous release branch to the latest release branch. # Metabase + - Locally, create a database to store metabase's internals, and use/modify `metabase.env`, django's `settings.DATABASES` and `settings.DATABASE_ROUTERS` to point to said database. - You can create django data migrations to insert your custom queries into the metabase application database. - To create a data migration within the metabase django app: -- ```python manage.py makemigrations --empty metabase``` +- `python manage.py makemigrations --empty metabase` - Then, using `RunPython` and django's `QuerySet` API, you may read/insert/update/delete data from metabase's application database. - For custom queries, the internal metabase table of interest would probably be `report_card` (the associated model is `ReportCard`). - To make your `RunPython` "script" cleaner, consider putting the actual queries themselves in separate sql files and reading from those in `RunPython` - To uncouple metabase from django, simply remove metabase from `settings.INSTALLED_APPS`. # Updating packages + - From time to time, we may become aware of package updates (mainly the packages in package.json (frontend) and requirements.py (backend)). - Tools like Dependabot (https://github.com/dependabot) may raise PRs that update these packages. - If the package that can be updated is a npm package and is a transitive dependency (a dependency of an immediate dependency), we can implement the update using `overrides` (https://docs.npmjs.com/cli/v10/configuring-npm/package-json#overrides). @@ -73,27 +80,27 @@ The Clean Transportation Data Hub provides an evidence base for the Clean Transp - When an entire image is scanned by some tool, there may be deeper, OS level dependencies that show as being critically out of date/vulnerable; in cases like this, if an updated image is not yet available, there are usually `alpine` versions of images that simply don't include many of these dependencies; whether they will work for our purposes is another question. # License -The code is a fork from Richard's personal project. Please do not clone, copy or replicate this project unless you're authorized to do so. +The code is a fork from Richard's personal project. Please do not clone, copy or replicate this project unless you're authorized to do so. # List of Dev Work | What to do before bringing in a new ticket into a Sprint -This is a list that was created on 2023-02-01 with all Zelda Devs to provide alternative work instead of bringing in a new ticket. +This is a list that was created on 2023-02-01 with all Zelda Devs to provide alternative work instead of bringing in a new ticket. -**Team Rule* Do not bring in ticket After Friday +\*_Team Rule_ Do not bring in ticket After Friday -1. Help another Dev - see if other Devs need help to finish their ticket +1. Help another Dev - see if other Devs need help to finish their ticket -2. PR Reviews – linked to the task above +2. PR Reviews – linked to the task above -3. Writing additional tests – for both tront and back end +3. Writing additional tests – for both tront and back end -4. Take a look at Tech Debt tickets - If we bring in tickets let's bring in Tech Debt first +4. Take a look at Tech Debt tickets - If we bring in tickets let's bring in Tech Debt first -5. Learning time: +5. Learning time: -- Take the opportunity to familiarize yourself with business logic, tech (anything around work we do) +- Take the opportunity to familiarize yourself with business logic, tech (anything around work we do) -- New learning and applying it to our work +- New learning and applying it to our work -- Innovation work +- Innovation work diff --git a/charts/cthub-spilo/Readme.md b/charts/cthub-spilo/Readme.md index 71d31279..ff7fa6d6 100644 --- a/charts/cthub-spilo/Readme.md +++ b/charts/cthub-spilo/Readme.md @@ -1,27 +1,33 @@ ## Before running Helm -* Create secret cthub-patroni-admin - * Create the secret by using cthub/openshift/templates/spilo/cthub-patroni-admin.yaml, the three passwords are generated randomly -* Create secret cthub-patroni-app - * Create the secret by using cthub/openshift-v4/templates/spilo/cthub-patroni-app.yaml, the three password fields must be in sync with the existing secret patroni-dev - * It contains: app-db-name, app-db-password, app-db-username, metabaseuser-name, metabaseuser-password - * The replication- and superuser- are not needed - * If this secret is aleady existed, please verify the password fields +- Create secret cthub-patroni-admin -* Create Object Storage secret for database continuous backup, cthub-object-storage - * Create the secret by using cthub/openshift-v4/templates/object-storage/object-storage-secret.yaml - * The secret should have been created, verify it by using CyberDuck + - Create the secret by using cthub/openshift/templates/spilo/cthub-patroni-admin.yaml, the three passwords are generated randomly -* Create secret cthub-db-backup-s3 - * It includes AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_ENDPOINT - * The values are in sync with secret cthub-object-storage +- Create secret cthub-patroni-app -* Verify values-dev.yaml. Create the bucket on object storage if needed + - Create the secret by using cthub/openshift-v4/templates/spilo/cthub-patroni-app.yaml, the three password fields must be in sync with the existing secret patroni-dev + - It contains: app-db-name, app-db-password, app-db-username, metabaseuser-name, metabaseuser-password + - The replication- and superuser- are not needed + - If this secret is aleady existed, please verify the password fields -* Add new KNPs templates/knp/knp-env-pr-new-cthub-spilo.yaml - * oc process -f ./knp-env-pr-new-cthub-spilo.yaml ENVIRONMENT=test | oc apply -f - -n 30b186-dev +- Create Object Storage secret for database continuous backup, cthub-object-storage + + - Create the secret by using cthub/openshift-v4/templates/object-storage/object-storage-secret.yaml + - The secret should have been created, verify it by using CyberDuck + +- Create secret cthub-db-backup-s3 + + - It includes AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_ENDPOINT + - The values are in sync with secret cthub-object-storage + +- Verify values-dev.yaml. Create the bucket on object storage if needed + +- Add new KNPs templates/knp/knp-env-pr-new-cthub-spilo.yaml + - oc process -f ./knp-env-pr-new-cthub-spilo.yaml ENVIRONMENT=test | oc apply -f - -n 30b186-dev ## Heml command + helm install -n 30b186-dev -f ./values-dev.yaml cthub-spilo . helm uninstall -n 30b186-dev cthub-spilo @@ -32,51 +38,59 @@ helm uninstall -n 30b186-dev cthub-spilo ### Run a final backup on backup container ### Create cthub database user and database -* Login to the cthub-spilo leader pod -* If the username contains upper case letters, should be double quoted - * create user for cthub database, the username should be the same on v10 otherwise the restore may encounter issue - * create user [username] with password '[password]' - * The password can be found in secret cthub-patroni-app - * create cthub database - * create database cthub owner [username] ENCODING 'UTF8' LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8' + +- Login to the cthub-spilo leader pod +- If the username contains upper case letters, should be double quoted + - create user for cthub database, the username should be the same on v10 otherwise the restore may encounter issue + - create user [username] with password '[password]' + - The password can be found in secret cthub-patroni-app + - create cthub database + - create database cthub owner [username] ENCODING 'UTF8' LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8' + ### Reset postgresql logging -* login cthub-spilo leader pod, run the following psql to only keep 24 hours log files, otherwise they take too much space - ALTER SYSTEM SET log_filename='postgresql-%H.log'; - ALTER SYSTEM SET log_connections='off'; - ALTER SYSTEM SET log_disconnections='off'; - ALTER SYSTEM SET log_checkpoints='off'; - select pg_reload_conf(); + +- login cthub-spilo leader pod, run the following psql to only keep 24 hours log files, otherwise they take too much space + ALTER SYSTEM SET log_filename='postgresql-%H.log'; + ALTER SYSTEM SET log_connections='off'; + ALTER SYSTEM SET log_disconnections='off'; + ALTER SYSTEM SET log_checkpoints='off'; + select pg_reload_conf(); + ### Create metabase user -* login cthub-spilo leader pod - CREATE USER metabaseuser WITH PASSWORD 'xxxxxx'; - GRANT CONNECT ON DATABASE cthub TO metabaseuser; - GRANT USAGE ON SCHEMA public TO metabaseuser; - GRANT SELECT ON ALL TABLES IN SCHEMA public TO metabaseuser; - ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO metabaseuser; - verify permissions are granted: select * from information_schema.role_table_grants where grantee='metabaseuser'; + +- login cthub-spilo leader pod + CREATE USER metabaseuser WITH PASSWORD 'xxxxxx'; + GRANT CONNECT ON DATABASE cthub TO metabaseuser; + GRANT USAGE ON SCHEMA public TO metabaseuser; + GRANT SELECT ON ALL TABLES IN SCHEMA public TO metabaseuser; + ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO metabaseuser; + verify permissions are granted: select \* from information_schema.role_table_grants where grantee='metabaseuser'; ## Backup the existing v10 database and restore to v14 cluster -* Make sure the application is stopped -* Login to patroni-dev leader pod - * make an empty dir /home/postgres/migration and cd into it - * backup cthub database: pg_dump cthub > cthub.sql -* Restore cthub database - * psql cthub < ./cthub.sql >> ./restore.log 2>&1 - * verify the restore.log when complete - -* Point the applications to v14 cluster, update the enviuronment variables for - * backend: DATABASE_SERVICE_NAME, POSTGRESQL_SERVICE_HOST - * celery: DATABASE_SERVICE_NAME - * scan-handler: DATABASE_SERVICE_NAME -* Bring down the v10 cluster -* Bring down the maintenance page -* Bring up the cthub appliation -* Update patroni backup to only backup minio data -* Update metabase connection from CTHUB -* Update dbServiceName to be cthub-spilo in .pipeline/lib/config.js + +- Make sure the application is stopped +- Login to patroni-dev leader pod + - make an empty dir /home/postgres/migration and cd into it + - backup cthub database: pg_dump cthub > cthub.sql +- Restore cthub database + + - psql cthub < ./cthub.sql >> ./restore.log 2>&1 + - verify the restore.log when complete + +- Point the applications to v14 cluster, update the enviuronment variables for + - backend: DATABASE_SERVICE_NAME, POSTGRESQL_SERVICE_HOST + - celery: DATABASE_SERVICE_NAME + - scan-handler: DATABASE_SERVICE_NAME +- Bring down the v10 cluster +- Bring down the maintenance page +- Bring up the cthub appliation +- Update patroni backup to only backup minio data +- Update metabase connection from CTHUB +- Update dbServiceName to be cthub-spilo in .pipeline/lib/config.js ## Notes for uninstalling cthub-spilo when needed -* After the helm uninstall command, remember to remove the followings: - * The two configmaps: cthub-spilo-config, cthub-spilo-leader - * The PVCs storage-volume-cthub-spilo-* - * The backup bucket in object storage + +- After the helm uninstall command, remember to remove the followings: + - The two configmaps: cthub-spilo-config, cthub-spilo-leader + - The PVCs storage-volume-cthub-spilo-\* + - The backup bucket in object storage diff --git a/charts/spilo/docs/restore.md b/charts/spilo/docs/restore.md index 4f806707..81679496 100644 --- a/charts/spilo/docs/restore.md +++ b/charts/spilo/docs/restore.md @@ -8,11 +8,14 @@ Make sure there are no connections to the database cluster. ### Stop Patroni failover and shutdown Postgresql database -1. On the leader pod, disable the failover +1. On the leader pod, disable the failover + ``` $ patronictl pause [patroni cluster name] ``` -2. On the the secondary pods, stop the postgresql databse + +2. On the the secondary pods, stop the postgresql databse + ``` $ pg_ctl stop ``` @@ -20,6 +23,7 @@ $ pg_ctl stop 3. On leader pod, stop the postgresql databse by running the same command as above 4. Make sure all pods are stopped and maintenance mode is on + ``` $ patronictl list ``` @@ -29,13 +33,16 @@ $ patronictl list Retrieve the latest base backup and all archieved WAL files. 1. On the leader pod, fetch the latest backup from S3 Object Storage + ``` $ envdir /run/etc/wal-e.d/env wal-g backup-fetch /home/postgres/pgdata/pgroot/latest-backup LATEST It copies the latest base backup base_0000..0037 according to the sample below. ``` + ![archieved files on S3 storage](./s3.png) - + 2. Rename data folder to data-ori and rename latest-backup to data + ``` $ cd /home/postgres/pgdata/pgroot $ mv data data-ori @@ -45,7 +52,8 @@ $ mv latest-backup data 3. Download, unzip and copy the files under wal_005 folder to /home/postgres/pgdata/pgroot/allWALs 4. Copy the files didn't had a chance to be archieved -Compare the files under /home/postgres/pgdata/pgroot/data-ori/pg_wal and the filder under wal_005 folder and copy the additional files to /home/postgres/pgdata/pgroot/allWALs if there are any + Compare the files under /home/postgres/pgdata/pgroot/data-ori/pg_wal and the filder under wal_005 folder and copy the additional files to /home/postgres/pgdata/pgroot/allWALs if there are any + ``` According to the sample, the final files in allWALs folder should be 000000010000000000000037.00000028.backup -- from S3 storage @@ -58,16 +66,19 @@ According to the sample, the final files in allWALs folder should be ### Restore 1. Create recovery.signal file + ``` $ touch /home/postgres/pgdata/pgroot/data/recovery.signal ``` 2. Add the recovery command to postgresql.conf + ``` restore_command = 'cp /home/postgres/pgdata/pgroot/allWALs/%f "%p"' ``` 3. Start the postgresql on the leader pod + ``` $ pg_ctl start The file recovery.signal will be removed @@ -78,10 +89,10 @@ The file recovery.signal will be removed 5. Run patronistl list, the maintenance mond is still on 6. Resume the patroni cluster on the leader pod + ``` $ patronictl resume ``` + Now the patroni cluster is fully restored, login to the database to verify the laest changes The restore_command=.. in postgresql.conf is removed automatically. - - diff --git a/django/README.md b/django/README.md index 6bb2b6a2..5e497ad1 100644 --- a/django/README.md +++ b/django/README.md @@ -1,7 +1,9 @@ # Backend ## Database Migrations + Create migration + ```bash # Log in to the api docker docker-compose exec api bash @@ -18,38 +20,44 @@ docker-compose exec db psql -U postgres ``` If you need to change a migration you can back up by doing the following: + 1. List the migrations to find where you want to go back to -> `python manage.py showmigrations` + > `python manage.py showmigrations` 2. Move migration to the appropriat state -> `python manage.py migrate --fake api 0003_name_of_migration_before_one_to_redo` + > `python manage.py migrate --fake api 0003_name_of_migration_before_one_to_redo` 3. Delete the migration file 4. Delete table if necessary 5. Re-run migration -> `python manage.py makemigrations` - + > `python manage.py makemigrations` ## Data Loads + Copy the spreadsheet into the _api_ docker container. + ```bash docker cp 'EV_Fast-Charging Stations_20210520.xlsx' cthub_api_1:/tmp/ ``` + This can also be done by temporarily placing the Excel file in the _django_ folder. This location is mounted onto the container. Log into the docker container and run the following command. + ```bash python manage.py import_charger_rebates '/tmp/EV_Fast-Charging Stations_20210520.xlsx' ``` ## Fixtures + If docker doesn't load your fixtures and the dataset dropdown list is empty use use the same as above to load fixtures docker-compose exec api bash -python manage.py loaddata api/fixtures/0001_add_ldv_rebates_datasets.json -or -python manage.py loaddata api/fixtures/00* +python manage.py loaddata api/fixtures/0001_add_ldv_rebates_datasets.json +or +python manage.py loaddata api/fixtures/00\* ## Creating User Account + After running all the fixtures to create the dataset dropdown list and the user_permissions table. You will need to run a few SQL commands to allow your account to upload documents locally. @@ -58,4 +66,4 @@ insert into user_permission (create_user, permission_id, user_id) values ('test' insert into user_permission (create_user, permission_id, user_id) values ('test', 2, 1); Only after running these will you be able to upload into CTHUB locally. -If you're encountering errors make sure you've run the fixture for creating the user_permission table and that you're not missing any fields in SQL. \ No newline at end of file +If you're encountering errors make sure you've run the fixture for creating the user_permission table and that you're not missing any fields in SQL. diff --git a/frontend/src/uploads/UploadContainer.js b/frontend/src/uploads/UploadContainer.js index a30cc902..0856d9c8 100644 --- a/frontend/src/uploads/UploadContainer.js +++ b/frontend/src/uploads/UploadContainer.js @@ -64,18 +64,17 @@ const UploadContainer = () => { errors: 0, warnings: 0, }; - + issueArray.forEach((issue) => { - Object.keys(issue).forEach((column) => { const errorDetails = issue[column]; - + Object.keys(errorDetails).forEach((errorType) => { const severity = errorDetails[errorType].Severity; const expectedType = errorDetails[errorType]["Expected Type"]; const rows = errorDetails[errorType].Rows; const rowCount = rows.length; - + if (severity === "Error") { totalIssueCount.errors += rowCount; if (!groupedErrors[column]) { @@ -106,11 +105,9 @@ const UploadContainer = () => { }); }); }); - + return { groupedErrors, groupedWarnings, totalIssueCount }; }; - - const showError = (error) => { const { response: errorResponse } = error; @@ -153,15 +150,13 @@ const UploadContainer = () => { Promise.all(uploadPromises) .then((responses) => { - const errorCheck = responses.some( - (response) => !response.data.success - ); + const errorCheck = responses.some((response) => !response.data.success); setAlertSeverity(errorCheck ? "error" : "success"); const message = responses .map( (response) => - `${response.data.message}${response.data.errors ? "\nErrors: " + response.data.errors.join("\n") : ""}` + `${response.data.message}${response.data.errors ? "\nErrors: " + response.data.errors.join("\n") : ""}`, ) .join("\n"); setAlert(true); @@ -210,7 +205,6 @@ const UploadContainer = () => { confirmAction: () => setOpenDialog(false), }); setOpenDialog(true); - } }) .catch((error) => { @@ -265,14 +259,14 @@ const UploadContainer = () => { }; const handleConfirmDataInsert = () => { - setGroupedWarnings({}) - setGroupedErrors({}) - setTotalIssueCount({}) + setGroupedWarnings({}); + setGroupedErrors({}); + setTotalIssueCount({}); setOpenDialog(false); setAlert(false); setAlertContent(""); doUpload(false); // Upload with the checkForWarnings flag set to false! - setUploadFiles([]) + setUploadFiles([]); }; const handleReplaceDataConfirm = () => { @@ -304,57 +298,57 @@ const UploadContainer = () => { ) : null; - return ( -
-
- <> - - - {(totalIssueCount.errors > 0 || totalIssueCount.warnings > 0) && ( - - - - )} - - +
+ <> + + + {(totalIssueCount.errors > 0 || totalIssueCount.warnings > 0) && ( + + - {adminUser && ( - - - - )} - - -
+ )} + + + + {adminUser && ( + + + + )} +
+
- ); - }; +
+ ); +}; export default withRouter(UploadContainer); diff --git a/frontend/src/uploads/components/UploadIssuesDetail.js b/frontend/src/uploads/components/UploadIssuesDetail.js index f2d93ba3..59ce7d65 100644 --- a/frontend/src/uploads/components/UploadIssuesDetail.js +++ b/frontend/src/uploads/components/UploadIssuesDetail.js @@ -38,7 +38,9 @@ const UploadIssuesDetail = ({ type, issues, totalIssueCount, msg }) => { Column: {column} {Object.keys(issues[column]).map((errorType, index) => (
-
{type.charAt(0).toUpperCase() + type.slice(1)} Name: {errorType}
+
+ {type.charAt(0).toUpperCase() + type.slice(1)} Name: {errorType} +
Expected value:{" "} {issues[column][errorType].ExpectedType || diff --git a/frontend/src/users/UsersContainer.js b/frontend/src/users/UsersContainer.js index 745d31f9..e4a7c4a7 100644 --- a/frontend/src/users/UsersContainer.js +++ b/frontend/src/users/UsersContainer.js @@ -57,7 +57,7 @@ const UsersContainer = (props) => { userToChange.user_permissions[permissionType] = checked; }), ); - setSaveButtonEnabled(true) + setSaveButtonEnabled(true); }, []); const handleDeleteUserClick = (idir) => { diff --git a/frontend/src/users/components/UsersPage.js b/frontend/src/users/components/UsersPage.js index 20304553..a0e124c5 100644 --- a/frontend/src/users/components/UsersPage.js +++ b/frontend/src/users/components/UsersPage.js @@ -23,7 +23,7 @@ const UsersPage = (props) => { newUser, setMessage, handleXClick, - saveButtonEnabled + saveButtonEnabled, } = props; const userRow = (user) => { diff --git a/openshift/README.md b/openshift/README.md index 7376164b..2f8da02f 100644 --- a/openshift/README.md +++ b/openshift/README.md @@ -1,30 +1,36 @@ # Openshift ## Grant Developer's access -* Create the edit/admin RoleBinding for developers GitHub account, + +- Create the edit/admin RoleBinding for developers GitHub account, - kind: User apiGroup: rbac.authorization.k8s.io name: @github - + ## Add role to group otherwise dev, test and prod can't pull images from tools + oc policy add-role-to-group system:image-puller system:serviceaccounts:30b186-dev -n 30b186-tools oc policy add-role-to-group system:image-puller system:serviceaccounts:30b186-test -n 30b186-tools oc policy add-role-to-group system:image-puller system:serviceaccounts:30b186-prod -n 30b186-tools ## Keycloak + openshift/templates/keycloak/README.md ## Minio + openshift/templates/minio/README.md ## Patroni + openshift/templates/patroni-2.1.1/README.md ## Backend + openshift/templates/backend/README.md ## Frontend + openshift/templates/frontend/README.md ## Backup Container - diff --git a/openshift/templates/backend/README.md b/openshift/templates/backend/README.md index f6b579aa..be31c01e 100644 --- a/openshift/templates/backend/README.md +++ b/openshift/templates/backend/README.md @@ -1,4 +1,5 @@ ### Files included + * backend-bc.yaml backend build config * backend-dc.yaml backend deployment config * django-secret-template.yaml create template.django-secret, it is not in pipeline and needs to run independently, it is used by backend-dc.yaml diff --git a/openshift/templates/backup-container-2.3.3/openshift/README.md b/openshift/templates/backup-container-2.3.3/openshift/README.md index 7f63f1ac..074b778a 100644 --- a/openshift/templates/backup-container-2.3.3/openshift/README.md +++ b/openshift/templates/backup-container-2.3.3/openshift/README.md @@ -1,44 +1,45 @@ ### Files included -* backup-build.yaml build backup container image -* backup-config.yaml create backup-conf configmap -* backup-deploy.yaml deploy backup container + +- backup-build.yaml build backup container image +- backup-config.yaml create backup-conf configmap +- backup-deploy.yaml deploy backup container ## Setup Backup container,use Test as example + 1. Build patroni-backup image -oc -n 30b186-tools process -f ./backup/backup-build.yaml \ --p NAME=patroni-backup GIT_REPO_URL=https://github.com/BCDevOps/backup-container.git GIT_REF=2.3.3 OUTPUT_IMAGE_TAG=2.3.3 \ -| oc -n 30b186-tools apply -f - + oc -n 30b186-tools process -f ./backup/backup-build.yaml \ + -p NAME=patroni-backup GIT_REPO_URL=https://github.com/BCDevOps/backup-container.git GIT_REF=2.3.3 OUTPUT_IMAGE_TAG=2.3.3 \ + | oc -n 30b186-tools apply -f - 2. Create the configmap in env project 3. add to ./config/backup.conf, 9pm run backup, 10pm run verification -postgres=patroni-master-test:5432/cthub -postgres=patroni-master-test-metabase:5432/metabase -0 1 * * * default ./backup.sh -s -0 7 * * * default ./backup.sh -s -0 13 * * * default ./backup.sh -s -0 19 * * * default ./backup.sh -s -0 22 * * * default ./backup.sh -s -v all + postgres=patroni-master-test:5432/cthub + postgres=patroni-master-test-metabase:5432/metabase + 0 1 \* \* _ default ./backup.sh -s + 0 7 _ \* _ default ./backup.sh -s + 0 13 _ \* _ default ./backup.sh -s + 0 19 _ \* _ default ./backup.sh -s + 0 22 _ \* \* default ./backup.sh -s -v all 4. create deployment config for backup container -4.1 for test -oc -n 30b186-test process -f ./backup-deploy.yaml \ - -p NAME=patroni-backup \ - -p ENV_NAME_UPPERCASE=TEST \ - -p ENV_NAME_LOWERCASE=test \ - -p BACKUP_STRATEGY=rolling \ - -p BACKUP_DIR=/backups/patroni-backup/ \ - -p DAILY_BACKUPS=28 \ - -p WEEKLY_BACKUPS=16 \ - -p MONTHLY_BACKUPS=4 \ - -p CONFIG_MAP_NAME=backup-conf \ - -p CONFIG_MOUNT_PATH=/ \ - -p BACKUP_VOLUME_NAME=backup-test \ - -p VERIFICATION_VOLUME_NAME=backup-verification-test \ - -p VERIFICATION_VOLUME_MOUNT_PATH=/var/lib/pgsql/data \ - -p CPU_REQUEST=35m \ - -p CPU_LIMIT=70m \ - -p MEMORY_REQUEST=50Mi \ - -p MEMORY_LIMIT=100Mi \ - | oc create -f - -n 30b186-test - + 4.1 for test + oc -n 30b186-test process -f ./backup-deploy.yaml \ + -p NAME=patroni-backup \ + -p ENV_NAME_UPPERCASE=TEST \ + -p ENV_NAME_LOWERCASE=test \ + -p BACKUP_STRATEGY=rolling \ + -p BACKUP_DIR=/backups/patroni-backup/ \ + -p DAILY_BACKUPS=28 \ + -p WEEKLY_BACKUPS=16 \ + -p MONTHLY_BACKUPS=4 \ + -p CONFIG_MAP_NAME=backup-conf \ + -p CONFIG_MOUNT_PATH=/ \ + -p BACKUP_VOLUME_NAME=backup-test \ + -p VERIFICATION_VOLUME_NAME=backup-verification-test \ + -p VERIFICATION_VOLUME_MOUNT_PATH=/var/lib/pgsql/data \ + -p CPU_REQUEST=35m \ + -p CPU_LIMIT=70m \ + -p MEMORY_REQUEST=50Mi \ + -p MEMORY_LIMIT=100Mi \ + | oc create -f - -n 30b186-test diff --git a/openshift/templates/backup-container-2.6.1/cronjob.md b/openshift/templates/backup-container-2.6.1/cronjob.md index 25b81607..e8fee3d3 100644 --- a/openshift/templates/backup-container-2.6.1/cronjob.md +++ b/openshift/templates/backup-container-2.6.1/cronjob.md @@ -1,12 +1,14 @@ # Cronjob prerequisites + Backup PVC: backup KNP: allow CronJob to connect to Spilo # Create database backup cronjob + oc process -f ./db-backup-cronjob-2.6.1.yaml \ JOB_NAME=cthub-db-backup \ JOB_PERSISTENT_STORAGE_NAME=backup \ -SCHEDULE="00 07,21 * * *" \ +SCHEDULE="00 07,21 \* \* \*" \ TAG_NAME=2.6.1 \ DATABASE_SERVICE_NAME=cthub-test-crunchy-replicas \ DATABASE_DEFAULT_PORT=5432 \ @@ -19,4 +21,3 @@ BACKUP_DIR=/backups \ DAILY_BACKUPS=30 \ WEEKLY_BACKUPS=8 \ MONTHLY_BACKUPS=2 | oc apply -f - -n 30b186-test - diff --git a/openshift/templates/crunchydb/readme.md b/openshift/templates/crunchydb/readme.md index 5e6205d2..4e20782d 100644 --- a/openshift/templates/crunchydb/readme.md +++ b/openshift/templates/crunchydb/readme.md @@ -2,30 +2,31 @@ ## Create CrunchyDB Cluster -Create Cluster +Create Cluster ## Migrate metabase database to CrunchyDB ### Create metabase user under psql prompt -create user ******** password '********'; + +create user **\*\*\*\*** password '**\*\*\*\***'; create database metabase owner metabaseuser ENCODING 'utf8' LC_COLLATE = 'en_US.utf-8' LC_CTYPE = 'en_US.utf-8'; CREATE EXTENSION IF NOT EXISTS citext WITH SCHEMA public; -CREATE EXTENSION IF NOT EXISTS set_user WITH SCHEMA public; +CREATE EXTENSION IF NOT EXISTS set_user WITH SCHEMA public; ### Dump and restore metabase data pg_dump -f matabase-data.sql -n public -d metabase -psql metabase < ./matabase-data.sql >> ./metabase-restore.log 2>&1 +psql metabase < ./matabase-data.sql >> ./metabase-restore.log 2>&1 -## Migrate cthub database to CrunchyDB +## Migrate cthub database to CrunchyDB -create user ******** password '********'; +create user **\*\*\*\*** password '**\*\*\*\***'; create database cthub owner cthubpqaitvng ENCODING 'utf8' LC_COLLATE = 'en_US.utf-8' LC_CTYPE = 'en_US.utf-8'; CREATE EXTENSION IF NOT EXISTS citext WITH SCHEMA public; -CREATE EXTENSION IF NOT EXISTS set_user WITH SCHEMA public; +CREATE EXTENSION IF NOT EXISTS set_user WITH SCHEMA public; ### Dump and restore cthub data -pg_dump -f cthub-data.sql -n public -d cthub +pg_dump -f cthub-data.sql -n public -d cthub psql cthub < ./cthub-data.sql >> ./cthub-restore.log 2>&1 - \ No newline at end of file + diff --git a/openshift/templates/keycloak/README.md b/openshift/templates/keycloak/README.md index 10a48e20..bea2d25d 100644 --- a/openshift/templates/keycloak/README.md +++ b/openshift/templates/keycloak/README.md @@ -1,5 +1,7 @@ ### Files included -* keycloak-secret.yaml includes keycloak secrets + +- keycloak-secret.yaml includes keycloak secrets ### Create Secret keycloak-secret.yaml in tools, dev, test and prod env. The value for tools and dev should be same -* The values in the keycloak-secret.yaml are from https://bcgov.github.io/sso-requests/ + +- The values in the keycloak-secret.yaml are from https://bcgov.github.io/sso-requests/ diff --git a/openshift/templates/metabase-postgresql/README.md b/openshift/templates/metabase-postgresql/README.md index e4232fd9..44a2f918 100644 --- a/openshift/templates/metabase-postgresql/README.md +++ b/openshift/templates/metabase-postgresql/README.md @@ -1,29 +1,35 @@ ## Files included -* Dockerfile build metabase -* metabase-bc.yaml build metabase image on Openshift -* metabase-dc.yaml deploy metabase image on Openshift + +- Dockerfile build metabase +- metabase-bc.yaml build metabase image on Openshift +- metabase-dc.yaml deploy metabase image on Openshift ## Metabase to TFRS and ZEVA database access + The network policy allow-patroni-accepts-cthub-metabase-test in both TFRS and ZEVA open the access from the Metabase in CTHUB. ## Create read only user metabaseuser in TFRS, ZEVA and ITVR for Metabase connection from CTHUB + ```//login zeva database as postgres user, psql zeva CREATE USER metabaseuser WITH PASSWORD 'xxxxxx'; GRANT CONNECT ON DATABASE [tfrs/zeva/itvr] TO metabaseuser; GRANT USAGE ON SCHEMA public TO metabaseuser; GRANT SELECT ON ALL TABLES IN SCHEMA public TO metabaseuser; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO metabaseuser; -// verify permissions are granted. +// verify permissions are granted. // select * from information_schema.role_table_grants where grantee='metabaseuser'; ``` + Notes: replace zeva to be tfrs when ron on TFRS project Login to metabase pod and test the connection to tfrs and zeva database Remember store the metabaseuser password in a secret When create database connection in Metabase console, use the patroni master service otherwise the tables will not be shown + ``` curl [patroni master service name].e52f12-[env].svc.cluster.local:5432 ``` ## Notes -* Use metabase-dc-spilo.yaml to deploy metabase with spilo -* Use metabase-dc.yaml to deploy metabase with patroni v12 + +- Use metabase-dc-spilo.yaml to deploy metabase with spilo +- Use metabase-dc.yaml to deploy metabase with patroni v12 diff --git a/openshift/templates/metabase/README.md b/openshift/templates/metabase/README.md index 29ecec6e..5b25b6a3 100644 --- a/openshift/templates/metabase/README.md +++ b/openshift/templates/metabase/README.md @@ -1,6 +1,7 @@ ## Files included -* Dockerfile build metabase -* metabase-bc.yaml build metabase image on Openshift -* metabase-dc.yaml deploy metabase image on Openshift -Notes: the image uses file system as metabase database storage \ No newline at end of file +- Dockerfile build metabase +- metabase-bc.yaml build metabase image on Openshift +- metabase-dc.yaml deploy metabase image on Openshift + +Notes: the image uses file system as metabase database storage diff --git a/openshift/templates/minio/README.md b/openshift/templates/minio/README.md index 1dfbda0e..35f3fba9 100644 --- a/openshift/templates/minio/README.md +++ b/openshift/templates/minio/README.md @@ -1,8 +1,8 @@ ### Files included -* minio-bc.yaml minio build config -* minio-dc.yaml minio deployment config -* secret-template.yaml the secret template +- minio-bc.yaml minio build config +- minio-dc.yaml minio deployment config +- secret-template.yaml the secret template ### build minio @@ -24,4 +24,4 @@ NAME=cthub ENV_NAME=test SUFFIX=-test \ oc process -f ./minio-dc.yaml \ NAME=cthub ENV_NAME=prod SUFFIX=-prod \ -| oc create -f - -n 30b186-prod \ No newline at end of file +| oc create -f - -n 30b186-prod diff --git a/openshift/templates/patroni-2.1.1/README.md b/openshift/templates/patroni-2.1.1/README.md index af3c72b7..b1b3146a 100644 --- a/openshift/templates/patroni-2.1.1/README.md +++ b/openshift/templates/patroni-2.1.1/README.md @@ -1,12 +1,14 @@ ## Build and deploy Patroni 2.1.1 on top of Postgresql 12.4 ### Files included -* The files included are from https://github.com/bcgov/patroni-postgres-container.git -* The post_init.sh is changed to create extensions and metabase db and user -* The deploy.yaml is changed to provide metabase credentials + +- The files included are from https://github.com/bcgov/patroni-postgres-container.git +- The post_init.sh is changed to create extensions and metabase db and user +- The deploy.yaml is changed to provide metabase credentials ### How to create patroni cluster -* Use build.yaml to build patroni image and store it under tools project -* Use secret-template.yaml to create template.paroni-patroni -* Use deploy.yaml to deploy to test and prod environment -* For dev environment, patroni is part of pipeline + +- Use build.yaml to build patroni image and store it under tools project +- Use secret-template.yaml to create template.paroni-patroni +- Use deploy.yaml to deploy to test and prod environment +- For dev environment, patroni is part of pipeline diff --git a/openshift/templates/redis/readme.md b/openshift/templates/redis/readme.md index 538af9d9..5abcea9d 100644 --- a/openshift/templates/redis/readme.md +++ b/openshift/templates/redis/readme.md @@ -2,16 +2,16 @@ ## Source -* https://artifacthub.io/packages/helm/bitnami/redis +- https://artifacthub.io/packages/helm/bitnami/redis -* https://github.com/bitnami/charts/tree/main/bitnami/redis +- https://github.com/bitnami/charts/tree/main/bitnami/redis ### Install and Version -helm repo add bitnami https://charts.bitnami.com/bitnami +helm repo add bitnami https://charts.bitnami.com/bitnami helm -n 30b186-dev upgrade --install -f ./cthub-dev-values.yaml cthub-redis-dev bitnami/redis --version 18.2.0 -helm -n 30b186-test upgrade --install -f ./cthub-test-values.yaml cthub-redis-test bitnami/redis --version 18.2.0 +helm -n 30b186-test upgrade --install -f ./cthub-test-values.yaml cthub-redis-test bitnami/redis --version 18.2.0 helm -n 30b186-dev uninstall cthub-redis-dev diff --git a/openshift/templates/superset/readme.md b/openshift/templates/superset/readme.md index 9450d684..741f2753 100644 --- a/openshift/templates/superset/readme.md +++ b/openshift/templates/superset/readme.md @@ -1,28 +1,20 @@ - - https://artifacthub.io/packages/helm/superset/superset helm repo add superset http://apache.github.io/superset/ -helm upgrade --install --set +helm upgrade --install --set cthub-superset-dev superset/superset --version 0.10.14 - supersetNode.connections.redis_host=cthub-redis-dev-headless supersetNode.connections.redis_password=xxx supersetNode.connections.db_host=cthub-crunchy-dev-pgbouncer supersetNode.connections.db_user=xxx supersetNode.connections.db_pass=xxx - supersetNode.connections.redis_password=xxxxx\\ - create supersetuser in database update patroni secret to ass superset_username and superset_password create superset user and superset database in crunchy - - - diff --git a/superset/README.md b/superset/README.md index c867121d..329a38f4 100644 --- a/superset/README.md +++ b/superset/README.md @@ -47,8 +47,8 @@ Steps: 1. Create `./docker/requirements-local.txt` 2. Add your new packages 3. Rebuild docker-compose - 1. `docker-compose down -v` - 2. `docker-compose up` + 1. `docker-compose down -v` + 2. `docker-compose up` ## Initializing Database From 3eabf2ca76e6b122f827130183ead3d3c262569d Mon Sep 17 00:00:00 2001 From: Kuan Fan Date: Wed, 31 Jul 2024 12:13:44 -0700 Subject: [PATCH 06/14] add fail_on_error --- .github/workflows/prettier-test.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/prettier-test.yaml b/.github/workflows/prettier-test.yaml index 01042b8e..0f1d6ccf 100644 --- a/.github/workflows/prettier-test.yaml +++ b/.github/workflows/prettier-test.yaml @@ -29,4 +29,5 @@ jobs: uses: DataDog/action-py-black-formatter@v2.5 with: check_mode: "true" + fail_on_error: "false" \ No newline at end of file From 130392eb3c559401af0606c3c9d976c803c61cfe Mon Sep 17 00:00:00 2001 From: kuanfandevops Date: Wed, 31 Jul 2024 19:15:38 +0000 Subject: [PATCH 07/14] Prettified Code! --- openshift/templates/crunchydb/readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openshift/templates/crunchydb/readme.md b/openshift/templates/crunchydb/readme.md index 4e20782d..f0b21a4b 100644 --- a/openshift/templates/crunchydb/readme.md +++ b/openshift/templates/crunchydb/readme.md @@ -28,5 +28,4 @@ CREATE EXTENSION IF NOT EXISTS set_user WITH SCHEMA public; ### Dump and restore cthub data pg_dump -f cthub-data.sql -n public -d cthub -psql cthub < ./cthub-data.sql >> ./cthub-restore.log 2>&1 - +psql cthub < ./cthub-data.sql >> ./cthub-restore.log 2>&1 From c3f1763324af56a11a2b8ab64acd6d1c735568b0 Mon Sep 17 00:00:00 2001 From: Kuan Fan Date: Wed, 31 Jul 2024 12:16:56 -0700 Subject: [PATCH 08/14] remove checkomode --- .github/workflows/prettier-test.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/prettier-test.yaml b/.github/workflows/prettier-test.yaml index 0f1d6ccf..427d87e0 100644 --- a/.github/workflows/prettier-test.yaml +++ b/.github/workflows/prettier-test.yaml @@ -28,6 +28,5 @@ jobs: - name: Run python black code formatter uses: DataDog/action-py-black-formatter@v2.5 with: - check_mode: "true" fail_on_error: "false" \ No newline at end of file From d26d5bf0f811688c977bc00b3a3e35983411845a Mon Sep 17 00:00:00 2001 From: Kuan Fan Date: Wed, 31 Jul 2024 13:11:22 -0700 Subject: [PATCH 09/14] print current folder --- .github/workflows/prettier-test.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/prettier-test.yaml b/.github/workflows/prettier-test.yaml index 427d87e0..22d5109e 100644 --- a/.github/workflows/prettier-test.yaml +++ b/.github/workflows/prettier-test.yaml @@ -24,6 +24,10 @@ jobs: with: prettier_options: --write **/*.{js,md} + - name: pwd + run: | + pwd + ls -l - name: Run python black code formatter uses: DataDog/action-py-black-formatter@v2.5 From 8b47e39e777af8405bfa6a33751a24c6b9450160 Mon Sep 17 00:00:00 2001 From: Kuan Fan Date: Wed, 31 Jul 2024 13:18:03 -0700 Subject: [PATCH 10/14] push formatted py file back --- .github/workflows/prettier-test.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/prettier-test.yaml b/.github/workflows/prettier-test.yaml index 22d5109e..3d1dce90 100644 --- a/.github/workflows/prettier-test.yaml +++ b/.github/workflows/prettier-test.yaml @@ -33,4 +33,10 @@ jobs: uses: DataDog/action-py-black-formatter@v2.5 with: fail_on_error: "false" - \ No newline at end of file + + - name: Commit Python files + uses: EndBug/add-and-commit@v9.1.4 + with: + add: 'django' + committer_name: 'kuan' + message: 'python files changed after formater DataDog/action-py-black-formatter' \ No newline at end of file From e757cbb7e860707482561257ae912fa25243b59a Mon Sep 17 00:00:00 2001 From: kuanfandevops Date: Wed, 31 Jul 2024 20:18:53 +0000 Subject: [PATCH 11/14] python files changed after formater DataDog/action-py-black-formatter --- django/api/constants/constants.py | 39 +- django/api/constants/misc.py | 21 +- django/api/keycloak_authentication.py | 2 +- django/api/logging_filters.py | 11 +- .../commands/create_app_user_and_token.py | 2 +- django/api/migrations/0001_initial.py | 1 - django/api/migrations/0002_ldvrebates.py | 1 - .../migrations/0003_vindecodedinformation.py | 1 - .../api/migrations/0004_auto_20211116_1813.py | 1 - .../0005_vindecodedinformation_vin.py | 1 - .../0006_specialityusevehicleincentives.py | 1 - django/api/migrations/0007_datasets.py | 1 - django/api/migrations/0008_chargerrebates.py | 1 - django/api/migrations/0009_publiccharging.py | 1 - .../0010_chargerrebates_fix_columns.py | 1 - .../api/migrations/0011_auto_20211216_1944.py | 1 - .../api/migrations/0012_hydrogrenfueling.py | 1 - django/api/migrations/0013_hydrogenfleets.py | 1 - django/api/migrations/0014_datafleets.py | 1 - .../api/migrations/0015_arcprojecttracking.py | 1 - django/api/migrations/0016_scrapit.py | 1 - .../api/migrations/0017_whitelistedusers.py | 1 - .../api/migrations/0018_auto_20231201_2301.py | 1 - .../api/migrations/0019_auto_20240223_1820.py | 1 - .../api/migrations/0020_auto_20240311_2136.py | 1 - .../api/migrations/0021_auto_20240326_2152.py | 1 - .../api/migrations/0022_auto_20240503_1823.py | 66 +- .../api/migrations/0023_auto_20240514_1721.py | 209 +- .../api/migrations/0024_auto_20240516_2114.py | 79 +- .../api/migrations/0025_auto_20240516_2248.py | 11 +- .../0026_alter_uploadedvinsfile_chunk_size.py | 7 +- ...027_goelectricrebates_rebate_adjustment.py | 7 +- .../api/migrations/0028_auto_20240611_0251.py | 15 +- .../0029_alter_uploadedvinrecord_timestamp.py | 7 +- .../0030_goelectricrebates_notes.py | 7 +- .../api/migrations/0031_auto_20240712_2036.py | 15 +- django/api/models/app_user.py | 8 +- django/api/models/arc_project_tracking.py | 1 - django/api/models/charger_rebates.py | 1 - django/api/models/go_electric_rebates.py | 1 + django/api/models/hydrogen_fleets.py | 1 - django/api/models/hydrogen_fueling.py | 1 - django/api/models/public_charging.py | 1 - django/api/models/scrap_it.py | 1 - django/api/models/uploaded_vins_file.py | 1 - django/api/serializers/datasets.py | 1 - django/api/services/minio.py | 1 + django/api/services/spreadsheet_uploader.py | 54 +- .../api/services/spreadsheet_uploader_prep.py | 197 +- django/api/settings.py | 6 +- django/api/tests/test_spreadsheet_uploader.py | 253 +-- django/api/tests/test_user.py | 91 +- django/api/viewsets/healthcheck.py | 4 +- django/api/viewsets/upload.py | 27 +- django/auditable/models.py | 24 +- django/auditable/views.py | 19 +- django/gunicorn.cfg.py | 2 +- django/manage.py | 4 +- django/metabase/apps.py | 2 +- django/metabase/db_router.py | 3 +- django/metabase/migrations/0001_initial.py | 1707 ++++++++++------- django/metabase/models.py | 341 ++-- django/tfrs/apps.py | 2 +- django/tfrs/migrations/0001_initial.py | 1024 +++++++--- django/tfrs/models/CompliancePeriod.py | 8 +- django/tfrs/models/CreditTrade.py | 39 +- django/tfrs/models/CreditTradeStatus.py | 15 +- django/tfrs/models/CreditTradeType.py | 2 +- django/tfrs/models/CreditTradeZeroReason.py | 2 +- django/tfrs/models/Document.py | 7 +- django/tfrs/models/DocumentCategory.py | 9 +- django/tfrs/models/DocumentCreditTrade.py | 14 +- django/tfrs/models/DocumentStatus.py | 9 +- django/tfrs/models/DocumentType.py | 17 +- django/tfrs/models/Organization.py | 27 +- django/tfrs/models/OrganizationActionsType.py | 2 +- django/tfrs/models/OrganizationStatus.py | 13 +- django/tfrs/models/OrganizationType.py | 13 +- django/tfrs/models/User.py | 55 +- django/tfrs/models/mixins/Auditable.py | 25 +- django/tfrs/models/mixins/DocumentData.py | 27 +- django/tfrs/models/mixins/EffectiveDates.py | 11 +- django/wsgi.py | 14 +- 83 files changed, 2741 insertions(+), 1865 deletions(-) diff --git a/django/api/constants/constants.py b/django/api/constants/constants.py index b1570408..820d8ff8 100644 --- a/django/api/constants/constants.py +++ b/django/api/constants/constants.py @@ -23,7 +23,7 @@ typo_checker, location_checker, email_validator, - validate_field_values + validate_field_values, ) from api.services.resolvers import get_google_resolver from api.constants.misc import GER_VALID_FIELD_VALUES @@ -411,7 +411,6 @@ class GoElectricRebatesColumnMapping(Enum): notes = "Notes" - FIELD_TYPES = { "ARC Project Tracking": { "funding_call": str, @@ -588,7 +587,6 @@ class GoElectricRebatesColumnMapping(Enum): "rebate_adjustment": str, "notes": str, }, - } DATASET_CONFIG = { @@ -655,11 +653,34 @@ class GoElectricRebatesColumnMapping(Enum): "sheet_name": "Distribution List - Master", "preparation_functions": [prepare_go_electric_rebates], "validation_functions": [ - {"function": validate_phone_numbers, "columns": ["Phone Number"], "kwargs": {"indices_offset": 2}}, - {"function": typo_checker, "columns": ["Applicant Name"], "kwargs": {"cutoff": 0.8, "indices_offset": 2}}, - {"function": location_checker, "columns": ["City"], "kwargs": {"indices_offset":2}}, - {"function": email_validator, "columns": ["Email"], "kwargs": {"indices_offset":2, "get_resolver": get_google_resolver}}, - {"function": validate_field_values, "columns": [], "kwargs": {"indices_offset":2, "fields_and_values": GER_VALID_FIELD_VALUES}} - ] + { + "function": validate_phone_numbers, + "columns": ["Phone Number"], + "kwargs": {"indices_offset": 2}, + }, + { + "function": typo_checker, + "columns": ["Applicant Name"], + "kwargs": {"cutoff": 0.8, "indices_offset": 2}, + }, + { + "function": location_checker, + "columns": ["City"], + "kwargs": {"indices_offset": 2}, + }, + { + "function": email_validator, + "columns": ["Email"], + "kwargs": {"indices_offset": 2, "get_resolver": get_google_resolver}, + }, + { + "function": validate_field_values, + "columns": [], + "kwargs": { + "indices_offset": 2, + "fields_and_values": GER_VALID_FIELD_VALUES, + }, + }, + ], }, } diff --git a/django/api/constants/misc.py b/django/api/constants/misc.py index c89b2d0f..b8556b17 100644 --- a/django/api/constants/misc.py +++ b/django/api/constants/misc.py @@ -78,12 +78,17 @@ ] GER_VALID_FIELD_VALUES = { - 'Approvals': ['Approved', 'Approved Fraudulent'], - 'Category': [ - 'Forklift', 'Low Speed', 'Motorcycle', 'Medium & Heavy Duty', - 'Airport & Port Specialty Vehicle', 'Cargo E-Bike', 'Utility Vehicle' + "Approvals": ["Approved", "Approved Fraudulent"], + "Category": [ + "Forklift", + "Low Speed", + "Motorcycle", + "Medium & Heavy Duty", + "Airport & Port Specialty Vehicle", + "Cargo E-Bike", + "Utility Vehicle", ], - 'Fleet/Individuals': ['Fleet', 'Individual'], - 'Rebate adjustment (discount)': ['Yes'], - 'Class': ['2B', '3', '4', '5', '6', '7', '8'] - } \ No newline at end of file + "Fleet/Individuals": ["Fleet", "Individual"], + "Rebate adjustment (discount)": ["Yes"], + "Class": ["2B", "3", "4", "5", "6", "7", "8"], +} diff --git a/django/api/keycloak_authentication.py b/django/api/keycloak_authentication.py index b532a5b3..439e0ea8 100644 --- a/django/api/keycloak_authentication.py +++ b/django/api/keycloak_authentication.py @@ -10,7 +10,7 @@ def authenticate(self, request): auth = request.headers.get("Authorization", None) if settings.KEYCLOAK_TESTING: try: - user = User.objects.get(idir=auth['idir']) + user = User.objects.get(idir=auth["idir"]) return user.idir, None except User.DoesNotExist as exc: # print("Testing User does not exist") diff --git a/django/api/logging_filters.py b/django/api/logging_filters.py index f04b64e2..1e20be46 100644 --- a/django/api/logging_filters.py +++ b/django/api/logging_filters.py @@ -1,8 +1,9 @@ import logging + class HealthcheckFilter(logging.Filter): - def filter(self, record): - msg = record.getMessage() - if "GET /api/healthcheck HTTP/1.1" in msg: - return False - return True \ No newline at end of file + def filter(self, record): + msg = record.getMessage() + if "GET /api/healthcheck HTTP/1.1" in msg: + return False + return True diff --git a/django/api/management/commands/create_app_user_and_token.py b/django/api/management/commands/create_app_user_and_token.py index 37fc5538..52241d3f 100644 --- a/django/api/management/commands/create_app_user_and_token.py +++ b/django/api/management/commands/create_app_user_and_token.py @@ -18,4 +18,4 @@ def handle(self, *args, **options): except Exception: raise CommandError("Error generating user and token") - self.stdout.write("Generated token {} for app {}".format(token.key, app_name)) \ No newline at end of file + self.stdout.write("Generated token {} for app {}".format(token.key, app_name)) diff --git a/django/api/migrations/0001_initial.py b/django/api/migrations/0001_initial.py index 3f96b76d..b3ad472f 100644 --- a/django/api/migrations/0001_initial.py +++ b/django/api/migrations/0001_initial.py @@ -5,7 +5,6 @@ class Migration(migrations.Migration): - initial = True dependencies = [] diff --git a/django/api/migrations/0002_ldvrebates.py b/django/api/migrations/0002_ldvrebates.py index cab9f1e5..c2555b86 100644 --- a/django/api/migrations/0002_ldvrebates.py +++ b/django/api/migrations/0002_ldvrebates.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0001_initial"), ] diff --git a/django/api/migrations/0003_vindecodedinformation.py b/django/api/migrations/0003_vindecodedinformation.py index 46fff5ad..708f4319 100644 --- a/django/api/migrations/0003_vindecodedinformation.py +++ b/django/api/migrations/0003_vindecodedinformation.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0002_ldvrebates"), ] diff --git a/django/api/migrations/0004_auto_20211116_1813.py b/django/api/migrations/0004_auto_20211116_1813.py index 84812e6f..85e3518c 100644 --- a/django/api/migrations/0004_auto_20211116_1813.py +++ b/django/api/migrations/0004_auto_20211116_1813.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0003_vindecodedinformation"), ] diff --git a/django/api/migrations/0005_vindecodedinformation_vin.py b/django/api/migrations/0005_vindecodedinformation_vin.py index ed268227..8f82dfb8 100644 --- a/django/api/migrations/0005_vindecodedinformation_vin.py +++ b/django/api/migrations/0005_vindecodedinformation_vin.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0004_auto_20211116_1813"), ] diff --git a/django/api/migrations/0006_specialityusevehicleincentives.py b/django/api/migrations/0006_specialityusevehicleincentives.py index 12e0cc60..1d779110 100644 --- a/django/api/migrations/0006_specialityusevehicleincentives.py +++ b/django/api/migrations/0006_specialityusevehicleincentives.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0005_vindecodedinformation_vin"), ] diff --git a/django/api/migrations/0007_datasets.py b/django/api/migrations/0007_datasets.py index 810af89a..def926ac 100644 --- a/django/api/migrations/0007_datasets.py +++ b/django/api/migrations/0007_datasets.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0006_specialityusevehicleincentives"), ] diff --git a/django/api/migrations/0008_chargerrebates.py b/django/api/migrations/0008_chargerrebates.py index 6a996256..c4439e7c 100644 --- a/django/api/migrations/0008_chargerrebates.py +++ b/django/api/migrations/0008_chargerrebates.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0007_datasets"), ] diff --git a/django/api/migrations/0009_publiccharging.py b/django/api/migrations/0009_publiccharging.py index 7ba704ba..33025278 100644 --- a/django/api/migrations/0009_publiccharging.py +++ b/django/api/migrations/0009_publiccharging.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0008_chargerrebates"), ] diff --git a/django/api/migrations/0010_chargerrebates_fix_columns.py b/django/api/migrations/0010_chargerrebates_fix_columns.py index a889d8a6..ab2ccaa5 100644 --- a/django/api/migrations/0010_chargerrebates_fix_columns.py +++ b/django/api/migrations/0010_chargerrebates_fix_columns.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0009_publiccharging"), ] diff --git a/django/api/migrations/0011_auto_20211216_1944.py b/django/api/migrations/0011_auto_20211216_1944.py index c26c14c2..42863e0c 100644 --- a/django/api/migrations/0011_auto_20211216_1944.py +++ b/django/api/migrations/0011_auto_20211216_1944.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0010_chargerrebates_fix_columns"), ] diff --git a/django/api/migrations/0012_hydrogrenfueling.py b/django/api/migrations/0012_hydrogrenfueling.py index b105f33c..b0a90435 100644 --- a/django/api/migrations/0012_hydrogrenfueling.py +++ b/django/api/migrations/0012_hydrogrenfueling.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0011_auto_20211216_1944"), ] diff --git a/django/api/migrations/0013_hydrogenfleets.py b/django/api/migrations/0013_hydrogenfleets.py index 322359ec..4291096e 100644 --- a/django/api/migrations/0013_hydrogenfleets.py +++ b/django/api/migrations/0013_hydrogenfleets.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0012_hydrogrenfueling"), ] diff --git a/django/api/migrations/0014_datafleets.py b/django/api/migrations/0014_datafleets.py index 07ea9ff8..4276fa10 100644 --- a/django/api/migrations/0014_datafleets.py +++ b/django/api/migrations/0014_datafleets.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0013_hydrogenfleets"), ] diff --git a/django/api/migrations/0015_arcprojecttracking.py b/django/api/migrations/0015_arcprojecttracking.py index 8b5e0c22..3d570d19 100644 --- a/django/api/migrations/0015_arcprojecttracking.py +++ b/django/api/migrations/0015_arcprojecttracking.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0014_datafleets"), ] diff --git a/django/api/migrations/0016_scrapit.py b/django/api/migrations/0016_scrapit.py index 1a4bcacb..f7f3feb7 100644 --- a/django/api/migrations/0016_scrapit.py +++ b/django/api/migrations/0016_scrapit.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0015_arcprojecttracking"), ] diff --git a/django/api/migrations/0017_whitelistedusers.py b/django/api/migrations/0017_whitelistedusers.py index d06d72c1..caefdba5 100644 --- a/django/api/migrations/0017_whitelistedusers.py +++ b/django/api/migrations/0017_whitelistedusers.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0016_scrapit"), ] diff --git a/django/api/migrations/0018_auto_20231201_2301.py b/django/api/migrations/0018_auto_20231201_2301.py index 58d1ec08..22f80592 100644 --- a/django/api/migrations/0018_auto_20231201_2301.py +++ b/django/api/migrations/0018_auto_20231201_2301.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0017_whitelistedusers"), ] diff --git a/django/api/migrations/0019_auto_20240223_1820.py b/django/api/migrations/0019_auto_20240223_1820.py index 34384558..a747e381 100644 --- a/django/api/migrations/0019_auto_20240223_1820.py +++ b/django/api/migrations/0019_auto_20240223_1820.py @@ -5,7 +5,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0018_auto_20231201_2301"), ] diff --git a/django/api/migrations/0020_auto_20240311_2136.py b/django/api/migrations/0020_auto_20240311_2136.py index 0475c7d1..68e73852 100644 --- a/django/api/migrations/0020_auto_20240311_2136.py +++ b/django/api/migrations/0020_auto_20240311_2136.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0019_auto_20240223_1820"), ] diff --git a/django/api/migrations/0021_auto_20240326_2152.py b/django/api/migrations/0021_auto_20240326_2152.py index 6ba7c96b..19baca2e 100644 --- a/django/api/migrations/0021_auto_20240326_2152.py +++ b/django/api/migrations/0021_auto_20240326_2152.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("api", "0020_auto_20240311_2136"), ] diff --git a/django/api/migrations/0022_auto_20240503_1823.py b/django/api/migrations/0022_auto_20240503_1823.py index e5d284cd..1a311cd9 100644 --- a/django/api/migrations/0022_auto_20240503_1823.py +++ b/django/api/migrations/0022_auto_20240503_1823.py @@ -4,38 +4,60 @@ class Migration(migrations.Migration): - dependencies = [ - ('api', '0021_auto_20240326_2152'), + ("api", "0021_auto_20240326_2152"), ] operations = [ migrations.CreateModel( - name='GoElectricRebates', + name="GoElectricRebates", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('approvals', models.CharField(blank=True, max_length=20, null=True)), - ('date', models.DateField(blank=True, max_length=20, null=True)), - ('fleet', models.CharField(max_length=20)), - ('applicant_name', models.CharField(blank=True, max_length=250, null=True)), - ('max_incentive_amount_requested', models.IntegerField(blank=True, null=True)), - ('category', models.CharField(blank=True, max_length=250, null=True)), - ('applicant_type', models.CharField(blank=True, max_length=50, null=True)), - ('incentive_paid', models.IntegerField(blank=True, null=True)), - ('total_purchase_price', models.IntegerField(blank=True, null=True)), - ('manufacturer', models.CharField(blank=True, max_length=250, null=True)), - ('model', models.CharField(blank=True, max_length=250, null=True)), - ('ger_class', models.CharField(blank=True, max_length=50, null=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("approvals", models.CharField(blank=True, max_length=20, null=True)), + ("date", models.DateField(blank=True, max_length=20, null=True)), + ("fleet", models.CharField(max_length=20)), + ( + "applicant_name", + models.CharField(blank=True, max_length=250, null=True), + ), + ( + "max_incentive_amount_requested", + models.IntegerField(blank=True, null=True), + ), + ("category", models.CharField(blank=True, max_length=250, null=True)), + ( + "applicant_type", + models.CharField(blank=True, max_length=50, null=True), + ), + ("incentive_paid", models.IntegerField(blank=True, null=True)), + ("total_purchase_price", models.IntegerField(blank=True, null=True)), + ( + "manufacturer", + models.CharField(blank=True, max_length=250, null=True), + ), + ("model", models.CharField(blank=True, max_length=250, null=True)), + ("ger_class", models.CharField(blank=True, max_length=50, null=True)), ], options={ - 'db_table': 'go_electric_rebates', + "db_table": "go_electric_rebates", }, ), migrations.DeleteModel( - name='SpecialityUseVehicleIncentives', + name="SpecialityUseVehicleIncentives", ), ] diff --git a/django/api/migrations/0023_auto_20240514_1721.py b/django/api/migrations/0023_auto_20240514_1721.py index dd3f0be7..eb897e35 100644 --- a/django/api/migrations/0023_auto_20240514_1721.py +++ b/django/api/migrations/0023_auto_20240514_1721.py @@ -5,112 +5,193 @@ class Migration(migrations.Migration): - dependencies = [ - ('api', '0022_auto_20240503_1823'), + ("api", "0022_auto_20240503_1823"), ] operations = [ migrations.CreateModel( - name='AppToken', + name="AppToken", fields=[ - ('key', models.CharField(max_length=40, primary_key=True, serialize=False, verbose_name='Key')), - ('created', models.DateTimeField(auto_now_add=True, verbose_name='Created')), + ( + "key", + models.CharField( + max_length=40, + primary_key=True, + serialize=False, + verbose_name="Key", + ), + ), + ( + "created", + models.DateTimeField(auto_now_add=True, verbose_name="Created"), + ), ], options={ - 'db_table': 'app_token', + "db_table": "app_token", }, ), migrations.CreateModel( - name='AppUser', + name="AppUser", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('is_active', models.BooleanField(default=True)), - ('app_name', models.CharField(max_length=100, unique=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("is_active", models.BooleanField(default=True)), + ("app_name", models.CharField(max_length=100, unique=True)), ], options={ - 'db_table': 'app_user', + "db_table": "app_user", }, ), migrations.CreateModel( - name='UploadedVinRecord', + name="UploadedVinRecord", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('vin', models.CharField(max_length=17)), - ('postal_code', models.CharField(blank=True, max_length=7, null=True)), - ('data', models.JSONField()), - ('vpic_current_decode_successful', models.BooleanField(default=False)), - ('vpic_number_of_current_decode_attempts', models.IntegerField(default=0)), - ('vinpower_current_decode_successful', models.BooleanField(default=False)), - ('vinpower_number_of_current_decode_attempts', models.IntegerField(default=0)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("vin", models.CharField(max_length=17)), + ("postal_code", models.CharField(blank=True, max_length=7, null=True)), + ("data", models.JSONField()), + ("vpic_current_decode_successful", models.BooleanField(default=False)), + ( + "vpic_number_of_current_decode_attempts", + models.IntegerField(default=0), + ), + ( + "vinpower_current_decode_successful", + models.BooleanField(default=False), + ), + ( + "vinpower_number_of_current_decode_attempts", + models.IntegerField(default=0), + ), ], options={ - 'db_table': 'uploaded_vin_record', + "db_table": "uploaded_vin_record", }, ), migrations.CreateModel( - name='UploadedVinsFile', + name="UploadedVinsFile", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('filename', models.CharField(max_length=32, unique=True)), - ('chunk_size', models.IntegerField(default=25000)), - ('chunks_per_run', models.IntegerField(default=4)), - ('start_index', models.IntegerField(default=0)), - ('processed', models.BooleanField(default=False)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("filename", models.CharField(max_length=32, unique=True)), + ("chunk_size", models.IntegerField(default=25000)), + ("chunks_per_run", models.IntegerField(default=4)), + ("start_index", models.IntegerField(default=0)), + ("processed", models.BooleanField(default=False)), ], options={ - 'db_table': 'uploaded_vins_file', + "db_table": "uploaded_vins_file", }, ), migrations.CreateModel( - name='VinpowerDecodedVinRecord', + name="VinpowerDecodedVinRecord", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('vin', models.CharField(max_length=17, unique=True)), - ('data', models.JSONField()), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("vin", models.CharField(max_length=17, unique=True)), + ("data", models.JSONField()), ], options={ - 'db_table': 'vinpower_decoded_vin_record', + "db_table": "vinpower_decoded_vin_record", }, ), migrations.CreateModel( - name='VpicDecodedVinRecord', + name="VpicDecodedVinRecord", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('vin', models.CharField(max_length=17, unique=True)), - ('data', models.JSONField()), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("vin", models.CharField(max_length=17, unique=True)), + ("data", models.JSONField()), ], options={ - 'db_table': 'vpic_decoded_vin_record', + "db_table": "vpic_decoded_vin_record", }, ), migrations.AddConstraint( - model_name='uploadedvinrecord', - constraint=models.UniqueConstraint(fields=('vin', 'postal_code'), name='unique_vin_postal_code'), + model_name="uploadedvinrecord", + constraint=models.UniqueConstraint( + fields=("vin", "postal_code"), name="unique_vin_postal_code" + ), ), migrations.AddField( - model_name='apptoken', - name='user', - field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='auth_token', to='api.appuser', verbose_name='User'), + model_name="apptoken", + name="user", + field=models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + related_name="auth_token", + to="api.appuser", + verbose_name="User", + ), ), ] diff --git a/django/api/migrations/0024_auto_20240516_2114.py b/django/api/migrations/0024_auto_20240516_2114.py index 3915815b..d0149e4c 100644 --- a/django/api/migrations/0024_auto_20240516_2114.py +++ b/django/api/migrations/0024_auto_20240516_2114.py @@ -5,95 +5,94 @@ class Migration(migrations.Migration): - dependencies = [ - ('api', '0023_auto_20240514_1721'), + ("api", "0023_auto_20240514_1721"), ] operations = [ migrations.RenameField( - model_name='goelectricrebates', - old_name='ger_class', - new_name='vehicle_class', + model_name="goelectricrebates", + old_name="ger_class", + new_name="vehicle_class", ), migrations.AddField( - model_name='goelectricrebates', - name='city', + model_name="goelectricrebates", + name="city", field=models.CharField(default=django.utils.timezone.now, max_length=250), preserve_default=False, ), migrations.AddField( - model_name='goelectricrebates', - name='email', - field=models.CharField(default='a', max_length=50), + model_name="goelectricrebates", + name="email", + field=models.CharField(default="a", max_length=50), preserve_default=False, ), migrations.AddField( - model_name='goelectricrebates', - name='flagged', + model_name="goelectricrebates", + name="flagged", field=models.CharField(blank=True, max_length=50, null=True), ), migrations.AddField( - model_name='goelectricrebates', - name='phone', - field=models.CharField(default='123', max_length=20), + model_name="goelectricrebates", + name="phone", + field=models.CharField(default="123", max_length=20), preserve_default=False, ), migrations.AddField( - model_name='goelectricrebates', - name='postal_code', + model_name="goelectricrebates", + name="postal_code", field=models.CharField(blank=True, max_length=250, null=True), ), migrations.AddField( - model_name='goelectricrebates', - name='vin', + model_name="goelectricrebates", + name="vin", field=models.CharField(blank=True, max_length=100, null=True), ), migrations.AlterField( - model_name='goelectricrebates', - name='applicant_name', - field=models.CharField(default='a', max_length=250), + model_name="goelectricrebates", + name="applicant_name", + field=models.CharField(default="a", max_length=250), preserve_default=False, ), migrations.AlterField( - model_name='goelectricrebates', - name='approvals', - field=models.CharField(default='a', max_length=20), + model_name="goelectricrebates", + name="approvals", + field=models.CharField(default="a", max_length=20), preserve_default=False, ), migrations.AlterField( - model_name='goelectricrebates', - name='category', - field=models.CharField(default='a', max_length=250), + model_name="goelectricrebates", + name="category", + field=models.CharField(default="a", max_length=250), preserve_default=False, ), migrations.AlterField( - model_name='goelectricrebates', - name='date', + model_name="goelectricrebates", + name="date", field=models.DateField(default=django.utils.timezone.now, max_length=20), preserve_default=False, ), migrations.AlterField( - model_name='goelectricrebates', - name='incentive_paid', + model_name="goelectricrebates", + name="incentive_paid", field=models.IntegerField(default=1), preserve_default=False, ), migrations.AlterField( - model_name='goelectricrebates', - name='manufacturer', - field=models.CharField(default='a', max_length=250), + model_name="goelectricrebates", + name="manufacturer", + field=models.CharField(default="a", max_length=250), preserve_default=False, ), migrations.AlterField( - model_name='goelectricrebates', - name='model', - field=models.CharField(default='a', max_length=250), + model_name="goelectricrebates", + name="model", + field=models.CharField(default="a", max_length=250), preserve_default=False, ), migrations.AlterField( - model_name='goelectricrebates', - name='total_purchase_price', + model_name="goelectricrebates", + name="total_purchase_price", field=models.IntegerField(default=1), preserve_default=False, ), diff --git a/django/api/migrations/0025_auto_20240516_2248.py b/django/api/migrations/0025_auto_20240516_2248.py index e10058bd..4eb91be9 100644 --- a/django/api/migrations/0025_auto_20240516_2248.py +++ b/django/api/migrations/0025_auto_20240516_2248.py @@ -4,18 +4,17 @@ class Migration(migrations.Migration): - dependencies = [ - ('api', '0024_auto_20240516_2114'), + ("api", "0024_auto_20240516_2114"), ] operations = [ migrations.RemoveField( - model_name='goelectricrebates', - name='flagged', + model_name="goelectricrebates", + name="flagged", ), migrations.RemoveField( - model_name='goelectricrebates', - name='fleet', + model_name="goelectricrebates", + name="fleet", ), ] diff --git a/django/api/migrations/0026_alter_uploadedvinsfile_chunk_size.py b/django/api/migrations/0026_alter_uploadedvinsfile_chunk_size.py index 292cb0e6..ef37c0df 100644 --- a/django/api/migrations/0026_alter_uploadedvinsfile_chunk_size.py +++ b/django/api/migrations/0026_alter_uploadedvinsfile_chunk_size.py @@ -4,15 +4,14 @@ class Migration(migrations.Migration): - dependencies = [ - ('api', '0025_auto_20240516_2248'), + ("api", "0025_auto_20240516_2248"), ] operations = [ migrations.AlterField( - model_name='uploadedvinsfile', - name='chunk_size', + model_name="uploadedvinsfile", + name="chunk_size", field=models.IntegerField(default=5000), ), ] diff --git a/django/api/migrations/0027_goelectricrebates_rebate_adjustment.py b/django/api/migrations/0027_goelectricrebates_rebate_adjustment.py index a376303c..4f703f66 100644 --- a/django/api/migrations/0027_goelectricrebates_rebate_adjustment.py +++ b/django/api/migrations/0027_goelectricrebates_rebate_adjustment.py @@ -4,15 +4,14 @@ class Migration(migrations.Migration): - dependencies = [ - ('api', '0026_alter_uploadedvinsfile_chunk_size'), + ("api", "0026_alter_uploadedvinsfile_chunk_size"), ] operations = [ migrations.AddField( - model_name='goelectricrebates', - name='rebate_adjustment', + model_name="goelectricrebates", + name="rebate_adjustment", field=models.CharField(blank=True, max_length=50, null=True), ), ] diff --git a/django/api/migrations/0028_auto_20240611_0251.py b/django/api/migrations/0028_auto_20240611_0251.py index 3ffde2ad..5f49c79b 100644 --- a/django/api/migrations/0028_auto_20240611_0251.py +++ b/django/api/migrations/0028_auto_20240611_0251.py @@ -4,24 +4,23 @@ class Migration(migrations.Migration): - dependencies = [ - ('api', '0027_goelectricrebates_rebate_adjustment'), + ("api", "0027_goelectricrebates_rebate_adjustment"), ] operations = [ migrations.RemoveField( - model_name='uploadedvinsfile', - name='chunks_per_run', + model_name="uploadedvinsfile", + name="chunks_per_run", ), migrations.AddField( - model_name='uploadedvinrecord', - name='timestamp', + model_name="uploadedvinrecord", + name="timestamp", field=models.DateTimeField(blank=True, null=True), ), migrations.AlterField( - model_name='uploadedvinrecord', - name='postal_code', + model_name="uploadedvinrecord", + name="postal_code", field=models.CharField(max_length=7), ), ] diff --git a/django/api/migrations/0029_alter_uploadedvinrecord_timestamp.py b/django/api/migrations/0029_alter_uploadedvinrecord_timestamp.py index d59c32a0..b5fba709 100644 --- a/django/api/migrations/0029_alter_uploadedvinrecord_timestamp.py +++ b/django/api/migrations/0029_alter_uploadedvinrecord_timestamp.py @@ -4,15 +4,14 @@ class Migration(migrations.Migration): - dependencies = [ - ('api', '0028_auto_20240611_0251'), + ("api", "0028_auto_20240611_0251"), ] operations = [ migrations.AlterField( - model_name='uploadedvinrecord', - name='timestamp', + model_name="uploadedvinrecord", + name="timestamp", field=models.DateTimeField(), ), ] diff --git a/django/api/migrations/0030_goelectricrebates_notes.py b/django/api/migrations/0030_goelectricrebates_notes.py index dbb27341..60dccc7e 100644 --- a/django/api/migrations/0030_goelectricrebates_notes.py +++ b/django/api/migrations/0030_goelectricrebates_notes.py @@ -4,15 +4,14 @@ class Migration(migrations.Migration): - dependencies = [ - ('api', '0029_alter_uploadedvinrecord_timestamp'), + ("api", "0029_alter_uploadedvinrecord_timestamp"), ] operations = [ migrations.AddField( - model_name='goelectricrebates', - name='notes', + model_name="goelectricrebates", + name="notes", field=models.CharField(blank=True, max_length=250, null=True), ), ] diff --git a/django/api/migrations/0031_auto_20240712_2036.py b/django/api/migrations/0031_auto_20240712_2036.py index d186b5a0..d1cf9179 100644 --- a/django/api/migrations/0031_auto_20240712_2036.py +++ b/django/api/migrations/0031_auto_20240712_2036.py @@ -4,25 +4,24 @@ class Migration(migrations.Migration): - dependencies = [ - ('api', '0030_goelectricrebates_notes'), + ("api", "0030_goelectricrebates_notes"), ] operations = [ migrations.AlterField( - model_name='goelectricrebates', - name='email', + model_name="goelectricrebates", + name="email", field=models.CharField(blank=True, max_length=50, null=True), ), migrations.AlterField( - model_name='goelectricrebates', - name='phone', + model_name="goelectricrebates", + name="phone", field=models.CharField(blank=True, max_length=20, null=True), ), migrations.AlterField( - model_name='goelectricrebates', - name='total_purchase_price', + model_name="goelectricrebates", + name="total_purchase_price", field=models.IntegerField(blank=True, null=True), ), ] diff --git a/django/api/models/app_user.py b/django/api/models/app_user.py index 10a75f36..6d9fda02 100644 --- a/django/api/models/app_user.py +++ b/django/api/models/app_user.py @@ -16,7 +16,9 @@ def is_authenticated(self): class Meta: db_table = "app_user" - db_table_comment = "represents an external application that integrates this app via API" + db_table_comment = ( + "represents an external application that integrates this app via API" + ) class AppToken(Token): @@ -30,4 +32,6 @@ class AppToken(Token): class Meta: db_table = "app_token" - db_table_comment = "the token of an external application that integrates this app via API" + db_table_comment = ( + "the token of an external application that integrates this app via API" + ) diff --git a/django/api/models/arc_project_tracking.py b/django/api/models/arc_project_tracking.py index 8c66bc92..18d1458a 100644 --- a/django/api/models/arc_project_tracking.py +++ b/django/api/models/arc_project_tracking.py @@ -3,7 +3,6 @@ class ARCProjectTracking(Auditable): - funding_call = models.CharField(blank=True, null=True, max_length=50, unique=False) proponent = models.CharField(blank=True, null=True, max_length=500, unique=False) diff --git a/django/api/models/charger_rebates.py b/django/api/models/charger_rebates.py index baea6aee..bfac834c 100644 --- a/django/api/models/charger_rebates.py +++ b/django/api/models/charger_rebates.py @@ -3,7 +3,6 @@ class ChargerRebates(Auditable): - organization = models.CharField(blank=True, null=True, max_length=250, unique=False) region = models.CharField(blank=True, null=True, max_length=200, unique=False) diff --git a/django/api/models/go_electric_rebates.py b/django/api/models/go_electric_rebates.py index 3b3a8e75..b1a799af 100644 --- a/django/api/models/go_electric_rebates.py +++ b/django/api/models/go_electric_rebates.py @@ -31,5 +31,6 @@ class GoElectricRebates(Auditable): vehicle_class = models.CharField(blank=True, null=True, max_length=50) rebate_adjustment = models.CharField(blank=True, null=True, max_length=50) notes = models.CharField(blank=True, null=True, max_length=250) + class Meta: db_table = "go_electric_rebates" diff --git a/django/api/models/hydrogen_fleets.py b/django/api/models/hydrogen_fleets.py index 9420eeb4..6dc5615b 100644 --- a/django/api/models/hydrogen_fleets.py +++ b/django/api/models/hydrogen_fleets.py @@ -3,7 +3,6 @@ class HydrogenFleets(Auditable): - application_number = models.IntegerField(blank=True, null=True) fleet_number = models.IntegerField(blank=True, null=True) diff --git a/django/api/models/hydrogen_fueling.py b/django/api/models/hydrogen_fueling.py index 50eb6e6a..609b99f0 100644 --- a/django/api/models/hydrogen_fueling.py +++ b/django/api/models/hydrogen_fueling.py @@ -9,7 +9,6 @@ class HydrogrenFueling(EffectiveDates, Auditable): - class Meta: db_table = "hydrogen_fueling" diff --git a/django/api/models/public_charging.py b/django/api/models/public_charging.py index c4ee262a..5041f2d5 100644 --- a/django/api/models/public_charging.py +++ b/django/api/models/public_charging.py @@ -9,7 +9,6 @@ class PublicCharging(EffectiveDates, Auditable): - class Meta: db_table = "public_charging" diff --git a/django/api/models/scrap_it.py b/django/api/models/scrap_it.py index 1f8c9fd9..38bcb465 100644 --- a/django/api/models/scrap_it.py +++ b/django/api/models/scrap_it.py @@ -3,7 +3,6 @@ class ScrapIt(Auditable): - approval_number = models.IntegerField(blank=True, null=True) application_received_date = models.CharField( diff --git a/django/api/models/uploaded_vins_file.py b/django/api/models/uploaded_vins_file.py index 853397f7..6b6749d7 100644 --- a/django/api/models/uploaded_vins_file.py +++ b/django/api/models/uploaded_vins_file.py @@ -15,4 +15,3 @@ class Meta: db_table = "uploaded_vins_file" db_table_comment = "represents a file containing VINs, and parsing information" - diff --git a/django/api/serializers/datasets.py b/django/api/serializers/datasets.py index 2e8152bb..6e1d99f5 100644 --- a/django/api/serializers/datasets.py +++ b/django/api/serializers/datasets.py @@ -4,7 +4,6 @@ class DatasetsSerializer(ModelSerializer): - class Meta: model = Datasets fields = ("name", "id") diff --git a/django/api/services/minio.py b/django/api/services/minio.py index 692225f1..f32fedbf 100644 --- a/django/api/services/minio.py +++ b/django/api/services/minio.py @@ -3,6 +3,7 @@ from django.conf import settings + def get_minio_client(): return Minio( settings.MINIO_ENDPOINT, diff --git a/django/api/services/spreadsheet_uploader.py b/django/api/services/spreadsheet_uploader.py index 1c9cb552..8ae6a822 100644 --- a/django/api/services/spreadsheet_uploader.py +++ b/django/api/services/spreadsheet_uploader.py @@ -3,6 +3,7 @@ import traceback from django.db import transaction + def get_field_default(model, field): field = model._meta.get_field(field) @@ -49,7 +50,7 @@ def transform_data( df = df[[col for col in df.columns if col in required_columns]] missing_columns = [col for col in required_columns if col not in df.columns] - if (missing_columns): + if missing_columns: raise ValueError(f"Missing columns: {', '.join(missing_columns)}") for prep_func in preparation_functions: @@ -75,17 +76,23 @@ def transform_data( errors_and_warnings[column]["Empty Value"] = { "Expected Type": "Expected value where there isn't one.", "Rows": [], - "Severity": "Error" + "Severity": "Error", } errors_and_warnings[column]["Empty Value"]["Rows"].append(index + 1) - if expected_type in [int, float, Decimal] and value is not None and pd.notna(value): - value = str(value).replace(',', '').strip() + if ( + expected_type in [int, float, Decimal] + and value is not None + and pd.notna(value) + ): + value = str(value).replace(",", "").strip() try: if expected_type == int: row_dict[column] = int(float(value)) elif expected_type == Decimal: - row_dict[column] = Decimal(value).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP) + row_dict[column] = Decimal(value).quantize( + Decimal("0.01"), rounding=ROUND_HALF_UP + ) else: row_dict[column] = float(value) except ValueError: @@ -93,21 +100,32 @@ def transform_data( errors_and_warnings[column] = {} if "Incorrect Type" not in errors_and_warnings[column]: errors_and_warnings[column]["Incorrect Type"] = { - "Expected Type": "The following rows contained incorrect value types for the " + column + " column", + "Expected Type": "The following rows contained incorrect value types for the " + + column + + " column", "Rows": [], - "Severity": "Error" + "Severity": "Error", } - errors_and_warnings[column]["Incorrect Type"]["Rows"].append(index + 1) + errors_and_warnings[column]["Incorrect Type"]["Rows"].append( + index + 1 + ) # Check if expected_type is valid before using isinstance - elif expected_type is not None and isinstance(expected_type, type) and not isinstance(row_dict[column], expected_type) and value != "": + elif ( + expected_type is not None + and isinstance(expected_type, type) + and not isinstance(row_dict[column], expected_type) + and value != "" + ): if column not in errors_and_warnings: errors_and_warnings[column] = {} if "Incorrect Type" not in errors_and_warnings[column]: errors_and_warnings[column]["Incorrect Type"] = { - "Expected Type": "The following rows contained incorrect value types for the " + column + " column", + "Expected Type": "The following rows contained incorrect value types for the " + + column + + " column", "Rows": [], - "Severity": "Error" + "Severity": "Error", } errors_and_warnings[column]["Incorrect Type"]["Rows"].append(index + 1) @@ -126,10 +144,12 @@ def transform_data( errors_and_warnings[column][issue] = { "Expected Type": details.get("Expected Type", "Unknown"), "Rows": details.get("Rows", []), - "Severity": details.get("Severity", "Error") + "Severity": details.get("Severity", "Error"), } else: - errors_and_warnings[column][issue]["Rows"].extend(details.get("Rows", [])) + errors_and_warnings[column][issue]["Rows"].extend( + details.get("Rows", []) + ) column_mapping = {col.name: col.value for col in column_mapping_enum} inverse_column_mapping = {v: k for k, v in column_mapping.items()} @@ -144,7 +164,7 @@ def load_data(df, model, replace_data, user): if replace_data: model.objects.all().delete() - + for index, row in df.iterrows(): row_dict = row.to_dict() row_dict["update_user"] = user @@ -196,7 +216,7 @@ def import_from_xls( "errors_and_warnings": errors_and_warnings, } else: - print('no warnings') + print("no warnings") result = load_data(df, model, replace_data, user, errors_and_warnings) @@ -207,8 +227,8 @@ def import_from_xls( "success": True, "message": f"All {inserted_rows} records successfully inserted out of {total_rows}.", "rows_processed": result["row_count"], - } - + } + except Exception as error: traceback.print_exc() error_msg = f"Unexpected error: {str(error)}" diff --git a/django/api/services/spreadsheet_uploader_prep.py b/django/api/services/spreadsheet_uploader_prep.py index 3753c823..dffed751 100644 --- a/django/api/services/spreadsheet_uploader_prep.py +++ b/django/api/services/spreadsheet_uploader_prep.py @@ -6,6 +6,7 @@ from api.utilities.series import get_map_of_values_to_indices from api.constants.misc import AREA_CODES + def prepare_arc_project_tracking(df): df["Publicly Announced"] = df["Publicly Announced"].replace( {"No": False, "N": False, "Yes": True, "Y": True} @@ -18,8 +19,8 @@ def prepare_hydrogen_fleets(df): df.apply(lambda x: x.fillna(0) if x.dtype.kind in "biufc" else x.fillna("")) return df -def prepare_hydrogen_fueling(df): +def prepare_hydrogen_fueling(df): decimal_columns = ["Capital Funding Awarded", "O&M Funding Potential"] for column in ["700 Bar", "350 Bar"]: @@ -59,7 +60,6 @@ def prepare_ldv_rebates(df): def prepare_public_charging(df): - df = df.applymap(lambda s: s.upper() if type(s) == str else s) df = df.apply(lambda x: x.fillna(0) if x.dtype.kind in "biufc" else x.fillna("")) @@ -71,14 +71,13 @@ def prepare_public_charging(df): def prepare_scrap_it(df): - df = df.applymap(lambda s: s.upper() if type(s) == str else s) df = df.apply(lambda x: x.fillna(0) if x.dtype.kind in "biufc" else x.fillna("")) return df -def prepare_go_electric_rebates(df): +def prepare_go_electric_rebates(df): df = df.applymap(lambda s: s.upper() if type(s) == str else s) num_columns = df.select_dtypes(include=["number"]).columns.tolist() @@ -87,42 +86,52 @@ def prepare_go_electric_rebates(df): non_num_columns = df.columns.difference(num_columns) df[non_num_columns] = df[non_num_columns].fillna("") format_dict = { - 'title': ['Approvals', 'Applicant Name', 'Category', - 'Fleet/Individuals', 'Rebate adjustment (discount)', - 'Manufacturer', 'City'], - 'upper': ['Model', 'Postal code', 'VIN Number'], - 'lower': ['Email'], - 'skip': ['Phone Number'], - 'sentence': ['Notes'], -} + "title": [ + "Approvals", + "Applicant Name", + "Category", + "Fleet/Individuals", + "Rebate adjustment (discount)", + "Manufacturer", + "City", + ], + "upper": ["Model", "Postal code", "VIN Number"], + "lower": ["Email"], + "skip": ["Phone Number"], + "sentence": ["Notes"], + } for key in format_dict: - df[format_dict[key]] = df[format_dict[key]].apply(format_case, case = key) + df[format_dict[key]] = df[format_dict[key]].apply(format_case, case=key) make_names_consistent(df) make_prepositions_consistent(df) adjust_ger_manufacturer_names(df) return df -def format_case(s, case = 'skip', ignore_list = []): + +def format_case(s, case="skip", ignore_list=[]): s[s.notna()] = ( - s[s.notna()] # I am applying this function to non NaN values only. If you do not, they get converted from NaN to nan and are more annoying to work with. - .astype(str) # Convert to string - .str.strip() # Strip white spaces (this dataset suffers from extra tabs, lines, etc.) - ) - if case == 'title': + s[ + s.notna() + ] # I am applying this function to non NaN values only. If you do not, they get converted from NaN to nan and are more annoying to work with. + .astype(str) # Convert to string + .str.strip() # Strip white spaces (this dataset suffers from extra tabs, lines, etc.) + ) + if case == "title": s = s.str.title() - elif case == 'upper': + elif case == "upper": s = s.str.upper() - elif case == 'lower': + elif case == "lower": s = s.str.lower() - elif case == 'sentence': + elif case == "sentence": ##filter out the temporary null records before changing to sentence case - s = s[s != 'TEMP_NULL'].str.capitalize() - elif case == 'skip': + s = s[s != "TEMP_NULL"].str.capitalize() + elif case == "skip": pass return s + def make_names_consistent(df): """ This step is done after formatting because people use all kinds of cases (`LTD`, `ltd', 'LIMITED'`, etc.). @@ -137,61 +146,80 @@ def make_names_consistent(df): - `Incorporated` - From `Dba` to `DBA` i.e. "doing business as" - + """ consistent_name_dict = ( - dict.fromkeys([ - '\\bLtd(?!\\.)\\b', # Matches word "Ltd" not followed by "." - 'Limited$', # Matches "Limited" at the end of the string - 'Limited\\.$', # Matches "Limited." at the end of the string - ', Ltd.' - ], 'Ltd.') | - dict.fromkeys([ - '\\bInc(?!\\.)\\b', # Matches "Inc" not followed by "." - 'Incorporated'], 'Inc.') | - {', Inc.': ' Inc.', - '(?i)\\bdba\\b': 'DBA'} # Matches word "dba" regardless of case -) - df[['Applicant Name', 'Manufacturer']] = df[['Applicant Name', 'Manufacturer']].replace( - consistent_name_dict, - regex=True) + dict.fromkeys( + [ + "\\bLtd(?!\\.)\\b", # Matches word "Ltd" not followed by "." + "Limited$", # Matches "Limited" at the end of the string + "Limited\\.$", # Matches "Limited." at the end of the string + ", Ltd.", + ], + "Ltd.", + ) + | dict.fromkeys( + ["\\bInc(?!\\.)\\b", "Incorporated"], # Matches "Inc" not followed by "." + "Inc.", + ) + | { + ", Inc.": " Inc.", + "(?i)\\bdba\\b": "DBA", + } # Matches word "dba" regardless of case + ) + df[["Applicant Name", "Manufacturer"]] = df[ + ["Applicant Name", "Manufacturer"] + ].replace(consistent_name_dict, regex=True) + def make_prepositions_consistent(df): - df[['Applicant Name', 'Manufacturer']] = df[['Applicant Name', 'Manufacturer']].replace( - dict.fromkeys( - ['(?i)\\bbc(?=\\W)', # Matches word "bc" regardless of case - '(?i)\\bb\\.c\\.(?=\\W)'], 'BC'), # Matches word "b.c." regardless of case - regex=True - ).replace( - {'BC Ltd.': 'B.C. Ltd.', - '\\bOf(?=\\W)': 'of', - '\\bAnd(?=\\W)': 'and', # Matches word "And" - '\\bThe(?=\\W)': 'the', - '\\bA(?=\\W)': 'a', - '\\bAn(?=\\W)': 'an'}, - regex=True + df[["Applicant Name", "Manufacturer"]] = ( + df[["Applicant Name", "Manufacturer"]] + .replace( + dict.fromkeys( + [ + "(?i)\\bbc(?=\\W)", # Matches word "bc" regardless of case + "(?i)\\bb\\.c\\.(?=\\W)", + ], + "BC", + ), # Matches word "b.c." regardless of case + regex=True, + ) + .replace( + { + "BC Ltd.": "B.C. Ltd.", + "\\bOf(?=\\W)": "of", + "\\bAnd(?=\\W)": "and", # Matches word "And" + "\\bThe(?=\\W)": "the", + "\\bA(?=\\W)": "a", + "\\bAn(?=\\W)": "an", + }, + regex=True, + ) ) ##The first letter should be capitalized - df[['Applicant Name', 'Manufacturer']] = df[['Applicant Name', 'Manufacturer'] - ].applymap(lambda x: x[0].upper() + x[1:]) - + df[["Applicant Name", "Manufacturer"]] = df[ + ["Applicant Name", "Manufacturer"] + ].applymap(lambda x: x[0].upper() + x[1:]) + + def adjust_ger_manufacturer_names(df): """"" This function is currently GER specific updating the manufacturer names to have casing that makes more sense since currently all manufacturer column entries are set to sentence casing. - """"" + """ "" name_replacements = { - 'International Ic Bus': 'International IC Bus', - 'Lightning Emotors': 'Lightning eMotors', - 'Avro Gse': 'Avro GSE', - 'Bmw': 'BMW', - 'Ego': 'EGO', - 'Sc Carts': 'SC Carts' + "International Ic Bus": "International IC Bus", + "Lightning Emotors": "Lightning eMotors", + "Avro Gse": "Avro GSE", + "Bmw": "BMW", + "Ego": "EGO", + "Sc Carts": "SC Carts", } - df[['Manufacturer']] = df[['Manufacturer']].replace(name_replacements, regex=False) + df[["Manufacturer"]] = df[["Manufacturer"]].replace(name_replacements, regex=False) def typo_checker(df, *columns, **kwargs): @@ -201,14 +229,14 @@ def typo_checker(df, *columns, **kwargs): series = df[column] unique_vals = set(series) - map_of_values_to_indices = get_map_of_values_to_indices(series, kwargs.get("indices_offset", 0)) + map_of_values_to_indices = get_map_of_values_to_indices( + series, kwargs.get("indices_offset", 0) + ) for value in unique_vals: singleton = set() singleton.add(value) matches = dl.get_close_matches( - value, - unique_vals.difference(singleton), - cutoff=kwargs["cutoff"] + value, unique_vals.difference(singleton), cutoff=kwargs["cutoff"] ) if matches: value_indices = map_of_values_to_indices[value] @@ -223,7 +251,7 @@ def typo_checker(df, *columns, **kwargs): "Similar Values Detected": { "Expected Type": "We detected applicant names that sound very similar. If these names refer to the same person/entity, please replace the applicant names in your dataset to the preferred spelling to ensure consistency", "Rows": sorted(list(set(indices))), - "Severity": "Warning" + "Severity": "Warning", } } return result @@ -235,15 +263,19 @@ def validate_phone_numbers(df, *columns, **kwargs): indices = [] series = df[column] for index, phone_number in series.items(): - formatted_number = str(phone_number).strip().replace('-', '') - if formatted_number == '' or len(formatted_number) != 10 or int(formatted_number[:3]) not in AREA_CODES: + formatted_number = str(phone_number).strip().replace("-", "") + if ( + formatted_number == "" + or len(formatted_number) != 10 + or int(formatted_number[:3]) not in AREA_CODES + ): indices.append(index + kwargs.get("indices_offset", 0)) if indices: result[column] = { "Phone Number Appears Incorrect": { "Expected Type": "Ensure phone numbers match the Canadian format (XXX-XXX-XXXX)", "Rows": indices, - "Severity": "Warning" + "Severity": "Warning", } } return result @@ -254,7 +286,9 @@ def location_checker(df, *columns, **kwargs): for column in columns: indices = [] series = df[column] - map_of_values_to_indices = get_map_of_values_to_indices(series, kwargs.get("indices_offset", 0)) + map_of_values_to_indices = get_map_of_values_to_indices( + series, kwargs.get("indices_offset", 0) + ) values = series.to_list() unique_values = set(series) @@ -270,7 +304,7 @@ def location_checker(df, *columns, **kwargs): "Unrecognized City Names": { "Expected Type": "The following city names are not in the list of geographic names. Please double check that these places exist or have correct spelling and adjust your dataset accordingly.", "Rows": sorted(list(set(indices))), - "Severity": "Warning" + "Severity": "Warning", } } return result @@ -295,7 +329,7 @@ def email_validator(df, *columns, **kwargs): "Possible Errors in Email Addresses": { "Expected Type": "Verify email addresses are valid", "Rows": indices, - "Severity": "Warning" + "Severity": "Warning", } } return result @@ -310,15 +344,20 @@ def validate_field_values(df, *columns, **kwargs): indices = [] series = df[column] for index, value in series.items(): - if str(value) not in allowed_values[column] and value != '' and value is not None and not pd.isna(value): + if ( + str(value) not in allowed_values[column] + and value != "" + and value is not None + and not pd.isna(value) + ): indices.append(index + kwargs.get("indices_offset", 0)) if indices: result[column] = { "Invalid Values": { "Expected Type": "The following rows only allow specific values", "Rows": indices, - "Severity": "Error" + "Severity": "Error", } } - - return result \ No newline at end of file + + return result diff --git a/django/api/settings.py b/django/api/settings.py index 80592f15..623f3e3e 100644 --- a/django/api/settings.py +++ b/django/api/settings.py @@ -55,7 +55,7 @@ "django_q", ] -DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' +DEFAULT_AUTO_FIELD = "django.db.models.AutoField" MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware", @@ -229,4 +229,6 @@ }, } -PLACENAMES_ENDPOINT = PLACENAMES_ENDPOINT = os.getenv("PLACENAMES_ENDPOINT", "https://apps.gov.bc.ca/pub/bcgnws/names/search") +PLACENAMES_ENDPOINT = PLACENAMES_ENDPOINT = os.getenv( + "PLACENAMES_ENDPOINT", "https://apps.gov.bc.ca/pub/bcgnws/names/search" +) diff --git a/django/api/tests/test_spreadsheet_uploader.py b/django/api/tests/test_spreadsheet_uploader.py index db23cbc0..139794eb 100644 --- a/django/api/tests/test_spreadsheet_uploader.py +++ b/django/api/tests/test_spreadsheet_uploader.py @@ -7,118 +7,123 @@ from api.constants.constants import ScrapItColumnMapping, ScrapItColumns from api.services.spreadsheet_uploader_prep import prepare_scrap_it + class UploadTests(TestCase): def setUp(self): - self.field_types = { - 'approval_number': int, - 'application_received_date': str, - 'completion_date': str, - 'postal_code': str, - 'vin': str, - 'application_city_fuel': Decimal, - 'incentive_type': str, - 'incentive_cost': Decimal, - 'cheque_number': str, - 'budget_code': str, - 'scrap_date': str + "approval_number": int, + "application_received_date": str, + "completion_date": str, + "postal_code": str, + "vin": str, + "application_city_fuel": Decimal, + "incentive_type": str, + "incentive_cost": Decimal, + "cheque_number": str, + "budget_code": str, + "scrap_date": str, } def test_wrong_cell_types(self): data = { - 'approval_number': [1], - 'application_recieved_date': ['Monday'], - 'completion_date': ['Tuesday'], - 'postal_code': ['ABCDEFG'], - 'vin': [123], - 'application_city_fuel': ['Zero Point One'], - 'incentive_type': ['A'], - 'incentive_cost': [0.50], - 'cheque_number': ['string'], - 'budget_code': ['string'], - 'scrap_date': ['string'] + "approval_number": [1], + "application_recieved_date": ["Monday"], + "completion_date": ["Tuesday"], + "postal_code": ["ABCDEFG"], + "vin": [123], + "application_city_fuel": ["Zero Point One"], + "incentive_type": ["A"], + "incentive_cost": [0.50], + "cheque_number": ["string"], + "budget_code": ["string"], + "scrap_date": ["string"], } rename_columns = { - 'approval_number': 'Approval Num', - 'application_recieved_date': "App Recv'd Date", - 'completion_date': 'Completion Date', - 'postal_code': 'Postal Code', - 'vin': 'VIN', - 'application_city_fuel': 'App City Fuel', - 'incentive_type': 'Incentive Type', - 'incentive_cost': 'Incentive Cost', - 'cheque_number': 'Cheque #', - 'budget_code': 'Budget Code', - 'scrap_date': 'Scrap Date' + "approval_number": "Approval Num", + "application_recieved_date": "App Recv'd Date", + "completion_date": "Completion Date", + "postal_code": "Postal Code", + "vin": "VIN", + "application_city_fuel": "App City Fuel", + "incentive_type": "Incentive Type", + "incentive_cost": "Incentive Cost", + "cheque_number": "Cheque #", + "budget_code": "Budget Code", + "scrap_date": "Scrap Date", } - + df = pd.DataFrame(data) df.rename(columns=rename_columns, inplace=True) excel_buffer = io.BytesIO() - df.to_excel(excel_writer=excel_buffer, sheet_name='TOP OTHER TRANSACTIONS', index=False) + df.to_excel( + excel_writer=excel_buffer, sheet_name="TOP OTHER TRANSACTIONS", index=False + ) excel_buffer.seek(0) response = import_from_xls( excel_file=excel_buffer, - sheet_name='TOP OTHER TRANSACTIONS', + sheet_name="TOP OTHER TRANSACTIONS", model=ScrapIt, dataset_columns=ScrapItColumns, header_row=0, column_mapping_enum=ScrapItColumnMapping, field_types=self.field_types, replace_data=False, - user='Tester', - preparation_functions=[prepare_scrap_it] + user="Tester", + preparation_functions=[prepare_scrap_it], ) - self.assertFalse(response['success']) - self.assertIn("Row 1: Incorrect type for 'vin'", response['errors'][0]) - self.assertIn("Row 1: Incorrect type for 'application_city_fuel'", response['errors'][1]) + self.assertFalse(response["success"]) + self.assertIn("Row 1: Incorrect type for 'vin'", response["errors"][0]) + self.assertIn( + "Row 1: Incorrect type for 'application_city_fuel'", response["errors"][1] + ) def test_missing_columns(self): - data = { - 'approval_number': [1], - 'application_recieved_date': ['Monday'], - 'completion_date': ['Tuesday'], - 'postal_code': ['ABCDEFG'], - 'incentive_type': ['A'], - 'incentive_cost': [0.50], - 'cheque_number': ['string'], - 'budget_code': ['string'], - 'scrap_date': ['string'] + "approval_number": [1], + "application_recieved_date": ["Monday"], + "completion_date": ["Tuesday"], + "postal_code": ["ABCDEFG"], + "incentive_type": ["A"], + "incentive_cost": [0.50], + "cheque_number": ["string"], + "budget_code": ["string"], + "scrap_date": ["string"], } rename_columns = { - 'approval_number': 'Approval Num', - 'application_recieved_date': "App Recv'd Date", - 'completion_date': 'Completion Date', - 'postal_code': 'Postal Code', - 'incentive_type': 'Incentive Type', - 'incentive_cost': 'Incentive Cost', - 'cheque_number': 'Cheque #', - 'budget_code': 'Budget Code', - 'scrap_date': 'Scrap Date' + "approval_number": "Approval Num", + "application_recieved_date": "App Recv'd Date", + "completion_date": "Completion Date", + "postal_code": "Postal Code", + "incentive_type": "Incentive Type", + "incentive_cost": "Incentive Cost", + "cheque_number": "Cheque #", + "budget_code": "Budget Code", + "scrap_date": "Scrap Date", } df = pd.DataFrame(data) df.rename(columns=rename_columns, inplace=True) excel_buffer = io.BytesIO() - df.to_excel(excel_writer=excel_buffer, sheet_name='TOP OTHER TRANSACTIONS', index=False) + df.to_excel( + excel_writer=excel_buffer, sheet_name="TOP OTHER TRANSACTIONS", index=False + ) excel_buffer.seek(0) response = import_from_xls( excel_file=excel_buffer, - sheet_name='TOP OTHER TRANSACTIONS', + sheet_name="TOP OTHER TRANSACTIONS", model=ScrapIt, dataset_columns=ScrapItColumns, header_row=0, column_mapping_enum=ScrapItColumnMapping, field_types=self.field_types, replace_data=False, - user='Tester', - preparation_functions=[prepare_scrap_it] + user="Tester", + preparation_functions=[prepare_scrap_it], ) self.assertFalse(response["success"]) @@ -126,105 +131,111 @@ def test_missing_columns(self): self.assertIn("Missing columns: VIN, App City Fuel", response["errors"][0]) def test_missing_worksheet(self): - data = { - 'approval_number': [1], - 'application_recieved_date': ['Monday'], - 'completion_date': ['Tuesday'], - 'postal_code': ['ABCDEFG'], - 'vin': ['string'], - 'application_city_fuel': [0.50], - 'incentive_type': ['A'], - 'incentive_cost': [0.50], - 'cheque_number': ['string'], - 'budget_code': ['string'], - 'scrap_date': ['string'] + "approval_number": [1], + "application_recieved_date": ["Monday"], + "completion_date": ["Tuesday"], + "postal_code": ["ABCDEFG"], + "vin": ["string"], + "application_city_fuel": [0.50], + "incentive_type": ["A"], + "incentive_cost": [0.50], + "cheque_number": ["string"], + "budget_code": ["string"], + "scrap_date": ["string"], } rename_columns = { - 'approval_number': 'Approval Num', - 'application_recieved_date': "App Recv'd Date", - 'completion_date': 'Completion Date', - 'postal_code': 'Postal Code', - 'vin': 'VIN', - 'application_city_fuel': 'App City Fuel', - 'incentive_type': 'Incentive Type', - 'incentive_cost': 'Incentive Cost', - 'cheque_number': 'Cheque #', - 'budget_code': 'Budget Code', - 'scrap_date': 'Scrap Date' + "approval_number": "Approval Num", + "application_recieved_date": "App Recv'd Date", + "completion_date": "Completion Date", + "postal_code": "Postal Code", + "vin": "VIN", + "application_city_fuel": "App City Fuel", + "incentive_type": "Incentive Type", + "incentive_cost": "Incentive Cost", + "cheque_number": "Cheque #", + "budget_code": "Budget Code", + "scrap_date": "Scrap Date", } df = pd.DataFrame(data) df.rename(columns=rename_columns, inplace=True) excel_buffer = io.BytesIO() - df.to_excel(excel_writer=excel_buffer, sheet_name='Wrong Sheet Name', index=False) + df.to_excel( + excel_writer=excel_buffer, sheet_name="Wrong Sheet Name", index=False + ) excel_buffer.seek(0) response = import_from_xls( excel_file=excel_buffer, - sheet_name='TOP OTHER TRANSACTIONS', + sheet_name="TOP OTHER TRANSACTIONS", model=ScrapIt, dataset_columns=ScrapItColumns, header_row=0, column_mapping_enum=ScrapItColumnMapping, field_types=self.field_types, replace_data=False, - user='Tester', - preparation_functions=[prepare_scrap_it] + user="Tester", + preparation_functions=[prepare_scrap_it], ) self.assertFalse(response["success"]) - self.assertIn("Worksheet named 'TOP OTHER TRANSACTIONS' not found", response["errors"][0]) + self.assertIn( + "Worksheet named 'TOP OTHER TRANSACTIONS' not found", response["errors"][0] + ) def test_successful_upload(self): - data = { - 'approval_number': [1], - 'application_recieved_date': ['Monday'], - 'completion_date': ['Tuesday'], - 'postal_code': ['ABCDEFG'], - 'vin': ['string'], - 'application_city_fuel': [0.50], - 'incentive_type': ['A'], - 'incentive_cost': [0.50], - 'cheque_number': ['string'], - 'budget_code': ['string'], - 'scrap_date': ['string'] + "approval_number": [1], + "application_recieved_date": ["Monday"], + "completion_date": ["Tuesday"], + "postal_code": ["ABCDEFG"], + "vin": ["string"], + "application_city_fuel": [0.50], + "incentive_type": ["A"], + "incentive_cost": [0.50], + "cheque_number": ["string"], + "budget_code": ["string"], + "scrap_date": ["string"], } rename_columns = { - 'approval_number': 'Approval Num', - 'application_recieved_date': "App Recv'd Date", - 'completion_date': 'Completion Date', - 'postal_code': 'Postal Code', - 'vin': 'VIN', - 'application_city_fuel': 'App City Fuel', - 'incentive_type': 'Incentive Type', - 'incentive_cost': 'Incentive Cost', - 'cheque_number': 'Cheque #', - 'budget_code': 'Budget Code', - 'scrap_date': 'Scrap Date' + "approval_number": "Approval Num", + "application_recieved_date": "App Recv'd Date", + "completion_date": "Completion Date", + "postal_code": "Postal Code", + "vin": "VIN", + "application_city_fuel": "App City Fuel", + "incentive_type": "Incentive Type", + "incentive_cost": "Incentive Cost", + "cheque_number": "Cheque #", + "budget_code": "Budget Code", + "scrap_date": "Scrap Date", } df = pd.DataFrame(data) df.rename(columns=rename_columns, inplace=True) excel_buffer = io.BytesIO() - df.to_excel(excel_writer=excel_buffer, sheet_name='TOP OTHER TRANSACTIONS', index=False) + df.to_excel( + excel_writer=excel_buffer, sheet_name="TOP OTHER TRANSACTIONS", index=False + ) excel_buffer.seek(0) response = import_from_xls( excel_file=excel_buffer, - sheet_name='TOP OTHER TRANSACTIONS', + sheet_name="TOP OTHER TRANSACTIONS", model=ScrapIt, dataset_columns=ScrapItColumns, header_row=0, column_mapping_enum=ScrapItColumnMapping, field_types=self.field_types, replace_data=False, - user='Tester', - preparation_functions=[prepare_scrap_it] + user="Tester", + preparation_functions=[prepare_scrap_it], ) self.assertTrue(response["success"]) - self.assertIn('All 1 records successfully inserted out of 1.', response['message']) \ No newline at end of file + self.assertIn( + "All 1 records successfully inserted out of 1.", response["message"] + ) diff --git a/django/api/tests/test_user.py b/django/api/tests/test_user.py index 59711280..c6f6b2a2 100644 --- a/django/api/tests/test_user.py +++ b/django/api/tests/test_user.py @@ -13,62 +13,52 @@ from api.viewsets.user import UserViewSet from api.viewsets.upload import UploadViewset from api.decorators.permission import check_upload_permission, check_admin_permission + + class TestUsers(TestCase): def setUp(self): self.factory = APIRequestFactory() self.userauth = KeycloakAuthentication() - self.view = UserViewSet.as_view({'get': 'list'}) - #user with no permission - self.test_user = User.objects.create(idir='test_user') - - #user with admin permission - self.test_admin_permission = Permission.objects.create(description='admin') - self.test_admin_user = User.objects.create(idir='test_admin_user') - self.admin_user_permission = UserPermission.objects.create(user=self.test_admin_user, permission=self.test_admin_permission) - - #user with upload permission - self.test_upload_permission = Permission.objects.create(description='uploader') - self.test_upload_user = User.objects.create(idir='test_upload_user') - self.upload_user_permission = UserPermission.objects.create(user=self.test_upload_user, permission=self.test_upload_permission) - + self.view = UserViewSet.as_view({"get": "list"}) + # user with no permission + self.test_user = User.objects.create(idir="test_user") + + # user with admin permission + self.test_admin_permission = Permission.objects.create(description="admin") + self.test_admin_user = User.objects.create(idir="test_admin_user") + self.admin_user_permission = UserPermission.objects.create( + user=self.test_admin_user, permission=self.test_admin_permission + ) + + # user with upload permission + self.test_upload_permission = Permission.objects.create(description="uploader") + self.test_upload_user = User.objects.create(idir="test_upload_user") + self.upload_user_permission = UserPermission.objects.create( + user=self.test_upload_user, permission=self.test_upload_permission + ) def test_get_user_list(self): - self.assertTrue(User.objects.filter(idir='test_user').exists()) - request = self.factory.get('/api/users/list') - request.META = { - 'HTTP_AUTHORIZATION': { - 'idir': 'test_user' - } - } + self.assertTrue(User.objects.filter(idir="test_user").exists()) + request = self.factory.get("/api/users/list") + request.META = {"HTTP_AUTHORIZATION": {"idir": "test_user"}} response = self.view(request) self.assertEqual(response.status_code, 403) # Forbidden status code - self.assertTrue(User.objects.filter(idir='test_upload_user').exists()) - request_uploader = self.factory.get('/api/users/list') - request_uploader.META = { - 'HTTP_AUTHORIZATION': { - 'idir': 'test_upload_user' - } - } + self.assertTrue(User.objects.filter(idir="test_upload_user").exists()) + request_uploader = self.factory.get("/api/users/list") + request_uploader.META = {"HTTP_AUTHORIZATION": {"idir": "test_upload_user"}} response = self.view(request_uploader) self.assertEqual(response.status_code, 403) # Forbidden status code - self.assertTrue(User.objects.filter(idir='test_admin_user').exists()) - request_admin = self.factory.get('/api/users/list') - request_admin.META = { - 'HTTP_AUTHORIZATION': { - 'idir': 'test_admin_user' - } - } + self.assertTrue(User.objects.filter(idir="test_admin_user").exists()) + request_admin = self.factory.get("/api/users/list") + request_admin.META = {"HTTP_AUTHORIZATION": {"idir": "test_admin_user"}} response = self.view(request_admin) self.assertEqual(response.status_code, 200) # OK status code + def test_not_authenticated_user(self): - request = self.factory.get('/api/users/list') - request.META = { - 'HTTP_AUTHORIZATION': { - 'idir': 'test' - } - } + request = self.factory.get("/api/users/list") + request.META = {"HTTP_AUTHORIZATION": {"idir": "test"}} with self.assertRaises(User.DoesNotExist): _user, _auth = self.userauth.authenticate(request) @@ -77,13 +67,14 @@ def test_upload_user_permissions(self): @check_upload_permission() def mock_import_function(request): return HttpResponse() - request = self.factory.post('/api/users/list') - request.user = 'test_upload_user' + + request = self.factory.post("/api/users/list") + request.user = "test_upload_user" response = mock_import_function(request) self.assertEqual(response.status_code, 200) # OK status code - request_admin = self.factory.post('/api/users/list') - request_admin.user = 'test_admin_user' + request_admin = self.factory.post("/api/users/list") + request_admin.user = "test_admin_user" response = mock_import_function(request_admin) self.assertEqual(response.status_code, 403) # Forbidden! @@ -91,13 +82,13 @@ def test_change_user_permissions(self): @check_admin_permission() def mock_change_permission_function(request): return HttpResponse() - request = self.factory.post('/api/users/update_permissions') - request.user = 'test_admin_user' + + request = self.factory.post("/api/users/update_permissions") + request.user = "test_admin_user" response = mock_change_permission_function(request) self.assertEqual(response.status_code, 200) - request_uploader = self.factory.post('/api/users/update_permissions') - request_uploader.user = 'test_upload_user' + request_uploader = self.factory.post("/api/users/update_permissions") + request_uploader.user = "test_upload_user" response = mock_change_permission_function(request_uploader) self.assertEqual(response.status_code, 403) - diff --git a/django/api/viewsets/healthcheck.py b/django/api/viewsets/healthcheck.py index 1972bbb8..a87d86c9 100644 --- a/django/api/viewsets/healthcheck.py +++ b/django/api/viewsets/healthcheck.py @@ -5,7 +5,7 @@ class HealthCheckViewset(GenericViewSet): authentication_classes = [] - permission_classes=[] + permission_classes = [] def list(self, request): - return Response(status=status.HTTP_200_OK) \ No newline at end of file + return Response(status=status.HTTP_200_OK) diff --git a/django/api/viewsets/upload.py b/django/api/viewsets/upload.py index 5981809e..ab289186 100644 --- a/django/api/viewsets/upload.py +++ b/django/api/viewsets/upload.py @@ -26,7 +26,6 @@ class UploadViewset(GenericViewSet): @action(detail=False, methods=["get"]) def datasets_list(self, request): - incomplete_datasets = [ "LDV Rebates", "Public Charging", @@ -52,20 +51,26 @@ def import_data(self, request): replace_data = request.data.get("replaceData", False) filepath = request.data.get("filepath") check_for_warnings = request.data.get("checkForWarnings") - #boolean, if true show warnings before inserting data - #after displaying warnings, code can be rerun with show_warnings = false - #if warnings have been ignore + # boolean, if true show warnings before inserting data + # after displaying warnings, code can be rerun with show_warnings = false + # if warnings have been ignore if dataset_selected == "ICBC Vins": file_extension = pathlib.Path(filepath).suffix - if file_extension == '.csv': + if file_extension == ".csv": try: create_vins_file(filename) - return Response({"success": True, "message": "File successfully uploaded!"}, status=status.HTTP_200_OK) + return Response( + {"success": True, "message": "File successfully uploaded!"}, + status=status.HTTP_200_OK, + ) except Exception as error: return Response({"success": False, "message": str(error)}) else: - return Response({"success": False, "message": "File must be a csv."}, status=status.HTTP_400_BAD_REQUEST) + return Response( + {"success": False, "message": "File must be a csv."}, + status=status.HTTP_400_BAD_REQUEST, + ) try: url = minio_get_object(filename) urllib.request.urlretrieve(url, filename) @@ -98,7 +103,7 @@ def import_data(self, request): field_types=constants.FIELD_TYPES.get(dataset_selected), replace_data=replace_data, user=request.user, - check_for_warnings=check_for_warnings + check_for_warnings=check_for_warnings, ) if not result["success"]: @@ -126,9 +131,9 @@ def download_dataset(self, request): excel_file.read(), content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ) - response["Content-Disposition"] = ( - f'attachment; filename="{dataset_name}.xlsx"' - ) + response[ + "Content-Disposition" + ] = f'attachment; filename="{dataset_name}.xlsx"' return response except ValueError as e: return HttpResponse(str(e), status=400) diff --git a/django/auditable/models.py b/django/auditable/models.py index 7c940843..30c3e41b 100644 --- a/django/auditable/models.py +++ b/django/auditable/models.py @@ -6,25 +6,14 @@ class Auditable(models.Model): Parent model class to provide timestamps and users involved in creating and updating the model """ - create_timestamp = models.DateTimeField( - auto_now_add=True, blank=True, null=True - ) - create_user = models.CharField( - default="SYSTEM", - max_length=130 - ) - update_timestamp = models.DateTimeField( - auto_now=True, blank=True, null=True - ) - update_user = models.CharField( - max_length=130, - null=True - ) + + create_timestamp = models.DateTimeField(auto_now_add=True, blank=True, null=True) + create_user = models.CharField(default="SYSTEM", max_length=130) + update_timestamp = models.DateTimeField(auto_now=True, blank=True, null=True) + update_user = models.CharField(max_length=130, null=True) # Supplemental mapping for base class - db_column_supplemental_comments = { - 'id': 'Primary key' - } + db_column_supplemental_comments = {"id": "Primary key"} class Meta: abstract = True @@ -35,5 +24,6 @@ class Commentable(models.Model): Parent model class to just add the comments. The Auditable class contains timestamp fields, this one is blank. """ + class Meta: abstract = True diff --git a/django/auditable/views.py b/django/auditable/views.py index 4f972e1e..15e6974d 100644 --- a/django/auditable/views.py +++ b/django/auditable/views.py @@ -6,10 +6,12 @@ from api.models.user_profile import UserProfile -class AuditableMixin(object,): +class AuditableMixin( + object, +): def serialize_object(self, request, data): user = request.user - data.update({'create_user': user.username, 'update_user': user.username}) + data.update({"create_user": user.username, "update_user": user.username}) serializer = self.get_serializer(data=data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) @@ -31,20 +33,19 @@ def perform_create(self, serializer): instance = serializer.save() def update(self, request, *args, **kwargs): - if request.method == 'PATCH': - partial = kwargs.pop('partial', True) + if request.method == "PATCH": + partial = kwargs.pop("partial", True) else: - partial = kwargs.pop('partial', False) + partial = kwargs.pop("partial", False) instance = self.get_object() user = request.user - request.data.update({'update_user': user.id}) - serializer = self.get_serializer(instance, data=request.data, - partial=partial) + request.data.update({"update_user": user.id}) + serializer = self.get_serializer(instance, data=request.data, partial=partial) serializer.is_valid(raise_exception=True) self.perform_update(serializer) - if getattr(instance, '_prefetched_objects_cache', None): + if getattr(instance, "_prefetched_objects_cache", None): # If 'prefetch_related' has been applied to a queryset, we need to # forcibly invalidate the prefetch cache on the instance. instance._prefetched_objects_cache = {} diff --git a/django/gunicorn.cfg.py b/django/gunicorn.cfg.py index f6b80dc1..e855165d 100644 --- a/django/gunicorn.cfg.py +++ b/django/gunicorn.cfg.py @@ -50,4 +50,4 @@ bind = "0.0.0.0:8080" workers = 2 -timeout = 600 \ No newline at end of file +timeout = 600 diff --git a/django/manage.py b/django/manage.py index 8c45ccf3..7fbe8935 100755 --- a/django/manage.py +++ b/django/manage.py @@ -6,7 +6,7 @@ def main(): """Run administrative tasks.""" - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'api.settings') + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "api.settings") try: from django.core.management import execute_from_command_line except ImportError as exc: @@ -18,5 +18,5 @@ def main(): execute_from_command_line(sys.argv) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/django/metabase/apps.py b/django/metabase/apps.py index 947144ef..512ea154 100644 --- a/django/metabase/apps.py +++ b/django/metabase/apps.py @@ -2,4 +2,4 @@ class MetabaseConfig(AppConfig): - name = 'metabase' \ No newline at end of file + name = "metabase" diff --git a/django/metabase/db_router.py b/django/metabase/db_router.py index 702f540b..2a563cb3 100644 --- a/django/metabase/db_router.py +++ b/django/metabase/db_router.py @@ -1,5 +1,4 @@ class MetabaseRouter: - app_label = "metabase" metabase_db = "metabase" @@ -28,4 +27,4 @@ def allow_migrate(self, db, app_label, model_name=None, **hints): if is_metabase_data_migration: return True return False - return None \ No newline at end of file + return None diff --git a/django/metabase/migrations/0001_initial.py b/django/metabase/migrations/0001_initial.py index 581947b5..4cfffeb2 100644 --- a/django/metabase/migrations/0001_initial.py +++ b/django/metabase/migrations/0001_initial.py @@ -5,1132 +5,1353 @@ class Migration(migrations.Migration): - initial = True - dependencies = [ - ] + dependencies = [] # unmanaged models will not have any SQL generated for them when it comes to table creation, modification, or deletion # all metabase models should be unmanaged operations = [ migrations.CreateModel( - name='Action', + name="Action", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('type', models.TextField()), - ('name', models.CharField(max_length=254)), - ('description', models.TextField(blank=True, null=True)), - ('parameters', models.TextField(blank=True, null=True)), - ('parameter_mappings', models.TextField(blank=True, null=True)), - ('visualization_settings', models.TextField(blank=True, null=True)), - ('public_uuid', models.CharField(blank=True, max_length=36, null=True, unique=True)), - ('archived', models.BooleanField()), - ('entity_id', models.CharField(blank=True, max_length=21, null=True, unique=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ("type", models.TextField()), + ("name", models.CharField(max_length=254)), + ("description", models.TextField(blank=True, null=True)), + ("parameters", models.TextField(blank=True, null=True)), + ("parameter_mappings", models.TextField(blank=True, null=True)), + ("visualization_settings", models.TextField(blank=True, null=True)), + ( + "public_uuid", + models.CharField(blank=True, max_length=36, null=True, unique=True), + ), + ("archived", models.BooleanField()), + ( + "entity_id", + models.CharField(blank=True, max_length=21, null=True, unique=True), + ), ], options={ - 'db_table': 'action', - 'managed': False, + "db_table": "action", + "managed": False, }, ), migrations.CreateModel( - name='Activity', + name="Activity", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('topic', models.CharField(max_length=32)), - ('timestamp', models.DateTimeField()), - ('model', models.CharField(blank=True, max_length=16, null=True)), - ('model_id', models.IntegerField(blank=True, null=True)), - ('database_id', models.IntegerField(blank=True, null=True)), - ('table_id', models.IntegerField(blank=True, null=True)), - ('custom_id', models.CharField(blank=True, max_length=48, null=True)), - ('details', models.TextField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("topic", models.CharField(max_length=32)), + ("timestamp", models.DateTimeField()), + ("model", models.CharField(blank=True, max_length=16, null=True)), + ("model_id", models.IntegerField(blank=True, null=True)), + ("database_id", models.IntegerField(blank=True, null=True)), + ("table_id", models.IntegerField(blank=True, null=True)), + ("custom_id", models.CharField(blank=True, max_length=48, null=True)), + ("details", models.TextField()), ], options={ - 'db_table': 'activity', - 'managed': False, + "db_table": "activity", + "managed": False, }, ), migrations.CreateModel( - name='ApplicationPermissionsRevision', + name="ApplicationPermissionsRevision", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('before', models.TextField()), - ('after', models.TextField()), - ('created_at', models.DateTimeField()), - ('remark', models.TextField(blank=True, null=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("before", models.TextField()), + ("after", models.TextField()), + ("created_at", models.DateTimeField()), + ("remark", models.TextField(blank=True, null=True)), ], options={ - 'db_table': 'application_permissions_revision', - 'managed': False, + "db_table": "application_permissions_revision", + "managed": False, }, ), migrations.CreateModel( - name='BookmarkOrdering', + name="BookmarkOrdering", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('type', models.CharField(max_length=255)), - ('item_id', models.IntegerField()), - ('ordering', models.IntegerField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("type", models.CharField(max_length=255)), + ("item_id", models.IntegerField()), + ("ordering", models.IntegerField()), ], options={ - 'db_table': 'bookmark_ordering', - 'managed': False, + "db_table": "bookmark_ordering", + "managed": False, }, ), migrations.CreateModel( - name='CardBookmark', + name="CardBookmark", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('created_at', models.DateTimeField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("created_at", models.DateTimeField()), ], options={ - 'db_table': 'card_bookmark', - 'managed': False, + "db_table": "card_bookmark", + "managed": False, }, ), migrations.CreateModel( - name='CardLabel', + name="CardLabel", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), + ("id", models.IntegerField(primary_key=True, serialize=False)), ], options={ - 'db_table': 'card_label', - 'managed': False, + "db_table": "card_label", + "managed": False, }, ), migrations.CreateModel( - name='Collection', + name="Collection", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('name', models.TextField()), - ('description', models.TextField(blank=True, null=True)), - ('color', models.CharField(max_length=7)), - ('archived', models.BooleanField()), - ('location', models.CharField(max_length=254)), - ('slug', models.CharField(max_length=254)), - ('namespace', models.CharField(blank=True, max_length=254, null=True)), - ('authority_level', models.CharField(blank=True, max_length=255, null=True)), - ('entity_id', models.CharField(blank=True, max_length=21, null=True, unique=True)), - ('created_at', models.DateTimeField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("name", models.TextField()), + ("description", models.TextField(blank=True, null=True)), + ("color", models.CharField(max_length=7)), + ("archived", models.BooleanField()), + ("location", models.CharField(max_length=254)), + ("slug", models.CharField(max_length=254)), + ("namespace", models.CharField(blank=True, max_length=254, null=True)), + ( + "authority_level", + models.CharField(blank=True, max_length=255, null=True), + ), + ( + "entity_id", + models.CharField(blank=True, max_length=21, null=True, unique=True), + ), + ("created_at", models.DateTimeField()), ], options={ - 'db_table': 'collection', - 'managed': False, + "db_table": "collection", + "managed": False, }, ), migrations.CreateModel( - name='CollectionBookmark', + name="CollectionBookmark", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('created_at', models.DateTimeField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("created_at", models.DateTimeField()), ], options={ - 'db_table': 'collection_bookmark', - 'managed': False, + "db_table": "collection_bookmark", + "managed": False, }, ), migrations.CreateModel( - name='CollectionPermissionGraphRevision', + name="CollectionPermissionGraphRevision", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('before', models.TextField()), - ('after', models.TextField()), - ('created_at', models.DateTimeField()), - ('remark', models.TextField(blank=True, null=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("before", models.TextField()), + ("after", models.TextField()), + ("created_at", models.DateTimeField()), + ("remark", models.TextField(blank=True, null=True)), ], options={ - 'db_table': 'collection_permission_graph_revision', - 'managed': False, + "db_table": "collection_permission_graph_revision", + "managed": False, }, ), migrations.CreateModel( - name='ComputationJob', + name="ComputationJob", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('type', models.CharField(max_length=254)), - ('status', models.CharField(max_length=254)), - ('context', models.TextField(blank=True, null=True)), - ('ended_at', models.DateTimeField(blank=True, null=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ("type", models.CharField(max_length=254)), + ("status", models.CharField(max_length=254)), + ("context", models.TextField(blank=True, null=True)), + ("ended_at", models.DateTimeField(blank=True, null=True)), ], options={ - 'db_table': 'computation_job', - 'managed': False, + "db_table": "computation_job", + "managed": False, }, ), migrations.CreateModel( - name='ComputationJobResult', + name="ComputationJobResult", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('permanence', models.CharField(max_length=254)), - ('payload', models.TextField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ("permanence", models.CharField(max_length=254)), + ("payload", models.TextField()), ], options={ - 'db_table': 'computation_job_result', - 'managed': False, + "db_table": "computation_job_result", + "managed": False, }, ), migrations.CreateModel( - name='CoreSession', + name="CoreSession", fields=[ - ('id', models.CharField(max_length=254, primary_key=True, serialize=False)), - ('created_at', models.DateTimeField()), - ('anti_csrf_token', models.TextField(blank=True, null=True)), + ( + "id", + models.CharField(max_length=254, primary_key=True, serialize=False), + ), + ("created_at", models.DateTimeField()), + ("anti_csrf_token", models.TextField(blank=True, null=True)), ], options={ - 'db_table': 'core_session', - 'managed': False, + "db_table": "core_session", + "managed": False, }, ), migrations.CreateModel( - name='CoreUser', + name="CoreUser", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('email', models.TextField(unique=True)), - ('first_name', models.CharField(blank=True, max_length=254, null=True)), - ('last_name', models.CharField(blank=True, max_length=254, null=True)), - ('password', models.CharField(blank=True, max_length=254, null=True)), - ('password_salt', models.CharField(blank=True, max_length=254, null=True)), - ('date_joined', models.DateTimeField()), - ('last_login', models.DateTimeField(blank=True, null=True)), - ('is_superuser', models.BooleanField()), - ('is_active', models.BooleanField()), - ('reset_token', models.CharField(blank=True, max_length=254, null=True)), - ('reset_triggered', models.BigIntegerField(blank=True, null=True)), - ('is_qbnewb', models.BooleanField()), - ('google_auth', models.BooleanField()), - ('ldap_auth', models.BooleanField()), - ('login_attributes', models.TextField(blank=True, null=True)), - ('updated_at', models.DateTimeField(blank=True, null=True)), - ('sso_source', models.CharField(blank=True, max_length=254, null=True)), - ('locale', models.CharField(blank=True, max_length=5, null=True)), - ('is_datasetnewb', models.BooleanField()), - ('settings', models.TextField(blank=True, null=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("email", models.TextField(unique=True)), + ("first_name", models.CharField(blank=True, max_length=254, null=True)), + ("last_name", models.CharField(blank=True, max_length=254, null=True)), + ("password", models.CharField(blank=True, max_length=254, null=True)), + ( + "password_salt", + models.CharField(blank=True, max_length=254, null=True), + ), + ("date_joined", models.DateTimeField()), + ("last_login", models.DateTimeField(blank=True, null=True)), + ("is_superuser", models.BooleanField()), + ("is_active", models.BooleanField()), + ( + "reset_token", + models.CharField(blank=True, max_length=254, null=True), + ), + ("reset_triggered", models.BigIntegerField(blank=True, null=True)), + ("is_qbnewb", models.BooleanField()), + ("google_auth", models.BooleanField()), + ("ldap_auth", models.BooleanField()), + ("login_attributes", models.TextField(blank=True, null=True)), + ("updated_at", models.DateTimeField(blank=True, null=True)), + ("sso_source", models.CharField(blank=True, max_length=254, null=True)), + ("locale", models.CharField(blank=True, max_length=5, null=True)), + ("is_datasetnewb", models.BooleanField()), + ("settings", models.TextField(blank=True, null=True)), ], options={ - 'db_table': 'core_user', - 'managed': False, + "db_table": "core_user", + "managed": False, }, ), migrations.CreateModel( - name='DashboardBookmark', + name="DashboardBookmark", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('created_at', models.DateTimeField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("created_at", models.DateTimeField()), ], options={ - 'db_table': 'dashboard_bookmark', - 'managed': False, + "db_table": "dashboard_bookmark", + "managed": False, }, ), migrations.CreateModel( - name='DashboardcardSeries', + name="DashboardcardSeries", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('position', models.IntegerField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("position", models.IntegerField()), ], options={ - 'db_table': 'dashboardcard_series', - 'managed': False, + "db_table": "dashboardcard_series", + "managed": False, }, ), migrations.CreateModel( - name='DashboardFavorite', + name="DashboardFavorite", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), + ("id", models.IntegerField(primary_key=True, serialize=False)), ], options={ - 'db_table': 'dashboard_favorite', - 'managed': False, + "db_table": "dashboard_favorite", + "managed": False, }, ), migrations.CreateModel( - name='DataMigrations', + name="DataMigrations", fields=[ - ('id', models.CharField(max_length=254, primary_key=True, serialize=False)), - ('timestamp', models.DateTimeField()), + ( + "id", + models.CharField(max_length=254, primary_key=True, serialize=False), + ), + ("timestamp", models.DateTimeField()), ], options={ - 'db_table': 'data_migrations', - 'managed': False, + "db_table": "data_migrations", + "managed": False, }, ), migrations.CreateModel( - name='Dependency', + name="Dependency", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('model', models.CharField(max_length=32)), - ('model_id', models.IntegerField()), - ('dependent_on_model', models.CharField(max_length=32)), - ('dependent_on_id', models.IntegerField()), - ('created_at', models.DateTimeField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("model", models.CharField(max_length=32)), + ("model_id", models.IntegerField()), + ("dependent_on_model", models.CharField(max_length=32)), + ("dependent_on_id", models.IntegerField()), + ("created_at", models.DateTimeField()), ], options={ - 'db_table': 'dependency', - 'managed': False, + "db_table": "dependency", + "managed": False, }, ), migrations.CreateModel( - name='Dimension', + name="Dimension", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('name', models.CharField(max_length=254)), - ('type', models.CharField(max_length=254)), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('entity_id', models.CharField(blank=True, max_length=21, null=True, unique=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("name", models.CharField(max_length=254)), + ("type", models.CharField(max_length=254)), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ( + "entity_id", + models.CharField(blank=True, max_length=21, null=True, unique=True), + ), ], options={ - 'db_table': 'dimension', - 'managed': False, + "db_table": "dimension", + "managed": False, }, ), migrations.CreateModel( - name='ImplicitAction', + name="ImplicitAction", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('kind', models.TextField()), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("kind", models.TextField()), ], options={ - 'db_table': 'implicit_action', - 'managed': False, + "db_table": "implicit_action", + "managed": False, }, ), migrations.CreateModel( - name='Label', + name="Label", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('name', models.CharField(max_length=254)), - ('slug', models.CharField(max_length=254, unique=True)), - ('icon', models.CharField(blank=True, max_length=128, null=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("name", models.CharField(max_length=254)), + ("slug", models.CharField(max_length=254, unique=True)), + ("icon", models.CharField(blank=True, max_length=128, null=True)), ], options={ - 'db_table': 'label', - 'managed': False, + "db_table": "label", + "managed": False, }, ), migrations.CreateModel( - name='LoginHistory', + name="LoginHistory", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('timestamp', models.DateTimeField()), - ('device_id', models.CharField(max_length=36)), - ('device_description', models.TextField()), - ('ip_address', models.TextField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("timestamp", models.DateTimeField()), + ("device_id", models.CharField(max_length=36)), + ("device_description", models.TextField()), + ("ip_address", models.TextField()), ], options={ - 'db_table': 'login_history', - 'managed': False, + "db_table": "login_history", + "managed": False, }, ), migrations.CreateModel( - name='MetabaseDatabase', + name="MetabaseDatabase", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('name', models.CharField(max_length=254)), - ('description', models.TextField(blank=True, null=True)), - ('details', models.TextField()), - ('engine', models.CharField(max_length=254)), - ('is_sample', models.BooleanField()), - ('is_full_sync', models.BooleanField()), - ('points_of_interest', models.TextField(blank=True, null=True)), - ('caveats', models.TextField(blank=True, null=True)), - ('metadata_sync_schedule', models.CharField(max_length=254)), - ('cache_field_values_schedule', models.CharField(max_length=254)), - ('timezone', models.CharField(blank=True, max_length=254, null=True)), - ('is_on_demand', models.BooleanField()), - ('options', models.TextField(blank=True, null=True)), - ('auto_run_queries', models.BooleanField()), - ('refingerprint', models.BooleanField(blank=True, null=True)), - ('cache_ttl', models.IntegerField(blank=True, null=True)), - ('initial_sync_status', models.CharField(max_length=32)), - ('settings', models.TextField(blank=True, null=True)), - ('dbms_version', models.TextField(blank=True, null=True)), - ], + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ("name", models.CharField(max_length=254)), + ("description", models.TextField(blank=True, null=True)), + ("details", models.TextField()), + ("engine", models.CharField(max_length=254)), + ("is_sample", models.BooleanField()), + ("is_full_sync", models.BooleanField()), + ("points_of_interest", models.TextField(blank=True, null=True)), + ("caveats", models.TextField(blank=True, null=True)), + ("metadata_sync_schedule", models.CharField(max_length=254)), + ("cache_field_values_schedule", models.CharField(max_length=254)), + ("timezone", models.CharField(blank=True, max_length=254, null=True)), + ("is_on_demand", models.BooleanField()), + ("options", models.TextField(blank=True, null=True)), + ("auto_run_queries", models.BooleanField()), + ("refingerprint", models.BooleanField(blank=True, null=True)), + ("cache_ttl", models.IntegerField(blank=True, null=True)), + ("initial_sync_status", models.CharField(max_length=32)), + ("settings", models.TextField(blank=True, null=True)), + ("dbms_version", models.TextField(blank=True, null=True)), + ], options={ - 'db_table': 'metabase_database', - 'managed': False, + "db_table": "metabase_database", + "managed": False, }, ), migrations.CreateModel( - name='MetabaseField', + name="MetabaseField", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('name', models.CharField(max_length=254)), - ('base_type', models.CharField(max_length=255)), - ('semantic_type', models.CharField(blank=True, max_length=255, null=True)), - ('active', models.BooleanField()), - ('description', models.TextField(blank=True, null=True)), - ('preview_display', models.BooleanField()), - ('position', models.IntegerField()), - ('display_name', models.CharField(blank=True, max_length=254, null=True)), - ('visibility_type', models.CharField(max_length=32)), - ('fk_target_field_id', models.IntegerField(blank=True, null=True)), - ('last_analyzed', models.DateTimeField(blank=True, null=True)), - ('points_of_interest', models.TextField(blank=True, null=True)), - ('caveats', models.TextField(blank=True, null=True)), - ('fingerprint', models.TextField(blank=True, null=True)), - ('fingerprint_version', models.IntegerField()), - ('database_type', models.TextField()), - ('has_field_values', models.TextField(blank=True, null=True)), - ('settings', models.TextField(blank=True, null=True)), - ('database_position', models.IntegerField()), - ('custom_position', models.IntegerField()), - ('effective_type', models.CharField(blank=True, max_length=255, null=True)), - ('coercion_strategy', models.CharField(blank=True, max_length=255, null=True)), - ('nfc_path', models.CharField(blank=True, max_length=254, null=True)), - ('database_required', models.BooleanField()), - ('database_is_auto_increment', models.BooleanField()), - ], - options={ - 'db_table': 'metabase_field', - 'managed': False, + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ("name", models.CharField(max_length=254)), + ("base_type", models.CharField(max_length=255)), + ( + "semantic_type", + models.CharField(blank=True, max_length=255, null=True), + ), + ("active", models.BooleanField()), + ("description", models.TextField(blank=True, null=True)), + ("preview_display", models.BooleanField()), + ("position", models.IntegerField()), + ( + "display_name", + models.CharField(blank=True, max_length=254, null=True), + ), + ("visibility_type", models.CharField(max_length=32)), + ("fk_target_field_id", models.IntegerField(blank=True, null=True)), + ("last_analyzed", models.DateTimeField(blank=True, null=True)), + ("points_of_interest", models.TextField(blank=True, null=True)), + ("caveats", models.TextField(blank=True, null=True)), + ("fingerprint", models.TextField(blank=True, null=True)), + ("fingerprint_version", models.IntegerField()), + ("database_type", models.TextField()), + ("has_field_values", models.TextField(blank=True, null=True)), + ("settings", models.TextField(blank=True, null=True)), + ("database_position", models.IntegerField()), + ("custom_position", models.IntegerField()), + ( + "effective_type", + models.CharField(blank=True, max_length=255, null=True), + ), + ( + "coercion_strategy", + models.CharField(blank=True, max_length=255, null=True), + ), + ("nfc_path", models.CharField(blank=True, max_length=254, null=True)), + ("database_required", models.BooleanField()), + ("database_is_auto_increment", models.BooleanField()), + ], + options={ + "db_table": "metabase_field", + "managed": False, }, ), migrations.CreateModel( - name='MetabaseFieldvalues', + name="MetabaseFieldvalues", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('values', models.TextField(blank=True, null=True)), - ('human_readable_values', models.TextField(blank=True, null=True)), - ('has_more_values', models.BooleanField(blank=True, null=True)), - ('type', models.CharField(max_length=32)), - ('hash_key', models.TextField(blank=True, null=True)), - ('last_used_at', models.DateTimeField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ("values", models.TextField(blank=True, null=True)), + ("human_readable_values", models.TextField(blank=True, null=True)), + ("has_more_values", models.BooleanField(blank=True, null=True)), + ("type", models.CharField(max_length=32)), + ("hash_key", models.TextField(blank=True, null=True)), + ("last_used_at", models.DateTimeField()), + ], + options={ + "db_table": "metabase_fieldvalues", + "managed": False, + }, + ), + migrations.CreateModel( + name="MetabaseTable", + fields=[ + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ("name", models.CharField(max_length=254)), + ("description", models.TextField(blank=True, null=True)), + ( + "entity_type", + models.CharField(blank=True, max_length=254, null=True), + ), + ("active", models.BooleanField()), + ( + "display_name", + models.CharField(blank=True, max_length=254, null=True), + ), + ( + "visibility_type", + models.CharField(blank=True, max_length=254, null=True), + ), + ("schema", models.CharField(blank=True, max_length=254, null=True)), + ("points_of_interest", models.TextField(blank=True, null=True)), + ("caveats", models.TextField(blank=True, null=True)), + ("show_in_getting_started", models.BooleanField()), + ("field_order", models.CharField(max_length=254)), + ("initial_sync_status", models.CharField(max_length=32)), ], options={ - 'db_table': 'metabase_fieldvalues', - 'managed': False, + "db_table": "metabase_table", + "managed": False, }, ), migrations.CreateModel( - name='MetabaseTable', + name="Metric", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('name', models.CharField(max_length=254)), - ('description', models.TextField(blank=True, null=True)), - ('entity_type', models.CharField(blank=True, max_length=254, null=True)), - ('active', models.BooleanField()), - ('display_name', models.CharField(blank=True, max_length=254, null=True)), - ('visibility_type', models.CharField(blank=True, max_length=254, null=True)), - ('schema', models.CharField(blank=True, max_length=254, null=True)), - ('points_of_interest', models.TextField(blank=True, null=True)), - ('caveats', models.TextField(blank=True, null=True)), - ('show_in_getting_started', models.BooleanField()), - ('field_order', models.CharField(max_length=254)), - ('initial_sync_status', models.CharField(max_length=32)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("name", models.CharField(max_length=254)), + ("description", models.TextField(blank=True, null=True)), + ("archived", models.BooleanField()), + ("definition", models.TextField()), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ("points_of_interest", models.TextField(blank=True, null=True)), + ("caveats", models.TextField(blank=True, null=True)), + ("how_is_this_calculated", models.TextField(blank=True, null=True)), + ("show_in_getting_started", models.BooleanField()), + ( + "entity_id", + models.CharField(blank=True, max_length=21, null=True, unique=True), + ), ], options={ - 'db_table': 'metabase_table', - 'managed': False, + "db_table": "metric", + "managed": False, }, ), migrations.CreateModel( - name='Metric', + name="MetricImportantField", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('name', models.CharField(max_length=254)), - ('description', models.TextField(blank=True, null=True)), - ('archived', models.BooleanField()), - ('definition', models.TextField()), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('points_of_interest', models.TextField(blank=True, null=True)), - ('caveats', models.TextField(blank=True, null=True)), - ('how_is_this_calculated', models.TextField(blank=True, null=True)), - ('show_in_getting_started', models.BooleanField()), - ('entity_id', models.CharField(blank=True, max_length=21, null=True, unique=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), ], options={ - 'db_table': 'metric', - 'managed': False, + "db_table": "metric_important_field", + "managed": False, }, ), migrations.CreateModel( - name='MetricImportantField', + name="ModerationReview", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("updated_at", models.DateTimeField()), + ("created_at", models.DateTimeField()), + ("status", models.CharField(blank=True, max_length=255, null=True)), + ("text", models.TextField(blank=True, null=True)), + ("moderated_item_id", models.IntegerField()), + ("moderated_item_type", models.CharField(max_length=255)), + ("moderator_id", models.IntegerField()), + ("most_recent", models.BooleanField()), ], options={ - 'db_table': 'metric_important_field', - 'managed': False, + "db_table": "moderation_review", + "managed": False, }, ), migrations.CreateModel( - name='ModerationReview', + name="NativeQuerySnippet", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('updated_at', models.DateTimeField()), - ('created_at', models.DateTimeField()), - ('status', models.CharField(blank=True, max_length=255, null=True)), - ('text', models.TextField(blank=True, null=True)), - ('moderated_item_id', models.IntegerField()), - ('moderated_item_type', models.CharField(max_length=255)), - ('moderator_id', models.IntegerField()), - ('most_recent', models.BooleanField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("name", models.CharField(max_length=254, unique=True)), + ("description", models.TextField(blank=True, null=True)), + ("content", models.TextField()), + ("archived", models.BooleanField()), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ( + "entity_id", + models.CharField(blank=True, max_length=21, null=True, unique=True), + ), ], options={ - 'db_table': 'moderation_review', - 'managed': False, + "db_table": "native_query_snippet", + "managed": False, }, ), migrations.CreateModel( - name='NativeQuerySnippet', + name="ParameterCard", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('name', models.CharField(max_length=254, unique=True)), - ('description', models.TextField(blank=True, null=True)), - ('content', models.TextField()), - ('archived', models.BooleanField()), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('entity_id', models.CharField(blank=True, max_length=21, null=True, unique=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("updated_at", models.DateTimeField()), + ("created_at", models.DateTimeField()), + ("parameterized_object_type", models.CharField(max_length=32)), + ("parameterized_object_id", models.IntegerField()), + ("parameter_id", models.CharField(max_length=36)), + ( + "entity_id", + models.CharField(blank=True, max_length=21, null=True, unique=True), + ), ], options={ - 'db_table': 'native_query_snippet', - 'managed': False, + "db_table": "parameter_card", + "managed": False, }, ), migrations.CreateModel( - name='ParameterCard', + name="Permissions", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('updated_at', models.DateTimeField()), - ('created_at', models.DateTimeField()), - ('parameterized_object_type', models.CharField(max_length=32)), - ('parameterized_object_id', models.IntegerField()), - ('parameter_id', models.CharField(max_length=36)), - ('entity_id', models.CharField(blank=True, max_length=21, null=True, unique=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("object", models.CharField(max_length=254)), ], options={ - 'db_table': 'parameter_card', - 'managed': False, + "db_table": "permissions", + "managed": False, }, ), migrations.CreateModel( - name='Permissions', + name="PermissionsGroup", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('object', models.CharField(max_length=254)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("name", models.CharField(max_length=255, unique=True)), ], options={ - 'db_table': 'permissions', - 'managed': False, + "db_table": "permissions_group", + "managed": False, }, ), migrations.CreateModel( - name='PermissionsGroup', + name="PermissionsGroupMembership", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('name', models.CharField(max_length=255, unique=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("is_group_manager", models.BooleanField()), ], options={ - 'db_table': 'permissions_group', - 'managed': False, + "db_table": "permissions_group_membership", + "managed": False, }, ), migrations.CreateModel( - name='PermissionsGroupMembership', + name="PermissionsRevision", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('is_group_manager', models.BooleanField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("before", models.TextField()), + ("after", models.TextField()), + ("created_at", models.DateTimeField()), + ("remark", models.TextField(blank=True, null=True)), ], options={ - 'db_table': 'permissions_group_membership', - 'managed': False, + "db_table": "permissions_revision", + "managed": False, }, ), migrations.CreateModel( - name='PermissionsRevision', + name="PersistedInfo", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('before', models.TextField()), - ('after', models.TextField()), - ('created_at', models.DateTimeField()), - ('remark', models.TextField(blank=True, null=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("question_slug", models.TextField()), + ("table_name", models.TextField()), + ("definition", models.TextField(blank=True, null=True)), + ("query_hash", models.TextField(blank=True, null=True)), + ("active", models.BooleanField()), + ("state", models.TextField()), + ("refresh_begin", models.DateTimeField()), + ("refresh_end", models.DateTimeField(blank=True, null=True)), + ("state_change_at", models.DateTimeField(blank=True, null=True)), + ("error", models.TextField(blank=True, null=True)), + ("created_at", models.DateTimeField()), ], options={ - 'db_table': 'permissions_revision', - 'managed': False, + "db_table": "persisted_info", + "managed": False, }, ), migrations.CreateModel( - name='PersistedInfo', + name="Pulse", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('question_slug', models.TextField()), - ('table_name', models.TextField()), - ('definition', models.TextField(blank=True, null=True)), - ('query_hash', models.TextField(blank=True, null=True)), - ('active', models.BooleanField()), - ('state', models.TextField()), - ('refresh_begin', models.DateTimeField()), - ('refresh_end', models.DateTimeField(blank=True, null=True)), - ('state_change_at', models.DateTimeField(blank=True, null=True)), - ('error', models.TextField(blank=True, null=True)), - ('created_at', models.DateTimeField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("name", models.CharField(blank=True, max_length=254, null=True)), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ("skip_if_empty", models.BooleanField()), + ( + "alert_condition", + models.CharField(blank=True, max_length=254, null=True), + ), + ("alert_first_only", models.BooleanField(blank=True, null=True)), + ("alert_above_goal", models.BooleanField(blank=True, null=True)), + ( + "collection_position", + models.SmallIntegerField(blank=True, null=True), + ), + ("archived", models.BooleanField(blank=True, null=True)), + ("parameters", models.TextField()), + ( + "entity_id", + models.CharField(blank=True, max_length=21, null=True, unique=True), + ), ], options={ - 'db_table': 'persisted_info', - 'managed': False, + "db_table": "pulse", + "managed": False, }, ), migrations.CreateModel( - name='Pulse', + name="PulseCard", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('name', models.CharField(blank=True, max_length=254, null=True)), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('skip_if_empty', models.BooleanField()), - ('alert_condition', models.CharField(blank=True, max_length=254, null=True)), - ('alert_first_only', models.BooleanField(blank=True, null=True)), - ('alert_above_goal', models.BooleanField(blank=True, null=True)), - ('collection_position', models.SmallIntegerField(blank=True, null=True)), - ('archived', models.BooleanField(blank=True, null=True)), - ('parameters', models.TextField()), - ('entity_id', models.CharField(blank=True, max_length=21, null=True, unique=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("position", models.IntegerField()), + ("include_csv", models.BooleanField()), + ("include_xls", models.BooleanField()), + ( + "entity_id", + models.CharField(blank=True, max_length=21, null=True, unique=True), + ), ], options={ - 'db_table': 'pulse', - 'managed': False, + "db_table": "pulse_card", + "managed": False, }, ), migrations.CreateModel( - name='PulseCard', + name="PulseChannel", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('position', models.IntegerField()), - ('include_csv', models.BooleanField()), - ('include_xls', models.BooleanField()), - ('entity_id', models.CharField(blank=True, max_length=21, null=True, unique=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("channel_type", models.CharField(max_length=32)), + ("details", models.TextField()), + ("schedule_type", models.CharField(max_length=32)), + ("schedule_hour", models.IntegerField(blank=True, null=True)), + ( + "schedule_day", + models.CharField(blank=True, max_length=64, null=True), + ), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ( + "schedule_frame", + models.CharField(blank=True, max_length=32, null=True), + ), + ("enabled", models.BooleanField()), + ( + "entity_id", + models.CharField(blank=True, max_length=21, null=True, unique=True), + ), ], options={ - 'db_table': 'pulse_card', - 'managed': False, + "db_table": "pulse_channel", + "managed": False, }, ), migrations.CreateModel( - name='PulseChannel', + name="PulseChannelRecipient", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('channel_type', models.CharField(max_length=32)), - ('details', models.TextField()), - ('schedule_type', models.CharField(max_length=32)), - ('schedule_hour', models.IntegerField(blank=True, null=True)), - ('schedule_day', models.CharField(blank=True, max_length=64, null=True)), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('schedule_frame', models.CharField(blank=True, max_length=32, null=True)), - ('enabled', models.BooleanField()), - ('entity_id', models.CharField(blank=True, max_length=21, null=True, unique=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), ], options={ - 'db_table': 'pulse_channel', - 'managed': False, + "db_table": "pulse_channel_recipient", + "managed": False, }, ), migrations.CreateModel( - name='PulseChannelRecipient', + name="QrtzCalendars", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), + ( + "sched_name", + models.CharField(max_length=120, primary_key=True, serialize=False), + ), + ("calendar_name", models.CharField(max_length=200)), + ("calendar", models.BinaryField()), ], options={ - 'db_table': 'pulse_channel_recipient', - 'managed': False, + "db_table": "qrtz_calendars", + "managed": False, }, ), migrations.CreateModel( - name='QrtzCalendars', + name="QrtzFiredTriggers", fields=[ - ('sched_name', models.CharField(max_length=120, primary_key=True, serialize=False)), - ('calendar_name', models.CharField(max_length=200)), - ('calendar', models.BinaryField()), + ( + "sched_name", + models.CharField(max_length=120, primary_key=True, serialize=False), + ), + ("entry_id", models.CharField(max_length=95)), + ("trigger_name", models.CharField(max_length=200)), + ("trigger_group", models.CharField(max_length=200)), + ("instance_name", models.CharField(max_length=200)), + ("fired_time", models.BigIntegerField()), + ("sched_time", models.BigIntegerField(blank=True, null=True)), + ("priority", models.IntegerField()), + ("state", models.CharField(max_length=16)), + ("job_name", models.CharField(blank=True, max_length=200, null=True)), + ("job_group", models.CharField(blank=True, max_length=200, null=True)), + ("is_nonconcurrent", models.BooleanField(blank=True, null=True)), + ("requests_recovery", models.BooleanField(blank=True, null=True)), ], options={ - 'db_table': 'qrtz_calendars', - 'managed': False, + "db_table": "qrtz_fired_triggers", + "managed": False, }, ), migrations.CreateModel( - name='QrtzFiredTriggers', + name="QrtzJobDetails", fields=[ - ('sched_name', models.CharField(max_length=120, primary_key=True, serialize=False)), - ('entry_id', models.CharField(max_length=95)), - ('trigger_name', models.CharField(max_length=200)), - ('trigger_group', models.CharField(max_length=200)), - ('instance_name', models.CharField(max_length=200)), - ('fired_time', models.BigIntegerField()), - ('sched_time', models.BigIntegerField(blank=True, null=True)), - ('priority', models.IntegerField()), - ('state', models.CharField(max_length=16)), - ('job_name', models.CharField(blank=True, max_length=200, null=True)), - ('job_group', models.CharField(blank=True, max_length=200, null=True)), - ('is_nonconcurrent', models.BooleanField(blank=True, null=True)), - ('requests_recovery', models.BooleanField(blank=True, null=True)), + ( + "sched_name", + models.CharField(max_length=120, primary_key=True, serialize=False), + ), + ("job_name", models.CharField(max_length=200)), + ("job_group", models.CharField(max_length=200)), + ( + "description", + models.CharField(blank=True, max_length=250, null=True), + ), + ("job_class_name", models.CharField(max_length=250)), + ("is_durable", models.BooleanField()), + ("is_nonconcurrent", models.BooleanField()), + ("is_update_data", models.BooleanField()), + ("requests_recovery", models.BooleanField()), + ("job_data", models.BinaryField(blank=True, null=True)), ], options={ - 'db_table': 'qrtz_fired_triggers', - 'managed': False, + "db_table": "qrtz_job_details", + "managed": False, }, ), migrations.CreateModel( - name='QrtzJobDetails', + name="QrtzLocks", fields=[ - ('sched_name', models.CharField(max_length=120, primary_key=True, serialize=False)), - ('job_name', models.CharField(max_length=200)), - ('job_group', models.CharField(max_length=200)), - ('description', models.CharField(blank=True, max_length=250, null=True)), - ('job_class_name', models.CharField(max_length=250)), - ('is_durable', models.BooleanField()), - ('is_nonconcurrent', models.BooleanField()), - ('is_update_data', models.BooleanField()), - ('requests_recovery', models.BooleanField()), - ('job_data', models.BinaryField(blank=True, null=True)), + ( + "sched_name", + models.CharField(max_length=120, primary_key=True, serialize=False), + ), + ("lock_name", models.CharField(max_length=40)), ], options={ - 'db_table': 'qrtz_job_details', - 'managed': False, + "db_table": "qrtz_locks", + "managed": False, }, ), migrations.CreateModel( - name='QrtzLocks', + name="QrtzPausedTriggerGrps", fields=[ - ('sched_name', models.CharField(max_length=120, primary_key=True, serialize=False)), - ('lock_name', models.CharField(max_length=40)), + ( + "sched_name", + models.CharField(max_length=120, primary_key=True, serialize=False), + ), + ("trigger_group", models.CharField(max_length=200)), ], options={ - 'db_table': 'qrtz_locks', - 'managed': False, + "db_table": "qrtz_paused_trigger_grps", + "managed": False, }, ), migrations.CreateModel( - name='QrtzPausedTriggerGrps', + name="QrtzSchedulerState", fields=[ - ('sched_name', models.CharField(max_length=120, primary_key=True, serialize=False)), - ('trigger_group', models.CharField(max_length=200)), + ( + "sched_name", + models.CharField(max_length=120, primary_key=True, serialize=False), + ), + ("instance_name", models.CharField(max_length=200)), + ("last_checkin_time", models.BigIntegerField()), + ("checkin_interval", models.BigIntegerField()), ], options={ - 'db_table': 'qrtz_paused_trigger_grps', - 'managed': False, + "db_table": "qrtz_scheduler_state", + "managed": False, }, ), migrations.CreateModel( - name='QrtzSchedulerState', + name="Query", fields=[ - ('sched_name', models.CharField(max_length=120, primary_key=True, serialize=False)), - ('instance_name', models.CharField(max_length=200)), - ('last_checkin_time', models.BigIntegerField()), - ('checkin_interval', models.BigIntegerField()), + ("query_hash", models.BinaryField(primary_key=True, serialize=False)), + ("average_execution_time", models.IntegerField()), + ("query", models.TextField(blank=True, null=True)), ], options={ - 'db_table': 'qrtz_scheduler_state', - 'managed': False, + "db_table": "query", + "managed": False, }, ), migrations.CreateModel( - name='Query', + name="QueryCache", fields=[ - ('query_hash', models.BinaryField(primary_key=True, serialize=False)), - ('average_execution_time', models.IntegerField()), - ('query', models.TextField(blank=True, null=True)), + ("query_hash", models.BinaryField(primary_key=True, serialize=False)), + ("updated_at", models.DateTimeField()), + ("results", models.BinaryField()), ], options={ - 'db_table': 'query', - 'managed': False, + "db_table": "query_cache", + "managed": False, }, ), migrations.CreateModel( - name='QueryCache', + name="QueryExecution", fields=[ - ('query_hash', models.BinaryField(primary_key=True, serialize=False)), - ('updated_at', models.DateTimeField()), - ('results', models.BinaryField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("hash", models.BinaryField()), + ("started_at", models.DateTimeField()), + ("running_time", models.IntegerField()), + ("result_rows", models.IntegerField()), + ("native", models.BooleanField()), + ("context", models.CharField(blank=True, max_length=32, null=True)), + ("error", models.TextField(blank=True, null=True)), + ("executor_id", models.IntegerField(blank=True, null=True)), + ("card_id", models.IntegerField(blank=True, null=True)), + ("dashboard_id", models.IntegerField(blank=True, null=True)), + ("pulse_id", models.IntegerField(blank=True, null=True)), + ("database_id", models.IntegerField(blank=True, null=True)), + ("cache_hit", models.BooleanField(blank=True, null=True)), ], options={ - 'db_table': 'query_cache', - 'managed': False, + "db_table": "query_execution", + "managed": False, }, ), migrations.CreateModel( - name='QueryExecution', + name="ReportCard", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('hash', models.BinaryField()), - ('started_at', models.DateTimeField()), - ('running_time', models.IntegerField()), - ('result_rows', models.IntegerField()), - ('native', models.BooleanField()), - ('context', models.CharField(blank=True, max_length=32, null=True)), - ('error', models.TextField(blank=True, null=True)), - ('executor_id', models.IntegerField(blank=True, null=True)), - ('card_id', models.IntegerField(blank=True, null=True)), - ('dashboard_id', models.IntegerField(blank=True, null=True)), - ('pulse_id', models.IntegerField(blank=True, null=True)), - ('database_id', models.IntegerField(blank=True, null=True)), - ('cache_hit', models.BooleanField(blank=True, null=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ("name", models.CharField(max_length=254)), + ("description", models.TextField(blank=True, null=True)), + ("display", models.CharField(max_length=254)), + ("dataset_query", models.TextField()), + ("visualization_settings", models.TextField()), + ("query_type", models.CharField(blank=True, max_length=16, null=True)), + ("archived", models.BooleanField()), + ( + "public_uuid", + models.CharField(blank=True, max_length=36, null=True, unique=True), + ), + ("enable_embedding", models.BooleanField()), + ("embedding_params", models.TextField(blank=True, null=True)), + ("cache_ttl", models.IntegerField(blank=True, null=True)), + ("result_metadata", models.TextField(blank=True, null=True)), + ( + "collection_position", + models.SmallIntegerField(blank=True, null=True), + ), + ("dataset", models.BooleanField()), + ( + "entity_id", + models.CharField(blank=True, max_length=21, null=True, unique=True), + ), + ("parameters", models.TextField(blank=True, null=True)), + ("parameter_mappings", models.TextField(blank=True, null=True)), + ("collection_preview", models.BooleanField()), ], options={ - 'db_table': 'query_execution', - 'managed': False, + "db_table": "report_card", + "managed": False, }, ), migrations.CreateModel( - name='ReportCard', + name="ReportCardfavorite", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('name', models.CharField(max_length=254)), - ('description', models.TextField(blank=True, null=True)), - ('display', models.CharField(max_length=254)), - ('dataset_query', models.TextField()), - ('visualization_settings', models.TextField()), - ('query_type', models.CharField(blank=True, max_length=16, null=True)), - ('archived', models.BooleanField()), - ('public_uuid', models.CharField(blank=True, max_length=36, null=True, unique=True)), - ('enable_embedding', models.BooleanField()), - ('embedding_params', models.TextField(blank=True, null=True)), - ('cache_ttl', models.IntegerField(blank=True, null=True)), - ('result_metadata', models.TextField(blank=True, null=True)), - ('collection_position', models.SmallIntegerField(blank=True, null=True)), - ('dataset', models.BooleanField()), - ('entity_id', models.CharField(blank=True, max_length=21, null=True, unique=True)), - ('parameters', models.TextField(blank=True, null=True)), - ('parameter_mappings', models.TextField(blank=True, null=True)), - ('collection_preview', models.BooleanField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), ], options={ - 'db_table': 'report_card', - 'managed': False, + "db_table": "report_cardfavorite", + "managed": False, }, ), migrations.CreateModel( - name='ReportCardfavorite', + name="ReportDashboard", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ("name", models.CharField(max_length=254)), + ("description", models.TextField(blank=True, null=True)), + ("parameters", models.TextField()), + ("points_of_interest", models.TextField(blank=True, null=True)), + ("caveats", models.TextField(blank=True, null=True)), + ("show_in_getting_started", models.BooleanField()), + ( + "public_uuid", + models.CharField(blank=True, max_length=36, null=True, unique=True), + ), + ("enable_embedding", models.BooleanField()), + ("embedding_params", models.TextField(blank=True, null=True)), + ("archived", models.BooleanField()), + ("position", models.IntegerField(blank=True, null=True)), + ( + "collection_position", + models.SmallIntegerField(blank=True, null=True), + ), + ("cache_ttl", models.IntegerField(blank=True, null=True)), + ( + "entity_id", + models.CharField(blank=True, max_length=21, null=True, unique=True), + ), ], options={ - 'db_table': 'report_cardfavorite', - 'managed': False, + "db_table": "report_dashboard", + "managed": False, }, ), migrations.CreateModel( - name='ReportDashboard', + name="ReportDashboardcard", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('name', models.CharField(max_length=254)), - ('description', models.TextField(blank=True, null=True)), - ('parameters', models.TextField()), - ('points_of_interest', models.TextField(blank=True, null=True)), - ('caveats', models.TextField(blank=True, null=True)), - ('show_in_getting_started', models.BooleanField()), - ('public_uuid', models.CharField(blank=True, max_length=36, null=True, unique=True)), - ('enable_embedding', models.BooleanField()), - ('embedding_params', models.TextField(blank=True, null=True)), - ('archived', models.BooleanField()), - ('position', models.IntegerField(blank=True, null=True)), - ('collection_position', models.SmallIntegerField(blank=True, null=True)), - ('cache_ttl', models.IntegerField(blank=True, null=True)), - ('entity_id', models.CharField(blank=True, max_length=21, null=True, unique=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ("size_x", models.IntegerField()), + ("size_y", models.IntegerField()), + ("row", models.IntegerField()), + ("col", models.IntegerField()), + ("parameter_mappings", models.TextField()), + ("visualization_settings", models.TextField()), + ( + "entity_id", + models.CharField(blank=True, max_length=21, null=True, unique=True), + ), ], options={ - 'db_table': 'report_dashboard', - 'managed': False, + "db_table": "report_dashboardcard", + "managed": False, }, ), migrations.CreateModel( - name='ReportDashboardcard', + name="Revision", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('size_x', models.IntegerField()), - ('size_y', models.IntegerField()), - ('row', models.IntegerField()), - ('col', models.IntegerField()), - ('parameter_mappings', models.TextField()), - ('visualization_settings', models.TextField()), - ('entity_id', models.CharField(blank=True, max_length=21, null=True, unique=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("model", models.CharField(max_length=16)), + ("model_id", models.IntegerField()), + ("timestamp", models.DateTimeField()), + ("object", models.TextField()), + ("is_reversion", models.BooleanField()), + ("is_creation", models.BooleanField()), + ("message", models.TextField(blank=True, null=True)), ], options={ - 'db_table': 'report_dashboardcard', - 'managed': False, + "db_table": "revision", + "managed": False, }, ), migrations.CreateModel( - name='Revision', + name="Sandboxes", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('model', models.CharField(max_length=16)), - ('model_id', models.IntegerField()), - ('timestamp', models.DateTimeField()), - ('object', models.TextField()), - ('is_reversion', models.BooleanField()), - ('is_creation', models.BooleanField()), - ('message', models.TextField(blank=True, null=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("attribute_remappings", models.TextField(blank=True, null=True)), ], options={ - 'db_table': 'revision', - 'managed': False, + "db_table": "sandboxes", + "managed": False, }, ), migrations.CreateModel( - name='Sandboxes', + name="Secret", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('attribute_remappings', models.TextField(blank=True, null=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("version", models.IntegerField()), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField(blank=True, null=True)), + ("name", models.CharField(max_length=254)), + ("kind", models.CharField(max_length=254)), + ("source", models.CharField(blank=True, max_length=254, null=True)), + ("value", models.BinaryField()), ], options={ - 'db_table': 'sandboxes', - 'managed': False, + "db_table": "secret", + "managed": False, }, ), migrations.CreateModel( - name='Secret', + name="Segment", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('version', models.IntegerField()), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField(blank=True, null=True)), - ('name', models.CharField(max_length=254)), - ('kind', models.CharField(max_length=254)), - ('source', models.CharField(blank=True, max_length=254, null=True)), - ('value', models.BinaryField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("name", models.CharField(max_length=254)), + ("description", models.TextField(blank=True, null=True)), + ("archived", models.BooleanField()), + ("definition", models.TextField()), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ("points_of_interest", models.TextField(blank=True, null=True)), + ("caveats", models.TextField(blank=True, null=True)), + ("show_in_getting_started", models.BooleanField()), + ( + "entity_id", + models.CharField(blank=True, max_length=21, null=True, unique=True), + ), ], options={ - 'db_table': 'secret', - 'managed': False, + "db_table": "segment", + "managed": False, }, ), migrations.CreateModel( - name='Segment', + name="Setting", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('name', models.CharField(max_length=254)), - ('description', models.TextField(blank=True, null=True)), - ('archived', models.BooleanField()), - ('definition', models.TextField()), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('points_of_interest', models.TextField(blank=True, null=True)), - ('caveats', models.TextField(blank=True, null=True)), - ('show_in_getting_started', models.BooleanField()), - ('entity_id', models.CharField(blank=True, max_length=21, null=True, unique=True)), + ( + "key", + models.CharField(max_length=254, primary_key=True, serialize=False), + ), + ("value", models.TextField()), ], options={ - 'db_table': 'segment', - 'managed': False, + "db_table": "setting", + "managed": False, }, ), migrations.CreateModel( - name='Setting', + name="TaskHistory", fields=[ - ('key', models.CharField(max_length=254, primary_key=True, serialize=False)), - ('value', models.TextField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("task", models.CharField(max_length=254)), + ("db_id", models.IntegerField(blank=True, null=True)), + ("started_at", models.DateTimeField()), + ("ended_at", models.DateTimeField()), + ("duration", models.IntegerField()), + ("task_details", models.TextField(blank=True, null=True)), ], options={ - 'db_table': 'setting', - 'managed': False, + "db_table": "task_history", + "managed": False, }, ), migrations.CreateModel( - name='TaskHistory', + name="Timeline", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('task', models.CharField(max_length=254)), - ('db_id', models.IntegerField(blank=True, null=True)), - ('started_at', models.DateTimeField()), - ('ended_at', models.DateTimeField()), - ('duration', models.IntegerField()), - ('task_details', models.TextField(blank=True, null=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("name", models.CharField(max_length=255)), + ( + "description", + models.CharField(blank=True, max_length=255, null=True), + ), + ("icon", models.CharField(max_length=128)), + ("archived", models.BooleanField()), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), + ("default", models.BooleanField()), + ( + "entity_id", + models.CharField(blank=True, max_length=21, null=True, unique=True), + ), ], options={ - 'db_table': 'task_history', - 'managed': False, + "db_table": "timeline", + "managed": False, }, ), migrations.CreateModel( - name='Timeline', + name="TimelineEvent", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('name', models.CharField(max_length=255)), - ('description', models.CharField(blank=True, max_length=255, null=True)), - ('icon', models.CharField(max_length=128)), - ('archived', models.BooleanField()), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), - ('default', models.BooleanField()), - ('entity_id', models.CharField(blank=True, max_length=21, null=True, unique=True)), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("name", models.CharField(max_length=255)), + ( + "description", + models.CharField(blank=True, max_length=255, null=True), + ), + ("timestamp", models.DateTimeField()), + ("time_matters", models.BooleanField()), + ("timezone", models.CharField(max_length=255)), + ("icon", models.CharField(max_length=128)), + ("archived", models.BooleanField()), + ("created_at", models.DateTimeField()), + ("updated_at", models.DateTimeField()), ], options={ - 'db_table': 'timeline', - 'managed': False, + "db_table": "timeline_event", + "managed": False, }, ), migrations.CreateModel( - name='TimelineEvent', + name="ViewLog", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('name', models.CharField(max_length=255)), - ('description', models.CharField(blank=True, max_length=255, null=True)), - ('timestamp', models.DateTimeField()), - ('time_matters', models.BooleanField()), - ('timezone', models.CharField(max_length=255)), - ('icon', models.CharField(max_length=128)), - ('archived', models.BooleanField()), - ('created_at', models.DateTimeField()), - ('updated_at', models.DateTimeField()), + ("id", models.IntegerField(primary_key=True, serialize=False)), + ("model", models.CharField(max_length=16)), + ("model_id", models.IntegerField()), + ("timestamp", models.DateTimeField()), + ("metadata", models.TextField(blank=True, null=True)), ], options={ - 'db_table': 'timeline_event', - 'managed': False, + "db_table": "view_log", + "managed": False, }, ), migrations.CreateModel( - name='ViewLog', + name="HttpAction", fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('model', models.CharField(max_length=16)), - ('model_id', models.IntegerField()), - ('timestamp', models.DateTimeField()), - ('metadata', models.TextField(blank=True, null=True)), + ( + "action", + models.OneToOneField( + on_delete=django.db.models.deletion.DO_NOTHING, + primary_key=True, + serialize=False, + to="metabase.action", + ), + ), + ("template", models.TextField()), + ("response_handle", models.TextField(blank=True, null=True)), + ("error_handle", models.TextField(blank=True, null=True)), ], options={ - 'db_table': 'view_log', - 'managed': False, + "db_table": "http_action", + "managed": False, }, ), migrations.CreateModel( - name='HttpAction', + name="QrtzTriggers", fields=[ - ('action', models.OneToOneField(on_delete=django.db.models.deletion.DO_NOTHING, primary_key=True, serialize=False, to='metabase.action')), - ('template', models.TextField()), - ('response_handle', models.TextField(blank=True, null=True)), - ('error_handle', models.TextField(blank=True, null=True)), + ( + "sched_name", + models.OneToOneField( + db_column="sched_name", + on_delete=django.db.models.deletion.DO_NOTHING, + primary_key=True, + serialize=False, + to="metabase.qrtzjobdetails", + ), + ), + ("trigger_name", models.CharField(max_length=200)), + ("trigger_group", models.CharField(max_length=200)), + ("job_name", models.CharField(max_length=200)), + ("job_group", models.CharField(max_length=200)), + ( + "description", + models.CharField(blank=True, max_length=250, null=True), + ), + ("next_fire_time", models.BigIntegerField(blank=True, null=True)), + ("prev_fire_time", models.BigIntegerField(blank=True, null=True)), + ("priority", models.IntegerField(blank=True, null=True)), + ("trigger_state", models.CharField(max_length=16)), + ("trigger_type", models.CharField(max_length=8)), + ("start_time", models.BigIntegerField()), + ("end_time", models.BigIntegerField(blank=True, null=True)), + ( + "calendar_name", + models.CharField(blank=True, max_length=200, null=True), + ), + ("misfire_instr", models.SmallIntegerField(blank=True, null=True)), + ("job_data", models.BinaryField(blank=True, null=True)), ], options={ - 'db_table': 'http_action', - 'managed': False, + "db_table": "qrtz_triggers", + "managed": False, }, ), migrations.CreateModel( - name='QrtzTriggers', + name="QueryAction", fields=[ - ('sched_name', models.OneToOneField(db_column='sched_name', on_delete=django.db.models.deletion.DO_NOTHING, primary_key=True, serialize=False, to='metabase.qrtzjobdetails')), - ('trigger_name', models.CharField(max_length=200)), - ('trigger_group', models.CharField(max_length=200)), - ('job_name', models.CharField(max_length=200)), - ('job_group', models.CharField(max_length=200)), - ('description', models.CharField(blank=True, max_length=250, null=True)), - ('next_fire_time', models.BigIntegerField(blank=True, null=True)), - ('prev_fire_time', models.BigIntegerField(blank=True, null=True)), - ('priority', models.IntegerField(blank=True, null=True)), - ('trigger_state', models.CharField(max_length=16)), - ('trigger_type', models.CharField(max_length=8)), - ('start_time', models.BigIntegerField()), - ('end_time', models.BigIntegerField(blank=True, null=True)), - ('calendar_name', models.CharField(blank=True, max_length=200, null=True)), - ('misfire_instr', models.SmallIntegerField(blank=True, null=True)), - ('job_data', models.BinaryField(blank=True, null=True)), - ], - options={ - 'db_table': 'qrtz_triggers', - 'managed': False, - }, - ), - migrations.CreateModel( - name='QueryAction', - fields=[ - ('action', models.OneToOneField(on_delete=django.db.models.deletion.DO_NOTHING, primary_key=True, serialize=False, to='metabase.action')), - ('dataset_query', models.TextField()), - ], - options={ - 'db_table': 'query_action', - 'managed': False, - }, - ), - migrations.CreateModel( - name='QrtzBlobTriggers', - fields=[ - ('sched_name', models.OneToOneField(db_column='sched_name', on_delete=django.db.models.deletion.DO_NOTHING, primary_key=True, serialize=False, to='metabase.qrtztriggers')), - ('trigger_name', models.CharField(max_length=200)), - ('trigger_group', models.CharField(max_length=200)), - ('blob_data', models.BinaryField(blank=True, null=True)), - ], - options={ - 'db_table': 'qrtz_blob_triggers', - 'managed': False, - }, - ), - migrations.CreateModel( - name='QrtzCronTriggers', - fields=[ - ('sched_name', models.OneToOneField(db_column='sched_name', on_delete=django.db.models.deletion.DO_NOTHING, primary_key=True, serialize=False, to='metabase.qrtztriggers')), - ('trigger_name', models.CharField(max_length=200)), - ('trigger_group', models.CharField(max_length=200)), - ('cron_expression', models.CharField(max_length=120)), - ('time_zone_id', models.CharField(blank=True, max_length=80, null=True)), - ], - options={ - 'db_table': 'qrtz_cron_triggers', - 'managed': False, - }, - ), - migrations.CreateModel( - name='QrtzSimpleTriggers', - fields=[ - ('sched_name', models.OneToOneField(db_column='sched_name', on_delete=django.db.models.deletion.DO_NOTHING, primary_key=True, serialize=False, to='metabase.qrtztriggers')), - ('trigger_name', models.CharField(max_length=200)), - ('trigger_group', models.CharField(max_length=200)), - ('repeat_count', models.BigIntegerField()), - ('repeat_interval', models.BigIntegerField()), - ('times_triggered', models.BigIntegerField()), - ], - options={ - 'db_table': 'qrtz_simple_triggers', - 'managed': False, - }, - ), - migrations.CreateModel( - name='QrtzSimpropTriggers', - fields=[ - ('sched_name', models.OneToOneField(db_column='sched_name', on_delete=django.db.models.deletion.DO_NOTHING, primary_key=True, serialize=False, to='metabase.qrtztriggers')), - ('trigger_name', models.CharField(max_length=200)), - ('trigger_group', models.CharField(max_length=200)), - ('str_prop_1', models.CharField(blank=True, max_length=512, null=True)), - ('str_prop_2', models.CharField(blank=True, max_length=512, null=True)), - ('str_prop_3', models.CharField(blank=True, max_length=512, null=True)), - ('int_prop_1', models.IntegerField(blank=True, null=True)), - ('int_prop_2', models.IntegerField(blank=True, null=True)), - ('long_prop_1', models.BigIntegerField(blank=True, null=True)), - ('long_prop_2', models.BigIntegerField(blank=True, null=True)), - ('dec_prop_1', models.DecimalField(blank=True, decimal_places=4, max_digits=13, null=True)), - ('dec_prop_2', models.DecimalField(blank=True, decimal_places=4, max_digits=13, null=True)), - ('bool_prop_1', models.BooleanField(blank=True, null=True)), - ('bool_prop_2', models.BooleanField(blank=True, null=True)), - ], - options={ - 'db_table': 'qrtz_simprop_triggers', - 'managed': False, + ( + "action", + models.OneToOneField( + on_delete=django.db.models.deletion.DO_NOTHING, + primary_key=True, + serialize=False, + to="metabase.action", + ), + ), + ("dataset_query", models.TextField()), + ], + options={ + "db_table": "query_action", + "managed": False, + }, + ), + migrations.CreateModel( + name="QrtzBlobTriggers", + fields=[ + ( + "sched_name", + models.OneToOneField( + db_column="sched_name", + on_delete=django.db.models.deletion.DO_NOTHING, + primary_key=True, + serialize=False, + to="metabase.qrtztriggers", + ), + ), + ("trigger_name", models.CharField(max_length=200)), + ("trigger_group", models.CharField(max_length=200)), + ("blob_data", models.BinaryField(blank=True, null=True)), + ], + options={ + "db_table": "qrtz_blob_triggers", + "managed": False, + }, + ), + migrations.CreateModel( + name="QrtzCronTriggers", + fields=[ + ( + "sched_name", + models.OneToOneField( + db_column="sched_name", + on_delete=django.db.models.deletion.DO_NOTHING, + primary_key=True, + serialize=False, + to="metabase.qrtztriggers", + ), + ), + ("trigger_name", models.CharField(max_length=200)), + ("trigger_group", models.CharField(max_length=200)), + ("cron_expression", models.CharField(max_length=120)), + ( + "time_zone_id", + models.CharField(blank=True, max_length=80, null=True), + ), + ], + options={ + "db_table": "qrtz_cron_triggers", + "managed": False, + }, + ), + migrations.CreateModel( + name="QrtzSimpleTriggers", + fields=[ + ( + "sched_name", + models.OneToOneField( + db_column="sched_name", + on_delete=django.db.models.deletion.DO_NOTHING, + primary_key=True, + serialize=False, + to="metabase.qrtztriggers", + ), + ), + ("trigger_name", models.CharField(max_length=200)), + ("trigger_group", models.CharField(max_length=200)), + ("repeat_count", models.BigIntegerField()), + ("repeat_interval", models.BigIntegerField()), + ("times_triggered", models.BigIntegerField()), + ], + options={ + "db_table": "qrtz_simple_triggers", + "managed": False, + }, + ), + migrations.CreateModel( + name="QrtzSimpropTriggers", + fields=[ + ( + "sched_name", + models.OneToOneField( + db_column="sched_name", + on_delete=django.db.models.deletion.DO_NOTHING, + primary_key=True, + serialize=False, + to="metabase.qrtztriggers", + ), + ), + ("trigger_name", models.CharField(max_length=200)), + ("trigger_group", models.CharField(max_length=200)), + ("str_prop_1", models.CharField(blank=True, max_length=512, null=True)), + ("str_prop_2", models.CharField(blank=True, max_length=512, null=True)), + ("str_prop_3", models.CharField(blank=True, max_length=512, null=True)), + ("int_prop_1", models.IntegerField(blank=True, null=True)), + ("int_prop_2", models.IntegerField(blank=True, null=True)), + ("long_prop_1", models.BigIntegerField(blank=True, null=True)), + ("long_prop_2", models.BigIntegerField(blank=True, null=True)), + ( + "dec_prop_1", + models.DecimalField( + blank=True, decimal_places=4, max_digits=13, null=True + ), + ), + ( + "dec_prop_2", + models.DecimalField( + blank=True, decimal_places=4, max_digits=13, null=True + ), + ), + ("bool_prop_1", models.BooleanField(blank=True, null=True)), + ("bool_prop_2", models.BooleanField(blank=True, null=True)), + ], + options={ + "db_table": "qrtz_simprop_triggers", + "managed": False, }, ), ] diff --git a/django/metabase/models.py b/django/metabase/models.py index 8b29c27e..83902085 100644 --- a/django/metabase/models.py +++ b/django/metabase/models.py @@ -13,28 +13,40 @@ class Action(models.Model): created_at = models.DateTimeField() updated_at = models.DateTimeField() type = models.TextField() - model = models.ForeignKey('ReportCard', models.DO_NOTHING) + model = models.ForeignKey("ReportCard", models.DO_NOTHING) name = models.CharField(max_length=254) description = models.TextField(blank=True, null=True) parameters = models.TextField(blank=True, null=True) parameter_mappings = models.TextField(blank=True, null=True) visualization_settings = models.TextField(blank=True, null=True) public_uuid = models.CharField(unique=True, max_length=36, blank=True, null=True) - made_public_by = models.ForeignKey('CoreUser', models.DO_NOTHING, related_name="made_public_actions", blank=True, null=True) - creator = models.ForeignKey('CoreUser', models.DO_NOTHING, related_name="created_actions", blank=True, null=True) + made_public_by = models.ForeignKey( + "CoreUser", + models.DO_NOTHING, + related_name="made_public_actions", + blank=True, + null=True, + ) + creator = models.ForeignKey( + "CoreUser", + models.DO_NOTHING, + related_name="created_actions", + blank=True, + null=True, + ) archived = models.BooleanField() entity_id = models.CharField(unique=True, max_length=21, blank=True, null=True) class Meta: managed = False - db_table = 'action' + db_table = "action" class Activity(models.Model): id = models.IntegerField(primary_key=True) topic = models.CharField(max_length=32) timestamp = models.DateTimeField() - user = models.ForeignKey('CoreUser', models.DO_NOTHING, blank=True, null=True) + user = models.ForeignKey("CoreUser", models.DO_NOTHING, blank=True, null=True) model = models.CharField(max_length=16, blank=True, null=True) model_id = models.IntegerField(blank=True, null=True) database_id = models.IntegerField(blank=True, null=True) @@ -44,56 +56,59 @@ class Activity(models.Model): class Meta: managed = False - db_table = 'activity' + db_table = "activity" class ApplicationPermissionsRevision(models.Model): id = models.IntegerField(primary_key=True) before = models.TextField() after = models.TextField() - user = models.ForeignKey('CoreUser', models.DO_NOTHING) + user = models.ForeignKey("CoreUser", models.DO_NOTHING) created_at = models.DateTimeField() remark = models.TextField(blank=True, null=True) class Meta: managed = False - db_table = 'application_permissions_revision' + db_table = "application_permissions_revision" class BookmarkOrdering(models.Model): id = models.IntegerField(primary_key=True) - user = models.ForeignKey('CoreUser', models.DO_NOTHING) + user = models.ForeignKey("CoreUser", models.DO_NOTHING) type = models.CharField(max_length=255) item_id = models.IntegerField() ordering = models.IntegerField() class Meta: managed = False - db_table = 'bookmark_ordering' - unique_together = (('user', 'type', 'item_id'), ('user', 'ordering'),) + db_table = "bookmark_ordering" + unique_together = ( + ("user", "type", "item_id"), + ("user", "ordering"), + ) class CardBookmark(models.Model): id = models.IntegerField(primary_key=True) - user = models.ForeignKey('CoreUser', models.DO_NOTHING) - card = models.ForeignKey('ReportCard', models.DO_NOTHING) + user = models.ForeignKey("CoreUser", models.DO_NOTHING) + card = models.ForeignKey("ReportCard", models.DO_NOTHING) created_at = models.DateTimeField() class Meta: managed = False - db_table = 'card_bookmark' - unique_together = (('user', 'card'),) + db_table = "card_bookmark" + unique_together = (("user", "card"),) class CardLabel(models.Model): id = models.IntegerField(primary_key=True) - card = models.ForeignKey('ReportCard', models.DO_NOTHING) - label = models.ForeignKey('Label', models.DO_NOTHING) + card = models.ForeignKey("ReportCard", models.DO_NOTHING) + label = models.ForeignKey("Label", models.DO_NOTHING) class Meta: managed = False - db_table = 'card_label' - unique_together = (('card', 'label'),) + db_table = "card_label" + unique_together = (("card", "label"),) class Collection(models.Model): @@ -103,7 +118,9 @@ class Collection(models.Model): color = models.CharField(max_length=7) archived = models.BooleanField() location = models.CharField(max_length=254) - personal_owner = models.OneToOneField('CoreUser', models.DO_NOTHING, blank=True, null=True) + personal_owner = models.OneToOneField( + "CoreUser", models.DO_NOTHING, blank=True, null=True + ) slug = models.CharField(max_length=254) namespace = models.CharField(max_length=254, blank=True, null=True) authority_level = models.CharField(max_length=255, blank=True, null=True) @@ -112,37 +129,37 @@ class Collection(models.Model): class Meta: managed = False - db_table = 'collection' + db_table = "collection" class CollectionBookmark(models.Model): id = models.IntegerField(primary_key=True) - user = models.ForeignKey('CoreUser', models.DO_NOTHING) + user = models.ForeignKey("CoreUser", models.DO_NOTHING) collection = models.ForeignKey(Collection, models.DO_NOTHING) created_at = models.DateTimeField() class Meta: managed = False - db_table = 'collection_bookmark' - unique_together = (('user', 'collection'),) + db_table = "collection_bookmark" + unique_together = (("user", "collection"),) class CollectionPermissionGraphRevision(models.Model): id = models.IntegerField(primary_key=True) before = models.TextField() after = models.TextField() - user = models.ForeignKey('CoreUser', models.DO_NOTHING) + user = models.ForeignKey("CoreUser", models.DO_NOTHING) created_at = models.DateTimeField() remark = models.TextField(blank=True, null=True) class Meta: managed = False - db_table = 'collection_permission_graph_revision' + db_table = "collection_permission_graph_revision" class ComputationJob(models.Model): id = models.IntegerField(primary_key=True) - creator = models.ForeignKey('CoreUser', models.DO_NOTHING, blank=True, null=True) + creator = models.ForeignKey("CoreUser", models.DO_NOTHING, blank=True, null=True) created_at = models.DateTimeField() updated_at = models.DateTimeField() type = models.CharField(max_length=254) @@ -152,7 +169,7 @@ class ComputationJob(models.Model): class Meta: managed = False - db_table = 'computation_job' + db_table = "computation_job" class ComputationJobResult(models.Model): @@ -165,18 +182,18 @@ class ComputationJobResult(models.Model): class Meta: managed = False - db_table = 'computation_job_result' + db_table = "computation_job_result" class CoreSession(models.Model): id = models.CharField(primary_key=True, max_length=254) - user = models.ForeignKey('CoreUser', models.DO_NOTHING) + user = models.ForeignKey("CoreUser", models.DO_NOTHING) created_at = models.DateTimeField() anti_csrf_token = models.TextField(blank=True, null=True) class Meta: managed = False - db_table = 'core_session' + db_table = "core_session" class CoreUser(models.Model): @@ -204,41 +221,41 @@ class CoreUser(models.Model): class Meta: managed = False - db_table = 'core_user' + db_table = "core_user" class DashboardBookmark(models.Model): id = models.IntegerField(primary_key=True) user = models.ForeignKey(CoreUser, models.DO_NOTHING) - dashboard = models.ForeignKey('ReportDashboard', models.DO_NOTHING) + dashboard = models.ForeignKey("ReportDashboard", models.DO_NOTHING) created_at = models.DateTimeField() class Meta: managed = False - db_table = 'dashboard_bookmark' - unique_together = (('user', 'dashboard'),) + db_table = "dashboard_bookmark" + unique_together = (("user", "dashboard"),) class DashboardFavorite(models.Model): id = models.IntegerField(primary_key=True) user = models.ForeignKey(CoreUser, models.DO_NOTHING) - dashboard = models.ForeignKey('ReportDashboard', models.DO_NOTHING) + dashboard = models.ForeignKey("ReportDashboard", models.DO_NOTHING) class Meta: managed = False - db_table = 'dashboard_favorite' - unique_together = (('user', 'dashboard'),) + db_table = "dashboard_favorite" + unique_together = (("user", "dashboard"),) class DashboardcardSeries(models.Model): id = models.IntegerField(primary_key=True) - dashboardcard = models.ForeignKey('ReportDashboardcard', models.DO_NOTHING) - card = models.ForeignKey('ReportCard', models.DO_NOTHING) + dashboardcard = models.ForeignKey("ReportDashboardcard", models.DO_NOTHING) + card = models.ForeignKey("ReportCard", models.DO_NOTHING) position = models.IntegerField() class Meta: managed = False - db_table = 'dashboardcard_series' + db_table = "dashboardcard_series" class DataMigrations(models.Model): @@ -247,7 +264,7 @@ class DataMigrations(models.Model): class Meta: managed = False - db_table = 'data_migrations' + db_table = "data_migrations" # class Databasechangelog(models.Model): @@ -293,22 +310,30 @@ class Dependency(models.Model): class Meta: managed = False - db_table = 'dependency' + db_table = "dependency" class Dimension(models.Model): id = models.IntegerField(primary_key=True) - field = models.OneToOneField('MetabaseField', models.DO_NOTHING, related_name="field_dimensions") + field = models.OneToOneField( + "MetabaseField", models.DO_NOTHING, related_name="field_dimensions" + ) name = models.CharField(max_length=254) type = models.CharField(max_length=254) - human_readable_field = models.ForeignKey('MetabaseField', models.DO_NOTHING, related_name="human_readable_field_dimensions", blank=True, null=True) + human_readable_field = models.ForeignKey( + "MetabaseField", + models.DO_NOTHING, + related_name="human_readable_field_dimensions", + blank=True, + null=True, + ) created_at = models.DateTimeField() updated_at = models.DateTimeField() entity_id = models.CharField(unique=True, max_length=21, blank=True, null=True) class Meta: managed = False - db_table = 'dimension' + db_table = "dimension" class HttpAction(models.Model): @@ -319,7 +344,7 @@ class HttpAction(models.Model): class Meta: managed = False - db_table = 'http_action' + db_table = "http_action" class ImplicitAction(models.Model): @@ -328,7 +353,7 @@ class ImplicitAction(models.Model): class Meta: managed = False - db_table = 'implicit_action' + db_table = "implicit_action" class Label(models.Model): @@ -339,7 +364,7 @@ class Label(models.Model): class Meta: managed = False - db_table = 'label' + db_table = "label" class LoginHistory(models.Model): @@ -353,7 +378,7 @@ class LoginHistory(models.Model): class Meta: managed = False - db_table = 'login_history' + db_table = "login_history" class MetabaseDatabase(models.Model): @@ -383,7 +408,7 @@ class MetabaseDatabase(models.Model): class Meta: managed = False - db_table = 'metabase_database' + db_table = "metabase_database" class MetabaseField(models.Model): @@ -397,8 +422,8 @@ class MetabaseField(models.Model): description = models.TextField(blank=True, null=True) preview_display = models.BooleanField() position = models.IntegerField() - table = models.ForeignKey('MetabaseTable', models.DO_NOTHING) - parent = models.ForeignKey('self', models.DO_NOTHING, blank=True, null=True) + table = models.ForeignKey("MetabaseTable", models.DO_NOTHING) + parent = models.ForeignKey("self", models.DO_NOTHING, blank=True, null=True) display_name = models.CharField(max_length=254, blank=True, null=True) visibility_type = models.CharField(max_length=32) fk_target_field_id = models.IntegerField(blank=True, null=True) @@ -420,8 +445,11 @@ class MetabaseField(models.Model): class Meta: managed = False - db_table = 'metabase_field' - unique_together = (('table', 'parent', 'name'), ('table', 'name'),) + db_table = "metabase_field" + unique_together = ( + ("table", "parent", "name"), + ("table", "name"), + ) class MetabaseFieldvalues(models.Model): @@ -438,7 +466,7 @@ class MetabaseFieldvalues(models.Model): class Meta: managed = False - db_table = 'metabase_fieldvalues' + db_table = "metabase_fieldvalues" class MetabaseTable(models.Model): @@ -461,8 +489,11 @@ class MetabaseTable(models.Model): class Meta: managed = False - db_table = 'metabase_table' - unique_together = (('db', 'schema', 'name'), ('db', 'name'),) + db_table = "metabase_table" + unique_together = ( + ("db", "schema", "name"), + ("db", "name"), + ) class Metric(models.Model): @@ -483,7 +514,7 @@ class Metric(models.Model): class Meta: managed = False - db_table = 'metric' + db_table = "metric" class MetricImportantField(models.Model): @@ -493,8 +524,8 @@ class MetricImportantField(models.Model): class Meta: managed = False - db_table = 'metric_important_field' - unique_together = (('metric', 'field'),) + db_table = "metric_important_field" + unique_together = (("metric", "field"),) class ModerationReview(models.Model): @@ -510,7 +541,7 @@ class ModerationReview(models.Model): class Meta: managed = False - db_table = 'moderation_review' + db_table = "moderation_review" class NativeQuerySnippet(models.Model): @@ -527,14 +558,14 @@ class NativeQuerySnippet(models.Model): class Meta: managed = False - db_table = 'native_query_snippet' + db_table = "native_query_snippet" class ParameterCard(models.Model): id = models.IntegerField(primary_key=True) updated_at = models.DateTimeField() created_at = models.DateTimeField() - card = models.ForeignKey('ReportCard', models.DO_NOTHING) + card = models.ForeignKey("ReportCard", models.DO_NOTHING) parameterized_object_type = models.CharField(max_length=32) parameterized_object_id = models.IntegerField() parameter_id = models.CharField(max_length=36) @@ -542,19 +573,21 @@ class ParameterCard(models.Model): class Meta: managed = False - db_table = 'parameter_card' - unique_together = (('parameterized_object_id', 'parameterized_object_type', 'parameter_id'),) + db_table = "parameter_card" + unique_together = ( + ("parameterized_object_id", "parameterized_object_type", "parameter_id"), + ) class Permissions(models.Model): id = models.IntegerField(primary_key=True) object = models.CharField(max_length=254) - group = models.ForeignKey('PermissionsGroup', models.DO_NOTHING) + group = models.ForeignKey("PermissionsGroup", models.DO_NOTHING) class Meta: managed = False - db_table = 'permissions' - unique_together = (('group', 'object'),) + db_table = "permissions" + unique_together = (("group", "object"),) class PermissionsGroup(models.Model): @@ -563,7 +596,7 @@ class PermissionsGroup(models.Model): class Meta: managed = False - db_table = 'permissions_group' + db_table = "permissions_group" class PermissionsGroupMembership(models.Model): @@ -574,8 +607,8 @@ class PermissionsGroupMembership(models.Model): class Meta: managed = False - db_table = 'permissions_group_membership' - unique_together = (('user', 'group'),) + db_table = "permissions_group_membership" + unique_together = (("user", "group"),) class PermissionsRevision(models.Model): @@ -588,13 +621,13 @@ class PermissionsRevision(models.Model): class Meta: managed = False - db_table = 'permissions_revision' + db_table = "permissions_revision" class PersistedInfo(models.Model): id = models.IntegerField(primary_key=True) database = models.ForeignKey(MetabaseDatabase, models.DO_NOTHING) - card = models.OneToOneField('ReportCard', models.DO_NOTHING) + card = models.OneToOneField("ReportCard", models.DO_NOTHING) question_slug = models.TextField() table_name = models.TextField() definition = models.TextField(blank=True, null=True) @@ -610,7 +643,7 @@ class PersistedInfo(models.Model): class Meta: managed = False - db_table = 'persisted_info' + db_table = "persisted_info" class Pulse(models.Model): @@ -626,28 +659,32 @@ class Pulse(models.Model): collection = models.ForeignKey(Collection, models.DO_NOTHING, blank=True, null=True) collection_position = models.SmallIntegerField(blank=True, null=True) archived = models.BooleanField(blank=True, null=True) - dashboard = models.ForeignKey('ReportDashboard', models.DO_NOTHING, blank=True, null=True) + dashboard = models.ForeignKey( + "ReportDashboard", models.DO_NOTHING, blank=True, null=True + ) parameters = models.TextField() entity_id = models.CharField(unique=True, max_length=21, blank=True, null=True) class Meta: managed = False - db_table = 'pulse' + db_table = "pulse" class PulseCard(models.Model): id = models.IntegerField(primary_key=True) pulse = models.ForeignKey(Pulse, models.DO_NOTHING) - card = models.ForeignKey('ReportCard', models.DO_NOTHING) + card = models.ForeignKey("ReportCard", models.DO_NOTHING) position = models.IntegerField() include_csv = models.BooleanField() include_xls = models.BooleanField() - dashboard_card = models.ForeignKey('ReportDashboardcard', models.DO_NOTHING, blank=True, null=True) + dashboard_card = models.ForeignKey( + "ReportDashboardcard", models.DO_NOTHING, blank=True, null=True + ) entity_id = models.CharField(unique=True, max_length=21, blank=True, null=True) class Meta: managed = False - db_table = 'pulse_card' + db_table = "pulse_card" class PulseChannel(models.Model): @@ -666,7 +703,7 @@ class PulseChannel(models.Model): class Meta: managed = False - db_table = 'pulse_channel' + db_table = "pulse_channel" class PulseChannelRecipient(models.Model): @@ -676,19 +713,21 @@ class PulseChannelRecipient(models.Model): class Meta: managed = False - db_table = 'pulse_channel_recipient' + db_table = "pulse_channel_recipient" class QrtzBlobTriggers(models.Model): - sched_name = models.OneToOneField('QrtzTriggers', models.DO_NOTHING, db_column='sched_name', primary_key=True) + sched_name = models.OneToOneField( + "QrtzTriggers", models.DO_NOTHING, db_column="sched_name", primary_key=True + ) trigger_name = models.CharField(max_length=200) trigger_group = models.CharField(max_length=200) blob_data = models.BinaryField(blank=True, null=True) class Meta: managed = False - db_table = 'qrtz_blob_triggers' - unique_together = (('sched_name', 'trigger_name', 'trigger_group'),) + db_table = "qrtz_blob_triggers" + unique_together = (("sched_name", "trigger_name", "trigger_group"),) class QrtzCalendars(models.Model): @@ -698,12 +737,14 @@ class QrtzCalendars(models.Model): class Meta: managed = False - db_table = 'qrtz_calendars' - unique_together = (('sched_name', 'calendar_name'),) + db_table = "qrtz_calendars" + unique_together = (("sched_name", "calendar_name"),) class QrtzCronTriggers(models.Model): - sched_name = models.OneToOneField('QrtzTriggers', models.DO_NOTHING, db_column='sched_name', primary_key=True) + sched_name = models.OneToOneField( + "QrtzTriggers", models.DO_NOTHING, db_column="sched_name", primary_key=True + ) trigger_name = models.CharField(max_length=200) trigger_group = models.CharField(max_length=200) cron_expression = models.CharField(max_length=120) @@ -711,8 +752,8 @@ class QrtzCronTriggers(models.Model): class Meta: managed = False - db_table = 'qrtz_cron_triggers' - unique_together = (('sched_name', 'trigger_name', 'trigger_group'),) + db_table = "qrtz_cron_triggers" + unique_together = (("sched_name", "trigger_name", "trigger_group"),) class QrtzFiredTriggers(models.Model): @@ -732,8 +773,8 @@ class QrtzFiredTriggers(models.Model): class Meta: managed = False - db_table = 'qrtz_fired_triggers' - unique_together = (('sched_name', 'entry_id'),) + db_table = "qrtz_fired_triggers" + unique_together = (("sched_name", "entry_id"),) class QrtzJobDetails(models.Model): @@ -750,8 +791,8 @@ class QrtzJobDetails(models.Model): class Meta: managed = False - db_table = 'qrtz_job_details' - unique_together = (('sched_name', 'job_name', 'job_group'),) + db_table = "qrtz_job_details" + unique_together = (("sched_name", "job_name", "job_group"),) class QrtzLocks(models.Model): @@ -760,8 +801,8 @@ class QrtzLocks(models.Model): class Meta: managed = False - db_table = 'qrtz_locks' - unique_together = (('sched_name', 'lock_name'),) + db_table = "qrtz_locks" + unique_together = (("sched_name", "lock_name"),) class QrtzPausedTriggerGrps(models.Model): @@ -770,8 +811,8 @@ class QrtzPausedTriggerGrps(models.Model): class Meta: managed = False - db_table = 'qrtz_paused_trigger_grps' - unique_together = (('sched_name', 'trigger_group'),) + db_table = "qrtz_paused_trigger_grps" + unique_together = (("sched_name", "trigger_group"),) class QrtzSchedulerState(models.Model): @@ -782,12 +823,14 @@ class QrtzSchedulerState(models.Model): class Meta: managed = False - db_table = 'qrtz_scheduler_state' - unique_together = (('sched_name', 'instance_name'),) + db_table = "qrtz_scheduler_state" + unique_together = (("sched_name", "instance_name"),) class QrtzSimpleTriggers(models.Model): - sched_name = models.OneToOneField('QrtzTriggers', models.DO_NOTHING, db_column='sched_name', primary_key=True) + sched_name = models.OneToOneField( + "QrtzTriggers", models.DO_NOTHING, db_column="sched_name", primary_key=True + ) trigger_name = models.CharField(max_length=200) trigger_group = models.CharField(max_length=200) repeat_count = models.BigIntegerField() @@ -796,12 +839,14 @@ class QrtzSimpleTriggers(models.Model): class Meta: managed = False - db_table = 'qrtz_simple_triggers' - unique_together = (('sched_name', 'trigger_name', 'trigger_group'),) + db_table = "qrtz_simple_triggers" + unique_together = (("sched_name", "trigger_name", "trigger_group"),) class QrtzSimpropTriggers(models.Model): - sched_name = models.OneToOneField('QrtzTriggers', models.DO_NOTHING, db_column='sched_name', primary_key=True) + sched_name = models.OneToOneField( + "QrtzTriggers", models.DO_NOTHING, db_column="sched_name", primary_key=True + ) trigger_name = models.CharField(max_length=200) trigger_group = models.CharField(max_length=200) str_prop_1 = models.CharField(max_length=512, blank=True, null=True) @@ -811,19 +856,25 @@ class QrtzSimpropTriggers(models.Model): int_prop_2 = models.IntegerField(blank=True, null=True) long_prop_1 = models.BigIntegerField(blank=True, null=True) long_prop_2 = models.BigIntegerField(blank=True, null=True) - dec_prop_1 = models.DecimalField(max_digits=13, decimal_places=4, blank=True, null=True) - dec_prop_2 = models.DecimalField(max_digits=13, decimal_places=4, blank=True, null=True) + dec_prop_1 = models.DecimalField( + max_digits=13, decimal_places=4, blank=True, null=True + ) + dec_prop_2 = models.DecimalField( + max_digits=13, decimal_places=4, blank=True, null=True + ) bool_prop_1 = models.BooleanField(blank=True, null=True) bool_prop_2 = models.BooleanField(blank=True, null=True) class Meta: managed = False - db_table = 'qrtz_simprop_triggers' - unique_together = (('sched_name', 'trigger_name', 'trigger_group'),) + db_table = "qrtz_simprop_triggers" + unique_together = (("sched_name", "trigger_name", "trigger_group"),) class QrtzTriggers(models.Model): - sched_name = models.OneToOneField(QrtzJobDetails, models.DO_NOTHING, db_column='sched_name', primary_key=True) + sched_name = models.OneToOneField( + QrtzJobDetails, models.DO_NOTHING, db_column="sched_name", primary_key=True + ) trigger_name = models.CharField(max_length=200) trigger_group = models.CharField(max_length=200) job_name = models.CharField(max_length=200) @@ -842,8 +893,8 @@ class QrtzTriggers(models.Model): class Meta: managed = False - db_table = 'qrtz_triggers' - unique_together = (('sched_name', 'trigger_name', 'trigger_group'),) + db_table = "qrtz_triggers" + unique_together = (("sched_name", "trigger_name", "trigger_group"),) class Query(models.Model): @@ -853,7 +904,7 @@ class Query(models.Model): class Meta: managed = False - db_table = 'query' + db_table = "query" class QueryAction(models.Model): @@ -863,7 +914,7 @@ class QueryAction(models.Model): class Meta: managed = False - db_table = 'query_action' + db_table = "query_action" class QueryCache(models.Model): @@ -873,7 +924,7 @@ class QueryCache(models.Model): class Meta: managed = False - db_table = 'query_cache' + db_table = "query_cache" class QueryExecution(models.Model): @@ -894,7 +945,7 @@ class QueryExecution(models.Model): class Meta: managed = False - db_table = 'query_execution' + db_table = "query_execution" class ReportCard(models.Model): @@ -906,14 +957,22 @@ class ReportCard(models.Model): display = models.CharField(max_length=254) dataset_query = models.TextField() visualization_settings = models.TextField() - creator = models.ForeignKey(CoreUser, models.DO_NOTHING, related_name="creator_report_cards") + creator = models.ForeignKey( + CoreUser, models.DO_NOTHING, related_name="creator_report_cards" + ) database = models.ForeignKey(MetabaseDatabase, models.DO_NOTHING) table = models.ForeignKey(MetabaseTable, models.DO_NOTHING, blank=True, null=True) query_type = models.CharField(max_length=16, blank=True, null=True) archived = models.BooleanField() collection = models.ForeignKey(Collection, models.DO_NOTHING, blank=True, null=True) public_uuid = models.CharField(unique=True, max_length=36, blank=True, null=True) - made_public_by = models.ForeignKey(CoreUser, models.DO_NOTHING, blank=True, null=True, related_name="made_public_by_report_cards") + made_public_by = models.ForeignKey( + CoreUser, + models.DO_NOTHING, + blank=True, + null=True, + related_name="made_public_by_report_cards", + ) enable_embedding = models.BooleanField() embedding_params = models.TextField(blank=True, null=True) cache_ttl = models.IntegerField(blank=True, null=True) @@ -927,7 +986,7 @@ class ReportCard(models.Model): class Meta: managed = False - db_table = 'report_card' + db_table = "report_card" class ReportCardfavorite(models.Model): @@ -939,8 +998,8 @@ class ReportCardfavorite(models.Model): class Meta: managed = False - db_table = 'report_cardfavorite' - unique_together = (('card', 'owner'),) + db_table = "report_cardfavorite" + unique_together = (("card", "owner"),) class ReportDashboard(models.Model): @@ -949,13 +1008,21 @@ class ReportDashboard(models.Model): updated_at = models.DateTimeField() name = models.CharField(max_length=254) description = models.TextField(blank=True, null=True) - creator = models.ForeignKey(CoreUser, models.DO_NOTHING, related_name="creator_report_dashboards") + creator = models.ForeignKey( + CoreUser, models.DO_NOTHING, related_name="creator_report_dashboards" + ) parameters = models.TextField() points_of_interest = models.TextField(blank=True, null=True) caveats = models.TextField(blank=True, null=True) show_in_getting_started = models.BooleanField() public_uuid = models.CharField(unique=True, max_length=36, blank=True, null=True) - made_public_by = models.ForeignKey(CoreUser, models.DO_NOTHING, related_name="made_public_by_report_dashboards", blank=True, null=True) + made_public_by = models.ForeignKey( + CoreUser, + models.DO_NOTHING, + related_name="made_public_by_report_dashboards", + blank=True, + null=True, + ) enable_embedding = models.BooleanField() embedding_params = models.TextField(blank=True, null=True) archived = models.BooleanField() @@ -967,7 +1034,7 @@ class ReportDashboard(models.Model): class Meta: managed = False - db_table = 'report_dashboard' + db_table = "report_dashboard" class ReportDashboardcard(models.Model): @@ -987,7 +1054,7 @@ class ReportDashboardcard(models.Model): class Meta: managed = False - db_table = 'report_dashboardcard' + db_table = "report_dashboardcard" class Revision(models.Model): @@ -1003,7 +1070,7 @@ class Revision(models.Model): class Meta: managed = False - db_table = 'revision' + db_table = "revision" class Sandboxes(models.Model): @@ -1012,12 +1079,14 @@ class Sandboxes(models.Model): table = models.ForeignKey(MetabaseTable, models.DO_NOTHING) card = models.ForeignKey(ReportCard, models.DO_NOTHING, blank=True, null=True) attribute_remappings = models.TextField(blank=True, null=True) - permission = models.ForeignKey(Permissions, models.DO_NOTHING, blank=True, null=True) + permission = models.ForeignKey( + Permissions, models.DO_NOTHING, blank=True, null=True + ) class Meta: managed = False - db_table = 'sandboxes' - unique_together = (('table', 'group'),) + db_table = "sandboxes" + unique_together = (("table", "group"),) class Secret(models.Model): @@ -1033,8 +1102,8 @@ class Secret(models.Model): class Meta: managed = False - db_table = 'secret' - unique_together = (('id', 'version'),) + db_table = "secret" + unique_together = (("id", "version"),) class Segment(models.Model): @@ -1054,7 +1123,7 @@ class Segment(models.Model): class Meta: managed = False - db_table = 'segment' + db_table = "segment" class Setting(models.Model): @@ -1063,7 +1132,7 @@ class Setting(models.Model): class Meta: managed = False - db_table = 'setting' + db_table = "setting" class TaskHistory(models.Model): @@ -1077,7 +1146,7 @@ class TaskHistory(models.Model): class Meta: managed = False - db_table = 'task_history' + db_table = "task_history" class Timeline(models.Model): @@ -1095,7 +1164,7 @@ class Timeline(models.Model): class Meta: managed = False - db_table = 'timeline' + db_table = "timeline" class TimelineEvent(models.Model): @@ -1114,7 +1183,7 @@ class TimelineEvent(models.Model): class Meta: managed = False - db_table = 'timeline_event' + db_table = "timeline_event" class ViewLog(models.Model): @@ -1127,4 +1196,4 @@ class ViewLog(models.Model): class Meta: managed = False - db_table = 'view_log' + db_table = "view_log" diff --git a/django/tfrs/apps.py b/django/tfrs/apps.py index d0b3410f..51d9a258 100644 --- a/django/tfrs/apps.py +++ b/django/tfrs/apps.py @@ -2,4 +2,4 @@ class ApiConfig(AppConfig): - name = 'tfrs' + name = "tfrs" diff --git a/django/tfrs/migrations/0001_initial.py b/django/tfrs/migrations/0001_initial.py index b0316ef9..fc5cf5ce 100644 --- a/django/tfrs/migrations/0001_initial.py +++ b/django/tfrs/migrations/0001_initial.py @@ -6,379 +6,929 @@ class Migration(migrations.Migration): - initial = True - dependencies = [ - ] + dependencies = [] operations = [ migrations.CreateModel( - name='CompliancePeriod', + name="CompliancePeriod", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('display_order', models.IntegerField()), - ('effective_date', models.DateField(blank=True, null=True)), - ('expiration_date', models.DateField(blank=True, null=True)), - ('description', models.CharField(blank=True, max_length=1000, null=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("display_order", models.IntegerField()), + ("effective_date", models.DateField(blank=True, null=True)), + ("expiration_date", models.DateField(blank=True, null=True)), + ( + "description", + models.CharField(blank=True, max_length=1000, null=True), + ), ], options={ - 'db_table': 'compliance_period', + "db_table": "compliance_period", }, ), migrations.CreateModel( - name='CreditTrade', + name="CreditTrade", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('number_of_credits', models.IntegerField()), - ('fair_market_value_per_credit', models.DecimalField(blank=True, decimal_places=2, default=Decimal('0.00'), max_digits=10, null=True)), - ('trade_effective_date', models.DateField(blank=True, null=True)), - ('is_rescinded', models.BooleanField(default=False)), - ('compliance_period', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='credit_trades', to='tfrs.complianceperiod')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("number_of_credits", models.IntegerField()), + ( + "fair_market_value_per_credit", + models.DecimalField( + blank=True, + decimal_places=2, + default=Decimal("0.00"), + max_digits=10, + null=True, + ), + ), + ("trade_effective_date", models.DateField(blank=True, null=True)), + ("is_rescinded", models.BooleanField(default=False)), + ( + "compliance_period", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="credit_trades", + to="tfrs.complianceperiod", + ), + ), ], options={ - 'db_table': 'credit_trade', + "db_table": "credit_trade", }, ), migrations.CreateModel( - name='Document', + name="Document", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('title', models.CharField(max_length=120)), - ('milestone', models.CharField(blank=True, max_length=1000, null=True)), - ('compliance_period', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tfrs.complianceperiod')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("title", models.CharField(max_length=120)), + ("milestone", models.CharField(blank=True, max_length=1000, null=True)), + ( + "compliance_period", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="tfrs.complianceperiod", + ), + ), ], options={ - 'db_table': 'document', + "db_table": "document", }, ), migrations.CreateModel( - name='DocumentCategory', + name="DocumentCategory", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('display_order', models.IntegerField()), - ('name', models.CharField(blank=True, max_length=120, null=True, unique=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("display_order", models.IntegerField()), + ( + "name", + models.CharField( + blank=True, max_length=120, null=True, unique=True + ), + ), ], options={ - 'db_table': 'document_category', + "db_table": "document_category", }, ), migrations.CreateModel( - name='Organization', + name="Organization", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('name', models.CharField(max_length=500)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("name", models.CharField(max_length=500)), ], options={ - 'db_table': 'tfrs_organization', + "db_table": "tfrs_organization", }, ), migrations.CreateModel( - name='User', + name="User", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('last_login', models.DateTimeField(null=True)), - ('is_superuser', models.BooleanField(default=False)), - ('username', models.CharField(max_length=150, unique=True, verbose_name='username')), - ('first_name', models.CharField(max_length=30)), - ('last_name', models.CharField(max_length=30)), - ('is_staff', models.BooleanField(default=False)), - ('is_active', models.BooleanField(default=False)), - ('date_joined', models.DateTimeField()), - ('password', models.CharField(blank=True, max_length=128, null=True)), - ('email', models.EmailField(blank=True, max_length=254, null=True)), - ('title', models.CharField(blank=True, max_length=100, null=True)), - ('phone', models.CharField(blank=True, max_length=50, null=True)), - ('cell_phone', models.CharField(blank=True, max_length=50, null=True)), - ('_display_name', models.CharField(blank=True, db_column='display_name', max_length=500, null=True)), - ('create_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_user_CREATE_USER', to='tfrs.user')), - ('organization', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='users', to='tfrs.organization')), - ('update_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_user_UPDATE_USER', to='tfrs.user')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("last_login", models.DateTimeField(null=True)), + ("is_superuser", models.BooleanField(default=False)), + ( + "username", + models.CharField( + max_length=150, unique=True, verbose_name="username" + ), + ), + ("first_name", models.CharField(max_length=30)), + ("last_name", models.CharField(max_length=30)), + ("is_staff", models.BooleanField(default=False)), + ("is_active", models.BooleanField(default=False)), + ("date_joined", models.DateTimeField()), + ("password", models.CharField(blank=True, max_length=128, null=True)), + ("email", models.EmailField(blank=True, max_length=254, null=True)), + ("title", models.CharField(blank=True, max_length=100, null=True)), + ("phone", models.CharField(blank=True, max_length=50, null=True)), + ("cell_phone", models.CharField(blank=True, max_length=50, null=True)), + ( + "_display_name", + models.CharField( + blank=True, db_column="display_name", max_length=500, null=True + ), + ), + ( + "create_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_user_CREATE_USER", + to="tfrs.user", + ), + ), + ( + "organization", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="users", + to="tfrs.organization", + ), + ), + ( + "update_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_user_UPDATE_USER", + to="tfrs.user", + ), + ), ], options={ - 'db_table': 'tfrs_user', + "db_table": "tfrs_user", }, ), migrations.CreateModel( - name='OrganizationType', + name="OrganizationType", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('display_order', models.IntegerField()), - ('effective_date', models.DateField(blank=True, null=True)), - ('expiration_date', models.DateField(blank=True, null=True)), - ('type', models.CharField(max_length=25, unique=True)), - ('description', models.CharField(blank=True, max_length=1000, null=True)), - ('create_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_organizationtype_CREATE_USER', to='tfrs.user')), - ('update_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_organizationtype_UPDATE_USER', to='tfrs.user')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("display_order", models.IntegerField()), + ("effective_date", models.DateField(blank=True, null=True)), + ("expiration_date", models.DateField(blank=True, null=True)), + ("type", models.CharField(max_length=25, unique=True)), + ( + "description", + models.CharField(blank=True, max_length=1000, null=True), + ), + ( + "create_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_organizationtype_CREATE_USER", + to="tfrs.user", + ), + ), + ( + "update_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_organizationtype_UPDATE_USER", + to="tfrs.user", + ), + ), ], options={ - 'db_table': 'organization_type', + "db_table": "organization_type", }, ), migrations.CreateModel( - name='OrganizationStatus', + name="OrganizationStatus", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('display_order', models.IntegerField()), - ('effective_date', models.DateField(blank=True, null=True)), - ('expiration_date', models.DateField(blank=True, null=True)), - ('status', models.CharField(max_length=25, unique=True)), - ('description', models.CharField(blank=True, max_length=1000, null=True)), - ('create_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_organizationstatus_CREATE_USER', to='tfrs.user')), - ('update_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_organizationstatus_UPDATE_USER', to='tfrs.user')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("display_order", models.IntegerField()), + ("effective_date", models.DateField(blank=True, null=True)), + ("expiration_date", models.DateField(blank=True, null=True)), + ("status", models.CharField(max_length=25, unique=True)), + ( + "description", + models.CharField(blank=True, max_length=1000, null=True), + ), + ( + "create_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_organizationstatus_CREATE_USER", + to="tfrs.user", + ), + ), + ( + "update_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_organizationstatus_UPDATE_USER", + to="tfrs.user", + ), + ), ], options={ - 'db_table': 'tfrs_organization_status', + "db_table": "tfrs_organization_status", }, ), migrations.CreateModel( - name='OrganizationActionsType', + name="OrganizationActionsType", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('display_order', models.IntegerField()), - ('effective_date', models.DateField(blank=True, null=True)), - ('expiration_date', models.DateField(blank=True, null=True)), - ('the_type', models.CharField(max_length=25, unique=True)), - ('description', models.CharField(blank=True, max_length=1000, null=True)), - ('create_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_organizationactionstype_CREATE_USER', to='tfrs.user')), - ('update_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_organizationactionstype_UPDATE_USER', to='tfrs.user')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("display_order", models.IntegerField()), + ("effective_date", models.DateField(blank=True, null=True)), + ("expiration_date", models.DateField(blank=True, null=True)), + ("the_type", models.CharField(max_length=25, unique=True)), + ( + "description", + models.CharField(blank=True, max_length=1000, null=True), + ), + ( + "create_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_organizationactionstype_CREATE_USER", + to="tfrs.user", + ), + ), + ( + "update_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_organizationactionstype_UPDATE_USER", + to="tfrs.user", + ), + ), ], options={ - 'db_table': 'tfrs_organization_actions_type', + "db_table": "tfrs_organization_actions_type", }, ), migrations.AddField( - model_name='organization', - name='actions_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='organization_actions_type', to='tfrs.organizationactionstype'), + model_name="organization", + name="actions_type", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="organization_actions_type", + to="tfrs.organizationactionstype", + ), ), migrations.AddField( - model_name='organization', - name='create_user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_organization_CREATE_USER', to='tfrs.user'), + model_name="organization", + name="create_user", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_organization_CREATE_USER", + to="tfrs.user", + ), ), migrations.AddField( - model_name='organization', - name='status', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='organization_status', to='tfrs.organizationstatus'), + model_name="organization", + name="status", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="organization_status", + to="tfrs.organizationstatus", + ), ), migrations.AddField( - model_name='organization', - name='type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='organization_type', to='tfrs.organizationtype'), + model_name="organization", + name="type", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="organization_type", + to="tfrs.organizationtype", + ), ), migrations.AddField( - model_name='organization', - name='update_user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_organization_UPDATE_USER', to='tfrs.user'), + model_name="organization", + name="update_user", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_organization_UPDATE_USER", + to="tfrs.user", + ), ), migrations.CreateModel( - name='DocumentType', + name="DocumentType", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('effective_date', models.DateField(blank=True, null=True)), - ('expiration_date', models.DateField(blank=True, null=True)), - ('the_type', models.CharField(blank=True, max_length=100, null=True, unique=True)), - ('description', models.CharField(blank=True, max_length=1000, null=True)), - ('category', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='types', to='tfrs.documentcategory')), - ('create_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_documenttype_CREATE_USER', to='tfrs.user')), - ('update_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_documenttype_UPDATE_USER', to='tfrs.user')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("effective_date", models.DateField(blank=True, null=True)), + ("expiration_date", models.DateField(blank=True, null=True)), + ( + "the_type", + models.CharField( + blank=True, max_length=100, null=True, unique=True + ), + ), + ( + "description", + models.CharField(blank=True, max_length=1000, null=True), + ), + ( + "category", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="types", + to="tfrs.documentcategory", + ), + ), + ( + "create_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_documenttype_CREATE_USER", + to="tfrs.user", + ), + ), + ( + "update_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_documenttype_UPDATE_USER", + to="tfrs.user", + ), + ), ], options={ - 'db_table': 'document_type', + "db_table": "document_type", }, ), migrations.CreateModel( - name='DocumentStatus', + name="DocumentStatus", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('display_order', models.IntegerField()), - ('effective_date', models.DateField(blank=True, null=True)), - ('expiration_date', models.DateField(blank=True, null=True)), - ('status', models.CharField(blank=True, max_length=25, null=True, unique=True)), - ('create_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_documentstatus_CREATE_USER', to='tfrs.user')), - ('update_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_documentstatus_UPDATE_USER', to='tfrs.user')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("display_order", models.IntegerField()), + ("effective_date", models.DateField(blank=True, null=True)), + ("expiration_date", models.DateField(blank=True, null=True)), + ( + "status", + models.CharField(blank=True, max_length=25, null=True, unique=True), + ), + ( + "create_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_documentstatus_CREATE_USER", + to="tfrs.user", + ), + ), + ( + "update_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_documentstatus_UPDATE_USER", + to="tfrs.user", + ), + ), ], options={ - 'db_table': 'document_status', + "db_table": "document_status", }, ), migrations.CreateModel( - name='DocumentCreditTrade', + name="DocumentCreditTrade", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('create_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_documentcredittrade_CREATE_USER', to='tfrs.user')), - ('credit_trade', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tfrs.credittrade')), - ('document', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tfrs.document')), - ('update_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_documentcredittrade_UPDATE_USER', to='tfrs.user')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ( + "create_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_documentcredittrade_CREATE_USER", + to="tfrs.user", + ), + ), + ( + "credit_trade", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="tfrs.credittrade", + ), + ), + ( + "document", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="tfrs.document" + ), + ), + ( + "update_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_documentcredittrade_UPDATE_USER", + to="tfrs.user", + ), + ), ], options={ - 'db_table': 'document_credit_trade', - 'unique_together': {('credit_trade', 'document')}, + "db_table": "document_credit_trade", + "unique_together": {("credit_trade", "document")}, }, ), migrations.AddField( - model_name='documentcategory', - name='create_user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_documentcategory_CREATE_USER', to='tfrs.user'), + model_name="documentcategory", + name="create_user", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_documentcategory_CREATE_USER", + to="tfrs.user", + ), ), migrations.AddField( - model_name='documentcategory', - name='update_user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_documentcategory_UPDATE_USER', to='tfrs.user'), + model_name="documentcategory", + name="update_user", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_documentcategory_UPDATE_USER", + to="tfrs.user", + ), ), migrations.AddField( - model_name='document', - name='create_user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_document_CREATE_USER', to='tfrs.user'), + model_name="document", + name="create_user", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_document_CREATE_USER", + to="tfrs.user", + ), ), migrations.AddField( - model_name='document', - name='credit_trades', - field=models.ManyToManyField(through='tfrs.DocumentCreditTrade', to='tfrs.CreditTrade'), + model_name="document", + name="credit_trades", + field=models.ManyToManyField( + through="tfrs.DocumentCreditTrade", to="tfrs.CreditTrade" + ), ), migrations.AddField( - model_name='document', - name='status', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tfrs.documentstatus'), + model_name="document", + name="status", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="tfrs.documentstatus" + ), ), migrations.AddField( - model_name='document', - name='type', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tfrs.documenttype'), + model_name="document", + name="type", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="tfrs.documenttype" + ), ), migrations.AddField( - model_name='document', - name='update_user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_document_UPDATE_USER', to='tfrs.user'), + model_name="document", + name="update_user", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_document_UPDATE_USER", + to="tfrs.user", + ), ), migrations.CreateModel( - name='CreditTradeZeroReason', + name="CreditTradeZeroReason", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('display_order', models.IntegerField()), - ('effective_date', models.DateField(blank=True, null=True)), - ('expiration_date', models.DateField(blank=True, null=True)), - ('reason', models.CharField(max_length=25)), - ('description', models.CharField(max_length=1000)), - ('create_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_credittradezeroreason_CREATE_USER', to='tfrs.user')), - ('update_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_credittradezeroreason_UPDATE_USER', to='tfrs.user')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("display_order", models.IntegerField()), + ("effective_date", models.DateField(blank=True, null=True)), + ("expiration_date", models.DateField(blank=True, null=True)), + ("reason", models.CharField(max_length=25)), + ("description", models.CharField(max_length=1000)), + ( + "create_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_credittradezeroreason_CREATE_USER", + to="tfrs.user", + ), + ), + ( + "update_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_credittradezeroreason_UPDATE_USER", + to="tfrs.user", + ), + ), ], options={ - 'db_table': 'credit_trade_zero_reason', + "db_table": "credit_trade_zero_reason", }, ), migrations.CreateModel( - name='CreditTradeType', + name="CreditTradeType", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('display_order', models.IntegerField()), - ('effective_date', models.DateField(blank=True, null=True)), - ('expiration_date', models.DateField(blank=True, null=True)), - ('the_type', models.CharField(blank=True, max_length=25, null=True, unique=True)), - ('description', models.CharField(blank=True, max_length=1000, null=True)), - ('is_gov_only_type', models.BooleanField()), - ('create_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_credittradetype_CREATE_USER', to='tfrs.user')), - ('update_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_credittradetype_UPDATE_USER', to='tfrs.user')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("display_order", models.IntegerField()), + ("effective_date", models.DateField(blank=True, null=True)), + ("expiration_date", models.DateField(blank=True, null=True)), + ( + "the_type", + models.CharField(blank=True, max_length=25, null=True, unique=True), + ), + ( + "description", + models.CharField(blank=True, max_length=1000, null=True), + ), + ("is_gov_only_type", models.BooleanField()), + ( + "create_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_credittradetype_CREATE_USER", + to="tfrs.user", + ), + ), + ( + "update_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_credittradetype_UPDATE_USER", + to="tfrs.user", + ), + ), ], options={ - 'db_table': 'credit_trade_type', + "db_table": "credit_trade_type", }, ), migrations.CreateModel( - name='CreditTradeStatus', + name="CreditTradeStatus", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('display_order', models.IntegerField()), - ('effective_date', models.DateField(blank=True, null=True)), - ('expiration_date', models.DateField(blank=True, null=True)), - ('status', models.CharField(blank=True, max_length=25, null=True, unique=True)), - ('description', models.CharField(blank=True, max_length=4000, null=True)), - ('create_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_credittradestatus_CREATE_USER', to='tfrs.user')), - ('update_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_credittradestatus_UPDATE_USER', to='tfrs.user')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("display_order", models.IntegerField()), + ("effective_date", models.DateField(blank=True, null=True)), + ("expiration_date", models.DateField(blank=True, null=True)), + ( + "status", + models.CharField(blank=True, max_length=25, null=True, unique=True), + ), + ( + "description", + models.CharField(blank=True, max_length=4000, null=True), + ), + ( + "create_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_credittradestatus_CREATE_USER", + to="tfrs.user", + ), + ), + ( + "update_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_credittradestatus_UPDATE_USER", + to="tfrs.user", + ), + ), ], options={ - 'db_table': 'credit_trade_status', + "db_table": "credit_trade_status", }, ), migrations.AddField( - model_name='credittrade', - name='create_user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_credittrade_CREATE_USER', to='tfrs.user'), + model_name="credittrade", + name="create_user", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_credittrade_CREATE_USER", + to="tfrs.user", + ), ), migrations.AddField( - model_name='credittrade', - name='documents', - field=models.ManyToManyField(through='tfrs.DocumentCreditTrade', to='tfrs.Document'), + model_name="credittrade", + name="documents", + field=models.ManyToManyField( + through="tfrs.DocumentCreditTrade", to="tfrs.Document" + ), ), migrations.AddField( - model_name='credittrade', - name='initiator', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='initiator_credit_trades', to='tfrs.organization'), + model_name="credittrade", + name="initiator", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="initiator_credit_trades", + to="tfrs.organization", + ), ), migrations.AddField( - model_name='credittrade', - name='respondent', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='respondent_credit_trades', to='tfrs.organization'), + model_name="credittrade", + name="respondent", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="respondent_credit_trades", + to="tfrs.organization", + ), ), migrations.AddField( - model_name='credittrade', - name='status', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='credit_trades', to='tfrs.credittradestatus'), + model_name="credittrade", + name="status", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="credit_trades", + to="tfrs.credittradestatus", + ), ), migrations.AddField( - model_name='credittrade', - name='type', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='credit_trades', to='tfrs.credittradetype'), + model_name="credittrade", + name="type", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="credit_trades", + to="tfrs.credittradetype", + ), ), migrations.AddField( - model_name='credittrade', - name='update_user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_credittrade_UPDATE_USER', to='tfrs.user'), + model_name="credittrade", + name="update_user", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_credittrade_UPDATE_USER", + to="tfrs.user", + ), ), migrations.AddField( - model_name='credittrade', - name='zero_reason', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='credit_trades', to='tfrs.credittradezeroreason'), + model_name="credittrade", + name="zero_reason", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="credit_trades", + to="tfrs.credittradezeroreason", + ), ), migrations.AddField( - model_name='complianceperiod', - name='create_user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_complianceperiod_CREATE_USER', to='tfrs.user'), + model_name="complianceperiod", + name="create_user", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_complianceperiod_CREATE_USER", + to="tfrs.user", + ), ), migrations.AddField( - model_name='complianceperiod', - name='update_user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tfrs_complianceperiod_UPDATE_USER', to='tfrs.user'), + model_name="complianceperiod", + name="update_user", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="tfrs_complianceperiod_UPDATE_USER", + to="tfrs.user", + ), ), ] diff --git a/django/tfrs/models/CompliancePeriod.py b/django/tfrs/models/CompliancePeriod.py index fda98d97..65e68a54 100644 --- a/django/tfrs/models/CompliancePeriod.py +++ b/django/tfrs/models/CompliancePeriod.py @@ -6,11 +6,7 @@ class CompliancePeriod(Auditable, DisplayOrder, EffectiveDates): - description = models.CharField( - max_length=1000, - blank=True, - null=True - ) + description = models.CharField(max_length=1000, blank=True, null=True) class Meta: - db_table = 'compliance_period' + db_table = "compliance_period" diff --git a/django/tfrs/models/CreditTrade.py b/django/tfrs/models/CreditTrade.py index c68867f8..a5c213a9 100644 --- a/django/tfrs/models/CreditTrade.py +++ b/django/tfrs/models/CreditTrade.py @@ -13,37 +13,30 @@ class CreditTrade(Auditable): status = models.ForeignKey( - CreditTradeStatus, - related_name='credit_trades', - on_delete=models.PROTECT + CreditTradeStatus, related_name="credit_trades", on_delete=models.PROTECT ) initiator = models.ForeignKey( Organization, - related_name='initiator_credit_trades', - blank=True, null=True, - on_delete=models.PROTECT + related_name="initiator_credit_trades", + blank=True, + null=True, + on_delete=models.PROTECT, ) respondent = models.ForeignKey( Organization, - related_name='respondent_credit_trades', + related_name="respondent_credit_trades", on_delete=models.PROTECT, ) type = models.ForeignKey( - CreditTradeType, - related_name='credit_trades', - on_delete=models.PROTECT + CreditTradeType, related_name="credit_trades", on_delete=models.PROTECT ) number_of_credits = models.IntegerField() fair_market_value_per_credit = models.DecimalField( - null=True, - blank=True, - max_digits=10, - decimal_places=2, - default=Decimal('0.00') + null=True, blank=True, max_digits=10, decimal_places=2, default=Decimal("0.00") ) zero_reason = models.ForeignKey( CreditTradeZeroReason, - related_name='credit_trades', + related_name="credit_trades", blank=True, null=True, on_delete=models.PROTECT, @@ -54,17 +47,15 @@ class CreditTrade(Auditable): ) compliance_period = models.ForeignKey( CompliancePeriod, - related_name='credit_trades', - blank=True, null=True, - on_delete=models.PROTECT + related_name="credit_trades", + blank=True, + null=True, + on_delete=models.PROTECT, ) is_rescinded = models.BooleanField( default=False, ) - documents = ManyToManyField( - 'Document', - through='DocumentCreditTrade' - ) + documents = ManyToManyField("Document", through="DocumentCreditTrade") class Meta: - db_table = 'credit_trade' + db_table = "credit_trade" diff --git a/django/tfrs/models/CreditTradeStatus.py b/django/tfrs/models/CreditTradeStatus.py index b28c5631..3c24c190 100644 --- a/django/tfrs/models/CreditTradeStatus.py +++ b/django/tfrs/models/CreditTradeStatus.py @@ -6,17 +6,8 @@ class CreditTradeStatus(Auditable, DisplayOrder, EffectiveDates): - status = models.CharField( - max_length=25, - blank=True, - null=True, - unique=True - ) - description = models.CharField( - max_length=4000, - blank=True, - null=True - ) + status = models.CharField(max_length=25, blank=True, null=True, unique=True) + description = models.CharField(max_length=4000, blank=True, null=True) class Meta: - db_table = 'credit_trade_status' + db_table = "credit_trade_status" diff --git a/django/tfrs/models/CreditTradeType.py b/django/tfrs/models/CreditTradeType.py index ae8edb31..091c2d6f 100644 --- a/django/tfrs/models/CreditTradeType.py +++ b/django/tfrs/models/CreditTradeType.py @@ -20,4 +20,4 @@ class CreditTradeType(Auditable, DisplayOrder, EffectiveDates): is_gov_only_type = models.BooleanField() class Meta: - db_table = 'credit_trade_type' + db_table = "credit_trade_type" diff --git a/django/tfrs/models/CreditTradeZeroReason.py b/django/tfrs/models/CreditTradeZeroReason.py index 96dddc37..9eb41b38 100644 --- a/django/tfrs/models/CreditTradeZeroReason.py +++ b/django/tfrs/models/CreditTradeZeroReason.py @@ -10,4 +10,4 @@ class CreditTradeZeroReason(Auditable, DisplayOrder, EffectiveDates): description = models.CharField(max_length=1000) class Meta: - db_table = 'credit_trade_zero_reason' + db_table = "credit_trade_zero_reason" diff --git a/django/tfrs/models/Document.py b/django/tfrs/models/Document.py index 83dd1153..823b11b0 100644 --- a/django/tfrs/models/Document.py +++ b/django/tfrs/models/Document.py @@ -6,10 +6,7 @@ class Document(Auditable, DocumentData): - credit_trades = ManyToManyField( - 'CreditTrade', - through='DocumentCreditTrade' - ) + credit_trades = ManyToManyField("CreditTrade", through="DocumentCreditTrade") class Meta: - db_table = 'document' + db_table = "document" diff --git a/django/tfrs/models/DocumentCategory.py b/django/tfrs/models/DocumentCategory.py index ad059883..57bf809c 100644 --- a/django/tfrs/models/DocumentCategory.py +++ b/django/tfrs/models/DocumentCategory.py @@ -5,12 +5,7 @@ class DocumentCategory(Auditable, DisplayOrder): - name = models.CharField( - max_length=120, - blank=True, - null=True, - unique=True - ) + name = models.CharField(max_length=120, blank=True, null=True, unique=True) class Meta: - db_table = 'document_category' + db_table = "document_category" diff --git a/django/tfrs/models/DocumentCreditTrade.py b/django/tfrs/models/DocumentCreditTrade.py index 1560f7a9..0a8019d7 100644 --- a/django/tfrs/models/DocumentCreditTrade.py +++ b/django/tfrs/models/DocumentCreditTrade.py @@ -4,15 +4,9 @@ class DocumentCreditTrade(Auditable): - credit_trade = models.ForeignKey( - 'CreditTrade', - on_delete=models.PROTECT - ) - document = models.ForeignKey( - 'Document', - on_delete=models.PROTECT - ) + credit_trade = models.ForeignKey("CreditTrade", on_delete=models.PROTECT) + document = models.ForeignKey("Document", on_delete=models.PROTECT) class Meta: - db_table = 'document_credit_trade' - unique_together = (('credit_trade', 'document'),) + db_table = "document_credit_trade" + unique_together = (("credit_trade", "document"),) diff --git a/django/tfrs/models/DocumentStatus.py b/django/tfrs/models/DocumentStatus.py index d1d35198..773c18ac 100644 --- a/django/tfrs/models/DocumentStatus.py +++ b/django/tfrs/models/DocumentStatus.py @@ -6,12 +6,7 @@ class DocumentStatus(Auditable, DisplayOrder, EffectiveDates): - status = models.CharField( - max_length=25, - blank=True, - null=True, - unique=True - ) + status = models.CharField(max_length=25, blank=True, null=True, unique=True) class Meta: - db_table = 'document_status' + db_table = "document_status" diff --git a/django/tfrs/models/DocumentType.py b/django/tfrs/models/DocumentType.py index 5b95d892..0cbf500a 100644 --- a/django/tfrs/models/DocumentType.py +++ b/django/tfrs/models/DocumentType.py @@ -6,23 +6,16 @@ class DocumentType(Auditable, EffectiveDates): - the_type = models.CharField( - max_length=100, - blank=True, - null=True, - unique=True - ) - description = models.CharField( - max_length=1000, blank=True, null=True - ) + the_type = models.CharField(max_length=100, blank=True, null=True, unique=True) + description = models.CharField(max_length=1000, blank=True, null=True) category = models.ForeignKey( DocumentCategory, blank=False, null=False, unique=False, - related_name='types', - on_delete=models.PROTECT + related_name="types", + on_delete=models.PROTECT, ) class Meta: - db_table = 'document_type' + db_table = "document_type" diff --git a/django/tfrs/models/Organization.py b/django/tfrs/models/Organization.py index 726f37de..b3cc038c 100644 --- a/django/tfrs/models/Organization.py +++ b/django/tfrs/models/Organization.py @@ -4,25 +4,24 @@ class Organization(Auditable): - name = models.CharField( - max_length=500 - ) + name = models.CharField(max_length=500) status = models.ForeignKey( - 'OrganizationStatus', - related_name='organization_status', - on_delete=models.PROTECT + "OrganizationStatus", + related_name="organization_status", + on_delete=models.PROTECT, ) actions_type = models.ForeignKey( - 'OrganizationActionsType', - related_name='organization_actions_type', - on_delete=models.PROTECT + "OrganizationActionsType", + related_name="organization_actions_type", + on_delete=models.PROTECT, ) type = models.ForeignKey( - 'OrganizationType', - related_name='organization_type', - blank=True, null=True, - on_delete=models.PROTECT + "OrganizationType", + related_name="organization_type", + blank=True, + null=True, + on_delete=models.PROTECT, ) class Meta: - db_table = 'tfrs_organization' + db_table = "tfrs_organization" diff --git a/django/tfrs/models/OrganizationActionsType.py b/django/tfrs/models/OrganizationActionsType.py index 61f1001f..28e39c57 100644 --- a/django/tfrs/models/OrganizationActionsType.py +++ b/django/tfrs/models/OrganizationActionsType.py @@ -17,4 +17,4 @@ class OrganizationActionsType(Auditable, DisplayOrder, EffectiveDates): ) class Meta: - db_table = 'tfrs_organization_actions_type' + db_table = "tfrs_organization_actions_type" diff --git a/django/tfrs/models/OrganizationStatus.py b/django/tfrs/models/OrganizationStatus.py index 051a8c37..9b22d14b 100644 --- a/django/tfrs/models/OrganizationStatus.py +++ b/django/tfrs/models/OrganizationStatus.py @@ -6,15 +6,8 @@ class OrganizationStatus(Auditable, EffectiveDates, DisplayOrder): - status = models.CharField( - max_length=25, - unique=True - ) - description = models.CharField( - max_length=1000, - blank=True, - null=True - ) + status = models.CharField(max_length=25, unique=True) + description = models.CharField(max_length=1000, blank=True, null=True) class Meta: - db_table = 'tfrs_organization_status' + db_table = "tfrs_organization_status" diff --git a/django/tfrs/models/OrganizationType.py b/django/tfrs/models/OrganizationType.py index c6673d0b..9387a4ee 100644 --- a/django/tfrs/models/OrganizationType.py +++ b/django/tfrs/models/OrganizationType.py @@ -6,15 +6,8 @@ class OrganizationType(Auditable, DisplayOrder, EffectiveDates): - type = models.CharField( - max_length=25, - unique=True - ) - description = models.CharField( - max_length=1000, - blank=True, - null=True - ) + type = models.CharField(max_length=25, unique=True) + description = models.CharField(max_length=1000, blank=True, null=True) class Meta: - db_table = 'organization_type' + db_table = "organization_type" diff --git a/django/tfrs/models/User.py b/django/tfrs/models/User.py index e74eb133..b0443e98 100644 --- a/django/tfrs/models/User.py +++ b/django/tfrs/models/User.py @@ -5,44 +5,17 @@ class User(Auditable): - last_login = models.DateTimeField( - null=True - ) - is_superuser = models.BooleanField( - default=False - ) - username = models.CharField( - max_length=150, - unique=True, - verbose_name='username' - ) - first_name = models.CharField( - max_length=30 - ) - last_name = models.CharField( - max_length=30 - ) - is_staff = models.BooleanField( - default=False - ) - is_active = models.BooleanField( - default=False - ) + last_login = models.DateTimeField(null=True) + is_superuser = models.BooleanField(default=False) + username = models.CharField(max_length=150, unique=True, verbose_name="username") + first_name = models.CharField(max_length=30) + last_name = models.CharField(max_length=30) + is_staff = models.BooleanField(default=False) + is_active = models.BooleanField(default=False) date_joined = models.DateTimeField() - password = models.CharField( - max_length=128, - blank=True, - null=True - ) - email = models.EmailField( - blank=True, - null=True - ) - title = models.CharField( - max_length=100, - blank=True, - null=True - ) + password = models.CharField(max_length=128, blank=True, null=True) + email = models.EmailField(blank=True, null=True) + title = models.CharField(max_length=100, blank=True, null=True) phone = models.CharField( max_length=50, blank=True, @@ -57,15 +30,15 @@ class User(Auditable): max_length=500, blank=True, null=True, - db_column='display_name', + db_column="display_name", ) organization = models.ForeignKey( Organization, - related_name='users', + related_name="users", blank=True, null=True, - on_delete=models.SET_NULL + on_delete=models.SET_NULL, ) class Meta: - db_table = 'tfrs_user' + db_table = "tfrs_user" diff --git a/django/tfrs/models/mixins/Auditable.py b/django/tfrs/models/mixins/Auditable.py index 04ed8213..df6a97d0 100644 --- a/django/tfrs/models/mixins/Auditable.py +++ b/django/tfrs/models/mixins/Auditable.py @@ -2,28 +2,21 @@ class Auditable(models.Model): - create_timestamp = models.DateTimeField( - auto_now_add=True, - blank=True, - null=True - ) + create_timestamp = models.DateTimeField(auto_now_add=True, blank=True, null=True) create_user = models.ForeignKey( - 'tfrs.User', - related_name='%(app_label)s_%(class)s_CREATE_USER', + "tfrs.User", + related_name="%(app_label)s_%(class)s_CREATE_USER", blank=True, null=True, on_delete=models.CASCADE, ) - update_timestamp = models.DateTimeField( - auto_now=True, - blank=True, - null=True - ) + update_timestamp = models.DateTimeField(auto_now=True, blank=True, null=True) update_user = models.ForeignKey( - 'tfrs.User', - related_name='%(app_label)s_%(class)s_UPDATE_USER', - blank=True, null=True, - on_delete=models.CASCADE + "tfrs.User", + related_name="%(app_label)s_%(class)s_UPDATE_USER", + blank=True, + null=True, + on_delete=models.CASCADE, ) class Meta: diff --git a/django/tfrs/models/mixins/DocumentData.py b/django/tfrs/models/mixins/DocumentData.py index 03eace38..2bef3615 100644 --- a/django/tfrs/models/mixins/DocumentData.py +++ b/django/tfrs/models/mixins/DocumentData.py @@ -6,30 +6,13 @@ class DocumentData(models.Model): - title = models.CharField( - max_length=120, - blank=False - ) - status = models.ForeignKey( - DocumentStatus, - on_delete=models.PROTECT, - null=False - ) - type = models.ForeignKey( - DocumentType, - on_delete=models.PROTECT, - null=False - ) + title = models.CharField(max_length=120, blank=False) + status = models.ForeignKey(DocumentStatus, on_delete=models.PROTECT, null=False) + type = models.ForeignKey(DocumentType, on_delete=models.PROTECT, null=False) compliance_period = models.ForeignKey( - CompliancePeriod, - on_delete=models.PROTECT, - null=False - ) - milestone = models.CharField( - blank=True, - max_length=1000, - null=True + CompliancePeriod, on_delete=models.PROTECT, null=False ) + milestone = models.CharField(blank=True, max_length=1000, null=True) class Meta: abstract = True diff --git a/django/tfrs/models/mixins/EffectiveDates.py b/django/tfrs/models/mixins/EffectiveDates.py index 1f67f55b..633adb4a 100644 --- a/django/tfrs/models/mixins/EffectiveDates.py +++ b/django/tfrs/models/mixins/EffectiveDates.py @@ -2,15 +2,8 @@ class EffectiveDates(models.Model): - - effective_date = models.DateField( - blank=True, - null=True - ) - expiration_date = models.DateField( - blank=True, - null=True - ) + effective_date = models.DateField(blank=True, null=True) + expiration_date = models.DateField(blank=True, null=True) class Meta: abstract = True diff --git a/django/wsgi.py b/django/wsgi.py index e503321b..b729a4b9 100644 --- a/django/wsgi.py +++ b/django/wsgi.py @@ -13,7 +13,7 @@ from dotenv import load_dotenv try: - ENV = '.env' + ENV = ".env" load_dotenv(dotenv_path=ENV) except TypeError: pass # path doesn't exist. no cause for alarm. @@ -30,14 +30,14 @@ def application(environ, start_response): This function is based from an answer in StackOverflow https://stackoverflow.com/questions/33051034/django-not-taking-script-name-header-from-nginx """ - script_name = os.getenv('BASE_PATH', '') - environ['SCRIPT_NAME'] = script_name - path_info = environ['PATH_INFO'] + script_name = os.getenv("BASE_PATH", "") + environ["SCRIPT_NAME"] = script_name + path_info = environ["PATH_INFO"] if path_info.startswith(script_name): - environ['PATH_INFO'] = path_info[len(script_name):] + environ["PATH_INFO"] = path_info[len(script_name) :] - scheme = environ.get('HTTP_X_SCHEME', '') + scheme = environ.get("HTTP_X_SCHEME", "") if scheme: - environ['wsgi.url_scheme'] = scheme + environ["wsgi.url_scheme"] = scheme return _APPLICATION(environ, start_response) From 703afa07745b9dbb33a505e109d45a4a7e96bc8e Mon Sep 17 00:00:00 2001 From: Kuan Fan Date: Wed, 31 Jul 2024 13:20:50 -0700 Subject: [PATCH 12/14] format yaml --- .github/workflows/prettier-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prettier-test.yaml b/.github/workflows/prettier-test.yaml index 3d1dce90..207462dd 100644 --- a/.github/workflows/prettier-test.yaml +++ b/.github/workflows/prettier-test.yaml @@ -22,7 +22,7 @@ jobs: - name: Prettify code uses: creyD/prettier_action@v4.3 with: - prettier_options: --write **/*.{js,md} + prettier_options: --write **/*.{js,md,yaml} - name: pwd run: | From 65d97fc26fd0e7eac5565d0debfc7228f2ceb43b Mon Sep 17 00:00:00 2001 From: Kuan Fan Date: Wed, 31 Jul 2024 13:31:27 -0700 Subject: [PATCH 13/14] add html --- .github/workflows/prettier-test.yaml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/prettier-test.yaml b/.github/workflows/prettier-test.yaml index 207462dd..e5a8aec8 100644 --- a/.github/workflows/prettier-test.yaml +++ b/.github/workflows/prettier-test.yaml @@ -22,12 +22,7 @@ jobs: - name: Prettify code uses: creyD/prettier_action@v4.3 with: - prettier_options: --write **/*.{js,md,yaml} - - - name: pwd - run: | - pwd - ls -l + prettier_options: --write **/*.{js,md,html} - name: Run python black code formatter uses: DataDog/action-py-black-formatter@v2.5 From d3fb2f5cfa79594ae8126eec81f8399a0c3ca7fa Mon Sep 17 00:00:00 2001 From: kuanfandevops Date: Wed, 31 Jul 2024 20:32:22 +0000 Subject: [PATCH 14/14] Prettified Code! --- frontend/public/index.html | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/frontend/public/index.html b/frontend/public/index.html index bc0e7679..671fb32f 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -1,4 +1,4 @@ - + @@ -22,11 +22,14 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - - + + <% if (process.env.NODE_ENV === 'production') { %> - + <% } %> CTHUB