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.

Files changed (336) hide show
  1. {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.74.0rc1.dist-info}/METADATA +2 -1
  2. {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.74.0rc1.dist-info}/RECORD +273 -276
  3. fides/_version.py +3 -3
  4. fides/api/alembic/migrations/versions/xx_2025_10_29_1659_80d28dea3b6b_added_duplicate_group_table.py +79 -0
  5. fides/api/alembic/migrations/versions/xx_2025_11_05_0200_f1a2b3c4d5e6_create_staged_resource_error_table.py +82 -0
  6. fides/api/api/v1/endpoints/privacy_request_endpoints.py +33 -6
  7. fides/api/db/database.py +225 -0
  8. fides/api/models/detection_discovery/__init__.py +2 -0
  9. fides/api/models/detection_discovery/core.py +10 -0
  10. fides/api/models/detection_discovery/staged_resource_error.py +25 -0
  11. fides/api/models/privacy_preference.py +1 -0
  12. fides/api/models/privacy_request/duplicate_group.py +84 -0
  13. fides/api/models/privacy_request/privacy_request.py +53 -8
  14. fides/api/schemas/privacy_request.py +16 -4
  15. fides/api/service/async_dsr/strategies/async_dsr_strategy_polling.py +13 -6
  16. fides/api/service/privacy_request/duplication_detection.py +424 -0
  17. fides/api/service/privacy_request/request_runner_service.py +5 -0
  18. fides/api/service/saas_request/saas_request_override_factory.py +7 -2
  19. fides/api/util/logger_context_utils.py +3 -1
  20. fides/api/util/memory_watchdog.py +118 -0
  21. fides/common/api/v1/urn_registry.py +1 -0
  22. fides/config/__init__.py +7 -1
  23. fides/config/celery_settings.py +42 -0
  24. fides/service/privacy_request/privacy_request_service.py +66 -5
  25. fides/ui-build/static/admin/404.html +1 -1
  26. fides/ui-build/static/admin/_next/static/FZTEUgamBvOhgPWce135w/_buildManifest.js +1 -0
  27. fides/ui-build/static/admin/_next/static/chunks/{1115-26393b586775ea29.js → 1115-0da062111df309bf.js} +1 -1
  28. fides/ui-build/static/admin/_next/static/chunks/{6148-59a59d5c5925344f.js → 1533-84e250d1f26e6d7d.js} +1 -1
  29. fides/ui-build/static/admin/_next/static/chunks/1817-508b16628e8eb225.js +1 -0
  30. fides/ui-build/static/admin/_next/static/chunks/1840-5bbe6d878ed73fb4.js +1 -0
  31. fides/ui-build/static/admin/_next/static/chunks/3214-90ce0a366b0f461a.js +1 -0
  32. fides/ui-build/static/admin/_next/static/chunks/3377-eb5cd82b3ee6ab0c.js +1 -0
  33. fides/ui-build/static/admin/_next/static/chunks/3615-5e2d062d684b8fa1.js +1 -0
  34. fides/ui-build/static/admin/_next/static/chunks/3655-93ecd09f1cb9dbef.js +1 -0
  35. fides/ui-build/static/admin/_next/static/chunks/{4259.d1507e0db19cbed7.js → 4259.05038c9b78467244.js} +1 -1
  36. fides/ui-build/static/admin/_next/static/chunks/4277-13bcf4516326d474.js +1 -0
  37. fides/ui-build/static/admin/_next/static/chunks/454-d5c2c84f1a14e4f1.js +1 -0
  38. fides/ui-build/static/admin/_next/static/chunks/5487-8dedd1ca94fbba54.js +1 -0
  39. fides/ui-build/static/admin/_next/static/chunks/549-6e2442db533a711e.js +1 -0
  40. fides/ui-build/static/admin/_next/static/chunks/5643-55d758444a8d7162.js +1 -0
  41. fides/ui-build/static/admin/_next/static/chunks/5724-1e40975cefa405f0.js +1 -0
  42. fides/ui-build/static/admin/_next/static/chunks/6084-82e2df433fe5ba85.js +1 -0
  43. fides/ui-build/static/admin/_next/static/chunks/6344-3e21444374f8059f.js +1 -0
  44. fides/ui-build/static/admin/_next/static/chunks/6362-12e3fd23130ccf15.js +1 -0
  45. fides/ui-build/static/admin/_next/static/chunks/6372-a8d0f08dac1ebd0e.js +1 -0
  46. fides/ui-build/static/admin/_next/static/chunks/6780-3db5133c1f4c6f1e.js +1 -0
  47. fides/ui-build/static/admin/_next/static/chunks/6954-aa0c60ee1092be8e.js +1 -0
  48. fides/ui-build/static/admin/_next/static/chunks/7079-6e6efc3396ff1ebb.js +1 -0
  49. fides/ui-build/static/admin/_next/static/chunks/7218-d297a4a06f924b09.js +1 -0
  50. fides/ui-build/static/admin/_next/static/chunks/{7245-c9bc628d078c2170.js → 7245-686665c197b58e68.js} +1 -1
  51. fides/ui-build/static/admin/_next/static/chunks/7654-716cf37a020b3d11.js +1 -0
  52. fides/ui-build/static/admin/_next/static/chunks/8939-4925751c57c51f87.js +1 -0
  53. fides/ui-build/static/admin/_next/static/chunks/9014-eeae6f581158e645.js +1 -0
  54. fides/ui-build/static/admin/_next/static/chunks/{9046-d9c6498368b993d1.js → 9046-e4daf28840a69fd6.js} +1 -1
  55. fides/ui-build/static/admin/_next/static/chunks/{5596-29a7c8322530b7cf.js → 9195-550bd50d538c5f79.js} +3 -3
  56. fides/ui-build/static/admin/_next/static/chunks/9341-bfc0e59bcc56c604.js +1 -0
  57. fides/ui-build/static/admin/_next/static/chunks/9450-b7b7bb1d755ecf57.js +1 -0
  58. fides/ui-build/static/admin/_next/static/chunks/9682-da69ac5d06f281da.js +1 -0
  59. fides/ui-build/static/admin/_next/static/chunks/9911-ece086f2230e34f0.js +1 -0
  60. fides/ui-build/static/admin/_next/static/chunks/9965-56c5e4fc9cd3b3a5.js +1 -0
  61. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-ee588a308812715d.js → _app-e64fd8510033a27c.js} +63 -63
  62. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-7081e0e49f67716c.js → manual-ddd9d7d40847fc28.js} +1 -1
  63. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-1b02a4991201b7e4.js → [id]-9b1f2b1c06968166.js} +1 -1
  64. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-a5e738a234dadc7e.js → new-115a085e5d42de45.js} +1 -1
  65. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-8c164c4b8310214e.js → [id]-3de34624829cbce8.js} +1 -1
  66. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-db789002d84c8829.js → new-dc95e7ed278d1a29.js} +1 -1
  67. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-e3ad3a55624e302a.js +1 -0
  68. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-32bd7a7c990e5bf6.js → [resourceUrn]-dd82729296dee5c5.js} +1 -1
  69. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-49e5477eb1a11b92.js +1 -0
  70. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{projects-07e7d38ce34e1e6c.js → projects-dfc1ead4a12c9ffa.js} +1 -1
  71. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-b07a0707f8c2ec0d.js → [resourceUrn]-8442eb219958ac7e.js} +1 -1
  72. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources-feda358d1801c18d.js +1 -0
  73. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-d16acb6fc07aad46.js +1 -0
  74. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore/[monitorId]-c51a1e98c45d231a.js +1 -0
  75. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]/[systemId]-bcfe38eebca30f8c.js +1 -0
  76. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/{[monitorId]-73085f50abb775c0.js → [monitorId]-f66d0655897c4400.js} +1 -1
  77. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-6f1e012cd641da19.js +1 -0
  78. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{activity-24a82e07a0008516.js → activity-581d6248fcf98d17.js} +1 -1
  79. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-b072cf25aefc98f6.js → [resourceUrn]-ddc1c1641e1e9430.js} +1 -1
  80. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-fd3e8817d8e6dee4.js → detection-2b48f7e524743b2b.js} +1 -1
  81. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-146624cf59792bf7.js → [resourceUrn]-862b67418600251e.js} +1 -1
  82. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-9695cc9c85592ec5.js → discovery-0ffec855f5df262c.js} +1 -1
  83. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-6a030ab8c2e2b0db.js +1 -0
  84. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-5f88280db168083e.js → [...subfieldNames]-6cb66f649b8ca4bf.js} +1 -1
  85. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-bfbcf19c28c794ae.js → [collectionName]-0b008dad90b00aaa.js} +1 -1
  86. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{[datasetId]-6fbe2b584a509226.js → [datasetId]-5566edf9a9d1be2d.js} +1 -1
  87. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-d4ca1f485b6e9e02.js +1 -0
  88. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-85dee7e81dc4bafb.js +1 -0
  89. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-e905e018a2cab35d.js +1 -0
  90. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-912723bc86299b1a.js +1 -0
  91. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-f1f0affc18327033.js +1 -0
  92. fides/ui-build/static/admin/_next/static/chunks/pages/{fides-js-docs-1f4335dca5c09860.js → fides-js-docs-5235760b3e508d7d.js} +1 -1
  93. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-1b94e2d769a182b2.js +1 -0
  94. fides/ui-build/static/admin/_next/static/chunks/pages/{integrations-a733e5d7c3ce9bb8.js → integrations-adfe6c5ac5b703d0.js} +1 -1
  95. fides/ui-build/static/admin/_next/static/chunks/pages/new-privacy-requests-f9be7080ebbb7445.js +1 -0
  96. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/{[key]-720cde29f81db47f.js → [key]-f94e3accf9507ebf.js} +1 -1
  97. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/{new-3668866076b53016.js → new-5e83220ff1f2a250.js} +1 -1
  98. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates-1621a4b87c432117.js +1 -0
  99. fides/ui-build/static/admin/_next/static/chunks/pages/poc/{ant-components-9cfb469de7b4aeab.js → ant-components-e02516d9fd314528.js} +1 -1
  100. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-1fe486f3af832c80.js +1 -0
  101. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-2c0ec8fed16c20ae.js +1 -0
  102. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-baf77d34a3b3bece.js +1 -0
  103. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-ee8820fe0fa14c77.js +1 -0
  104. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/{[id]-8634aae3259def37.js → [id]-8eb862182f19a6c2.js} +1 -1
  105. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/{new-2d9dcca17965dc57.js → new-37c29ef618e9fe3c.js} +1 -1
  106. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-1db425150dcb1b6b.js +1 -0
  107. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-f108bf5015144d2f.js +1 -0
  108. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-59c89489fa32a4cb.js → [id]-0e7c7228d01290ea.js} +1 -1
  109. fides/ui-build/static/admin/_next/static/chunks/pages/{systems-cfaa37a0df83674b.js → systems-adc13b542e10a37d.js} +1 -1
  110. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-23dd250da26511c5.js +1 -0
  111. fides/ui-build/static/admin/_next/static/chunks/webpack-6f97ebe373e7ef6b.js +1 -0
  112. fides/ui-build/static/admin/_next/static/css/65ae906f224cd8ae.css +1 -0
  113. fides/ui-build/static/admin/_next/static/css/d5701118537cbdd2.css +1 -0
  114. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  115. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  116. fides/ui-build/static/admin/add-systems.html +1 -1
  117. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  118. fides/ui-build/static/admin/consent/configure.html +1 -1
  119. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  120. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  121. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  122. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  123. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  124. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  125. fides/ui-build/static/admin/consent/properties.html +1 -1
  126. fides/ui-build/static/admin/consent/reporting.html +1 -1
  127. fides/ui-build/static/admin/consent.html +1 -1
  128. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  129. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  130. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  131. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  132. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  133. fides/ui-build/static/admin/data-catalog.html +1 -1
  134. fides/ui-build/static/admin/data-discovery/action-center/datastore/[monitorId].html +1 -1
  135. fides/ui-build/static/admin/data-discovery/action-center/datastore.html +1 -1
  136. fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId]/[systemId].html +1 -1
  137. fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId].html +1 -1
  138. fides/ui-build/static/admin/data-discovery/action-center/website.html +1 -1
  139. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  140. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  141. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  142. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  143. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  144. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  145. fides/ui-build/static/admin/datamap.html +1 -1
  146. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  147. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  148. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  149. fides/ui-build/static/admin/dataset/new.html +1 -1
  150. fides/ui-build/static/admin/dataset.html +1 -1
  151. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  152. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  153. fides/ui-build/static/admin/datastore-connection.html +1 -1
  154. fides/ui-build/static/admin/index.html +1 -1
  155. fides/ui-build/static/admin/integrations/[id].html +1 -1
  156. fides/ui-build/static/admin/integrations.html +1 -1
  157. fides/ui-build/static/admin/lib/fides-ext-gpp.js +1 -1
  158. fides/ui-build/static/admin/lib/fides-preview.js +1 -1
  159. fides/ui-build/static/admin/lib/fides-tcf.js +2 -2
  160. fides/ui-build/static/admin/login/[provider].html +1 -1
  161. fides/ui-build/static/admin/login.html +1 -1
  162. fides/ui-build/static/admin/new-privacy-requests.html +1 -1
  163. fides/ui-build/static/admin/notifications/digests/[id].html +1 -1
  164. fides/ui-build/static/admin/notifications/digests/new.html +1 -1
  165. fides/ui-build/static/admin/notifications/digests.html +1 -1
  166. fides/ui-build/static/admin/notifications/providers/[key].html +1 -1
  167. fides/ui-build/static/admin/notifications/providers/new.html +1 -1
  168. fides/ui-build/static/admin/notifications/providers.html +1 -1
  169. fides/ui-build/static/admin/notifications/templates/[id].html +1 -1
  170. fides/ui-build/static/admin/notifications/templates/add-template.html +1 -1
  171. fides/ui-build/static/admin/notifications/templates.html +1 -1
  172. fides/ui-build/static/admin/notifications.html +1 -1
  173. fides/ui-build/static/admin/poc/ant-components.html +1 -1
  174. fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
  175. fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
  176. fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
  177. fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
  178. fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
  179. fides/ui-build/static/admin/poc/forms.html +1 -1
  180. fides/ui-build/static/admin/poc/table-migration.html +1 -1
  181. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  182. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  183. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  184. fides/ui-build/static/admin/privacy-requests.html +1 -1
  185. fides/ui-build/static/admin/properties/[id].html +1 -1
  186. fides/ui-build/static/admin/properties/add-property.html +1 -1
  187. fides/ui-build/static/admin/properties.html +1 -1
  188. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  189. fides/ui-build/static/admin/sandbox/privacy-notices.html +1 -1
  190. fides/ui-build/static/admin/settings/about/alpha.html +1 -1
  191. fides/ui-build/static/admin/settings/about.html +1 -1
  192. fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
  193. fides/ui-build/static/admin/settings/consent.html +1 -1
  194. fides/ui-build/static/admin/settings/custom-fields/[id].html +1 -1
  195. fides/ui-build/static/admin/settings/custom-fields/new.html +1 -1
  196. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  197. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  198. fides/ui-build/static/admin/settings/domains.html +1 -1
  199. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  200. fides/ui-build/static/admin/settings/locations.html +1 -1
  201. fides/ui-build/static/admin/settings/organization.html +1 -1
  202. fides/ui-build/static/admin/settings/privacy-requests.html +1 -1
  203. fides/ui-build/static/admin/settings/regulations.html +1 -1
  204. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  205. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  206. fides/ui-build/static/admin/systems.html +1 -1
  207. fides/ui-build/static/admin/taxonomy.html +1 -1
  208. fides/ui-build/static/admin/user-management/new.html +1 -1
  209. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  210. fides/ui-build/static/admin/user-management.html +1 -1
  211. fides/ui-build/static/admin/_next/static/chunks/1099-31f9d973bc287df8.js +0 -1
  212. fides/ui-build/static/admin/_next/static/chunks/1316-2606e19807c08aa5.js +0 -1
  213. fides/ui-build/static/admin/_next/static/chunks/1437-8b1f6c8797c68bfd.js +0 -1
  214. fides/ui-build/static/admin/_next/static/chunks/1467-8808ec8836e033f9.js +0 -1
  215. fides/ui-build/static/admin/_next/static/chunks/155-f6302d32cba4cab6.js +0 -1
  216. fides/ui-build/static/admin/_next/static/chunks/1817-2d5cf537a2992c79.js +0 -1
  217. fides/ui-build/static/admin/_next/static/chunks/2962-342ad1b4ab402ded.js +0 -1
  218. fides/ui-build/static/admin/_next/static/chunks/3377-988ac2f3a2e8d5d4.js +0 -1
  219. fides/ui-build/static/admin/_next/static/chunks/3446-f40c352c43ac950c.js +0 -1
  220. fides/ui-build/static/admin/_next/static/chunks/346-aa3b88efb85f2e28.js +0 -1
  221. fides/ui-build/static/admin/_next/static/chunks/3700-f695f2f6b8251971.js +0 -1
  222. fides/ui-build/static/admin/_next/static/chunks/3772-9f1713f9d5f97a10.js +0 -1
  223. fides/ui-build/static/admin/_next/static/chunks/3873-d18e47b327445db5.js +0 -1
  224. fides/ui-build/static/admin/_next/static/chunks/5163-e682273cd76a7d07.js +0 -1
  225. fides/ui-build/static/admin/_next/static/chunks/5279-bd6cccabdd6ca447.js +0 -1
  226. fides/ui-build/static/admin/_next/static/chunks/549-28537a6de666944b.js +0 -1
  227. fides/ui-build/static/admin/_next/static/chunks/5619-9b50cec521203989.js +0 -1
  228. fides/ui-build/static/admin/_next/static/chunks/5643-3459282d296a3c59.js +0 -1
  229. fides/ui-build/static/admin/_next/static/chunks/6277-3759894435cb8569.js +0 -1
  230. fides/ui-build/static/admin/_next/static/chunks/6315-e2fb5ea77179a871.js +0 -1
  231. fides/ui-build/static/admin/_next/static/chunks/6344-ca66a6e10d128179.js +0 -1
  232. fides/ui-build/static/admin/_next/static/chunks/6419-11d67f7fd4e2f247.js +0 -1
  233. fides/ui-build/static/admin/_next/static/chunks/6954-84789a4e4fb04eb9.js +0 -1
  234. fides/ui-build/static/admin/_next/static/chunks/699-8ca44b0de9fa20f0.js +0 -1
  235. fides/ui-build/static/admin/_next/static/chunks/7488-cf92601852e3c509.js +0 -1
  236. fides/ui-build/static/admin/_next/static/chunks/7773-9ae233109bc64ec2.js +0 -1
  237. fides/ui-build/static/admin/_next/static/chunks/8011-75af8b480fa114e6.js +0 -1
  238. fides/ui-build/static/admin/_next/static/chunks/8373-22b4d20e8cc06b3a.js +0 -1
  239. fides/ui-build/static/admin/_next/static/chunks/8765-f622a35b40a7ec63.js +0 -1
  240. fides/ui-build/static/admin/_next/static/chunks/9037-453224ba3ee65b13.js +0 -1
  241. fides/ui-build/static/admin/_next/static/chunks/9187-7438242f0d380bb0.js +0 -1
  242. fides/ui-build/static/admin/_next/static/chunks/9278-08cc704317fe535e.js +0 -1
  243. fides/ui-build/static/admin/_next/static/chunks/9682-d1a3afa1394f8304.js +0 -1
  244. fides/ui-build/static/admin/_next/static/chunks/9729-fcf6ff4e3534e4a8.js +0 -1
  245. fides/ui-build/static/admin/_next/static/chunks/9899-d6437facac926264.js +0 -1
  246. fides/ui-build/static/admin/_next/static/chunks/9965-25621dd507e0cfd6.js +0 -1
  247. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-11f1683aa15e1a62.js +0 -1
  248. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-d60761c20382b259.js +0 -1
  249. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources-aed94957009eb3fd.js +0 -1
  250. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-127c114dd8f102ed.js +0 -1
  251. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore/[monitorId]-5aa7a9fa96160de8.js +0 -1
  252. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]/[systemId]-899bf30dde8b3292.js +0 -1
  253. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-823d0dd77e66585b.js +0 -1
  254. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-3b100c44ea9e3988.js +0 -1
  255. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-3d1e48f4b95d7f6b.js +0 -1
  256. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-d3c6ecf7f29bea6e.js +0 -1
  257. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-0a4aa42be2da0255.js +0 -1
  258. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-14313e441a13192c.js +0 -1
  259. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-f139d1ce26404f30.js +0 -1
  260. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-b2d3d28b10a758e6.js +0 -1
  261. fides/ui-build/static/admin/_next/static/chunks/pages/new-privacy-requests-df0c95e408c54c7e.js +0 -1
  262. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates-a14c876b49422597.js +0 -1
  263. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-cdd3754289a28317.js +0 -1
  264. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-6e4c535b6d614596.js +0 -1
  265. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-632b3ee563d070f2.js +0 -1
  266. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-5b6807dced8d03c5.js +0 -1
  267. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-7dce52bfc1b2652c.js +0 -1
  268. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-b72d36243a0a545c.js +0 -1
  269. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-56a5434969cbe9ba.js +0 -1
  270. fides/ui-build/static/admin/_next/static/chunks/webpack-c2c11809187b9f84.js +0 -1
  271. fides/ui-build/static/admin/_next/static/css/d41a048a166d50e4.css +0 -1
  272. fides/ui-build/static/admin/_next/static/css/d78390d6134d8328.css +0 -1
  273. fides/ui-build/static/admin/_next/static/wCNFtmYQhEDMaMPeBB4BM/_buildManifest.js +0 -1
  274. {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.74.0rc1.dist-info}/WHEEL +0 -0
  275. {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.74.0rc1.dist-info}/entry_points.txt +0 -0
  276. {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.74.0rc1.dist-info}/licenses/LICENSE +0 -0
  277. {ethyca_fides-2.73.2b0.dist-info → ethyca_fides-2.74.0rc1.dist-info}/top_level.txt +0 -0
  278. /fides/ui-build/static/admin/_next/static/{wCNFtmYQhEDMaMPeBB4BM → FZTEUgamBvOhgPWce135w}/_ssgManifest.js +0 -0
  279. /fides/ui-build/static/admin/_next/static/chunks/{2040-7eed8491ca7276ed.js → 2040-fe1a06d82c0413f1.js} +0 -0
  280. /fides/ui-build/static/admin/_next/static/chunks/{2397-083fc511acb6105d.js → 2397-40b8db1cb2f23e2a.js} +0 -0
  281. /fides/ui-build/static/admin/_next/static/chunks/{2921-34a43f2f8f5e5e69.js → 2921-b10bbc3a9104933b.js} +0 -0
  282. /fides/ui-build/static/admin/_next/static/chunks/{3696-6f90e41a53d22920.js → 3696-6db05a35ae806825.js} +0 -0
  283. /fides/ui-build/static/admin/_next/static/chunks/{3923-f0a85dc5c3684fa0.js → 3923-44255a63d6d80ff5.js} +0 -0
  284. /fides/ui-build/static/admin/_next/static/chunks/{401-7c345d019bb9bcbd.js → 401-fe8db8b5d8f600de.js} +0 -0
  285. /fides/ui-build/static/admin/_next/static/chunks/{4496-4ff19366c597ec16.js → 4496-bed72bd5639075be.js} +0 -0
  286. /fides/ui-build/static/admin/_next/static/chunks/{4817-1f3e6ea38625d8d5.js → 4817-d29f40d4ce729f37.js} +0 -0
  287. /fides/ui-build/static/admin/_next/static/chunks/{5185-e7f8b81dd3dfbe0b.js → 5185-b2ac9fecc00b67e7.js} +0 -0
  288. /fides/ui-build/static/admin/_next/static/chunks/{5258-62d6bc19add60aa6.js → 5258-4672eae0656430f9.js} +0 -0
  289. /fides/ui-build/static/admin/_next/static/chunks/{5783-21775c232dce7af7.js → 5783-6055edba275155ca.js} +0 -0
  290. /fides/ui-build/static/admin/_next/static/chunks/{6853-de9905d28e5b19b3.js → 6853-1adbdf6418ec3d62.js} +0 -0
  291. /fides/ui-build/static/admin/_next/static/chunks/{7059-2bb7c38578549703.js → 7059-12be23a345a94c1e.js} +0 -0
  292. /fides/ui-build/static/admin/_next/static/chunks/{7476-a02d970ea4d3f7d0.js → 7476-a43c046c24de37cc.js} +0 -0
  293. /fides/ui-build/static/admin/_next/static/chunks/{7630-a11610c2b31ab2ca.js → 7630-c654c61ba98d8c74.js} +0 -0
  294. /fides/ui-build/static/admin/_next/static/chunks/{796-e36d610066135f8c.js → 796-e83ace3c6ab99ac7.js} +0 -0
  295. /fides/ui-build/static/admin/_next/static/chunks/{8212-393420e5a9751791.js → 8212-b9e8295ca883c9f8.js} +0 -0
  296. /fides/ui-build/static/admin/_next/static/chunks/{9330-f753636a31c4ea04.js → 9330-e519adec48222d45.js} +0 -0
  297. /fides/ui-build/static/admin/_next/static/chunks/{9826-a737a9956c1d0905.js → 9826-657652d55936a8c6.js} +0 -0
  298. /fides/ui-build/static/admin/_next/static/chunks/pages/{404-eb019192ce498f32.js → 404-d079b8bf35250874.js} +0 -0
  299. /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-a188f84239f4b2a8.js → multiple-b4d18c1f4d414f5f.js} +0 -0
  300. /fides/ui-build/static/admin/_next/static/chunks/pages/{add-systems-ee9df33ebd471099.js → add-systems-d451bc8932330141.js} +0 -0
  301. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-4f9cf087fcee87e6.js → add-vendors-c24663cd5dec57db.js} +0 -0
  302. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-9af75caefc74eaca.js → configure-d93418688bd258eb.js} +0 -0
  303. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-b08abefec298ccf1.js → privacy-experience-d9b7b311195df29e.js} +0 -0
  304. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-notices-6528eb24165aceb6.js → privacy-notices-cdfc9bb19f47c709.js} +0 -0
  305. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-5cba30eba1e97e56.js → properties-0b995b01dc4dbd1f.js} +0 -0
  306. /fides/ui-build/static/admin/_next/static/chunks/pages/{consent-614af0a2c2ba966c.js → consent-b37ed76849330edd.js} +0 -0
  307. /fides/ui-build/static/admin/_next/static/chunks/pages/{index-1343fa525a206571.js → index-692d27dbe9392c9f.js} +0 -0
  308. /fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/{[id]-63b3be660fb12c0f.js → [id]-caaa8602a1d449b1.js} +0 -0
  309. /fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/{new-d3b577962dd33266.js → new-9b106b1d2d93985b.js} +0 -0
  310. /fides/ui-build/static/admin/_next/static/chunks/pages/notifications/{digests-aed9afd988a48acf.js → digests-6a1ded8cdde836c4.js} +0 -0
  311. /fides/ui-build/static/admin/_next/static/chunks/pages/notifications/{providers-36a0ac36062abd02.js → providers-a03cbd698a23e5b3.js} +0 -0
  312. /fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/{[id]-8063dceb32310c85.js → [id]-3cde574b3c8447c0.js} +0 -0
  313. /fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/{add-template-4931c70bee62232f.js → add-template-0448bb4ae8536c58.js} +0 -0
  314. /fides/ui-build/static/admin/_next/static/chunks/pages/{notifications-93af719dab3bd053.js → notifications-4ea28f6b1dd63642.js} +0 -0
  315. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{AntForm-e715cc654fb6a5cd.js → AntForm-fec08bea801b4918.js} +0 -0
  316. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikAntFormItem-72ae299bcb6adae6.js → FormikAntFormItem-d911e5fbf5a4a888.js} +0 -0
  317. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikControlled-2337f8c81a766eb0.js → FormikControlled-91b1adcac6a57b2d.js} +0 -0
  318. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikField-0af454f55494f6fa.js → FormikField-de309d8813b1ebfb.js} +0 -0
  319. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{forms-d1b90ffa996fbd89.js → forms-f2943c1309062284.js} +0 -0
  320. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{table-migration-19724b9e0581b96d.js → table-migration-03eda417711ae909.js} +0 -0
  321. /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{storage-cc41ae605f2b55ae.js → storage-ea6f78fa8b2d3f6c.js} +0 -0
  322. /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-fa82cffba448ccd8.js → configure-bda7b474493e7128.js} +0 -0
  323. /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-bc1c289647e52c48.js → [id]-30d298a47e85709f.js} +0 -0
  324. /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-cbfaa23d96f5ed0b.js → add-property-438084cca0d0f10d.js} +0 -0
  325. /fides/ui-build/static/admin/_next/static/chunks/pages/{properties-a15a3fd0ed88f39c.js → properties-17fd44d98f5bd5b6.js} +0 -0
  326. /fides/ui-build/static/admin/_next/static/chunks/pages/sandbox/{privacy-notices-afe921f6e2a526fb.js → privacy-notices-8c80391025ca7339.js} +0 -0
  327. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/{[purpose_id]-19de0024418a4924.js → [purpose_id]-7c19810858b708cc.js} +0 -0
  328. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-3b87002753b23ca5.js → domain-records-e334b43fa5c5b1e6.js} +0 -0
  329. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-aacd9d0ad47082d4.js → domains-9d18eb5c38d85522.js} +0 -0
  330. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-3cdd0b39901190ba.js → email-templates-cb937ed7c4b1e5a8.js} +0 -0
  331. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-61076eedbfd137b9.js → locations-835281251f0785cd.js} +0 -0
  332. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-b07b11d6002f8c8c.js → organization-7fd050c92866938c.js} +0 -0
  333. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{privacy-requests-084a2b4431d35322.js → privacy-requests-59ea66130fca0d05.js} +0 -0
  334. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-b7c0d3b1b754e70f.js → regulations-b0fe1051d908f366.js} +0 -0
  335. /fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-5d5a68e555d18693.js → [id]-aed30fb22ae7c9ec.js} +0 -0
  336. /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-10-30T20:40:29+0000",
11
+ "date": "2025-11-05T17:23:50-0600",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "b17dcbb16dfac3ce994a9bd97fd39d126ec66d9f",
15
- "version": "2.73.2b0"
14
+ "full-revisionid": "dd2f04e2b4b8386e585ebaf9cd935173dc333b11",
15
+ "version": "2.74.0rc1"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -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 == 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.get_cached_identity_data()
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)
@@ -44,6 +44,7 @@ class RequestOrigin(Enum):
44
44
  banner_and_modal = "banner_and_modal"
45
45
  api = "api"
46
46
  tcf_overlay = "tcf_overlay"
47
+ headless = "headless"
47
48
 
48
49
 
49
50
  class ConsentMethod(Enum):
@@ -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)