ethyca-fides 2.64.1rc0__py2.py3-none-any.whl → 2.64.2b0__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 (270) hide show
  1. {ethyca_fides-2.64.1rc0.dist-info → ethyca_fides-2.64.2b0.dist-info}/METADATA +2 -2
  2. {ethyca_fides-2.64.1rc0.dist-info → ethyca_fides-2.64.2b0.dist-info}/RECORD +235 -235
  3. fides/_version.py +3 -3
  4. fides/api/alembic/migrations/versions/6a76a1fa4f3f_add_manual_task_instance_table.py +256 -0
  5. fides/api/alembic/migrations/versions/aadfe83c5644_add_manual_task_to_connectiontype_enum.py +46 -0
  6. fides/api/db/base.py +4 -0
  7. fides/api/db/database.py +27 -2
  8. fides/api/models/attachment.py +15 -3
  9. fides/api/models/comment.py +22 -5
  10. fides/api/models/connectionconfig.py +11 -0
  11. fides/api/models/db_cache.py +1 -1
  12. fides/api/models/detection_discovery/core.py +15 -15
  13. fides/api/models/fides_user_respondent_email_verification.py +27 -2
  14. fides/api/models/manual_tasks/__init__.py +7 -1
  15. fides/api/models/manual_tasks/manual_task.py +68 -4
  16. fides/api/models/manual_tasks/manual_task_config.py +123 -12
  17. fides/api/models/manual_tasks/manual_task_instance.py +294 -0
  18. fides/api/models/manual_tasks/manual_task_log.py +48 -10
  19. fides/api/models/tcf_publisher_restrictions.py +16 -4
  20. fides/api/schemas/manual_tasks/manual_task_schemas.py +42 -0
  21. fides/api/schemas/manual_tasks/manual_task_status.py +107 -46
  22. fides/common/api/v1/urn_registry.py +4 -0
  23. fides/service/manual_tasks/manual_task_config_service.py +17 -5
  24. fides/service/manual_tasks/manual_task_instance_service.py +285 -0
  25. fides/service/manual_tasks/manual_task_service.py +66 -10
  26. fides/ui-build/static/admin/404.html +1 -1
  27. fides/ui-build/static/admin/_next/static/chunks/{1040-630c7f4284dc6f70.js → 1040-fa06cd3b94d97493.js} +1 -1
  28. fides/ui-build/static/admin/_next/static/chunks/1169-f75d7958fbe6e136.js +1 -0
  29. fides/ui-build/static/admin/_next/static/chunks/1807-3beab149351d5ded.js +1 -0
  30. fides/ui-build/static/admin/_next/static/chunks/{1817-b4688ba5042ec687.js → 1817-a3813209d7a6d28d.js} +1 -1
  31. fides/ui-build/static/admin/_next/static/chunks/{2921-aabf41bf3d7573f9.js → 2921-81a48418f77bc9a7.js} +1 -1
  32. fides/ui-build/static/admin/_next/static/chunks/{3450-bdaeb35442d810b4.js → 3450-2bb9f1b5a23fb520.js} +1 -1
  33. fides/ui-build/static/admin/_next/static/chunks/3615-5e2d062d684b8fa1.js +1 -0
  34. fides/ui-build/static/admin/_next/static/chunks/{3855-0dec3e7d9e886550.js → 3855-b85ad4e52433d519.js} +1 -1
  35. fides/ui-build/static/admin/_next/static/chunks/{3872-ffa16c2df7ef0ab6.js → 3872-09f81435f7905d76.js} +1 -1
  36. fides/ui-build/static/admin/_next/static/chunks/{3923-5d580fbb1dd6ae01.js → 3923-2565d952c662555c.js} +1 -1
  37. fides/ui-build/static/admin/_next/static/chunks/{401-fceaae662cfca5a5.js → 401-8ea41700c5437d38.js} +1 -1
  38. fides/ui-build/static/admin/_next/static/chunks/{409-037cfc3f096150f0.js → 409-e0d39af1d9ce8ff2.js} +1 -1
  39. fides/ui-build/static/admin/_next/static/chunks/4121-55f5b0bcb5ba41fb.js +1 -0
  40. fides/ui-build/static/admin/_next/static/chunks/{4230-1cdb7ea1be370ed3.js → 4230-b3fe52af1035dff5.js} +1 -1
  41. fides/ui-build/static/admin/_next/static/chunks/{431-f72599f01b98f07d.js → 431-c74dab231c8ac968.js} +1 -1
  42. fides/ui-build/static/admin/_next/static/chunks/{5309-4511df9708d5a63c.js → 5309-0e44dbd914896514.js} +1 -1
  43. fides/ui-build/static/admin/_next/static/chunks/{5574-3cd33b3a6c937899.js → 5574-917c5ff63d222308.js} +1 -1
  44. fides/ui-build/static/admin/_next/static/chunks/570-c99f07161bd339cd.js +1 -0
  45. fides/ui-build/static/admin/_next/static/chunks/6084-57446e3c99078be8.js +1 -0
  46. fides/ui-build/static/admin/_next/static/chunks/6662-45b8977f48a219f5.js +1 -0
  47. fides/ui-build/static/admin/_next/static/chunks/{6853-a4097260e402980e.js → 6853-8d0a099f61c758d1.js} +1 -1
  48. fides/ui-build/static/admin/_next/static/chunks/{6882-3cc73d407a088d7d.js → 6882-13d6f8d95b1e404f.js} +1 -1
  49. fides/ui-build/static/admin/_next/static/chunks/{6954-13a25cef3a8fdd76.js → 6954-4e106b3f7097fe6e.js} +1 -1
  50. fides/ui-build/static/admin/_next/static/chunks/7476-b5fb1c0cf4ad8f63.js +1 -0
  51. fides/ui-build/static/admin/_next/static/chunks/7630-e3d06546f9dfeb91.js +1 -0
  52. fides/ui-build/static/admin/_next/static/chunks/787-381156db4e81dbe8.js +1 -0
  53. fides/ui-build/static/admin/_next/static/chunks/{79-5670e31eb65d0a53.js → 79-3f742fe4efd9893f.js} +1 -1
  54. fides/ui-build/static/admin/_next/static/chunks/{796-9a6b13c838e25538.js → 796-83a8bbdcdb67f2ba.js} +1 -1
  55. fides/ui-build/static/admin/_next/static/chunks/827-c6fe34fb336467ae.js +1 -0
  56. fides/ui-build/static/admin/_next/static/chunks/9014-eeae6f581158e645.js +1 -0
  57. fides/ui-build/static/admin/_next/static/chunks/{9046-fdf53cc7e926a8c1.js → 9046-6995482a030e323c.js} +1 -1
  58. fides/ui-build/static/admin/_next/static/chunks/{905-742074a074be1055.js → 905-ffdbd0b14167e8bd.js} +1 -1
  59. fides/ui-build/static/admin/_next/static/chunks/{9226-ba6587e46ec7659a.js → 9226-2be3a6efb127148f.js} +1 -1
  60. fides/ui-build/static/admin/_next/static/chunks/{9392.25024e070026343d.js → 9392.9a948112de74781b.js} +1 -1
  61. fides/ui-build/static/admin/_next/static/chunks/{9676.e60a53f1f5890847.js → 9676.cc515c853b8cf578.js} +1 -1
  62. fides/ui-build/static/admin/_next/static/chunks/9767-980699a4d0f56acc.js +1 -0
  63. fides/ui-build/static/admin/_next/static/chunks/9826-303b14ef4fc7ab4a.js +1 -0
  64. fides/ui-build/static/admin/_next/static/chunks/{9951-f9ab5cac7e2c05ab.js → 9951-57c0a671463e0ebb.js} +1 -1
  65. fides/ui-build/static/admin/_next/static/chunks/pages/{404-ac2f0844e5c4b4cd.js → 404-488f8f03fe0ffbc7.js} +1 -1
  66. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-8ec6e466f3373ac0.js → _app-5e6fbbf17a62ac76.js} +68 -65
  67. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-0a5f2310ce6b1059.js → manual-1e88ac28bc7a41b6.js} +1 -1
  68. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-00cb904825aad7e3.js → multiple-f2c9451fffaaa529.js} +1 -1
  69. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-40a6b572d49c2b68.js +1 -0
  70. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-fa7305b88c1afd20.js → add-vendors-b17d160147365cf3.js} +1 -1
  71. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-f140ec9d8e8a0f7a.js → configure-8e168d78acdf0cfe.js} +1 -1
  72. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-0edb7c92518e7d21.js → [id]-5ca2467de7986929.js} +1 -1
  73. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-a0039f216fb3eb93.js → new-06bb3b0bf097fcdb.js} +1 -1
  74. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-d8d926f0735a2546.js → privacy-experience-3c11fecc2797ab68.js} +1 -1
  75. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-5c949f2e3cef2398.js → [id]-92bc6c7b82a679b4.js} +1 -1
  76. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-130155cfb4a0bcc7.js → new-a3da3243526b7ecb.js} +1 -1
  77. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-notices-1135ad8924d32c36.js → privacy-notices-b7d82386e7521041.js} +1 -1
  78. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-776855e370414beb.js → properties-20a2029b7e7fc895.js} +1 -1
  79. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{reporting-21c23f75ff1135d9.js → reporting-0ce299131db4c3e5.js} +1 -1
  80. fides/ui-build/static/admin/_next/static/chunks/pages/{consent-4d5ea70a77df1bb8.js → consent-9f6a7a231bba17b7.js} +1 -1
  81. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-c623d6f1a61c8ea9.js → [resourceUrn]-11d52f1570759c4d.js} +1 -1
  82. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-030ee304cbe5e530.js → [projectUrn]-fd705968b357e99a.js} +1 -1
  83. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{projects-cfac259a30641e68.js → projects-45b585deee0b2371.js} +1 -1
  84. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-57bd5cdf784f059f.js → [resourceUrn]-b83afa5565d0c84e.js} +1 -1
  85. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-51d99174c8006eb5.js → resources-d8db234a44a2ddf4.js} +1 -1
  86. fides/ui-build/static/admin/_next/static/chunks/pages/{data-catalog-7b5aec33da578745.js → data-catalog-4fd60a74c0369e3e.js} +1 -1
  87. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/{[systemId]-c948f93c833d4358.js → [systemId]-e861699a8866c64b.js} +1 -1
  88. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/{[monitorId]-333f53caab751428.js → [monitorId]-5dd2fbf33e228f9c.js} +1 -1
  89. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{action-center-27205f8457a1ecb0.js → action-center-806cae6bc128cd38.js} +1 -1
  90. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{activity-20a1043f6a06198f.js → activity-487285bd5eca2595.js} +1 -1
  91. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-06edce289876dea1.js → [resourceUrn]-393e20924c83373e.js} +1 -1
  92. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-faf326a6200637d0.js → detection-8733807dad4bc96e.js} +1 -1
  93. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-64acf269256ee74f.js → [resourceUrn]-14bd7500362ff224.js} +1 -1
  94. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-8c3e4be6d36da66d.js → discovery-9e7dfd5a6acc2e8f.js} +1 -1
  95. fides/ui-build/static/admin/_next/static/chunks/pages/{datamap-fb50de22f83edd4a.js → datamap-c9509d72c538d22b.js} +1 -1
  96. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-41ab27c4195cfa93.js → [...subfieldNames]-4e8a436297a055b2.js} +1 -1
  97. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-6e2caba24b3e78c2.js → [collectionName]-6ce02295bb7f5b6d.js} +1 -1
  98. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{[datasetId]-904d43e31157aa55.js → [datasetId]-9eaa907437fde063.js} +1 -1
  99. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-de5e9ccfecdf31b1.js +1 -0
  100. fides/ui-build/static/admin/_next/static/chunks/pages/{dataset-8f7d16bc5e9229c8.js → dataset-dcdec3644f05188d.js} +1 -1
  101. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-4a33dd0371dbaebc.js → [id]-81ab412e337d2888.js} +1 -1
  102. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{new-e88509346b2d2851.js → new-34dfc172165dbb1c.js} +1 -1
  103. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-cdb77886d7fd4f44.js +1 -0
  104. fides/ui-build/static/admin/_next/static/chunks/pages/{index-1adb6bcb71701ac2.js → index-de954b741cbca022.js} +1 -1
  105. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/{[id]-fdc2964fa7d1d8fd.js → [id]-dba625eddca48f69.js} +1 -1
  106. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-40a3cd14264796e2.js +1 -0
  107. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{[id]-9b4d1d61c7c97509.js → [id]-42edcab11e8b5c3c.js} +1 -1
  108. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{add-template-f8fd4795e260887c.js → add-template-333e54ac8c3ad57a.js} +1 -1
  109. fides/ui-build/static/admin/_next/static/chunks/pages/{messaging-aa744ae8b61e5ff2.js → messaging-8e1e6f3782983225.js} +1 -1
  110. fides/ui-build/static/admin/_next/static/chunks/pages/poc/{ant-components-3407158757fb3627.js → ant-components-25c74d51a49b2403.js} +1 -1
  111. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{AntForm-47e947c02ae90fd0.js → AntForm-920338760f5a71b5.js} +1 -1
  112. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikAntFormItem-24f9a44512ce8827.js → FormikAntFormItem-7462fb387a9de3f8.js} +1 -1
  113. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikControlled-e567a69f8c37fb9a.js → FormikControlled-6148fce7a4e2e9ca.js} +1 -1
  114. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikField-35a33f9c7def2220.js → FormikField-30efd8c937bf19e4.js} +1 -1
  115. fides/ui-build/static/admin/_next/static/chunks/pages/poc/{forms-780e18dde8e38099.js → forms-c44de83e0952d1e0.js} +1 -1
  116. fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-7852aa60090c8c9a.js +1 -0
  117. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-11dd6152bf6607cc.js +1 -0
  118. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-83a548813fec4f90.js +1 -0
  119. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-a087847d6cbccc65.js +1 -0
  120. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-1a1aa83a3f88844c.js → configure-1d981663e1a84166.js} +1 -1
  121. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-6a5794999a1cc0b6.js +1 -0
  122. fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-19737d4f21aadbee.js → [id]-b08a69b1c460c7fe.js} +1 -1
  123. fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-9ccb295110feee20.js → add-property-a5d1c65ec21df69d.js} +1 -1
  124. fides/ui-build/static/admin/_next/static/chunks/pages/{properties-3a1037a2e036212a.js → properties-3a75c6ed8308d126.js} +1 -1
  125. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/{datamap-4cdbbb8cd1d8698e.js → datamap-911996819aa16e04.js} +1 -1
  126. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/{alpha-965cc21889b25e44.js → alpha-6773158ba6ccf4b0.js} +1 -1
  127. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-0e1c381d488a7ada.js → about-2e046d177d52465c.js} +1 -1
  128. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/{[purpose_id]-d0e350d2a2667883.js → [purpose_id]-a5420c3ba02fe6a5.js} +1 -1
  129. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-2a95eb36aa2b47a6.js +1 -0
  130. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{custom-fields-6f866bc799a5f67f.js → custom-fields-06075fbf122c98d0.js} +1 -1
  131. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-0b44b2b224077dcd.js → domain-records-2c7ecff0a8a74c42.js} +1 -1
  132. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-afed8ba5498a9f93.js +1 -0
  133. fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-c1d3f3cb9c6ca463.js +1 -0
  134. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-811dadb489f23d7d.js → locations-8d4383584c72eb5a.js} +1 -1
  135. fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-aae79a344a96a367.js +1 -0
  136. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-54f142bc3e4c95ba.js → regulations-29892065d99ff113.js} +1 -1
  137. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-9669fa6b20545530.js +1 -0
  138. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-6eb886e7b7e6785b.js → [id]-8fa8a2f238e08791.js} +1 -1
  139. fides/ui-build/static/admin/_next/static/chunks/pages/{systems-7b71274334c559a4.js → systems-acdbdd3dfd21162f.js} +1 -1
  140. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-9b4d28f02df3a238.js +1 -0
  141. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-b124cc24b930c9e1.js → new-a2524414e968f862.js} +1 -1
  142. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-75d41fde668b9025.js → [id]-87ed17fa1d9f8f72.js} +1 -1
  143. fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-dd43755b687c09a7.js → user-management-6b4e0764bb8816b8.js} +1 -1
  144. fides/ui-build/static/admin/_next/static/chunks/webpack-da78c536f3d86d06.js +1 -0
  145. fides/ui-build/static/admin/_next/static/css/{c693338e3bc8dcc6.css → 67ac3d00a5f134a2.css} +1 -1
  146. fides/ui-build/static/admin/_next/static/jg8bMUMFAG7KlEnEbTRct/_buildManifest.js +1 -0
  147. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  148. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  149. fides/ui-build/static/admin/add-systems.html +1 -1
  150. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  151. fides/ui-build/static/admin/consent/configure.html +1 -1
  152. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  153. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  154. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  155. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  156. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  157. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  158. fides/ui-build/static/admin/consent/properties.html +1 -1
  159. fides/ui-build/static/admin/consent/reporting.html +1 -1
  160. fides/ui-build/static/admin/consent.html +1 -1
  161. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  162. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  163. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  164. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  165. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  166. fides/ui-build/static/admin/data-catalog.html +1 -1
  167. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
  168. fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
  169. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  170. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  171. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  172. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  173. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  174. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  175. fides/ui-build/static/admin/datamap.html +1 -1
  176. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  177. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  178. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  179. fides/ui-build/static/admin/dataset/new.html +1 -1
  180. fides/ui-build/static/admin/dataset.html +1 -1
  181. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  182. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  183. fides/ui-build/static/admin/datastore-connection.html +1 -1
  184. fides/ui-build/static/admin/index.html +1 -1
  185. fides/ui-build/static/admin/integrations/[id].html +1 -1
  186. fides/ui-build/static/admin/integrations.html +1 -1
  187. fides/ui-build/static/admin/lib/fides-headless.js +1 -1
  188. fides/ui-build/static/admin/lib/fides-preview.js +1 -1
  189. fides/ui-build/static/admin/lib/fides-tcf.js +2 -2
  190. fides/ui-build/static/admin/lib/fides.js +2 -2
  191. fides/ui-build/static/admin/login/[provider].html +1 -1
  192. fides/ui-build/static/admin/login.html +1 -1
  193. fides/ui-build/static/admin/messaging/[id].html +1 -1
  194. fides/ui-build/static/admin/messaging/add-template.html +1 -1
  195. fides/ui-build/static/admin/messaging.html +1 -1
  196. fides/ui-build/static/admin/poc/ant-components.html +1 -1
  197. fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
  198. fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
  199. fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
  200. fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
  201. fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
  202. fides/ui-build/static/admin/poc/forms.html +1 -1
  203. fides/ui-build/static/admin/poc/table-migration.html +1 -1
  204. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  205. fides/ui-build/static/admin/privacy-requests/configure/messaging.html +1 -1
  206. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  207. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  208. fides/ui-build/static/admin/privacy-requests.html +1 -1
  209. fides/ui-build/static/admin/properties/[id].html +1 -1
  210. fides/ui-build/static/admin/properties/add-property.html +1 -1
  211. fides/ui-build/static/admin/properties.html +1 -1
  212. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  213. fides/ui-build/static/admin/settings/about/alpha.html +1 -1
  214. fides/ui-build/static/admin/settings/about.html +1 -1
  215. fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
  216. fides/ui-build/static/admin/settings/consent.html +1 -1
  217. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  218. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  219. fides/ui-build/static/admin/settings/domains.html +1 -1
  220. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  221. fides/ui-build/static/admin/settings/locations.html +1 -1
  222. fides/ui-build/static/admin/settings/organization.html +1 -1
  223. fides/ui-build/static/admin/settings/regulations.html +1 -1
  224. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  225. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  226. fides/ui-build/static/admin/systems.html +1 -1
  227. fides/ui-build/static/admin/taxonomy.html +1 -1
  228. fides/ui-build/static/admin/user-management/new.html +1 -1
  229. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  230. fides/ui-build/static/admin/user-management.html +1 -1
  231. fides/ui-build/static/admin/_next/static/chunks/1100-d43cb04522a6505c.js +0 -1
  232. fides/ui-build/static/admin/_next/static/chunks/2430-b480401d44c55416.js +0 -1
  233. fides/ui-build/static/admin/_next/static/chunks/3505-a79256cd851dfab4.js +0 -1
  234. fides/ui-build/static/admin/_next/static/chunks/3513-8677ee280eaef0da.js +0 -1
  235. fides/ui-build/static/admin/_next/static/chunks/3670-2abd9b2f17770872.js +0 -1
  236. fides/ui-build/static/admin/_next/static/chunks/3983-17ae9c232bddc413.js +0 -1
  237. fides/ui-build/static/admin/_next/static/chunks/4060-71cd041e5a57ca5a.js +0 -1
  238. fides/ui-build/static/admin/_next/static/chunks/4121-78a76e980acbd539.js +0 -1
  239. fides/ui-build/static/admin/_next/static/chunks/4481-f597a7cf03f8c9e1.js +0 -1
  240. fides/ui-build/static/admin/_next/static/chunks/6060-cb1ab5be7067bf7b.js +0 -4
  241. fides/ui-build/static/admin/_next/static/chunks/6277-3fb4c7fc790a6d20.js +0 -1
  242. fides/ui-build/static/admin/_next/static/chunks/6659-b2088f525bf13c17.js +0 -1
  243. fides/ui-build/static/admin/_next/static/chunks/6662-6a6b90fc8f11558f.js +0 -1
  244. fides/ui-build/static/admin/_next/static/chunks/69-6889d6674c95e7b5.js +0 -1
  245. fides/ui-build/static/admin/_next/static/chunks/7553-a95939c32d54b5b7.js +0 -1
  246. fides/ui-build/static/admin/_next/static/chunks/8433-adb1fcb29d82f1b7.js +0 -1
  247. fides/ui-build/static/admin/_next/static/chunks/9767-e49b065d03ce4e80.js +0 -1
  248. fides/ui-build/static/admin/_next/static/chunks/c78d26b1-88a3e1bacb2a03c2.js +0 -1
  249. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-587e21d14e0a5196.js +0 -1
  250. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-d4e31a1c4a58800e.js +0 -1
  251. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-8f9b8890018e1ea5.js +0 -1
  252. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-adc286ff254e7f41.js +0 -1
  253. fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-7a17dffa515e5560.js +0 -1
  254. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-91dd0039cc2b70bc.js +0 -1
  255. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-b01cbbaac34dadbc.js +0 -1
  256. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-a15410de7f1d0f84.js +0 -1
  257. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-c4e1b69fb5bab61a.js +0 -1
  258. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-7796fbf458f8f159.js +0 -1
  259. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-5d00e1155bd11178.js +0 -1
  260. fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-d2cdbe770683e9df.js +0 -1
  261. fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-24108f615ff5e1e7.js +0 -1
  262. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-fef247a87baeb080.js +0 -1
  263. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-18534d2a79a3850b.js +0 -1
  264. fides/ui-build/static/admin/_next/static/chunks/webpack-0a61b5bd21a41fe6.js +0 -1
  265. fides/ui-build/static/admin/_next/static/hCJxUAFBWobWrps6RkP0K/_buildManifest.js +0 -1
  266. {ethyca_fides-2.64.1rc0.dist-info → ethyca_fides-2.64.2b0.dist-info}/WHEEL +0 -0
  267. {ethyca_fides-2.64.1rc0.dist-info → ethyca_fides-2.64.2b0.dist-info}/entry_points.txt +0 -0
  268. {ethyca_fides-2.64.1rc0.dist-info → ethyca_fides-2.64.2b0.dist-info}/licenses/LICENSE +0 -0
  269. {ethyca_fides-2.64.1rc0.dist-info → ethyca_fides-2.64.2b0.dist-info}/top_level.txt +0 -0
  270. /fides/ui-build/static/admin/_next/static/{hCJxUAFBWobWrps6RkP0K → jg8bMUMFAG7KlEnEbTRct}/_ssgManifest.js +0 -0
@@ -3,12 +3,18 @@ from fides.api.models.manual_tasks.manual_task_config import (
3
3
  ManualTaskConfig,
4
4
  ManualTaskConfigField,
5
5
  )
6
+ from fides.api.models.manual_tasks.manual_task_instance import (
7
+ ManualTaskInstance,
8
+ ManualTaskSubmission,
9
+ )
6
10
  from fides.api.models.manual_tasks.manual_task_log import ManualTaskLog
7
11
 
8
12
  __all__ = [
9
13
  "ManualTask",
10
14
  "ManualTaskConfig",
11
15
  "ManualTaskConfigField",
12
- "ManualTaskReference",
16
+ "ManualTaskInstance",
13
17
  "ManualTaskLog",
18
+ "ManualTaskReference",
19
+ "ManualTaskSubmission",
14
20
  ]
@@ -1,10 +1,11 @@
1
1
  from typing import TYPE_CHECKING, Any
2
2
 
3
- from sqlalchemy import Column, DateTime, ForeignKey, String
3
+ from sqlalchemy import Column, DateTime, ForeignKey, Index, String, UniqueConstraint
4
4
  from sqlalchemy.ext.declarative import declared_attr
5
5
  from sqlalchemy.orm import Session, relationship
6
+ from sqlalchemy.sql import func
6
7
 
7
- from fides.api.db.base_class import Base
8
+ from fides.api.db.base_class import Base, FidesBase
8
9
  from fides.api.db.util import EnumColumn
9
10
  from fides.api.models.manual_tasks.manual_task_log import ManualTaskLog
10
11
  from fides.api.schemas.manual_tasks.manual_task_schemas import (
@@ -18,6 +19,10 @@ if TYPE_CHECKING: # pragma: no cover
18
19
  from fides.api.models.manual_tasks.manual_task_config import ( # pragma: no cover
19
20
  ManualTaskConfig,
20
21
  )
22
+ from fides.api.models.manual_tasks.manual_task_instance import (
23
+ ManualTaskInstance,
24
+ ManualTaskSubmission,
25
+ )
21
26
 
22
27
 
23
28
  class ManualTask(Base):
@@ -36,6 +41,22 @@ class ManualTask(Base):
36
41
  """Overriding base class method to set the table name."""
37
42
  return "manual_task"
38
43
 
44
+ # redefined here because there's a minor, unintended discrepancy between
45
+ # this `id` field and that of the `Base` class, which explicitly sets `index=True`.
46
+ # TODO: we likely should _not_ be setting `index=True` on the `id`
47
+ # attribute of the `Base` class, as `primary_key=True` already specifies a
48
+ # primary key constraint, which will implicitly create an index for the field.
49
+ id = Column(String(255), primary_key=True, default=FidesBase.generate_uuid)
50
+ created_at = Column(
51
+ DateTime(timezone=True), server_default=func.now(), nullable=False
52
+ )
53
+ updated_at = Column(
54
+ DateTime(timezone=True),
55
+ server_default=func.now(),
56
+ onupdate=func.now(),
57
+ nullable=False,
58
+ )
59
+
39
60
  # Database columns
40
61
  task_type = Column(
41
62
  EnumColumn(ManualTaskType),
@@ -48,7 +69,16 @@ class ManualTask(Base):
48
69
  nullable=False,
49
70
  default=ManualTaskParentEntityType.connection_config,
50
71
  )
51
- due_date = Column(DateTime, nullable=True)
72
+
73
+ __table_args__ = (
74
+ UniqueConstraint(
75
+ "parent_entity_id",
76
+ "parent_entity_type",
77
+ name="uq_manual_task_parent_entity",
78
+ ),
79
+ Index("ix_manual_task_parent_entity", "parent_entity_type", "parent_entity_id"),
80
+ Index("ix_manual_task_task_type", "task_type"),
81
+ )
52
82
 
53
83
  # Relationships
54
84
  references = relationship(
@@ -68,6 +98,19 @@ class ManualTask(Base):
68
98
  "ManualTaskConfig",
69
99
  back_populates="task",
70
100
  cascade="all, delete-orphan",
101
+ uselist=True,
102
+ )
103
+ instances = relationship(
104
+ "ManualTaskInstance",
105
+ back_populates="task",
106
+ viewonly=True,
107
+ uselist=True,
108
+ )
109
+ submissions = relationship(
110
+ "ManualTaskSubmission",
111
+ back_populates="task",
112
+ uselist=True,
113
+ viewonly=True,
71
114
  )
72
115
 
73
116
  # Properties
@@ -109,6 +152,22 @@ class ManualTaskReference(Base):
109
152
  """Overriding base class method to set the table name."""
110
153
  return "manual_task_reference"
111
154
 
155
+ # redefined here because there's a minor, unintended discrepancy between
156
+ # this `id` field and that of the `Base` class, which explicitly sets `index=True`.
157
+ # TODO: we likely should _not_ be setting `index=True` on the `id`
158
+ # attribute of the `Base` class, as `primary_key=True` already specifies a
159
+ # primary key constraint, which will implicitly create an index for the field.
160
+ id = Column(String(255), primary_key=True, default=FidesBase.generate_uuid)
161
+ created_at = Column(
162
+ DateTime(timezone=True), server_default=func.now(), nullable=False
163
+ )
164
+ updated_at = Column(
165
+ DateTime(timezone=True),
166
+ server_default=func.now(),
167
+ onupdate=func.now(),
168
+ nullable=False,
169
+ )
170
+
112
171
  # Database columns
113
172
  task_id = Column(
114
173
  String, ForeignKey("manual_task.id", ondelete="CASCADE"), nullable=False
@@ -116,5 +175,10 @@ class ManualTaskReference(Base):
116
175
  reference_id = Column(String, nullable=False)
117
176
  reference_type = Column(EnumColumn(ManualTaskReferenceType), nullable=False)
118
177
 
178
+ __table_args__ = (
179
+ Index("ix_manual_task_reference_reference", "reference_id", "reference_type"),
180
+ Index("ix_manual_task_reference_task_id", "task_id"),
181
+ )
182
+
119
183
  # Relationships
120
- task = relationship("ManualTask", back_populates="references")
184
+ task = relationship("ManualTask", back_populates="references", viewonly=True)
@@ -1,11 +1,21 @@
1
- from typing import TYPE_CHECKING, Any, Optional
2
-
3
- from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
1
+ from typing import TYPE_CHECKING, Any, Optional, cast
2
+
3
+ from sqlalchemy import (
4
+ Boolean,
5
+ Column,
6
+ DateTime,
7
+ ForeignKey,
8
+ Index,
9
+ Integer,
10
+ String,
11
+ UniqueConstraint,
12
+ )
4
13
  from sqlalchemy.dialects.postgresql import JSONB
5
14
  from sqlalchemy.ext.declarative import declared_attr
6
15
  from sqlalchemy.orm import Session, relationship
16
+ from sqlalchemy.sql import func
7
17
 
8
- from fides.api.db.base_class import Base
18
+ from fides.api.db.base_class import Base, FidesBase
9
19
  from fides.api.db.util import EnumColumn
10
20
  from fides.api.models.manual_tasks.manual_task_log import ManualTaskLog
11
21
  from fides.api.schemas.manual_tasks.manual_task_config import (
@@ -13,10 +23,19 @@ from fides.api.schemas.manual_tasks.manual_task_config import (
13
23
  ManualTaskFieldMetadata,
14
24
  ManualTaskFieldType,
15
25
  )
16
- from fides.api.schemas.manual_tasks.manual_task_schemas import ManualTaskLogStatus
26
+ from fides.api.schemas.manual_tasks.manual_task_schemas import (
27
+ ManualTaskExecutionTiming,
28
+ ManualTaskLogStatus,
29
+ )
17
30
 
18
31
  if TYPE_CHECKING: # pragma: no cover
19
32
  from fides.api.models.manual_tasks.manual_task import ManualTask # pragma: no cover
33
+ from fides.api.models.manual_tasks.manual_task_instance import (
34
+ ManualTaskInstance, # pragma: no cover
35
+ )
36
+ from fides.api.models.manual_tasks.manual_task_instance import (
37
+ ManualTaskSubmission, # pragma: no cover
38
+ )
20
39
 
21
40
 
22
41
  class ManualTaskConfig(Base):
@@ -28,13 +47,53 @@ class ManualTaskConfig(Base):
28
47
  def __tablename__(cls) -> str:
29
48
  return "manual_task_config"
30
49
 
31
- task_id = Column(String, ForeignKey("manual_task.id"), nullable=False)
50
+ # redefined here because there's a minor, unintended discrepancy between
51
+ # this `id` field and that of the `Base` class, which explicitly sets `index=True`.
52
+ # TODO: we likely should _not_ be setting `index=True` on the `id`
53
+ # attribute of the `Base` class, as `primary_key=True` already specifies a
54
+ # primary key constraint, which will implicitly create an index for the field.
55
+ id = Column(String(255), primary_key=True, default=FidesBase.generate_uuid)
56
+ created_at = Column(
57
+ DateTime(timezone=True), server_default=func.now(), nullable=False
58
+ )
59
+ updated_at = Column(
60
+ DateTime(timezone=True),
61
+ server_default=func.now(),
62
+ onupdate=func.now(),
63
+ nullable=False,
64
+ )
65
+
66
+ task_id = Column(
67
+ String,
68
+ ForeignKey(
69
+ "manual_task.id",
70
+ name="manual_task_config_task_id_fkey",
71
+ ondelete="CASCADE",
72
+ ),
73
+ nullable=False,
74
+ )
32
75
  config_type = Column(EnumColumn(ManualTaskConfigurationType), nullable=False)
33
76
  version = Column(Integer, nullable=False, default=1)
34
77
  is_current = Column(Boolean, nullable=False, default=True)
78
+ execution_timing = Column(
79
+ EnumColumn(ManualTaskExecutionTiming),
80
+ nullable=False,
81
+ default=ManualTaskExecutionTiming.pre_execution,
82
+ )
83
+
84
+ __table_args__ = (
85
+ Index("ix_manual_task_config_config_type", "config_type"),
86
+ Index("ix_manual_task_config_task_id", "task_id"),
87
+ )
35
88
 
36
89
  # Relationships
37
- task = relationship("ManualTask", back_populates="configs")
90
+ task = relationship("ManualTask", back_populates="configs", viewonly=True)
91
+ instances = relationship(
92
+ "ManualTaskInstance", back_populates="config", uselist=True, viewonly=True
93
+ )
94
+ submissions = relationship(
95
+ "ManualTaskSubmission", back_populates="config", uselist=True, viewonly=True
96
+ )
38
97
  field_definitions = relationship(
39
98
  "ManualTaskConfigField",
40
99
  back_populates="config",
@@ -45,7 +104,7 @@ class ManualTaskConfig(Base):
45
104
  "ManualTaskLog",
46
105
  back_populates="config",
47
106
  primaryjoin="ManualTaskConfig.id == ManualTaskLog.config_id",
48
- viewonly=True,
107
+ cascade="all, delete-orphan",
49
108
  )
50
109
 
51
110
  @classmethod
@@ -89,20 +148,72 @@ class ManualTaskConfigField(Base):
89
148
  def __tablename__(cls) -> str:
90
149
  return "manual_task_config_field"
91
150
 
92
- task_id = Column(String, ForeignKey("manual_task.id"), nullable=False)
93
- config_id = Column(String, ForeignKey("manual_task_config.id"), nullable=False)
151
+ # redefined here because there's a minor, unintended discrepancy between
152
+ # this `id` field and that of the `Base` class, which explicitly sets `index=True`.
153
+ # TODO: we likely should _not_ be setting `index=True` on the `id`
154
+ # attribute of the `Base` class, as `primary_key=True` already specifies a
155
+ # primary key constraint, which will implicitly create an index for the field.
156
+ id = Column(String(255), primary_key=True, default=FidesBase.generate_uuid)
157
+ created_at = Column(
158
+ DateTime(timezone=True), server_default=func.now(), nullable=False
159
+ )
160
+ updated_at = Column(
161
+ DateTime(timezone=True),
162
+ server_default=func.now(),
163
+ onupdate=func.now(),
164
+ nullable=False,
165
+ )
166
+
167
+ task_id = Column(
168
+ String,
169
+ ForeignKey(
170
+ "manual_task.id",
171
+ name="manual_task_config_field_task_id_fkey",
172
+ ondelete="CASCADE",
173
+ ),
174
+ nullable=False,
175
+ )
176
+ config_id = Column(
177
+ String,
178
+ ForeignKey(
179
+ "manual_task_config.id",
180
+ name="manual_task_config_field_config_id_fkey",
181
+ ondelete="CASCADE",
182
+ ),
183
+ nullable=False,
184
+ )
94
185
  field_key = Column(String, nullable=False)
95
186
  field_type = Column(
96
187
  EnumColumn(ManualTaskFieldType), nullable=False
97
188
  ) # Using ManualTaskFieldType
98
- field_metadata = Column(JSONB, nullable=False, default={})
189
+ field_metadata: dict[str, Any] = cast(
190
+ dict[str, Any], Column(JSONB, nullable=False, default={})
191
+ )
192
+
193
+ __table_args__ = (
194
+ UniqueConstraint("config_id", "field_key", name="unique_field_key_per_config"),
195
+ Index("ix_manual_task_config_field_config_id", "config_id"),
196
+ Index("ix_manual_task_config_field_field_key", "field_key"),
197
+ Index("ix_manual_task_config_field_task_id", "task_id"),
198
+ )
99
199
 
100
200
  # Relationships
101
- config = relationship("ManualTaskConfig", back_populates="field_definitions")
201
+ config = relationship(
202
+ "ManualTaskConfig", back_populates="field_definitions", viewonly=True
203
+ )
204
+ submissions = relationship(
205
+ "ManualTaskSubmission",
206
+ back_populates="field",
207
+ uselist=True,
208
+ cascade="all, delete-orphan",
209
+ )
102
210
 
103
211
  @property
104
212
  def field_metadata_model(self) -> ManualTaskFieldMetadata:
105
213
  """Get the field metadata as a Pydantic model."""
214
+ assert isinstance(
215
+ self.field_metadata, dict
216
+ ), "field_metadata must be a dictionary"
106
217
  return ManualTaskFieldMetadata.model_validate(self.field_metadata)
107
218
 
108
219
  @classmethod
@@ -0,0 +1,294 @@
1
+ from datetime import datetime, timezone
2
+ from typing import TYPE_CHECKING, Optional
3
+
4
+ from sqlalchemy import Column, DateTime, ForeignKey, Index, String
5
+ from sqlalchemy.dialects.postgresql import JSONB
6
+ from sqlalchemy.ext.declarative import declared_attr
7
+ from sqlalchemy.orm import relationship
8
+ from sqlalchemy.sql import func
9
+
10
+ from fides.api.db.base_class import Base, FidesBase
11
+ from fides.api.db.util import EnumColumn
12
+ from fides.api.models.manual_tasks.manual_task_config import ManualTaskConfigField
13
+ from fides.api.schemas.manual_tasks.manual_task_schemas import ManualTaskEntityType
14
+ from fides.api.schemas.manual_tasks.manual_task_status import (
15
+ StatusTransitionMixin,
16
+ StatusType,
17
+ )
18
+
19
+ if TYPE_CHECKING: # pragma: no cover
20
+ from fides.api.models.attachment import Attachment # pragma: no cover
21
+ from fides.api.models.fides_user import FidesUser # pragma: no cover
22
+ from fides.api.models.manual_tasks.manual_task import ManualTask # pragma: no cover
23
+ from fides.api.models.manual_tasks.manual_task_config import (
24
+ ManualTaskConfig, # pragma: no cover
25
+ )
26
+ from fides.api.models.manual_tasks.manual_task_log import (
27
+ ManualTaskLog, # pragma: no cover; pragma: no cover
28
+ )
29
+
30
+
31
+ class ManualTaskInstance(Base, StatusTransitionMixin):
32
+ """Model for tracking task status per entity instance.
33
+
34
+ This model implements StatusTransitionProtocol through the StatusTransitionMixin.
35
+ """
36
+
37
+ @declared_attr
38
+ def __tablename__(cls) -> str:
39
+ """Overriding base class method to set the table name."""
40
+ return "manual_task_instance"
41
+
42
+ # redefined here because there's a minor, unintended discrepancy between
43
+ # this `id` field and that of the `Base` class, which explicitly sets `index=True`.
44
+ # TODO: we likely should _not_ be setting `index=True` on the `id`
45
+ # attribute of the `Base` class, as `primary_key=True` already specifies a
46
+ # primary key constraint, which will implicitly create an index for the field.
47
+ id = Column(String(255), primary_key=True, default=FidesBase.generate_uuid)
48
+ created_at = Column(
49
+ DateTime(timezone=True), server_default=func.now(), nullable=False
50
+ )
51
+ updated_at = Column(
52
+ DateTime(timezone=True),
53
+ server_default=func.now(),
54
+ onupdate=func.now(),
55
+ nullable=False,
56
+ )
57
+
58
+ # Database columns
59
+ task_id: Column[str] = Column(
60
+ String,
61
+ ForeignKey(
62
+ "manual_task.id",
63
+ name="manual_task_instance_task_id_fkey",
64
+ ondelete="CASCADE",
65
+ ),
66
+ nullable=False,
67
+ )
68
+ config_id: Column[str] = Column(
69
+ String,
70
+ ForeignKey(
71
+ "manual_task_config.id",
72
+ name="manual_task_instance_config_id_fkey",
73
+ ondelete="CASCADE",
74
+ ),
75
+ nullable=False,
76
+ )
77
+ # entity id is the entity that the instance relates to
78
+ # (e.g. a privacy request is an entity that has its own manual task instance)
79
+ entity_id: Column[str] = Column(String, nullable=False)
80
+ entity_type: Column[ManualTaskEntityType] = Column(
81
+ EnumColumn(ManualTaskEntityType), nullable=False
82
+ )
83
+ # ingnore[assignment] because the mypy and sqlalchemy types mismatch
84
+ # upgrading to 2.0 allows mapping which provides better type safety visibility.
85
+ status: Column[StatusType] = Column(EnumColumn(StatusType), nullable=False, default=StatusType.pending) # type: ignore[assignment]
86
+ completed_at: Column[Optional[datetime]] = Column(DateTime, nullable=True) # type: ignore[assignment]
87
+ completed_by_id: Column[Optional[str]] = Column(String, nullable=True) # type: ignore[assignment]
88
+ due_date: Column[Optional[datetime]] = Column(DateTime, nullable=True)
89
+
90
+ __table_args__ = (
91
+ Index("ix_manual_task_instance_completed_at", "completed_at"),
92
+ Index("ix_manual_task_instance_config_id", "config_id"),
93
+ Index("ix_manual_task_instance_entity", "entity_type", "entity_id"),
94
+ Index("ix_manual_task_instance_entity_id", "entity_id"),
95
+ Index("ix_manual_task_instance_entity_type", "entity_type"),
96
+ Index("ix_manual_task_instance_status", "status"),
97
+ Index("ix_manual_task_instance_task_id", "task_id"),
98
+ )
99
+
100
+ # Relationships
101
+ task = relationship("ManualTask", back_populates="instances")
102
+ config = relationship("ManualTaskConfig", back_populates="instances")
103
+ submissions = relationship(
104
+ "ManualTaskSubmission",
105
+ back_populates="instance",
106
+ cascade="all, delete-orphan",
107
+ uselist=True,
108
+ )
109
+ logs = relationship(
110
+ "ManualTaskLog",
111
+ back_populates="instance",
112
+ primaryjoin="ManualTaskInstance.id == ManualTaskLog.instance_id",
113
+ cascade="all, delete-orphan",
114
+ order_by="ManualTaskLog.created_at",
115
+ uselist=True,
116
+ )
117
+ attachments = relationship(
118
+ "Attachment",
119
+ secondary="attachment_reference",
120
+ primaryjoin="and_(ManualTaskInstance.id == ManualTaskSubmission.instance_id, "
121
+ "ManualTaskSubmission.id == AttachmentReference.reference_id, "
122
+ "AttachmentReference.reference_type == 'manual_task_submission')",
123
+ secondaryjoin="Attachment.id == AttachmentReference.attachment_id",
124
+ order_by="Attachment.created_at",
125
+ viewonly=True,
126
+ uselist=True,
127
+ )
128
+
129
+ @property
130
+ def required_fields(self) -> list["ManualTaskConfigField"]:
131
+ """Get all required fields."""
132
+ return [
133
+ field
134
+ for field in self.config.field_definitions
135
+ if field.field_metadata.get("required", False)
136
+ ]
137
+
138
+ @property
139
+ def incomplete_fields(self) -> list["ManualTaskConfigField"]:
140
+ """Get all fields that haven't been completed yet.
141
+ A field is considered incomplete if:
142
+ 1. It's required and has no submission
143
+ Returns:
144
+ list[ManualTaskConfigField]: List of incomplete fields
145
+ """
146
+ return [
147
+ field
148
+ for field in self.required_fields
149
+ if not self.get_submission_for_field(field.id)
150
+ ]
151
+
152
+ @property
153
+ def completed_fields(self) -> list["ManualTaskConfigField"]:
154
+ """Get all fields that have been completed."""
155
+ return [
156
+ field
157
+ for field in self.config.field_definitions
158
+ if field.field_metadata.get("required", False)
159
+ and self.get_submission_for_field(field.id)
160
+ ]
161
+
162
+ def get_submission_for_field(
163
+ self, field_id: str
164
+ ) -> Optional["ManualTaskSubmission"]:
165
+ """Get the submission for a specific field.
166
+
167
+ Args:
168
+ field_id: The ID of the field to get the submission for
169
+
170
+ Returns:
171
+ Optional[ManualTaskSubmission]: The submission for the field, or None if no submission exists
172
+ """
173
+ return next(
174
+ (
175
+ submission
176
+ for submission in self.submissions
177
+ if submission.field_id == field_id
178
+ ),
179
+ None,
180
+ )
181
+
182
+
183
+ class ManualTaskSubmission(Base):
184
+ """Model for storing user submissions.
185
+ Each submission represents data for a single field.
186
+ """
187
+
188
+ @declared_attr
189
+ def __tablename__(cls) -> str:
190
+ """Overriding base class method to set the table name."""
191
+ return "manual_task_submission"
192
+
193
+ # redefined here because there's a minor, unintended discrepancy between
194
+ # this `id` field and that of the `Base` class, which explicitly sets `index=True`.
195
+ # TODO: we likely should _not_ be setting `index=True` on the `id`
196
+ # attribute of the `Base` class, as `primary_key=True` already specifies a
197
+ # primary key constraint, which will implicitly create an index for the field.
198
+ id = Column(String(255), primary_key=True, default=FidesBase.generate_uuid)
199
+ created_at = Column(
200
+ DateTime(timezone=True), server_default=func.now(), nullable=False
201
+ )
202
+ updated_at = Column(
203
+ DateTime(timezone=True),
204
+ server_default=func.now(),
205
+ onupdate=func.now(),
206
+ nullable=False,
207
+ )
208
+
209
+ # Database columns
210
+ task_id = Column(
211
+ String,
212
+ ForeignKey(
213
+ "manual_task.id",
214
+ name="manual_task_submission_task_id_fkey",
215
+ ondelete="CASCADE",
216
+ ),
217
+ nullable=False,
218
+ )
219
+ config_id = Column(
220
+ String,
221
+ ForeignKey(
222
+ "manual_task_config.id",
223
+ name="manual_task_submission_config_id_fkey",
224
+ ondelete="CASCADE",
225
+ ),
226
+ nullable=False,
227
+ )
228
+ field_id = Column(
229
+ String,
230
+ ForeignKey(
231
+ "manual_task_config_field.id",
232
+ name="manual_task_submission_field_id_fkey",
233
+ ondelete="CASCADE",
234
+ ),
235
+ nullable=False,
236
+ )
237
+ instance_id = Column(
238
+ String,
239
+ ForeignKey(
240
+ "manual_task_instance.id",
241
+ name="manual_task_submission_instance_id_fkey",
242
+ ondelete="CASCADE",
243
+ ),
244
+ nullable=False,
245
+ )
246
+ submitted_by = Column(
247
+ String,
248
+ ForeignKey(
249
+ "fidesuser.id",
250
+ name="manual_task_submission_submitted_by_fkey",
251
+ ondelete="SET NULL",
252
+ ),
253
+ nullable=True,
254
+ )
255
+ submitted_at = Column(DateTime, default=datetime.now(timezone.utc), nullable=False)
256
+ data = Column(JSONB, nullable=False)
257
+
258
+ __table_args__ = (
259
+ Index("ix_manual_task_submission_config_id", "config_id"),
260
+ Index("ix_manual_task_submission_field_id", "field_id"),
261
+ Index("ix_manual_task_submission_instance_field", "instance_id", "field_id"),
262
+ Index("ix_manual_task_submission_instance_id", "instance_id"),
263
+ Index("ix_manual_task_submission_submitted_at", "submitted_at"),
264
+ Index("ix_manual_task_submission_submitted_by", "submitted_by"),
265
+ Index("ix_manual_task_submission_task_id", "task_id"),
266
+ )
267
+
268
+ # Relationships
269
+ task = relationship("ManualTask", back_populates="submissions", viewonly=True)
270
+ config = relationship(
271
+ "ManualTaskConfig", back_populates="submissions", viewonly=True
272
+ )
273
+ field = relationship(
274
+ "ManualTaskConfigField", back_populates="submissions", viewonly=True
275
+ )
276
+ instance = relationship(
277
+ "ManualTaskInstance", back_populates="submissions", viewonly=True
278
+ )
279
+ attachments = relationship(
280
+ "Attachment",
281
+ secondary="attachment_reference",
282
+ primaryjoin="and_(ManualTaskSubmission.id == AttachmentReference.reference_id, "
283
+ "AttachmentReference.reference_type == 'manual_task_submission')",
284
+ secondaryjoin="Attachment.id == AttachmentReference.attachment_id",
285
+ order_by="Attachment.created_at",
286
+ viewonly=True,
287
+ uselist=True,
288
+ )
289
+
290
+ user = relationship(
291
+ "FidesUser",
292
+ primaryjoin="FidesUser.id == ManualTaskSubmission.submitted_by",
293
+ viewonly=True,
294
+ )