ethyca-fides 2.73.2b0__py2.py3-none-any.whl → 2.76.0rc2__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.
Files changed (453) hide show
  1. {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/METADATA +2 -1
  2. {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/RECORD +349 -336
  3. fides/_version.py +3 -3
  4. fides/api/alembic/migrations/versions/303287c70600_migrate_resource_type_from_enum_to_.py +99 -0
  5. fides/api/alembic/migrations/versions/795f46f656c0_migrate_field_type_from_enum_to_string.py +61 -0
  6. fides/api/alembic/migrations/versions/xx_2025_10_29_1659_80d28dea3b6b_added_duplicate_group_table.py +79 -0
  7. fides/api/alembic/migrations/versions/xx_2025_11_05_0200_f1a2b3c4d5e6_create_staged_resource_error_table.py +82 -0
  8. fides/api/alembic/migrations/versions/xx_2025_11_07_1709_56fe6fad2d89_add_notice_display_order.py +47 -0
  9. fides/api/alembic/migrations/versions/xx_2025_11_10_1200_a1b2c3d4e5f6_add_test_datastore_to_connectiontype.py +53 -0
  10. fides/api/alembic/migrations/versions/xx_2025_11_11_1317_7d82c8fc4c34_store_saas_template_datasets.py +68 -0
  11. fides/api/alembic/migrations/versions/xx_2025_11_12_1430_b2c3d4e5f6a7_add_default_identity_definitions.py +81 -0
  12. fides/api/alembic/migrations/versions/xx_2025_11_25_1854_3ff6449c099e_add_index_on_providedidentity_privacy_.py +50 -0
  13. fides/api/api/v1/api.py +2 -0
  14. fides/api/api/v1/endpoints/admin.py +39 -0
  15. fides/api/api/v1/endpoints/connector_template_endpoints.py +167 -0
  16. fides/api/api/v1/endpoints/generic_overrides.py +6 -6
  17. fides/api/api/v1/endpoints/pre_approval_webhook_endpoints.py +5 -5
  18. fides/api/api/v1/endpoints/privacy_request_endpoints.py +101 -21
  19. fides/api/api/v1/endpoints/saas_config_endpoints.py +3 -44
  20. fides/api/api/v1/endpoints/storage_endpoints.py +5 -1
  21. fides/api/api/v1/endpoints/system.py +2 -2
  22. fides/api/api/v1/endpoints/user_endpoints.py +10 -4
  23. fides/api/db/base.py +1 -0
  24. fides/api/db/database.py +228 -1
  25. fides/api/db/seed.py +1 -1
  26. fides/api/email_templates/templates/external_user_welcome.html +9 -5
  27. fides/api/migrations/post_upgrade_index_creation.py +10 -0
  28. fides/api/models/connectionconfig.py +4 -1
  29. fides/api/models/detection_discovery/__init__.py +2 -0
  30. fides/api/models/detection_discovery/core.py +10 -0
  31. fides/api/models/detection_discovery/staged_resource_error.py +25 -0
  32. fides/api/models/experience_notices.py +6 -1
  33. fides/api/models/identity_definition.py +2 -1
  34. fides/api/models/location_regulation_selections.py +22 -0
  35. fides/api/models/manual_webhook.py +17 -6
  36. fides/api/models/messaging_template.py +7 -0
  37. fides/api/models/policy.py +3 -0
  38. fides/api/models/privacy_experience.py +20 -0
  39. fides/api/models/privacy_notice.py +45 -1
  40. fides/api/models/privacy_preference.py +1 -0
  41. fides/api/models/privacy_request/duplicate_group.py +84 -0
  42. fides/api/models/privacy_request/privacy_request.py +84 -9
  43. fides/api/models/privacy_request/provided_identity.py +22 -1
  44. fides/api/models/saas_template_dataset.py +63 -0
  45. fides/api/models/sql_models.py +150 -7
  46. fides/api/models/taxonomy.py +61 -1
  47. fides/api/oauth/roles.py +2 -0
  48. fides/api/schemas/connection_configuration/connection_secrets_mssql.py +5 -0
  49. fides/api/schemas/messaging/messaging.py +1 -0
  50. fides/api/schemas/oauth.py +2 -1
  51. fides/api/schemas/privacy_request.py +38 -6
  52. fides/api/schemas/saas/connector_template.py +14 -0
  53. fides/api/service/async_dsr/strategies/async_dsr_strategy_polling.py +19 -7
  54. fides/api/service/connectors/base_erasure_email_connector.py +7 -0
  55. fides/api/service/connectors/microsoft_sql_server_connector.py +6 -1
  56. fides/api/service/connectors/saas/connector_registry_service.py +45 -1
  57. fides/api/service/messaging/message_dispatch_service.py +44 -4
  58. fides/api/service/privacy_request/dsr_package/dsr_report_builder.py +3 -3
  59. fides/api/service/privacy_request/dsr_package/templates/attachments_index.html +41 -30
  60. fides/api/service/privacy_request/dsr_package/templates/clickme.html +68 -0
  61. fides/api/service/privacy_request/dsr_package/templates/dataset_index.html +30 -27
  62. fides/api/service/privacy_request/duplication_detection.py +439 -0
  63. fides/api/service/privacy_request/email_batch_service.py +2 -1
  64. fides/api/service/privacy_request/request_runner_service.py +31 -5
  65. fides/api/service/privacy_request/request_service.py +4 -2
  66. fides/api/service/saas_request/saas_request_override_factory.py +7 -2
  67. fides/api/task/conditional_dependencies/privacy_request/__init__.py +0 -0
  68. fides/api/task/conditional_dependencies/privacy_request/convenience_fields.py +155 -0
  69. fides/api/task/conditional_dependencies/privacy_request/privacy_request_data.py +140 -0
  70. fides/api/task/conditional_dependencies/privacy_request/schemas.py +212 -0
  71. fides/api/task/conditional_dependencies/util.py +111 -0
  72. fides/api/task/execute_request_tasks.py +17 -4
  73. fides/api/task/manual/manual_task_conditional_evaluation.py +32 -27
  74. fides/api/task/manual/manual_task_graph_task.py +4 -1
  75. fides/api/task/manual/manual_task_utils.py +63 -20
  76. fides/api/tasks/__init__.py +14 -0
  77. fides/api/util/cache.py +4 -0
  78. fides/api/util/connection_util.py +2 -3
  79. fides/api/util/fuzzy_search_utils.py +7 -1
  80. fides/api/util/lock.py +13 -3
  81. fides/api/util/logger.py +58 -4
  82. fides/api/util/logger_context_utils.py +3 -1
  83. fides/api/util/memory_watchdog.py +118 -0
  84. fides/api/util/saas_config_updater.py +12 -2
  85. fides/api/worker/__init__.py +4 -0
  86. fides/common/api/scope_registry.py +6 -0
  87. fides/common/api/v1/urn_registry.py +11 -2
  88. fides/config/__init__.py +8 -2
  89. fides/config/celery_settings.py +42 -0
  90. fides/service/messaging/messaging_service.py +75 -74
  91. fides/service/privacy_request/privacy_request_service.py +151 -19
  92. fides/ui-build/static/admin/404.html +1 -1
  93. fides/ui-build/static/admin/_next/static/chunks/1099-688fa865621531cc.js +1 -0
  94. fides/ui-build/static/admin/_next/static/chunks/{1115-26393b586775ea29.js → 1115-7fd171dac1eb0e51.js} +1 -1
  95. fides/ui-build/static/admin/_next/static/chunks/1276.deb10ae2643f8463.js +1 -0
  96. fides/ui-build/static/admin/_next/static/chunks/1438-8a33b3834d6e43f3.js +1 -0
  97. fides/ui-build/static/admin/_next/static/chunks/{6148-59a59d5c5925344f.js → 1533-84e250d1f26e6d7d.js} +1 -1
  98. fides/ui-build/static/admin/_next/static/chunks/1821-c1daa160f492aacf.js +1 -0
  99. fides/ui-build/static/admin/_next/static/chunks/1840-359ee056e4cf6629.js +1 -0
  100. fides/ui-build/static/admin/_next/static/chunks/{1975.afe8cad52f904fcf.js → 1975.bef017bc80e2012c.js} +1 -1
  101. fides/ui-build/static/admin/_next/static/chunks/{2040-7eed8491ca7276ed.js → 2040-70972e15960d9afe.js} +1 -1
  102. fides/ui-build/static/admin/_next/static/chunks/2121.321b0fd3932164d4.js +1 -0
  103. fides/ui-build/static/admin/_next/static/chunks/{2397-083fc511acb6105d.js → 2397-3434603a97f3f5d6.js} +1 -1
  104. fides/ui-build/static/admin/_next/static/chunks/2921-49ed0ed897832958.js +1 -0
  105. fides/ui-build/static/admin/_next/static/chunks/3150-da5406b80d25fe6d.js +1 -0
  106. fides/ui-build/static/admin/_next/static/chunks/3214-90ce0a366b0f461a.js +1 -0
  107. fides/ui-build/static/admin/_next/static/chunks/3377-02bf9780fd383d94.js +1 -0
  108. fides/ui-build/static/admin/_next/static/chunks/3615-5e2d062d684b8fa1.js +1 -0
  109. fides/ui-build/static/admin/_next/static/chunks/3655-5e1ba5dd68b5ec48.js +1 -0
  110. fides/ui-build/static/admin/_next/static/chunks/3729-31ff8ba51491bf21.js +1 -0
  111. fides/ui-build/static/admin/_next/static/chunks/3872-cff30ca0844fe2b1.js +1 -0
  112. fides/ui-build/static/admin/_next/static/chunks/3931-8bedde156fe83564.js +1 -0
  113. fides/ui-build/static/admin/_next/static/chunks/{401-7c345d019bb9bcbd.js → 401-582d9970d89deefe.js} +1 -1
  114. fides/ui-build/static/admin/_next/static/chunks/4093-7e47408c28de5375.js +1 -0
  115. fides/ui-build/static/admin/_next/static/chunks/{4259.d1507e0db19cbed7.js → 4259.05038c9b78467244.js} +1 -1
  116. fides/ui-build/static/admin/_next/static/chunks/4322-f6aeff6880726c83.js +1 -0
  117. fides/ui-build/static/admin/_next/static/chunks/4339-04a715ab07122744.js +1 -0
  118. fides/ui-build/static/admin/_next/static/chunks/4496-ccbce2459174e0d6.js +1 -0
  119. fides/ui-build/static/admin/_next/static/chunks/454-d5c2c84f1a14e4f1.js +1 -0
  120. fides/ui-build/static/admin/_next/static/chunks/4589-c1d83c6a8dab4d30.js +1 -0
  121. fides/ui-build/static/admin/_next/static/chunks/4809-a8f4a108a42f53ed.js +1 -0
  122. fides/ui-build/static/admin/_next/static/chunks/4903-19c0bc07a956dfa8.js +1 -0
  123. fides/ui-build/static/admin/_next/static/chunks/4910-d990773601f794c1.js +1 -0
  124. fides/ui-build/static/admin/_next/static/chunks/{5185-e7f8b81dd3dfbe0b.js → 5185-96423702fba70ced.js} +1 -1
  125. fides/ui-build/static/admin/_next/static/chunks/5258-4e308cca01d59367.js +1 -0
  126. fides/ui-build/static/admin/_next/static/chunks/5487-5c3501754bf027ba.js +1 -0
  127. fides/ui-build/static/admin/_next/static/chunks/549-1bdc3e6f3264c020.js +1 -0
  128. fides/ui-build/static/admin/_next/static/chunks/5505-43b9c39491b88e08.js +1 -0
  129. fides/ui-build/static/admin/_next/static/chunks/{5783-21775c232dce7af7.js → 5783-016dfcee8e49bf61.js} +1 -1
  130. fides/ui-build/static/admin/_next/static/chunks/5826-4db99ea4e5077911.js +1 -0
  131. fides/ui-build/static/admin/_next/static/chunks/590-be447cacf12419dd.js +1 -0
  132. fides/ui-build/static/admin/_next/static/chunks/6084-91badbc6569a0efb.js +1 -0
  133. fides/ui-build/static/admin/_next/static/chunks/6344-026cb323c1d49926.js +1 -0
  134. fides/ui-build/static/admin/_next/static/chunks/6362-ba0e12f2fc4cad94.js +1 -0
  135. fides/ui-build/static/admin/_next/static/chunks/{6853-de9905d28e5b19b3.js → 6853-882889659769d7b4.js} +1 -1
  136. fides/ui-build/static/admin/_next/static/chunks/6882-bb1b469d7d7f5335.js +1 -0
  137. fides/ui-build/static/admin/_next/static/chunks/6954-0dcf22a9aabe39c5.js +1 -0
  138. fides/ui-build/static/admin/_next/static/chunks/7170-46db82bb5b55e856.js +1 -0
  139. fides/ui-build/static/admin/_next/static/chunks/7218-2ace8c82e3e7eb74.js +1 -0
  140. fides/ui-build/static/admin/_next/static/chunks/{7245-c9bc628d078c2170.js → 7245-1cdafb35f289861b.js} +1 -1
  141. fides/ui-build/static/admin/_next/static/chunks/7630-7f75ab7b8df42eb3.js +1 -0
  142. fides/ui-build/static/admin/_next/static/chunks/7654-2e9a8be02e41769a.js +1 -0
  143. fides/ui-build/static/admin/_next/static/chunks/{8212-393420e5a9751791.js → 8212-348ddd2b6933db70.js} +1 -1
  144. fides/ui-build/static/admin/_next/static/chunks/9014-eeae6f581158e645.js +1 -0
  145. fides/ui-build/static/admin/_next/static/chunks/{5596-29a7c8322530b7cf.js → 9195-da717d324917b049.js} +3 -3
  146. fides/ui-build/static/admin/_next/static/chunks/9450-b7b7bb1d755ecf57.js +1 -0
  147. fides/ui-build/static/admin/_next/static/chunks/{9676.7d029a5383595b69.js → 9676.1f395eeb9cc34968.js} +1 -1
  148. fides/ui-build/static/admin/_next/static/chunks/{9826-a737a9956c1d0905.js → 9826-1078e46f3ac0b688.js} +1 -1
  149. fides/ui-build/static/admin/_next/static/chunks/9911-ece086f2230e34f0.js +1 -0
  150. fides/ui-build/static/admin/_next/static/chunks/pages/{404-eb019192ce498f32.js → 404-800be6996aaa999c.js} +1 -1
  151. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-ee588a308812715d.js → _app-de4b578c904df772.js} +70 -70
  152. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-7081e0e49f67716c.js → manual-f12020b82dd4bd1a.js} +1 -1
  153. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-a188f84239f4b2a8.js → multiple-a911b7990371704d.js} +1 -1
  154. fides/ui-build/static/admin/_next/static/chunks/pages/{add-systems-ee9df33ebd471099.js → add-systems-ad585b79953c2753.js} +1 -1
  155. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-4f9cf087fcee87e6.js → add-vendors-bb263d394ca1c8fa.js} +1 -1
  156. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-6907c368d8611c44.js +1 -0
  157. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-1b02a4991201b7e4.js → [id]-c32f381af358149b.js} +1 -1
  158. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-a5e738a234dadc7e.js → new-6efb3c069d8b47dd.js} +1 -1
  159. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-b08abefec298ccf1.js → privacy-experience-1975c529905eea9b.js} +1 -1
  160. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-8c164c4b8310214e.js → [id]-b05331178928ab52.js} +1 -1
  161. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-db789002d84c8829.js → new-516834e930bb0d0d.js} +1 -1
  162. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-985717f2565f9d9d.js +1 -0
  163. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-5cba30eba1e97e56.js → properties-2be773e08498e40c.js} +1 -1
  164. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-850afb74f4192e87.js +1 -0
  165. fides/ui-build/static/admin/_next/static/chunks/pages/{consent-614af0a2c2ba966c.js → consent-b63d1e395d879b86.js} +1 -1
  166. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]-5b28f0f674ea87bd.js +1 -0
  167. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-676177e2f3c9c2a2.js +1 -0
  168. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-794906929efb8e1d.js +1 -0
  169. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/[resourceUrn]-3ccbf7c0d06507b9.js +1 -0
  170. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources-81d1b50585468fb0.js +1 -0
  171. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-1ea0b24d306b1e67.js +1 -0
  172. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore/[monitorId]-d4861a4a218bb65a.js +1 -0
  173. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/infrastructure/[monitorId]-66bd265044daf97d.js +1 -0
  174. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/infrastructure-c9c79fa8576a4f77.js +1 -0
  175. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]/[systemId]-60cacc3232c2eead.js +1 -0
  176. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]-437bd64a3016de36.js +1 -0
  177. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-8349248c2da970a6.js +1 -0
  178. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-6919a1d6cadaa46b.js +1 -0
  179. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-b072cf25aefc98f6.js → [resourceUrn]-1a50d421897d3da1.js} +1 -1
  180. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-fd3e8817d8e6dee4.js → detection-49509414a15e8393.js} +1 -1
  181. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-146624cf59792bf7.js → [resourceUrn]-1a1bb80b586d0c0f.js} +1 -1
  182. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-9695cc9c85592ec5.js → discovery-49de61df1e8e7fba.js} +1 -1
  183. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-c2719f5cff20c0f8.js +1 -0
  184. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-5f88280db168083e.js → [...subfieldNames]-415015aebab60436.js} +1 -1
  185. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-bfbcf19c28c794ae.js → [collectionName]-5accb09715b5122d.js} +1 -1
  186. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-aebecca1d8ec5f98.js +1 -0
  187. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-9551a82ddec9f909.js +1 -0
  188. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-72f8fe47beef0f09.js +1 -0
  189. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-3a8aa3f633528e88.js +1 -0
  190. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-87512616f35ec6da.js +1 -0
  191. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-2f1bf4eac7aa55fd.js +1 -0
  192. fides/ui-build/static/admin/_next/static/chunks/pages/{fides-js-docs-1f4335dca5c09860.js → fides-js-docs-5235760b3e508d7d.js} +1 -1
  193. fides/ui-build/static/admin/_next/static/chunks/pages/{index-1343fa525a206571.js → index-8d67cd2872cb682a.js} +1 -1
  194. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-7a631df29cd0e31a.js +1 -0
  195. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-ea3bc43cdaf273de.js +1 -0
  196. fides/ui-build/static/admin/_next/static/chunks/pages/new-privacy-requests-5d8632bba1b81cd4.js +1 -0
  197. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/{[id]-63b3be660fb12c0f.js → [id]-92e01822ecde8fb8.js} +1 -1
  198. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/{new-d3b577962dd33266.js → new-1256cf6d3f6794e0.js} +1 -1
  199. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests-0daac00911d27617.js +1 -0
  200. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/{[key]-720cde29f81db47f.js → [key]-2d976fe5e8ba0a3a.js} +1 -1
  201. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/{new-3668866076b53016.js → new-7766ba497b863740.js} +1 -1
  202. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers-f2880d2ed4734270.js +1 -0
  203. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/{[id]-8063dceb32310c85.js → [id]-669f585c3458faff.js} +1 -1
  204. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/{add-template-4931c70bee62232f.js → add-template-c79e7724e4bc3899.js} +1 -1
  205. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates-891654e8dc13965c.js +1 -0
  206. fides/ui-build/static/admin/_next/static/chunks/pages/{notifications-93af719dab3bd053.js → notifications-40c8148244c5d347.js} +1 -1
  207. fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-1e86f3e28bd23ed6.js +1 -0
  208. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-9b7bd8c38f02c091.js +1 -0
  209. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-b18a53a940cf9e19.js +1 -0
  210. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-6d028d7450e77578.js +1 -0
  211. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-8399083ee2cd8cc2.js +1 -0
  212. fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-0a910125cdb2b3b8.js +1 -0
  213. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-acc90b6f7fe915cb.js +1 -0
  214. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-bbc42026f2685438.js +1 -0
  215. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-fa82cffba448ccd8.js → configure-c08ca6ad21c99799.js} +1 -1
  216. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-77c2db582f8823bc.js +1 -0
  217. fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-bc1c289647e52c48.js → [id]-74ccea4868408e3d.js} +1 -1
  218. fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-cbfaa23d96f5ed0b.js → add-property-7d9f09bfe9d44dfc.js} +1 -1
  219. fides/ui-build/static/admin/_next/static/chunks/pages/{properties-a15a3fd0ed88f39c.js → properties-cd77bc30672bb1fa.js} +1 -1
  220. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-cc3bd9540132d5ed.js +1 -0
  221. fides/ui-build/static/admin/_next/static/chunks/pages/sandbox/privacy-notices-7ce7d720107ab4b5.js +1 -0
  222. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/{[purpose_id]-19de0024418a4924.js → [purpose_id]-ae789892343c24f5.js} +1 -1
  223. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-13ee1b331ced0846.js +1 -0
  224. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/[id]-ee4e43692336a330.js +1 -0
  225. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/new-ca51d794abfcbf25.js +1 -0
  226. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-ecd1dc5db8e81409.js +1 -0
  227. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-3b87002753b23ca5.js → domain-records-df06f7e2f668c540.js} +1 -1
  228. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-aacd9d0ad47082d4.js → domains-da0c77bd510c6c51.js} +1 -1
  229. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-3cdd0b39901190ba.js → email-templates-950b0c115bf673d8.js} +1 -1
  230. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-61076eedbfd137b9.js → locations-7e36cb4756973a9d.js} +1 -1
  231. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-b07b11d6002f8c8c.js → organization-a0e5ed486d24ccf3.js} +1 -1
  232. fides/ui-build/static/admin/_next/static/chunks/pages/settings/privacy-requests-3cdebafb6870d3ad.js +1 -0
  233. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-b7c0d3b1b754e70f.js → regulations-159aad34f1021320.js} +1 -1
  234. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-dbd1a64090ad0946.js +1 -0
  235. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-59c89489fa32a4cb.js → [id]-7d042497a57a3788.js} +1 -1
  236. fides/ui-build/static/admin/_next/static/chunks/pages/systems-21f1172e73dfc9f0.js +1 -0
  237. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-e553161e6338ee48.js +1 -0
  238. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-7dce2916cc589c54.js → new-efc4af017723e57a.js} +1 -1
  239. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-5d5a68e555d18693.js → [id]-b152319d67372ee4.js} +1 -1
  240. fides/ui-build/static/admin/_next/static/chunks/pages/user-management-dba8692491f7935e.js +1 -0
  241. fides/ui-build/static/admin/_next/static/chunks/webpack-09ca52bc7beb0b43.js +1 -0
  242. fides/ui-build/static/admin/_next/static/css/3d66bb57ddcb0978.css +1 -0
  243. fides/ui-build/static/admin/_next/static/css/a1e4be9466578ef1.css +1 -0
  244. fides/ui-build/static/admin/_next/static/l2vgGUHB04Fi4oEVlVMrc/_buildManifest.js +1 -0
  245. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  246. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  247. fides/ui-build/static/admin/add-systems.html +1 -1
  248. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  249. fides/ui-build/static/admin/consent/configure.html +1 -1
  250. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  251. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  252. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  253. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  254. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  255. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  256. fides/ui-build/static/admin/consent/properties.html +1 -1
  257. fides/ui-build/static/admin/consent/reporting.html +1 -1
  258. fides/ui-build/static/admin/consent.html +1 -1
  259. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  260. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  261. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  262. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  263. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  264. fides/ui-build/static/admin/data-catalog.html +1 -1
  265. fides/ui-build/static/admin/data-discovery/action-center/datastore/[monitorId].html +1 -1
  266. fides/ui-build/static/admin/data-discovery/action-center/datastore.html +1 -1
  267. fides/ui-build/static/admin/data-discovery/action-center/infrastructure/[monitorId].html +1 -0
  268. fides/ui-build/static/admin/data-discovery/action-center/infrastructure.html +1 -0
  269. fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId]/[systemId].html +1 -1
  270. fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId].html +1 -1
  271. fides/ui-build/static/admin/data-discovery/action-center/website.html +1 -1
  272. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  273. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  274. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  275. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  276. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  277. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  278. fides/ui-build/static/admin/datamap.html +1 -1
  279. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  280. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  281. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  282. fides/ui-build/static/admin/dataset/new.html +1 -1
  283. fides/ui-build/static/admin/dataset.html +1 -1
  284. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  285. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  286. fides/ui-build/static/admin/datastore-connection.html +1 -1
  287. fides/ui-build/static/admin/index.html +1 -1
  288. fides/ui-build/static/admin/integrations/[id].html +1 -1
  289. fides/ui-build/static/admin/integrations.html +1 -1
  290. fides/ui-build/static/admin/lib/fides-ext-gpp.js +1 -1
  291. fides/ui-build/static/admin/lib/fides-headless.js +1 -1
  292. fides/ui-build/static/admin/lib/fides-preview.js +1 -1
  293. fides/ui-build/static/admin/lib/fides-tcf.js +2 -2
  294. fides/ui-build/static/admin/lib/fides.js +2 -2
  295. fides/ui-build/static/admin/login/[provider].html +1 -1
  296. fides/ui-build/static/admin/login.html +1 -1
  297. fides/ui-build/static/admin/new-privacy-requests.html +1 -1
  298. fides/ui-build/static/admin/notifications/digests/[id].html +1 -1
  299. fides/ui-build/static/admin/notifications/digests/new.html +1 -1
  300. fides/ui-build/static/admin/notifications/digests.html +1 -1
  301. fides/ui-build/static/admin/notifications/providers/[key].html +1 -1
  302. fides/ui-build/static/admin/notifications/providers/new.html +1 -1
  303. fides/ui-build/static/admin/notifications/providers.html +1 -1
  304. fides/ui-build/static/admin/notifications/templates/[id].html +1 -1
  305. fides/ui-build/static/admin/notifications/templates/add-template.html +1 -1
  306. fides/ui-build/static/admin/notifications/templates.html +1 -1
  307. fides/ui-build/static/admin/notifications.html +1 -1
  308. fides/ui-build/static/admin/poc/ant-components.html +1 -1
  309. fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
  310. fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
  311. fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
  312. fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
  313. fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
  314. fides/ui-build/static/admin/poc/forms.html +1 -1
  315. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  316. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  317. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  318. fides/ui-build/static/admin/privacy-requests.html +1 -1
  319. fides/ui-build/static/admin/properties/[id].html +1 -1
  320. fides/ui-build/static/admin/properties/add-property.html +1 -1
  321. fides/ui-build/static/admin/properties.html +1 -1
  322. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  323. fides/ui-build/static/admin/sandbox/privacy-notices.html +1 -1
  324. fides/ui-build/static/admin/settings/about/alpha.html +1 -1
  325. fides/ui-build/static/admin/settings/about.html +1 -1
  326. fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
  327. fides/ui-build/static/admin/settings/consent.html +1 -1
  328. fides/ui-build/static/admin/settings/custom-fields/[id].html +1 -1
  329. fides/ui-build/static/admin/settings/custom-fields/new.html +1 -1
  330. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  331. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  332. fides/ui-build/static/admin/settings/domains.html +1 -1
  333. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  334. fides/ui-build/static/admin/settings/locations.html +1 -1
  335. fides/ui-build/static/admin/settings/organization.html +1 -1
  336. fides/ui-build/static/admin/settings/privacy-requests.html +1 -1
  337. fides/ui-build/static/admin/settings/regulations.html +1 -1
  338. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  339. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  340. fides/ui-build/static/admin/systems.html +1 -1
  341. fides/ui-build/static/admin/taxonomy.html +1 -1
  342. fides/ui-build/static/admin/user-management/new.html +1 -1
  343. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  344. fides/ui-build/static/admin/user-management.html +1 -1
  345. fides/api/service/privacy_request/dsr_package/templates/welcome.html +0 -66
  346. fides/ui-build/static/admin/_next/static/chunks/1099-31f9d973bc287df8.js +0 -1
  347. fides/ui-build/static/admin/_next/static/chunks/1316-2606e19807c08aa5.js +0 -1
  348. fides/ui-build/static/admin/_next/static/chunks/1437-8b1f6c8797c68bfd.js +0 -1
  349. fides/ui-build/static/admin/_next/static/chunks/1467-8808ec8836e033f9.js +0 -1
  350. fides/ui-build/static/admin/_next/static/chunks/155-f6302d32cba4cab6.js +0 -1
  351. fides/ui-build/static/admin/_next/static/chunks/1817-2d5cf537a2992c79.js +0 -1
  352. fides/ui-build/static/admin/_next/static/chunks/2121.1de2fa060eae34aa.js +0 -1
  353. fides/ui-build/static/admin/_next/static/chunks/2921-34a43f2f8f5e5e69.js +0 -1
  354. fides/ui-build/static/admin/_next/static/chunks/2962-342ad1b4ab402ded.js +0 -1
  355. fides/ui-build/static/admin/_next/static/chunks/3377-988ac2f3a2e8d5d4.js +0 -1
  356. fides/ui-build/static/admin/_next/static/chunks/3446-f40c352c43ac950c.js +0 -1
  357. fides/ui-build/static/admin/_next/static/chunks/346-aa3b88efb85f2e28.js +0 -1
  358. fides/ui-build/static/admin/_next/static/chunks/3696-6f90e41a53d22920.js +0 -1
  359. fides/ui-build/static/admin/_next/static/chunks/3700-f695f2f6b8251971.js +0 -1
  360. fides/ui-build/static/admin/_next/static/chunks/3772-9f1713f9d5f97a10.js +0 -1
  361. fides/ui-build/static/admin/_next/static/chunks/3873-d18e47b327445db5.js +0 -1
  362. fides/ui-build/static/admin/_next/static/chunks/3923-f0a85dc5c3684fa0.js +0 -1
  363. fides/ui-build/static/admin/_next/static/chunks/4496-4ff19366c597ec16.js +0 -1
  364. fides/ui-build/static/admin/_next/static/chunks/4817-1f3e6ea38625d8d5.js +0 -1
  365. fides/ui-build/static/admin/_next/static/chunks/5163-e682273cd76a7d07.js +0 -1
  366. fides/ui-build/static/admin/_next/static/chunks/5258-62d6bc19add60aa6.js +0 -1
  367. fides/ui-build/static/admin/_next/static/chunks/5279-bd6cccabdd6ca447.js +0 -1
  368. fides/ui-build/static/admin/_next/static/chunks/549-28537a6de666944b.js +0 -1
  369. fides/ui-build/static/admin/_next/static/chunks/5619-9b50cec521203989.js +0 -1
  370. fides/ui-build/static/admin/_next/static/chunks/5643-3459282d296a3c59.js +0 -1
  371. fides/ui-build/static/admin/_next/static/chunks/6277-3759894435cb8569.js +0 -1
  372. fides/ui-build/static/admin/_next/static/chunks/6315-e2fb5ea77179a871.js +0 -1
  373. fides/ui-build/static/admin/_next/static/chunks/6344-ca66a6e10d128179.js +0 -1
  374. fides/ui-build/static/admin/_next/static/chunks/6419-11d67f7fd4e2f247.js +0 -1
  375. fides/ui-build/static/admin/_next/static/chunks/6954-84789a4e4fb04eb9.js +0 -1
  376. fides/ui-build/static/admin/_next/static/chunks/699-8ca44b0de9fa20f0.js +0 -1
  377. fides/ui-build/static/admin/_next/static/chunks/7059-2bb7c38578549703.js +0 -1
  378. fides/ui-build/static/admin/_next/static/chunks/7202.3febe9e89640c712.js +0 -1
  379. fides/ui-build/static/admin/_next/static/chunks/7476-a02d970ea4d3f7d0.js +0 -1
  380. fides/ui-build/static/admin/_next/static/chunks/7488-cf92601852e3c509.js +0 -1
  381. fides/ui-build/static/admin/_next/static/chunks/7630-a11610c2b31ab2ca.js +0 -1
  382. fides/ui-build/static/admin/_next/static/chunks/7773-9ae233109bc64ec2.js +0 -1
  383. fides/ui-build/static/admin/_next/static/chunks/796-e36d610066135f8c.js +0 -1
  384. fides/ui-build/static/admin/_next/static/chunks/8011-75af8b480fa114e6.js +0 -1
  385. fides/ui-build/static/admin/_next/static/chunks/8373-22b4d20e8cc06b3a.js +0 -1
  386. fides/ui-build/static/admin/_next/static/chunks/8765-f622a35b40a7ec63.js +0 -1
  387. fides/ui-build/static/admin/_next/static/chunks/9037-453224ba3ee65b13.js +0 -1
  388. fides/ui-build/static/admin/_next/static/chunks/9046-d9c6498368b993d1.js +0 -1
  389. fides/ui-build/static/admin/_next/static/chunks/9187-7438242f0d380bb0.js +0 -1
  390. fides/ui-build/static/admin/_next/static/chunks/9278-08cc704317fe535e.js +0 -1
  391. fides/ui-build/static/admin/_next/static/chunks/9330-f753636a31c4ea04.js +0 -1
  392. fides/ui-build/static/admin/_next/static/chunks/9682-d1a3afa1394f8304.js +0 -1
  393. fides/ui-build/static/admin/_next/static/chunks/9729-fcf6ff4e3534e4a8.js +0 -1
  394. fides/ui-build/static/admin/_next/static/chunks/9899-d6437facac926264.js +0 -1
  395. fides/ui-build/static/admin/_next/static/chunks/9965-25621dd507e0cfd6.js +0 -1
  396. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-9af75caefc74eaca.js +0 -1
  397. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-6528eb24165aceb6.js +0 -1
  398. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-11f1683aa15e1a62.js +0 -1
  399. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]-32bd7a7c990e5bf6.js +0 -1
  400. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-d60761c20382b259.js +0 -1
  401. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-07e7d38ce34e1e6c.js +0 -1
  402. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/[resourceUrn]-b07a0707f8c2ec0d.js +0 -1
  403. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources-aed94957009eb3fd.js +0 -1
  404. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-127c114dd8f102ed.js +0 -1
  405. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore/[monitorId]-5aa7a9fa96160de8.js +0 -1
  406. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]/[systemId]-899bf30dde8b3292.js +0 -1
  407. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]-73085f50abb775c0.js +0 -1
  408. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-823d0dd77e66585b.js +0 -1
  409. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-24a82e07a0008516.js +0 -1
  410. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-3b100c44ea9e3988.js +0 -1
  411. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-6fbe2b584a509226.js +0 -1
  412. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-3d1e48f4b95d7f6b.js +0 -1
  413. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-d3c6ecf7f29bea6e.js +0 -1
  414. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-0a4aa42be2da0255.js +0 -1
  415. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-14313e441a13192c.js +0 -1
  416. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-f139d1ce26404f30.js +0 -1
  417. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-b2d3d28b10a758e6.js +0 -1
  418. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-a733e5d7c3ce9bb8.js +0 -1
  419. fides/ui-build/static/admin/_next/static/chunks/pages/new-privacy-requests-df0c95e408c54c7e.js +0 -1
  420. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests-aed9afd988a48acf.js +0 -1
  421. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers-36a0ac36062abd02.js +0 -1
  422. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates-a14c876b49422597.js +0 -1
  423. fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-9cfb469de7b4aeab.js +0 -1
  424. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-e715cc654fb6a5cd.js +0 -1
  425. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-72ae299bcb6adae6.js +0 -1
  426. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-2337f8c81a766eb0.js +0 -1
  427. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-0af454f55494f6fa.js +0 -1
  428. fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-d1b90ffa996fbd89.js +0 -1
  429. fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-19724b9e0581b96d.js +0 -1
  430. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-cdd3754289a28317.js +0 -1
  431. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-cc41ae605f2b55ae.js +0 -1
  432. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-6e4c535b6d614596.js +0 -1
  433. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-632b3ee563d070f2.js +0 -1
  434. fides/ui-build/static/admin/_next/static/chunks/pages/sandbox/privacy-notices-afe921f6e2a526fb.js +0 -1
  435. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-5b6807dced8d03c5.js +0 -1
  436. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/[id]-8634aae3259def37.js +0 -1
  437. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/new-2d9dcca17965dc57.js +0 -1
  438. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-7dce52bfc1b2652c.js +0 -1
  439. fides/ui-build/static/admin/_next/static/chunks/pages/settings/privacy-requests-084a2b4431d35322.js +0 -1
  440. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-b72d36243a0a545c.js +0 -1
  441. fides/ui-build/static/admin/_next/static/chunks/pages/systems-cfaa37a0df83674b.js +0 -1
  442. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-56a5434969cbe9ba.js +0 -1
  443. fides/ui-build/static/admin/_next/static/chunks/pages/user-management-e6a211d8a0401086.js +0 -1
  444. fides/ui-build/static/admin/_next/static/chunks/webpack-c2c11809187b9f84.js +0 -1
  445. fides/ui-build/static/admin/_next/static/css/d41a048a166d50e4.css +0 -1
  446. fides/ui-build/static/admin/_next/static/css/d78390d6134d8328.css +0 -1
  447. fides/ui-build/static/admin/_next/static/wCNFtmYQhEDMaMPeBB4BM/_buildManifest.js +0 -1
  448. fides/ui-build/static/admin/poc/table-migration.html +0 -1
  449. {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/WHEEL +0 -0
  450. {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/entry_points.txt +0 -0
  451. {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/licenses/LICENSE +0 -0
  452. {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/top_level.txt +0 -0
  453. /fides/ui-build/static/admin/_next/static/{wCNFtmYQhEDMaMPeBB4BM → l2vgGUHB04Fi4oEVlVMrc}/_ssgManifest.js +0 -0
@@ -0,0 +1,68 @@
1
+ <html>
2
+ <head>
3
+ <link
4
+ rel="stylesheet"
5
+ href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600"
6
+ />
7
+ <link rel="stylesheet" href="data/main.css" />
8
+ <script>
9
+ // format the "requested at" datetime with the user's local date format
10
+ // and timezone if the Intl API is available in their browser, otherwise default to UTC
11
+ window.onload = function () {
12
+ var requestedAt = document.getElementById("requestedAt");
13
+ var dateString = requestedAt.textContent;
14
+
15
+ if (window.Intl) {
16
+ var formattedDate = new Intl.DateTimeFormat(navigator.language, {
17
+ year: "numeric",
18
+ month: "2-digit",
19
+ day: "2-digit",
20
+ hour: "2-digit",
21
+ minute: "2-digit",
22
+ timeZoneName: "short",
23
+ }).format(new Date(dateString));
24
+
25
+ requestedAt.textContent = formattedDate;
26
+ }
27
+ };
28
+ </script>
29
+ </head>
30
+
31
+ <body>
32
+ <div class="container">
33
+ <div class="header"></div>
34
+ <div class="content">
35
+ <h1>Your requested data</h1>
36
+ <div class="info-grid-container">
37
+ <div class="info-grid">
38
+ <div>Request ID:</div>
39
+ <div>{{ request.id }}</div>
40
+ <div>Request type:</div>
41
+ <div>{{ request.type }}</div>
42
+ {% for identity_type, identity_data in request.identity.items() %}
43
+ <div>{{ identity_data.label }}:</div>
44
+ <div>{{ identity_data.value }}</div>
45
+ {% endfor %}
46
+ <div>Requested at:</div>
47
+ <div id="requestedAt">{{ request.requested_at }}</div>
48
+ </div>
49
+ </div>
50
+ <div class="dsr-information-text">
51
+ <p>
52
+ This web link contains all data requested as part of your Data
53
+ Subject Request (DSR). Your information has been compiled from the
54
+ following areas. Unzip the archive, then click on each section to
55
+ open and view your data.
56
+ </p>
57
+ </div>
58
+ <div class="dataset-list">
59
+ {% for name, link in data.items() %}
60
+ <div class="dataset-item">
61
+ <a href="{{ link }}" class="dataset-link">{{ name }}</a>
62
+ </div>
63
+ {% endfor %}
64
+ </div>
65
+ </div>
66
+ </div>
67
+ </body>
68
+ </html>
@@ -1,30 +1,33 @@
1
1
  <html>
2
- <head>
3
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600">
4
- <link rel="stylesheet" href="../main.css">
5
- </head>
6
- <body>
7
- <div class="container">
8
- <div class="header"></div>
9
- <div class="content">
10
- <div class="button-container">
11
- <a href="../../welcome.html">
12
- <div class="button"><img src="../back.svg"></div>
13
- <span>Back to datasets</span>
14
- </a>
15
- </div>
16
- <h1>{{ heading }}</h1>
17
- <div class="table table-hover">
18
- <div class="table-row">
19
- <div class="table-cell" style="text-align: left;">Collection</div>
20
- </div>
21
- {% for name, link in data.items() %}
22
- <a href="{{ link }}" class="table-row">
23
- <div class="table-cell" style="text-align: left;">{{ name }}</div>
24
- </a>
25
- {% endfor %}
26
- </div>
27
- </div>
2
+ <head>
3
+ <link
4
+ rel="stylesheet"
5
+ href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600"
6
+ />
7
+ <link rel="stylesheet" href="../main.css" />
8
+ </head>
9
+ <body>
10
+ <div class="container">
11
+ <div class="header"></div>
12
+ <div class="content">
13
+ <div class="button-container">
14
+ <a href="../../clickme.html">
15
+ <div class="button"><img src="../back.svg" /></div>
16
+ <span>Back to datasets</span>
17
+ </a>
18
+ </div>
19
+ <h1>{{ heading }}</h1>
20
+ <div class="table table-hover">
21
+ <div class="table-row">
22
+ <div class="table-cell" style="text-align: left">Collection</div>
23
+ </div>
24
+ {% for name, link in data.items() %}
25
+ <a href="{{ link }}" class="table-row">
26
+ <div class="table-cell" style="text-align: left">{{ name }}</div>
27
+ </a>
28
+ {% endfor %}
29
+ </div>
28
30
  </div>
29
- </body>
31
+ </div>
32
+ </body>
30
33
  </html>
@@ -0,0 +1,439 @@
1
+ from datetime import datetime, timedelta, timezone
2
+ from typing import Optional
3
+ from uuid import UUID
4
+
5
+ from loguru import logger
6
+ from sqlalchemy.orm import Session, defer
7
+
8
+ from fides.api.models.privacy_request.duplicate_group import (
9
+ DuplicateGroup,
10
+ generate_rule_version,
11
+ )
12
+ from fides.api.models.privacy_request.privacy_request import PrivacyRequest
13
+ from fides.api.schemas.policy import ActionType
14
+ from fides.api.schemas.privacy_request import PrivacyRequestStatus
15
+ from fides.api.task.conditional_dependencies.schemas import (
16
+ Condition,
17
+ ConditionGroup,
18
+ ConditionLeaf,
19
+ GroupOperator,
20
+ Operator,
21
+ )
22
+ from fides.api.task.conditional_dependencies.sql_translator import (
23
+ SQLConditionTranslator,
24
+ )
25
+ from fides.config.config_proxy import ConfigProxy
26
+ from fides.config.duplicate_detection_settings import DuplicateDetectionSettings
27
+
28
+ ACTIONED_REQUEST_STATUSES = [
29
+ PrivacyRequestStatus.approved,
30
+ PrivacyRequestStatus.in_processing,
31
+ PrivacyRequestStatus.requires_manual_finalization,
32
+ PrivacyRequestStatus.requires_input,
33
+ PrivacyRequestStatus.paused,
34
+ PrivacyRequestStatus.awaiting_email_send,
35
+ PrivacyRequestStatus.error,
36
+ ]
37
+
38
+
39
+ class DuplicateDetectionService:
40
+ def __init__(self, db: Session):
41
+ self.db = db
42
+ self._config = ConfigProxy(db).privacy_request_duplicate_detection
43
+
44
+ def is_enabled(self) -> bool:
45
+ return self._config.enabled
46
+
47
+ def _create_identity_conditions(
48
+ self, current_request: PrivacyRequest
49
+ ) -> list[Condition]:
50
+ """Creates conditions for matching identity fields.
51
+
52
+ For identity field matching using the EAV pattern in ProvidedIdentity, we need to match both field_name
53
+ and hashed_value. This function creates the required nested conditions for each identity field.
54
+ Also adds a condition for the policy_id to ensure that we are only matching requests for the same policy.
55
+ """
56
+ conditions: list[Condition] = []
57
+ current_identities: dict[str, str] = {
58
+ pi.field_name: pi.hashed_value
59
+ for pi in current_request.provided_identities # type: ignore [attr-defined]
60
+ if pi.field_name in self._config.match_identity_fields
61
+ }
62
+ if len(current_identities) != len(self._config.match_identity_fields):
63
+ missing_fields = [
64
+ field
65
+ for field in self._config.match_identity_fields
66
+ if field not in current_identities.keys()
67
+ ]
68
+ logger.debug(
69
+ f"Some identity fields were not found in the current request: {missing_fields}"
70
+ )
71
+ return []
72
+
73
+ for field_name, hashed_value in current_identities.items():
74
+ identity_condition = ConditionGroup(
75
+ logical_operator=GroupOperator.and_,
76
+ conditions=[
77
+ ConditionLeaf(
78
+ field_address="privacyrequest.provided_identities.field_name",
79
+ operator=Operator.eq,
80
+ value=field_name,
81
+ ),
82
+ ConditionLeaf(
83
+ field_address="privacyrequest.provided_identities.hashed_value",
84
+ operator=Operator.eq,
85
+ value=hashed_value,
86
+ ),
87
+ ],
88
+ )
89
+ conditions.append(identity_condition)
90
+ policy_condition = ConditionLeaf(
91
+ field_address="privacyrequest.policy_id",
92
+ operator=Operator.eq,
93
+ value=current_request.policy_id,
94
+ )
95
+ conditions.append(policy_condition)
96
+ return conditions
97
+
98
+ def _create_time_window_condition(self, time_window_days: int) -> Condition:
99
+ """Creates a condition for matching requests within a time window."""
100
+ cutoff_date = datetime.now(timezone.utc) - timedelta(days=time_window_days)
101
+ condition = ConditionLeaf(
102
+ field_address="privacyrequest.created_at",
103
+ operator=Operator.gte,
104
+ value=cutoff_date.isoformat(),
105
+ )
106
+ return condition
107
+
108
+ def create_duplicate_detection_conditions(
109
+ self,
110
+ current_request: PrivacyRequest,
111
+ ) -> Optional[ConditionGroup]:
112
+ """
113
+ Create conditions for duplicate detection based on configuration.
114
+
115
+ Args:
116
+ current_request: The current privacy request to find duplicates for
117
+ config: Duplicate detection configuration settings
118
+
119
+ Returns:
120
+ A ConditionGroup with AND operator, or None if no conditions can be created
121
+ """
122
+ if len(self._config.match_identity_fields) == 0:
123
+ return None
124
+
125
+ identity_conditions = self._create_identity_conditions(current_request)
126
+ if not identity_conditions:
127
+ return None # Only proceed if we have identity conditions
128
+
129
+ time_window_condition = self._create_time_window_condition(
130
+ self._config.time_window_days
131
+ )
132
+
133
+ # Combine all conditions with AND operator
134
+ all_conditions: list[Condition] = [*identity_conditions, time_window_condition]
135
+ return ConditionGroup(
136
+ logical_operator=GroupOperator.and_, conditions=all_conditions
137
+ )
138
+
139
+ def find_duplicate_privacy_requests(
140
+ self,
141
+ current_request: PrivacyRequest,
142
+ ) -> list[PrivacyRequest]:
143
+ """
144
+ Find potential duplicate privacy requests based on duplicate detection configuration.
145
+
146
+ Uses the SQLConditionTranslator to build queries from conditions, which handles
147
+ the ProvidedIdentity relationship using SQLAlchemy's .any() method.
148
+
149
+ Args:
150
+ current_request: The privacy request to check for duplicates
151
+ config: Duplicate detection configuration settings
152
+
153
+ Returns:
154
+ List of PrivacyRequest objects that match the duplicate criteria,
155
+ does not include the current request
156
+ """
157
+ condition = self.create_duplicate_detection_conditions(current_request)
158
+
159
+ if condition is None:
160
+ return []
161
+
162
+ translator = SQLConditionTranslator(self.db)
163
+ query = translator.generate_query_from_condition(condition)
164
+
165
+ query = query.filter(PrivacyRequest.id != current_request.id).filter(
166
+ PrivacyRequest.deleted_at.is_(None)
167
+ )
168
+ # Apply defer options to prevent loading large columns when checking for duplicates
169
+ # pylint: disable=protected-access
170
+ query = query.options(
171
+ defer(PrivacyRequest._filtered_final_upload),
172
+ defer(PrivacyRequest.access_result_urls),
173
+ )
174
+ return query.all()
175
+
176
+ def generate_dedup_key(self, request: PrivacyRequest) -> str:
177
+ """
178
+ Generate a dedup key for a request based on the duplicate detection settings.
179
+ """
180
+ current_identities: dict[str, str] = {
181
+ pi.field_name: pi.hashed_value
182
+ for pi in request.provided_identities # type: ignore [attr-defined]
183
+ if pi.field_name in self._config.match_identity_fields
184
+ }
185
+ if len(current_identities) != len(self._config.match_identity_fields):
186
+ raise ValueError(
187
+ "This request does not contain the required identity fields for duplicate detection."
188
+ )
189
+ return "|".join(
190
+ [
191
+ current_identities[field]
192
+ for field in sorted(self._config.match_identity_fields)
193
+ ]
194
+ )
195
+
196
+ def update_duplicate_group_ids(
197
+ self,
198
+ request: PrivacyRequest,
199
+ duplicates: list[PrivacyRequest],
200
+ duplicate_group_id: UUID,
201
+ ) -> None:
202
+ """
203
+ Update the duplicate request group ids for a request and its duplicates.
204
+ Args:
205
+ request: The privacy request to update
206
+ duplicates: The list of duplicate requests to update
207
+ duplicate_group_id: The duplicate request group id to update
208
+ """
209
+ update_all = [request] + duplicates
210
+ try:
211
+ for privacy_request in update_all:
212
+ privacy_request.duplicate_request_group_id = duplicate_group_id # type: ignore [assignment]
213
+ except Exception as e:
214
+ logger.error(f"Failed to update duplicate request group ids: {e}")
215
+ raise e
216
+
217
+ def mark_as_duplicate(self, request: PrivacyRequest, message: str) -> None:
218
+ """
219
+ Mark a request as a duplicate.
220
+ """
221
+ request.update(self.db, data={"status": PrivacyRequestStatus.duplicate})
222
+ logger.debug(message)
223
+ request.add_skipped_execution_log(
224
+ self.db,
225
+ connection_key=None,
226
+ dataset_name="Duplicate Request Detection",
227
+ collection_name=None,
228
+ message=message,
229
+ action_type=(request.policy.get_action_type() if request.policy else None)
230
+ or ActionType.access,
231
+ )
232
+
233
+ def add_success_execution_log(self, request: PrivacyRequest, message: str) -> None:
234
+ request.add_success_execution_log(
235
+ db=self.db,
236
+ connection_key=None,
237
+ dataset_name="Duplicate Request Detection",
238
+ collection_name=None,
239
+ message=message,
240
+ action_type=(
241
+ request.policy.get_action_type() # type: ignore [arg-type]
242
+ if request.policy
243
+ else ActionType.access
244
+ ),
245
+ )
246
+
247
+ def verified_identity_cases(
248
+ self, request: PrivacyRequest, duplicates: list[PrivacyRequest]
249
+ ) -> bool:
250
+ """
251
+ Apply verified identity rules to determine if a request is a duplicate request.
252
+ - If this request does not have a verified identity, it may be a duplicate if another request in the group is verified.
253
+ - If this is the first request to be verified, it is not a duplicate request
254
+ - If other requests identities were verified before this request, it is a duplicate request
255
+ Args:
256
+ request: The privacy request to check
257
+ duplicates: The list of duplicate requests
258
+
259
+ Returns:
260
+ True if the request is a duplicate request, False otherwise
261
+ """
262
+ verified_in_group = [
263
+ duplicate for duplicate in duplicates if duplicate.identity_verified_at
264
+ ]
265
+
266
+ # The request identity is not verified.
267
+ if not request.identity_verified_at:
268
+ if len(verified_in_group) > 0:
269
+ message = f"Request {request.id} is a duplicate: it is duplicating request(s) {[duplicate.id for duplicate in verified_in_group]}."
270
+ self.mark_as_duplicate(request, message)
271
+ return True
272
+
273
+ canonical_request = min(duplicates, key=lambda x: x.created_at) # type: ignore [arg-type, return-value]
274
+ canonical_request_created_at = canonical_request.created_at or datetime.now(
275
+ timezone.utc
276
+ )
277
+ request_created_at = request.created_at or datetime.now(timezone.utc)
278
+ if request_created_at < canonical_request_created_at:
279
+ message = f"Request {request.id} is not a duplicate: it is the first request to be created in the group."
280
+ logger.debug(message)
281
+ self.add_success_execution_log(request, message)
282
+ return False
283
+
284
+ message = f"Request {request.id} is a duplicate: it is duplicating request(s) ['{canonical_request.id}']."
285
+ self.mark_as_duplicate(request, message)
286
+ return True
287
+
288
+ # The request identity is verified.
289
+ if not verified_in_group:
290
+ message = f"Request {request.id} is not a duplicate: it is the first request to be verified in the group."
291
+ logger.debug(message)
292
+ for duplicate in duplicates:
293
+ dup_message = f"Request {duplicate.id} is a duplicate: it is duplicating request(s) ['{request.id}']."
294
+ self.mark_as_duplicate(duplicate, dup_message)
295
+ self.add_success_execution_log(request, message)
296
+ return False
297
+
298
+ # If this request is the first with a verified identity, it is not a duplicate.
299
+ canonical_request = min(verified_in_group, key=lambda x: x.identity_verified_at) # type: ignore [arg-type, return-value]
300
+ canonical_request_verified_at = (
301
+ canonical_request.identity_verified_at or datetime.now(timezone.utc)
302
+ )
303
+ request_verified_at = request.identity_verified_at or datetime.now(timezone.utc)
304
+ if request_verified_at < canonical_request_verified_at:
305
+ message = f"Request {request.id} is not a duplicate: it is the first request to be verified in the group."
306
+ logger.debug(message)
307
+ self.add_success_execution_log(request, message)
308
+ for duplicate in duplicates:
309
+ dup_message = f"Request {duplicate.id} is a duplicate: it is duplicating request(s) ['{request.id}']."
310
+ self.mark_as_duplicate(duplicate, dup_message)
311
+ return False
312
+ message = f"Request {request.id} is a duplicate: it is duplicating request(s) ['{canonical_request.id}']."
313
+ self.mark_as_duplicate(request, message)
314
+ return True
315
+
316
+ # pylint: disable=too-many-return-statements
317
+ def is_duplicate_request(self, request: PrivacyRequest) -> bool:
318
+ """
319
+ Determine if a request is a duplicate request and assigns a duplicate request group id.
320
+
321
+ The hierarchy is:
322
+ 1. Actioned requests: if this request duplicates an actioned request, it is a duplicate.
323
+ 2. Verified identity requests:
324
+ a. if this request has a verified identity:
325
+ - If none of the duplicates have a verified identity, it is not a duplicate.
326
+ - If duplicates have verified identities, but this request is the first with a verified identity, it is not a duplicate.
327
+ b. if this request does not have a verified identity:
328
+ - If no duplicates have a verified identity, and this was the first created request, it is not a duplicate.
329
+ 3. First created request: if this is the first created request in the group, it is not a duplicate.
330
+ 4. If no canonical requests are found (meaning all requests are marked as duplicates), this request is not a duplicate.
331
+ - Could occur if configuration changes and previous requests were already marked as duplicates.
332
+
333
+ Args:
334
+ request: The privacy request to check
335
+ config: Duplicate detection configuration settings
336
+ Returns:
337
+ True if the request is a duplicate request, False otherwise
338
+ """
339
+ if request.policy.get_action_type() == ActionType.consent:
340
+ message = f"Consent request {request.id} is not a duplicate."
341
+ logger.info(message)
342
+ self.add_success_execution_log(request, message)
343
+ return False
344
+ duplicates = self.find_duplicate_privacy_requests(request)
345
+ rule_version = generate_rule_version(
346
+ DuplicateDetectionSettings(
347
+ enabled=self._config.enabled,
348
+ time_window_days=self._config.time_window_days,
349
+ match_identity_fields=self._config.match_identity_fields,
350
+ )
351
+ )
352
+ try:
353
+ dedup_key = self.generate_dedup_key(request)
354
+ except ValueError as e:
355
+ message = f"Request {request.id} is not a duplicate: {e}"
356
+ logger.warning(message)
357
+ self.add_success_execution_log(request, message)
358
+ return False
359
+
360
+ _, duplicate_group = DuplicateGroup.get_or_create(
361
+ db=self.db, data={"rule_version": rule_version, "dedup_key": dedup_key}
362
+ )
363
+ if duplicate_group is None:
364
+ message = f"Failed to create duplicate group for request {request.id} with dedup key {dedup_key}"
365
+ logger.error(message)
366
+ request.add_error_execution_log(
367
+ db=self.db,
368
+ connection_key=None,
369
+ dataset_name="Duplicate Request Detection",
370
+ collection_name=None,
371
+ message=message,
372
+ action_type=(
373
+ request.policy.get_action_type() # type: ignore [arg-type]
374
+ if request.policy
375
+ else ActionType.access
376
+ ),
377
+ )
378
+ return False
379
+
380
+ self.update_duplicate_group_ids(request, duplicates, duplicate_group.id) # type: ignore [arg-type]
381
+
382
+ if request.status in ACTIONED_REQUEST_STATUSES:
383
+ message = (
384
+ f"Request {request.id} is not a duplicate: it is an actioned request."
385
+ )
386
+ logger.debug(message)
387
+ self.add_success_execution_log(request, message)
388
+ return False
389
+
390
+ # if this is the only request in the group, it is not a duplicate
391
+ if len(duplicates) == 0:
392
+ message = f"Request {request.id} is not a duplicate."
393
+ logger.debug(message)
394
+ self.add_success_execution_log(request, message)
395
+ return False
396
+
397
+ if request.status == PrivacyRequestStatus.duplicate:
398
+ return True
399
+
400
+ # only compare to non-duplicate/complete requests for the following cases
401
+ canonical_requests = [
402
+ duplicate
403
+ for duplicate in duplicates
404
+ if duplicate.status
405
+ not in [
406
+ PrivacyRequestStatus.duplicate,
407
+ PrivacyRequestStatus.complete,
408
+ PrivacyRequestStatus.denied,
409
+ ]
410
+ ]
411
+ # If no non-duplicate requests are found, this request is not a duplicate.
412
+ if len(canonical_requests) == 0:
413
+ message = f"Request {request.id} is not a duplicate."
414
+ logger.debug(message)
415
+ self.add_success_execution_log(request, message)
416
+ return False
417
+
418
+ # If any requests in group are actioned, this request is a duplicate.
419
+ actioned_in_group = [
420
+ duplicate
421
+ for duplicate in canonical_requests
422
+ if duplicate.status in ACTIONED_REQUEST_STATUSES
423
+ ]
424
+ if len(actioned_in_group) > 0:
425
+ message = f"Request {request.id} is a duplicate: it is duplicating actioned request(s) {[duplicate.id for duplicate in actioned_in_group]}."
426
+ self.mark_as_duplicate(request, message)
427
+ return True
428
+ # Check against verified identity rules.
429
+ return self.verified_identity_cases(request, canonical_requests)
430
+
431
+
432
+ def check_for_duplicates(db: Session, privacy_request: PrivacyRequest) -> None:
433
+ duplicate_detection_service = DuplicateDetectionService(db)
434
+ if duplicate_detection_service.is_enabled():
435
+ logger.info(
436
+ "Duplicate detection is enabled. Checking if privacy request is a duplicate."
437
+ )
438
+ if duplicate_detection_service.is_duplicate_request(privacy_request):
439
+ logger.info("Terminating privacy request: request is a duplicate.")
@@ -50,8 +50,9 @@ def send_email_batch(self: DatabaseTask) -> EmailExitState:
50
50
  batch_id = str(uuid.uuid4())
51
51
  logger.info("Starting batch email send {}...", batch_id)
52
52
  with self.get_new_session() as session:
53
+ # Use query_without_large_columns to prevent OOM errors when processing many privacy requests
53
54
  privacy_requests: Query = (
54
- session.query(PrivacyRequest)
55
+ PrivacyRequest.query_without_large_columns(session)
55
56
  .filter(
56
57
  PrivacyRequest.status == PrivacyRequestStatus.awaiting_email_send
57
58
  )
@@ -10,7 +10,7 @@ from loguru import logger
10
10
  # pylint: disable=no-name-in-module
11
11
  from psycopg2.errors import InternalError_ # type: ignore[import-untyped]
12
12
  from pydantic import ValidationError as PydanticValidationError
13
- from sqlalchemy.orm import Query, Session
13
+ from sqlalchemy.orm import Query, Session, selectinload
14
14
 
15
15
  from fides.api import common_exceptions
16
16
  from fides.api.common_exceptions import (
@@ -71,6 +71,7 @@ from fides.api.service.privacy_request.attachment_handling import (
71
71
  get_attachments_content,
72
72
  process_attachments_for_upload,
73
73
  )
74
+ from fides.api.service.privacy_request.duplication_detection import check_for_duplicates
74
75
  from fides.api.service.storage.storage_uploader_service import upload
75
76
  from fides.api.task.filter_results import filter_data_categories
76
77
  from fides.api.task.graph_runners import access_runner, consent_runner, erasure_runner
@@ -426,7 +427,11 @@ def run_privacy_request(
426
427
  logger.info("Resuming privacy request from checkpoint: '{}'", from_step)
427
428
 
428
429
  with self.get_new_session() as session:
429
- privacy_request = PrivacyRequest.get(db=session, object_id=privacy_request_id)
430
+ privacy_request = (
431
+ PrivacyRequest.query_without_large_columns(session)
432
+ .filter(PrivacyRequest.id == privacy_request_id)
433
+ .first()
434
+ )
430
435
  if not privacy_request:
431
436
  raise common_exceptions.PrivacyRequestNotFound(
432
437
  f"Privacy request with id {privacy_request_id} not found"
@@ -446,6 +451,10 @@ def run_privacy_request(
446
451
  logger.info("Terminating privacy request: request deleted.")
447
452
  return
448
453
 
454
+ check_for_duplicates(db=session, privacy_request=privacy_request)
455
+ if privacy_request.status == PrivacyRequestStatus.duplicate:
456
+ return
457
+
449
458
  logger.info("Dispatching privacy request")
450
459
  privacy_request.start_processing(session)
451
460
 
@@ -489,7 +498,15 @@ def run_privacy_request(
489
498
  )
490
499
 
491
500
  try:
492
- datasets = DatasetConfig.all(db=session)
501
+ # Eager load connection_config and ctl_dataset to avoid N+1 queries
502
+ datasets = (
503
+ session.query(DatasetConfig)
504
+ .options(
505
+ selectinload(DatasetConfig.connection_config),
506
+ selectinload(DatasetConfig.ctl_dataset),
507
+ )
508
+ .all()
509
+ )
493
510
  dataset_graphs = [
494
511
  dataset_config.get_graph()
495
512
  for dataset_config in datasets
@@ -516,7 +533,12 @@ def run_privacy_request(
516
533
  key: value["value"] if isinstance(value, dict) else value
517
534
  for key, value in privacy_request.get_cached_identity_data().items()
518
535
  }
519
- connection_configs = ConnectionConfig.all(db=session)
536
+ # Eager load datasets relationship to avoid N+1 queries in filter_fides_connector_datasets
537
+ connection_configs = (
538
+ session.query(ConnectionConfig)
539
+ .options(selectinload(ConnectionConfig.datasets))
540
+ .all()
541
+ )
520
542
  fides_connector_datasets: set[str] = filter_fides_connector_datasets(
521
543
  connection_configs
522
544
  )
@@ -934,7 +956,11 @@ def mark_paused_privacy_request_as_expired(privacy_request_id: str) -> None:
934
956
  """Mark "paused" PrivacyRequest as "errored" after its associated identity data in the redis cache has expired."""
935
957
  SessionLocal = get_db_session(CONFIG)
936
958
  db = SessionLocal()
937
- privacy_request = PrivacyRequest.get(db=db, object_id=privacy_request_id)
959
+ privacy_request = (
960
+ PrivacyRequest.query_without_large_columns(db)
961
+ .filter(PrivacyRequest.id == privacy_request_id)
962
+ .first()
963
+ )
938
964
  if not privacy_request:
939
965
  logger.info(
940
966
  "Attempted to mark as expired. No privacy request with id '{}' found.",