ethyca-fides 2.73.2b0__py2.py3-none-any.whl → 2.74.0rc1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ethyca-fides might be problematic. Click here for more details.
- {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.74.0rc1.dist-info}/METADATA +2 -1
- {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.74.0rc1.dist-info}/RECORD +273 -276
- fides/_version.py +3 -3
- fides/api/alembic/migrations/versions/xx_2025_10_29_1659_80d28dea3b6b_added_duplicate_group_table.py +79 -0
- fides/api/alembic/migrations/versions/xx_2025_11_05_0200_f1a2b3c4d5e6_create_staged_resource_error_table.py +82 -0
- fides/api/api/v1/endpoints/privacy_request_endpoints.py +33 -6
- fides/api/db/database.py +225 -0
- fides/api/models/detection_discovery/__init__.py +2 -0
- fides/api/models/detection_discovery/core.py +10 -0
- fides/api/models/detection_discovery/staged_resource_error.py +25 -0
- fides/api/models/privacy_preference.py +1 -0
- fides/api/models/privacy_request/duplicate_group.py +84 -0
- fides/api/models/privacy_request/privacy_request.py +53 -8
- fides/api/schemas/privacy_request.py +16 -4
- fides/api/service/async_dsr/strategies/async_dsr_strategy_polling.py +13 -6
- fides/api/service/privacy_request/duplication_detection.py +424 -0
- fides/api/service/privacy_request/request_runner_service.py +5 -0
- fides/api/service/saas_request/saas_request_override_factory.py +7 -2
- fides/api/util/logger_context_utils.py +3 -1
- fides/api/util/memory_watchdog.py +118 -0
- fides/common/api/v1/urn_registry.py +1 -0
- fides/config/__init__.py +7 -1
- fides/config/celery_settings.py +42 -0
- fides/service/privacy_request/privacy_request_service.py +66 -5
- fides/ui-build/static/admin/404.html +1 -1
- fides/ui-build/static/admin/_next/static/FZTEUgamBvOhgPWce135w/_buildManifest.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{1115-26393b586775ea29.js → 1115-0da062111df309bf.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{6148-59a59d5c5925344f.js → 1533-84e250d1f26e6d7d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/1817-508b16628e8eb225.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1840-5bbe6d878ed73fb4.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3214-90ce0a366b0f461a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3377-eb5cd82b3ee6ab0c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3615-5e2d062d684b8fa1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3655-93ecd09f1cb9dbef.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{4259.d1507e0db19cbed7.js → 4259.05038c9b78467244.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/4277-13bcf4516326d474.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/454-d5c2c84f1a14e4f1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5487-8dedd1ca94fbba54.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/549-6e2442db533a711e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5643-55d758444a8d7162.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5724-1e40975cefa405f0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6084-82e2df433fe5ba85.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6344-3e21444374f8059f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6362-12e3fd23130ccf15.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6372-a8d0f08dac1ebd0e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6780-3db5133c1f4c6f1e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6954-aa0c60ee1092be8e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7079-6e6efc3396ff1ebb.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7218-d297a4a06f924b09.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{7245-c9bc628d078c2170.js → 7245-686665c197b58e68.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/7654-716cf37a020b3d11.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/8939-4925751c57c51f87.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9014-eeae6f581158e645.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{9046-d9c6498368b993d1.js → 9046-e4daf28840a69fd6.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{5596-29a7c8322530b7cf.js → 9195-550bd50d538c5f79.js} +3 -3
- fides/ui-build/static/admin/_next/static/chunks/9341-bfc0e59bcc56c604.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9450-b7b7bb1d755ecf57.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9682-da69ac5d06f281da.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9911-ece086f2230e34f0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9965-56c5e4fc9cd3b3a5.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{_app-ee588a308812715d.js → _app-e64fd8510033a27c.js} +63 -63
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-7081e0e49f67716c.js → manual-ddd9d7d40847fc28.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-1b02a4991201b7e4.js → [id]-9b1f2b1c06968166.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-a5e738a234dadc7e.js → new-115a085e5d42de45.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-8c164c4b8310214e.js → [id]-3de34624829cbce8.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-db789002d84c8829.js → new-dc95e7ed278d1a29.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-e3ad3a55624e302a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-32bd7a7c990e5bf6.js → [resourceUrn]-dd82729296dee5c5.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-49e5477eb1a11b92.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{projects-07e7d38ce34e1e6c.js → projects-dfc1ead4a12c9ffa.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-b07a0707f8c2ec0d.js → [resourceUrn]-8442eb219958ac7e.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources-feda358d1801c18d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-d16acb6fc07aad46.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore/[monitorId]-c51a1e98c45d231a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]/[systemId]-bcfe38eebca30f8c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/{[monitorId]-73085f50abb775c0.js → [monitorId]-f66d0655897c4400.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-6f1e012cd641da19.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{activity-24a82e07a0008516.js → activity-581d6248fcf98d17.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-b072cf25aefc98f6.js → [resourceUrn]-ddc1c1641e1e9430.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-fd3e8817d8e6dee4.js → detection-2b48f7e524743b2b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-146624cf59792bf7.js → [resourceUrn]-862b67418600251e.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-9695cc9c85592ec5.js → discovery-0ffec855f5df262c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datamap-6a030ab8c2e2b0db.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-5f88280db168083e.js → [...subfieldNames]-6cb66f649b8ca4bf.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-bfbcf19c28c794ae.js → [collectionName]-0b008dad90b00aaa.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{[datasetId]-6fbe2b584a509226.js → [datasetId]-5566edf9a9d1be2d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-d4ca1f485b6e9e02.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset-85dee7e81dc4bafb.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-e905e018a2cab35d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-912723bc86299b1a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-f1f0affc18327033.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{fides-js-docs-1f4335dca5c09860.js → fides-js-docs-5235760b3e508d7d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-1b94e2d769a182b2.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{integrations-a733e5d7c3ce9bb8.js → integrations-adfe6c5ac5b703d0.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/new-privacy-requests-f9be7080ebbb7445.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/{[key]-720cde29f81db47f.js → [key]-f94e3accf9507ebf.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/{new-3668866076b53016.js → new-5e83220ff1f2a250.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates-1621a4b87c432117.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/{ant-components-9cfb469de7b4aeab.js → ant-components-e02516d9fd314528.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-1fe486f3af832c80.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-2c0ec8fed16c20ae.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-baf77d34a3b3bece.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-ee8820fe0fa14c77.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/{[id]-8634aae3259def37.js → [id]-8eb862182f19a6c2.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/{new-2d9dcca17965dc57.js → new-37c29ef618e9fe3c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-1db425150dcb1b6b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-f108bf5015144d2f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-59c89489fa32a4cb.js → [id]-0e7c7228d01290ea.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{systems-cfaa37a0df83674b.js → systems-adc13b542e10a37d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-23dd250da26511c5.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/webpack-6f97ebe373e7ef6b.js +1 -0
- fides/ui-build/static/admin/_next/static/css/65ae906f224cd8ae.css +1 -0
- fides/ui-build/static/admin/_next/static/css/d5701118537cbdd2.css +1 -0
- fides/ui-build/static/admin/add-systems/manual.html +1 -1
- fides/ui-build/static/admin/add-systems/multiple.html +1 -1
- fides/ui-build/static/admin/add-systems.html +1 -1
- fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
- fides/ui-build/static/admin/consent/configure.html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
- fides/ui-build/static/admin/consent/properties.html +1 -1
- fides/ui-build/static/admin/consent/reporting.html +1 -1
- fides/ui-build/static/admin/consent.html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
- fides/ui-build/static/admin/data-catalog.html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/datastore/[monitorId].html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/datastore.html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId]/[systemId].html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId].html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/website.html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
- fides/ui-build/static/admin/data-discovery/activity.html +1 -1
- fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-discovery/detection.html +1 -1
- fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
- fides/ui-build/static/admin/datamap.html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
- fides/ui-build/static/admin/dataset/new.html +1 -1
- fides/ui-build/static/admin/dataset.html +1 -1
- fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
- fides/ui-build/static/admin/datastore-connection/new.html +1 -1
- fides/ui-build/static/admin/datastore-connection.html +1 -1
- fides/ui-build/static/admin/index.html +1 -1
- fides/ui-build/static/admin/integrations/[id].html +1 -1
- fides/ui-build/static/admin/integrations.html +1 -1
- fides/ui-build/static/admin/lib/fides-ext-gpp.js +1 -1
- fides/ui-build/static/admin/lib/fides-preview.js +1 -1
- fides/ui-build/static/admin/lib/fides-tcf.js +2 -2
- fides/ui-build/static/admin/login/[provider].html +1 -1
- fides/ui-build/static/admin/login.html +1 -1
- fides/ui-build/static/admin/new-privacy-requests.html +1 -1
- fides/ui-build/static/admin/notifications/digests/[id].html +1 -1
- fides/ui-build/static/admin/notifications/digests/new.html +1 -1
- fides/ui-build/static/admin/notifications/digests.html +1 -1
- fides/ui-build/static/admin/notifications/providers/[key].html +1 -1
- fides/ui-build/static/admin/notifications/providers/new.html +1 -1
- fides/ui-build/static/admin/notifications/providers.html +1 -1
- fides/ui-build/static/admin/notifications/templates/[id].html +1 -1
- fides/ui-build/static/admin/notifications/templates/add-template.html +1 -1
- fides/ui-build/static/admin/notifications/templates.html +1 -1
- fides/ui-build/static/admin/notifications.html +1 -1
- fides/ui-build/static/admin/poc/ant-components.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
- fides/ui-build/static/admin/poc/forms.html +1 -1
- fides/ui-build/static/admin/poc/table-migration.html +1 -1
- fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
- fides/ui-build/static/admin/privacy-requests.html +1 -1
- fides/ui-build/static/admin/properties/[id].html +1 -1
- fides/ui-build/static/admin/properties/add-property.html +1 -1
- fides/ui-build/static/admin/properties.html +1 -1
- fides/ui-build/static/admin/reporting/datamap.html +1 -1
- fides/ui-build/static/admin/sandbox/privacy-notices.html +1 -1
- fides/ui-build/static/admin/settings/about/alpha.html +1 -1
- fides/ui-build/static/admin/settings/about.html +1 -1
- fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
- fides/ui-build/static/admin/settings/consent.html +1 -1
- fides/ui-build/static/admin/settings/custom-fields/[id].html +1 -1
- fides/ui-build/static/admin/settings/custom-fields/new.html +1 -1
- fides/ui-build/static/admin/settings/custom-fields.html +1 -1
- fides/ui-build/static/admin/settings/domain-records.html +1 -1
- fides/ui-build/static/admin/settings/domains.html +1 -1
- fides/ui-build/static/admin/settings/email-templates.html +1 -1
- fides/ui-build/static/admin/settings/locations.html +1 -1
- fides/ui-build/static/admin/settings/organization.html +1 -1
- fides/ui-build/static/admin/settings/privacy-requests.html +1 -1
- fides/ui-build/static/admin/settings/regulations.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id].html +1 -1
- fides/ui-build/static/admin/systems.html +1 -1
- fides/ui-build/static/admin/taxonomy.html +1 -1
- fides/ui-build/static/admin/user-management/new.html +1 -1
- fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
- fides/ui-build/static/admin/user-management.html +1 -1
- fides/ui-build/static/admin/_next/static/chunks/1099-31f9d973bc287df8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1316-2606e19807c08aa5.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1437-8b1f6c8797c68bfd.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1467-8808ec8836e033f9.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/155-f6302d32cba4cab6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1817-2d5cf537a2992c79.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/2962-342ad1b4ab402ded.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3377-988ac2f3a2e8d5d4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3446-f40c352c43ac950c.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/346-aa3b88efb85f2e28.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3700-f695f2f6b8251971.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3772-9f1713f9d5f97a10.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3873-d18e47b327445db5.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5163-e682273cd76a7d07.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5279-bd6cccabdd6ca447.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/549-28537a6de666944b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5619-9b50cec521203989.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5643-3459282d296a3c59.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6277-3759894435cb8569.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6315-e2fb5ea77179a871.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6344-ca66a6e10d128179.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6419-11d67f7fd4e2f247.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6954-84789a4e4fb04eb9.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/699-8ca44b0de9fa20f0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7488-cf92601852e3c509.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7773-9ae233109bc64ec2.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/8011-75af8b480fa114e6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/8373-22b4d20e8cc06b3a.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/8765-f622a35b40a7ec63.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9037-453224ba3ee65b13.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9187-7438242f0d380bb0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9278-08cc704317fe535e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9682-d1a3afa1394f8304.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9729-fcf6ff4e3534e4a8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9899-d6437facac926264.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9965-25621dd507e0cfd6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-11f1683aa15e1a62.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-d60761c20382b259.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources-aed94957009eb3fd.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-127c114dd8f102ed.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore/[monitorId]-5aa7a9fa96160de8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]/[systemId]-899bf30dde8b3292.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-823d0dd77e66585b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datamap-3b100c44ea9e3988.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-3d1e48f4b95d7f6b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset-d3c6ecf7f29bea6e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-0a4aa42be2da0255.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-14313e441a13192c.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-f139d1ce26404f30.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-b2d3d28b10a758e6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/new-privacy-requests-df0c95e408c54c7e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates-a14c876b49422597.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-cdd3754289a28317.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-6e4c535b6d614596.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-632b3ee563d070f2.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-5b6807dced8d03c5.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-7dce52bfc1b2652c.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-b72d36243a0a545c.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-56a5434969cbe9ba.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/webpack-c2c11809187b9f84.js +0 -1
- fides/ui-build/static/admin/_next/static/css/d41a048a166d50e4.css +0 -1
- fides/ui-build/static/admin/_next/static/css/d78390d6134d8328.css +0 -1
- fides/ui-build/static/admin/_next/static/wCNFtmYQhEDMaMPeBB4BM/_buildManifest.js +0 -1
- {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.74.0rc1.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.74.0rc1.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.74.0rc1.dist-info}/licenses/LICENSE +0 -0
- {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.74.0rc1.dist-info}/top_level.txt +0 -0
- /fides/ui-build/static/admin/_next/static/{wCNFtmYQhEDMaMPeBB4BM → FZTEUgamBvOhgPWce135w}/_ssgManifest.js +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{2040-7eed8491ca7276ed.js → 2040-fe1a06d82c0413f1.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{2397-083fc511acb6105d.js → 2397-40b8db1cb2f23e2a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{2921-34a43f2f8f5e5e69.js → 2921-b10bbc3a9104933b.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3696-6f90e41a53d22920.js → 3696-6db05a35ae806825.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3923-f0a85dc5c3684fa0.js → 3923-44255a63d6d80ff5.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{401-7c345d019bb9bcbd.js → 401-fe8db8b5d8f600de.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{4496-4ff19366c597ec16.js → 4496-bed72bd5639075be.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{4817-1f3e6ea38625d8d5.js → 4817-d29f40d4ce729f37.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{5185-e7f8b81dd3dfbe0b.js → 5185-b2ac9fecc00b67e7.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{5258-62d6bc19add60aa6.js → 5258-4672eae0656430f9.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{5783-21775c232dce7af7.js → 5783-6055edba275155ca.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6853-de9905d28e5b19b3.js → 6853-1adbdf6418ec3d62.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{7059-2bb7c38578549703.js → 7059-12be23a345a94c1e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{7476-a02d970ea4d3f7d0.js → 7476-a43c046c24de37cc.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{7630-a11610c2b31ab2ca.js → 7630-c654c61ba98d8c74.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{796-e36d610066135f8c.js → 796-e83ace3c6ab99ac7.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{8212-393420e5a9751791.js → 8212-b9e8295ca883c9f8.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9330-f753636a31c4ea04.js → 9330-e519adec48222d45.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9826-a737a9956c1d0905.js → 9826-657652d55936a8c6.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{404-eb019192ce498f32.js → 404-d079b8bf35250874.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-a188f84239f4b2a8.js → multiple-b4d18c1f4d414f5f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{add-systems-ee9df33ebd471099.js → add-systems-d451bc8932330141.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-4f9cf087fcee87e6.js → add-vendors-c24663cd5dec57db.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-9af75caefc74eaca.js → configure-d93418688bd258eb.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-b08abefec298ccf1.js → privacy-experience-d9b7b311195df29e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-notices-6528eb24165aceb6.js → privacy-notices-cdfc9bb19f47c709.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-5cba30eba1e97e56.js → properties-0b995b01dc4dbd1f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{consent-614af0a2c2ba966c.js → consent-b37ed76849330edd.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{index-1343fa525a206571.js → index-692d27dbe9392c9f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/{[id]-63b3be660fb12c0f.js → [id]-caaa8602a1d449b1.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/{new-d3b577962dd33266.js → new-9b106b1d2d93985b.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/notifications/{digests-aed9afd988a48acf.js → digests-6a1ded8cdde836c4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/notifications/{providers-36a0ac36062abd02.js → providers-a03cbd698a23e5b3.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/{[id]-8063dceb32310c85.js → [id]-3cde574b3c8447c0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/{add-template-4931c70bee62232f.js → add-template-0448bb4ae8536c58.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{notifications-93af719dab3bd053.js → notifications-4ea28f6b1dd63642.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{AntForm-e715cc654fb6a5cd.js → AntForm-fec08bea801b4918.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikAntFormItem-72ae299bcb6adae6.js → FormikAntFormItem-d911e5fbf5a4a888.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikControlled-2337f8c81a766eb0.js → FormikControlled-91b1adcac6a57b2d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikField-0af454f55494f6fa.js → FormikField-de309d8813b1ebfb.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{forms-d1b90ffa996fbd89.js → forms-f2943c1309062284.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{table-migration-19724b9e0581b96d.js → table-migration-03eda417711ae909.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{storage-cc41ae605f2b55ae.js → storage-ea6f78fa8b2d3f6c.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-fa82cffba448ccd8.js → configure-bda7b474493e7128.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-bc1c289647e52c48.js → [id]-30d298a47e85709f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-cbfaa23d96f5ed0b.js → add-property-438084cca0d0f10d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{properties-a15a3fd0ed88f39c.js → properties-17fd44d98f5bd5b6.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/sandbox/{privacy-notices-afe921f6e2a526fb.js → privacy-notices-8c80391025ca7339.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/{[purpose_id]-19de0024418a4924.js → [purpose_id]-7c19810858b708cc.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-3b87002753b23ca5.js → domain-records-e334b43fa5c5b1e6.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-aacd9d0ad47082d4.js → domains-9d18eb5c38d85522.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-3cdd0b39901190ba.js → email-templates-cb937ed7c4b1e5a8.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-61076eedbfd137b9.js → locations-835281251f0785cd.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-b07b11d6002f8c8c.js → organization-7fd050c92866938c.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{privacy-requests-084a2b4431d35322.js → privacy-requests-59ea66130fca0d05.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-b7c0d3b1b754e70f.js → regulations-b0fe1051d908f366.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-5d5a68e555d18693.js → [id]-aed30fb22ae7c9ec.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-e6a211d8a0401086.js → user-management-6b88ca3e02ee67c9.js} +0 -0
fides/_version.py
CHANGED
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2025-
|
|
11
|
+
"date": "2025-11-05T17:23:50-0600",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.
|
|
14
|
+
"full-revisionid": "dd2f04e2b4b8386e585ebaf9cd935173dc333b11",
|
|
15
|
+
"version": "2.74.0rc1"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
fides/api/alembic/migrations/versions/xx_2025_10_29_1659_80d28dea3b6b_added_duplicate_group_table.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""added duplicate group table
|
|
2
|
+
|
|
3
|
+
Revision ID: 80d28dea3b6b
|
|
4
|
+
Revises: c09e76282dd1
|
|
5
|
+
Create Date: 2025-10-29 16:59:09.551676
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
from alembic import op
|
|
11
|
+
from sqlalchemy.dialects import postgresql
|
|
12
|
+
|
|
13
|
+
# revision identifiers, used by Alembic.
|
|
14
|
+
revision = "80d28dea3b6b"
|
|
15
|
+
down_revision = "c09e76282dd1"
|
|
16
|
+
branch_labels = None
|
|
17
|
+
depends_on = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def upgrade():
|
|
21
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
22
|
+
op.create_table(
|
|
23
|
+
"duplicate_group",
|
|
24
|
+
sa.Column(
|
|
25
|
+
"created_at",
|
|
26
|
+
sa.DateTime(timezone=True),
|
|
27
|
+
server_default=sa.text("now()"),
|
|
28
|
+
nullable=True,
|
|
29
|
+
),
|
|
30
|
+
sa.Column(
|
|
31
|
+
"updated_at",
|
|
32
|
+
sa.DateTime(timezone=True),
|
|
33
|
+
server_default=sa.text("now()"),
|
|
34
|
+
nullable=True,
|
|
35
|
+
),
|
|
36
|
+
sa.Column("id", postgresql.UUID(as_uuid=True), nullable=False),
|
|
37
|
+
sa.Column("rule_version", sa.Text(), nullable=False),
|
|
38
|
+
sa.Column("is_active", sa.Boolean(), server_default="t", nullable=False),
|
|
39
|
+
sa.Column("dedup_key", sa.Text(), nullable=False),
|
|
40
|
+
sa.PrimaryKeyConstraint("id"),
|
|
41
|
+
)
|
|
42
|
+
op.drop_index(
|
|
43
|
+
"ix_privacyrequest_duplicate_request_group_id", table_name="privacyrequest"
|
|
44
|
+
)
|
|
45
|
+
op.drop_column("privacyrequest", "duplicate_request_group_id")
|
|
46
|
+
op.add_column(
|
|
47
|
+
"privacyrequest",
|
|
48
|
+
sa.Column(
|
|
49
|
+
"duplicate_request_group_id", postgresql.UUID(as_uuid=True), nullable=True
|
|
50
|
+
),
|
|
51
|
+
)
|
|
52
|
+
op.create_foreign_key(
|
|
53
|
+
"fk_privacyrequest_duplicate_group",
|
|
54
|
+
"privacyrequest",
|
|
55
|
+
"duplicate_group",
|
|
56
|
+
["duplicate_request_group_id"],
|
|
57
|
+
["id"],
|
|
58
|
+
)
|
|
59
|
+
# ### end Alembic commands ###
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def downgrade():
|
|
63
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
64
|
+
op.drop_constraint(
|
|
65
|
+
"fk_privacyrequest_duplicate_group", "privacyrequest", type_="foreignkey"
|
|
66
|
+
)
|
|
67
|
+
op.drop_column("privacyrequest", "duplicate_request_group_id")
|
|
68
|
+
op.add_column(
|
|
69
|
+
"privacyrequest",
|
|
70
|
+
sa.Column("duplicate_request_group_id", sa.String(), nullable=True),
|
|
71
|
+
)
|
|
72
|
+
op.create_index(
|
|
73
|
+
"ix_privacyrequest_duplicate_request_group_id",
|
|
74
|
+
"privacyrequest",
|
|
75
|
+
["duplicate_request_group_id"],
|
|
76
|
+
unique=False,
|
|
77
|
+
)
|
|
78
|
+
op.drop_table("duplicate_group")
|
|
79
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""Create staged resource error table
|
|
2
|
+
|
|
3
|
+
Revision ID: f1a2b3c4d5e6
|
|
4
|
+
Revises: 80d28dea3b6b
|
|
5
|
+
Create Date: 2025-11-05 02:00:00.000000
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
from alembic import op
|
|
11
|
+
|
|
12
|
+
# revision identifiers, used by Alembic.
|
|
13
|
+
revision = "f1a2b3c4d5e6"
|
|
14
|
+
down_revision = "80d28dea3b6b"
|
|
15
|
+
branch_labels = None
|
|
16
|
+
depends_on = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def upgrade():
|
|
20
|
+
# Create the stagedresourceerror table
|
|
21
|
+
op.create_table(
|
|
22
|
+
"stagedresourceerror",
|
|
23
|
+
sa.Column("id", sa.String(), nullable=False),
|
|
24
|
+
sa.Column(
|
|
25
|
+
"created_at",
|
|
26
|
+
sa.DateTime(timezone=True),
|
|
27
|
+
server_default=sa.text("now()"),
|
|
28
|
+
nullable=True,
|
|
29
|
+
),
|
|
30
|
+
sa.Column(
|
|
31
|
+
"updated_at",
|
|
32
|
+
sa.DateTime(timezone=True),
|
|
33
|
+
server_default=sa.text("now()"),
|
|
34
|
+
nullable=True,
|
|
35
|
+
),
|
|
36
|
+
sa.Column(
|
|
37
|
+
"staged_resource_urn",
|
|
38
|
+
sa.String(),
|
|
39
|
+
nullable=False,
|
|
40
|
+
),
|
|
41
|
+
sa.Column("message", sa.String(), nullable=False),
|
|
42
|
+
sa.Column("timestamp", sa.DateTime(timezone=True), nullable=False),
|
|
43
|
+
sa.Column("error_type", sa.String(), nullable=False),
|
|
44
|
+
sa.Column("diff_status", sa.String(), nullable=False),
|
|
45
|
+
sa.Column("task_id", sa.String(), nullable=True),
|
|
46
|
+
sa.ForeignKeyConstraint(
|
|
47
|
+
["staged_resource_urn"],
|
|
48
|
+
["stagedresource.urn"],
|
|
49
|
+
name="stagedresourceerror_staged_resource_urn_fkey",
|
|
50
|
+
ondelete="CASCADE",
|
|
51
|
+
),
|
|
52
|
+
sa.PrimaryKeyConstraint("id"),
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
op.create_index(
|
|
56
|
+
"ix_stagedresourceerror_staged_resource_urn",
|
|
57
|
+
"stagedresourceerror",
|
|
58
|
+
["staged_resource_urn"],
|
|
59
|
+
unique=False,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
op.create_index(
|
|
63
|
+
"ix_stagedresourceerror_task_id",
|
|
64
|
+
"stagedresourceerror",
|
|
65
|
+
["task_id"],
|
|
66
|
+
unique=False,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def downgrade():
|
|
71
|
+
# Drop the indices
|
|
72
|
+
op.drop_index(
|
|
73
|
+
"ix_stagedresourceerror_task_id",
|
|
74
|
+
table_name="stagedresourceerror",
|
|
75
|
+
)
|
|
76
|
+
op.drop_index(
|
|
77
|
+
"ix_stagedresourceerror_staged_resource_urn",
|
|
78
|
+
table_name="stagedresourceerror",
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Drop the stagedresourceerror table
|
|
82
|
+
op.drop_table("stagedresourceerror")
|
|
@@ -91,6 +91,7 @@ from fides.api.schemas.privacy_request import (
|
|
|
91
91
|
BulkPostPrivacyRequests,
|
|
92
92
|
BulkReviewResponse,
|
|
93
93
|
BulkSoftDeletePrivacyRequests,
|
|
94
|
+
CancelPrivacyRequests,
|
|
94
95
|
CheckpointActionRequired,
|
|
95
96
|
DenyPrivacyRequests,
|
|
96
97
|
ExecutionLogDetailResponse,
|
|
@@ -147,6 +148,7 @@ from fides.common.api.v1.urn_registry import (
|
|
|
147
148
|
PRIVACY_REQUEST_BULK_FINALIZE,
|
|
148
149
|
PRIVACY_REQUEST_BULK_RETRY,
|
|
149
150
|
PRIVACY_REQUEST_BULK_SOFT_DELETE,
|
|
151
|
+
PRIVACY_REQUEST_CANCEL,
|
|
150
152
|
PRIVACY_REQUEST_DENY,
|
|
151
153
|
PRIVACY_REQUEST_FILTERED_RESULTS,
|
|
152
154
|
PRIVACY_REQUEST_FINALIZE,
|
|
@@ -486,7 +488,7 @@ def _filter_privacy_request_queryset(
|
|
|
486
488
|
errored_gt: Optional[datetime] = None,
|
|
487
489
|
external_id: Optional[str] = None,
|
|
488
490
|
location: Optional[str] = None,
|
|
489
|
-
action_type: Optional[ActionType] = None,
|
|
491
|
+
action_type: Optional[Union[ActionType, List[ActionType]]] = None,
|
|
490
492
|
include_consent_webhook_requests: Optional[bool] = False,
|
|
491
493
|
include_deleted_requests: Optional[bool] = False,
|
|
492
494
|
) -> Query:
|
|
@@ -676,9 +678,11 @@ def _filter_privacy_request_queryset(
|
|
|
676
678
|
PrivacyRequest.finished_processing_at > errored_gt,
|
|
677
679
|
)
|
|
678
680
|
if action_type:
|
|
681
|
+
if isinstance(action_type, ActionType):
|
|
682
|
+
action_type = [action_type]
|
|
679
683
|
policy_ids_for_action_type = (
|
|
680
684
|
db.query(Rule)
|
|
681
|
-
.filter(Rule.action_type
|
|
685
|
+
.filter(Rule.action_type.in_(action_type))
|
|
682
686
|
.with_entities(Rule.policy_id)
|
|
683
687
|
.distinct()
|
|
684
688
|
)
|
|
@@ -792,7 +796,7 @@ def _shared_privacy_request_search(
|
|
|
792
796
|
errored_gt: Optional[datetime] = None,
|
|
793
797
|
external_id: Optional[str] = None,
|
|
794
798
|
location: Optional[str] = None,
|
|
795
|
-
action_type: Optional[ActionType] = None,
|
|
799
|
+
action_type: Optional[Union[ActionType, List[ActionType]]] = None,
|
|
796
800
|
verbose: Optional[bool] = False,
|
|
797
801
|
include_identities: Optional[bool] = False,
|
|
798
802
|
include_custom_privacy_request_fields: Optional[bool] = False,
|
|
@@ -1357,10 +1361,10 @@ def restart_privacy_request_from_failure(
|
|
|
1357
1361
|
)
|
|
1358
1362
|
|
|
1359
1363
|
# Automatically resubmit the request if the cache has expired
|
|
1364
|
+
|
|
1360
1365
|
if (
|
|
1361
|
-
not privacy_request.
|
|
1362
|
-
and privacy_request.status
|
|
1363
|
-
not in [PrivacyRequestStatus.complete, PrivacyRequestStatus.pending]
|
|
1366
|
+
not privacy_request.verify_cache_for_identity_data()
|
|
1367
|
+
and privacy_request.status != PrivacyRequestStatus.complete
|
|
1364
1368
|
):
|
|
1365
1369
|
logger.info(
|
|
1366
1370
|
f"Cached data for privacy request {privacy_request.id} has expired, automatically resubmitting request"
|
|
@@ -1477,6 +1481,29 @@ def deny_privacy_request(
|
|
|
1477
1481
|
)
|
|
1478
1482
|
|
|
1479
1483
|
|
|
1484
|
+
@router.patch(
|
|
1485
|
+
PRIVACY_REQUEST_CANCEL,
|
|
1486
|
+
status_code=HTTP_200_OK,
|
|
1487
|
+
response_model=BulkReviewResponse,
|
|
1488
|
+
)
|
|
1489
|
+
def cancel_privacy_request(
|
|
1490
|
+
*,
|
|
1491
|
+
client: ClientDetail = Security(
|
|
1492
|
+
verify_oauth_client,
|
|
1493
|
+
scopes=[PRIVACY_REQUEST_REVIEW],
|
|
1494
|
+
),
|
|
1495
|
+
privacy_request_service: PrivacyRequestService = Depends(
|
|
1496
|
+
get_privacy_request_service
|
|
1497
|
+
),
|
|
1498
|
+
privacy_requests: CancelPrivacyRequests,
|
|
1499
|
+
) -> BulkReviewResponse:
|
|
1500
|
+
"""Cancel a list of privacy requests and/or report failure"""
|
|
1501
|
+
|
|
1502
|
+
return privacy_request_service.cancel_privacy_requests(
|
|
1503
|
+
privacy_requests.request_ids, privacy_requests.reason, user_id=client.user_id
|
|
1504
|
+
)
|
|
1505
|
+
|
|
1506
|
+
|
|
1480
1507
|
def _validate_privacy_request_pending_or_error(
|
|
1481
1508
|
db: Session, privacy_request_id: str
|
|
1482
1509
|
) -> None:
|
fides/api/db/database.py
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
Contains all of the logic related to the database including connections, setup, teardown, etc.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
import os
|
|
6
|
+
import subprocess
|
|
5
7
|
from os import path
|
|
8
|
+
from pathlib import Path
|
|
6
9
|
from typing import Literal, Optional, Tuple
|
|
7
10
|
|
|
8
11
|
from alembic import command, script
|
|
@@ -191,3 +194,225 @@ def check_missing_migrations(database_url: str) -> None:
|
|
|
191
194
|
log.error(f" - {item}")
|
|
192
195
|
raise SystemExit("Migration needs to be generated!")
|
|
193
196
|
print("No migrations need to be generated.")
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _get_base_branch_for_comparison() -> str:
|
|
200
|
+
"""
|
|
201
|
+
Determine the base branch to compare against for detecting new migrations.
|
|
202
|
+
|
|
203
|
+
In GitHub Actions PRs, uses GITHUB_BASE_REF (the PR target branch).
|
|
204
|
+
Otherwise, falls back to origin/main for local development.
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
The base branch reference (e.g., 'origin/main', 'origin/develop')
|
|
208
|
+
"""
|
|
209
|
+
base_ref = os.environ.get("GITHUB_BASE_REF")
|
|
210
|
+
if base_ref:
|
|
211
|
+
base_branch = f"origin/{base_ref}"
|
|
212
|
+
log.info(f"Comparing against PR target branch: {base_branch}")
|
|
213
|
+
else:
|
|
214
|
+
base_branch = "origin/main"
|
|
215
|
+
log.info(f"No GITHUB_BASE_REF found, comparing against: {base_branch}")
|
|
216
|
+
return base_branch
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def _get_new_migration_files(repo_root: str, base_branch: str) -> list[str]:
|
|
220
|
+
"""
|
|
221
|
+
Get list of new migration files added in the current branch.
|
|
222
|
+
|
|
223
|
+
Files are sorted by the timestamp in their filename to ensure chronological order.
|
|
224
|
+
Migration files follow the pattern: xx_YYYY_MM_DD_HHMM_revision_description.py
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
repo_root: Absolute path to the git repository root
|
|
228
|
+
base_branch: The base branch to compare against
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
List of relative file paths to new migration files, sorted chronologically
|
|
232
|
+
|
|
233
|
+
Raises:
|
|
234
|
+
SystemExit: If the migrations directory does not exist
|
|
235
|
+
"""
|
|
236
|
+
# Validate that the migrations directory exists
|
|
237
|
+
migrations_dir = (
|
|
238
|
+
Path(repo_root)
|
|
239
|
+
/ "src"
|
|
240
|
+
/ "fides"
|
|
241
|
+
/ "api"
|
|
242
|
+
/ "alembic"
|
|
243
|
+
/ "migrations"
|
|
244
|
+
/ "versions"
|
|
245
|
+
)
|
|
246
|
+
if not migrations_dir.exists():
|
|
247
|
+
log.error(f"Migrations directory not found: {migrations_dir}")
|
|
248
|
+
raise SystemExit(
|
|
249
|
+
f"Migration directory not found at expected path: {migrations_dir}\n"
|
|
250
|
+
"If the migrations directory has been moved, update the path in "
|
|
251
|
+
"fides.api.db.database._get_new_migration_files()"
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
migration_pattern = "src/fides/api/alembic/migrations/versions/*.py"
|
|
255
|
+
diff_output = subprocess.check_output(
|
|
256
|
+
[
|
|
257
|
+
"git",
|
|
258
|
+
"diff",
|
|
259
|
+
"--name-only",
|
|
260
|
+
"--diff-filter=A", # Only added files
|
|
261
|
+
f"{base_branch}...HEAD",
|
|
262
|
+
"--",
|
|
263
|
+
migration_pattern,
|
|
264
|
+
],
|
|
265
|
+
stderr=subprocess.STDOUT,
|
|
266
|
+
text=True,
|
|
267
|
+
cwd=repo_root,
|
|
268
|
+
).strip()
|
|
269
|
+
|
|
270
|
+
if not diff_output:
|
|
271
|
+
return []
|
|
272
|
+
|
|
273
|
+
migration_files = [f for f in diff_output.split("\n") if f]
|
|
274
|
+
|
|
275
|
+
# Sort by filename to ensure chronological order
|
|
276
|
+
# Files are named: xx_YYYY_MM_DD_HHMM_revision_description.py
|
|
277
|
+
# Sorting alphabetically will sort them chronologically due to the date format
|
|
278
|
+
migration_files.sort()
|
|
279
|
+
|
|
280
|
+
return migration_files
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def _parse_migration_revisions(migration_path: Path) -> tuple[str, Optional[str]]:
|
|
284
|
+
"""
|
|
285
|
+
Extract revision and down_revision IDs from a migration file.
|
|
286
|
+
|
|
287
|
+
Args:
|
|
288
|
+
migration_path: Path to the migration file
|
|
289
|
+
|
|
290
|
+
Returns:
|
|
291
|
+
Tuple of (revision, down_revision). down_revision may be None.
|
|
292
|
+
|
|
293
|
+
Raises:
|
|
294
|
+
SystemExit: If revision ID cannot be found in the file
|
|
295
|
+
"""
|
|
296
|
+
revision = None
|
|
297
|
+
down_revision = None
|
|
298
|
+
|
|
299
|
+
with open(migration_path, "r", encoding="utf-8") as f:
|
|
300
|
+
for line in f:
|
|
301
|
+
if line.strip().startswith("revision ="):
|
|
302
|
+
revision = line.split("=")[1].strip().strip("\"'")
|
|
303
|
+
elif line.strip().startswith("down_revision ="):
|
|
304
|
+
down_rev_value = line.split("=")[1].strip().strip("\"'")
|
|
305
|
+
if down_rev_value.lower() != "none":
|
|
306
|
+
down_revision = down_rev_value
|
|
307
|
+
|
|
308
|
+
if not revision:
|
|
309
|
+
log.error(f"Could not find revision ID in {migration_path}")
|
|
310
|
+
raise SystemExit(f"Invalid migration file: {migration_path}")
|
|
311
|
+
|
|
312
|
+
return revision, down_revision
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def _test_migrations_upgrade_downgrade_sequence(
|
|
316
|
+
alembic_config: Config,
|
|
317
|
+
migrations: list[tuple[str, str, Optional[str]]],
|
|
318
|
+
) -> None:
|
|
319
|
+
"""
|
|
320
|
+
Test multiple migrations can be upgraded and downgraded successfully in sequence.
|
|
321
|
+
|
|
322
|
+
Tests all new migrations together by:
|
|
323
|
+
1. Downgrading incrementally through all migrations (newest to oldest)
|
|
324
|
+
2. Upgrading incrementally back through all migrations (oldest to newest)
|
|
325
|
+
|
|
326
|
+
After Phase 2, the database is at the newest migration revision, which should
|
|
327
|
+
match HEAD for the new migrations being tested.
|
|
328
|
+
|
|
329
|
+
This approach tests migrations in a realistic sequence and can catch
|
|
330
|
+
interaction issues between migrations.
|
|
331
|
+
|
|
332
|
+
Args:
|
|
333
|
+
alembic_config: Alembic configuration
|
|
334
|
+
migrations: List of (migration_name, revision, down_revision) tuples
|
|
335
|
+
|
|
336
|
+
Raises:
|
|
337
|
+
SystemExit: If any migration upgrade/downgrade test fails
|
|
338
|
+
"""
|
|
339
|
+
if not migrations:
|
|
340
|
+
return
|
|
341
|
+
|
|
342
|
+
log.info(f"Testing {len(migrations)} migration(s) in sequence")
|
|
343
|
+
|
|
344
|
+
try:
|
|
345
|
+
# Phase 1: Downgrade through all migrations (newest to oldest)
|
|
346
|
+
log.info("Phase 1: Downgrading through all new migrations...")
|
|
347
|
+
for migration_name, revision, down_revision in reversed(migrations):
|
|
348
|
+
if down_revision:
|
|
349
|
+
log.info(f" Downgrading {migration_name} to {down_revision}...")
|
|
350
|
+
downgrade_db(alembic_config, down_revision)
|
|
351
|
+
else:
|
|
352
|
+
log.info(f" Skipping {migration_name} (no down_revision)")
|
|
353
|
+
|
|
354
|
+
# Phase 2: Upgrade back through all migrations (oldest to newest)
|
|
355
|
+
log.info("Phase 2: Upgrading back through all new migrations...")
|
|
356
|
+
for migration_name, revision, down_revision in migrations:
|
|
357
|
+
log.info(f" Upgrading {migration_name} to {revision}...")
|
|
358
|
+
upgrade_db(alembic_config, revision)
|
|
359
|
+
|
|
360
|
+
log.info(f"✓ All {len(migrations)} migration(s) passed upgrade/downgrade test")
|
|
361
|
+
|
|
362
|
+
except Exception as error:
|
|
363
|
+
log.error("Migration upgrade/downgrade sequence test failed!")
|
|
364
|
+
log.error(str(error))
|
|
365
|
+
raise SystemExit("Migration upgrade/downgrade test failed")
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def check_new_migrations_upgrade_downgrade(database_url: str) -> None:
|
|
369
|
+
"""
|
|
370
|
+
Detects new migrations added in the current branch and tests that they
|
|
371
|
+
can be successfully upgraded and downgraded.
|
|
372
|
+
|
|
373
|
+
Uses git to compare against the target/base branch to find new migration files.
|
|
374
|
+
In CI, uses GITHUB_BASE_REF if available, otherwise falls back to origin/main.
|
|
375
|
+
"""
|
|
376
|
+
try:
|
|
377
|
+
# Get the repo root directory
|
|
378
|
+
repo_root = subprocess.check_output(
|
|
379
|
+
["git", "rev-parse", "--show-toplevel"],
|
|
380
|
+
stderr=subprocess.STDOUT,
|
|
381
|
+
text=True,
|
|
382
|
+
).strip()
|
|
383
|
+
|
|
384
|
+
# Determine base branch and get new migration files
|
|
385
|
+
base_branch = _get_base_branch_for_comparison()
|
|
386
|
+
migration_files = _get_new_migration_files(repo_root, base_branch)
|
|
387
|
+
|
|
388
|
+
if not migration_files:
|
|
389
|
+
log.info("No new migration files detected in current branch")
|
|
390
|
+
print("No new migrations to test.")
|
|
391
|
+
return
|
|
392
|
+
|
|
393
|
+
log.info(f"Detected {len(migration_files)} new migration(s) to test")
|
|
394
|
+
|
|
395
|
+
# Log the migrations in order
|
|
396
|
+
for i, file_path in enumerate(migration_files, 1):
|
|
397
|
+
log.info(f" {i}. {Path(file_path).name}")
|
|
398
|
+
|
|
399
|
+
alembic_config = get_alembic_config(database_url)
|
|
400
|
+
|
|
401
|
+
# Parse all migrations first
|
|
402
|
+
migrations = []
|
|
403
|
+
for file_path in migration_files:
|
|
404
|
+
abs_path = Path(repo_root) / file_path
|
|
405
|
+
revision, down_revision = _parse_migration_revisions(abs_path)
|
|
406
|
+
migrations.append((abs_path.name, revision, down_revision))
|
|
407
|
+
|
|
408
|
+
# Test all migrations in sequence
|
|
409
|
+
_test_migrations_upgrade_downgrade_sequence(alembic_config, migrations)
|
|
410
|
+
|
|
411
|
+
print(
|
|
412
|
+
f"All {len(migration_files)} new migration(s) passed upgrade/downgrade tests."
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
except subprocess.CalledProcessError as error:
|
|
416
|
+
# Git command failed - might not be in a git repo or no origin/main
|
|
417
|
+
log.warning(f"Could not detect new migrations via git: {error}")
|
|
418
|
+
print("Skipping migration upgrade/downgrade check (git detection failed).")
|
|
@@ -17,6 +17,7 @@ from .monitor_task import (
|
|
|
17
17
|
create_monitor_task_with_execution_log,
|
|
18
18
|
update_monitor_task_with_execution_log,
|
|
19
19
|
)
|
|
20
|
+
from .staged_resource_error import StagedResourceError
|
|
20
21
|
|
|
21
22
|
__all__ = [
|
|
22
23
|
"ClassificationBenchmark",
|
|
@@ -27,6 +28,7 @@ __all__ = [
|
|
|
27
28
|
"SharedMonitorConfig",
|
|
28
29
|
"StagedResource",
|
|
29
30
|
"StagedResourceAncestor",
|
|
31
|
+
"StagedResourceError",
|
|
30
32
|
"fetch_staged_resources_by_type_query",
|
|
31
33
|
"MonitorTask",
|
|
32
34
|
"MonitorTaskExecutionLog",
|
|
@@ -29,6 +29,9 @@ from sqlalchemy.orm.query import Query
|
|
|
29
29
|
|
|
30
30
|
from fides.api.db.base_class import Base, FidesBase
|
|
31
31
|
from fides.api.models.connectionconfig import ConnectionConfig
|
|
32
|
+
from fides.api.models.detection_discovery.staged_resource_error import (
|
|
33
|
+
StagedResourceError,
|
|
34
|
+
)
|
|
32
35
|
from fides.api.models.sql_models import System # type: ignore[attr-defined]
|
|
33
36
|
|
|
34
37
|
|
|
@@ -573,6 +576,13 @@ class StagedResource(Base):
|
|
|
573
576
|
# diff-related fields
|
|
574
577
|
diff_status = Column(String, nullable=True, index=True)
|
|
575
578
|
|
|
579
|
+
errors: RelationshipProperty[List[StagedResourceError]] = relationship(
|
|
580
|
+
"StagedResourceError",
|
|
581
|
+
foreign_keys=[StagedResourceError.staged_resource_urn],
|
|
582
|
+
primaryjoin="StagedResource.urn == StagedResourceError.staged_resource_urn",
|
|
583
|
+
cascade="all, delete-orphan",
|
|
584
|
+
)
|
|
585
|
+
|
|
576
586
|
ancestor_links: RelationshipProperty[List[StagedResourceAncestor]] = relationship(
|
|
577
587
|
"StagedResourceAncestor",
|
|
578
588
|
back_populates="descendant_staged_resource",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Module for staged resource error tracking."""
|
|
2
|
+
|
|
3
|
+
from sqlalchemy import Column, DateTime, ForeignKey, String
|
|
4
|
+
|
|
5
|
+
from fides.api.db.base_class import Base, FidesBase
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class StagedResourceError(Base):
|
|
9
|
+
"""
|
|
10
|
+
DB model for tracking errors associated with staged resources.
|
|
11
|
+
Linked to StagedResource via FK with cascade delete.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
id = Column(String(255), primary_key=True, default=FidesBase.generate_uuid)
|
|
15
|
+
staged_resource_urn = Column(
|
|
16
|
+
String,
|
|
17
|
+
ForeignKey("stagedresource.urn", ondelete="CASCADE"),
|
|
18
|
+
nullable=False,
|
|
19
|
+
index=True,
|
|
20
|
+
)
|
|
21
|
+
message = Column(String, nullable=False)
|
|
22
|
+
timestamp = Column(DateTime(timezone=True), nullable=False)
|
|
23
|
+
error_type = Column(String, nullable=False)
|
|
24
|
+
diff_status = Column(String, nullable=False) # Phase where error occurred
|
|
25
|
+
task_id = Column(String, nullable=True, index=True)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
import json
|
|
3
|
+
import uuid
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
5
|
+
|
|
6
|
+
from sqlalchemy import Boolean, Column, Text
|
|
7
|
+
from sqlalchemy.dialects.postgresql import UUID
|
|
8
|
+
from sqlalchemy.ext.declarative import declared_attr
|
|
9
|
+
from sqlalchemy.orm import Session, relationship
|
|
10
|
+
|
|
11
|
+
from fides.api.db.base_class import Base # type: ignore[attr-defined]
|
|
12
|
+
from fides.config.duplicate_detection_settings import DuplicateDetectionSettings
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from fides.api.models.privacy_request.privacy_request import PrivacyRequest
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def generate_deterministic_uuid(rule_version: str, dedup_key: str) -> uuid.UUID:
|
|
19
|
+
"""Overrides the base class method to generate a deterministic group id.
|
|
20
|
+
|
|
21
|
+
The actual rule version is a hash of the duplicate detection settings config,
|
|
22
|
+
using simple examples here for illustration:
|
|
23
|
+
- under rule "email", duplicate@example.com → group A,
|
|
24
|
+
- under rule "email|phone", duplicate@example.com|1234567890 → group B.
|
|
25
|
+
- ... and so on.
|
|
26
|
+
|
|
27
|
+
No collisions, no overlap.
|
|
28
|
+
"""
|
|
29
|
+
# Combine the rule version and the key into a stable hash
|
|
30
|
+
hash_input = f"{rule_version}:{dedup_key}".encode("utf-8")
|
|
31
|
+
return uuid.UUID(hashlib.md5(hash_input).hexdigest())
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def generate_rule_version(config: DuplicateDetectionSettings) -> str:
|
|
35
|
+
"""Generate a stable short hash for the dedup rule config."""
|
|
36
|
+
normalized = json.dumps(config.model_dump(), sort_keys=True)
|
|
37
|
+
return hashlib.sha256(normalized.encode("utf-8")).hexdigest()[:8]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class DuplicateGroup(Base):
|
|
41
|
+
"""
|
|
42
|
+
A table for storing duplicate request group information.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
@declared_attr
|
|
46
|
+
def __tablename__(self) -> str:
|
|
47
|
+
return "duplicate_group"
|
|
48
|
+
|
|
49
|
+
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
50
|
+
rule_version = Column(Text, nullable=False)
|
|
51
|
+
# TODO: The is_active column is not used yet since we are defaulting to just email for
|
|
52
|
+
# duplicate detection. When we allow users to configure the duplicate detection settings,
|
|
53
|
+
# we will need to add a way to activate/deactivate duplicate groups.
|
|
54
|
+
# This should be done by getting the previous rule version and deactivating all groups with
|
|
55
|
+
# that rule version. New groups will be created with the new rule version.
|
|
56
|
+
is_active = Column(Boolean, default=True, nullable=False)
|
|
57
|
+
dedup_key = Column(Text, nullable=False)
|
|
58
|
+
privacy_requests = relationship(
|
|
59
|
+
"PrivacyRequest",
|
|
60
|
+
back_populates="duplicate_group",
|
|
61
|
+
lazy="dynamic",
|
|
62
|
+
primaryjoin="and_(DuplicateGroup.id == PrivacyRequest.duplicate_request_group_id)",
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
@classmethod
|
|
66
|
+
def create(
|
|
67
|
+
cls, db: Session, *, data: dict[str, Any], check_name: bool = False
|
|
68
|
+
) -> "DuplicateGroup":
|
|
69
|
+
"""Create a new duplicate group.
|
|
70
|
+
Override the base class method to generate a deterministic group id.
|
|
71
|
+
If the group already exists, update the is_active column to True and return the group.
|
|
72
|
+
"""
|
|
73
|
+
group_id = generate_deterministic_uuid(data["rule_version"], data["dedup_key"])
|
|
74
|
+
# If the group already exists, update the is_active column to True and return the group
|
|
75
|
+
duplicate_group = (
|
|
76
|
+
db.query(DuplicateGroup).filter(DuplicateGroup.id == group_id).one_or_none()
|
|
77
|
+
)
|
|
78
|
+
if duplicate_group:
|
|
79
|
+
duplicate_group.update(db, data={"is_active": True})
|
|
80
|
+
return duplicate_group
|
|
81
|
+
|
|
82
|
+
# If the group does not exist, create a new one
|
|
83
|
+
data["id"] = group_id
|
|
84
|
+
return super().create(db, data=data, check_name=check_name)
|