-
Notifications
You must be signed in to change notification settings - Fork 6
feat(cli): support per-workflow deletion dependencies in transcend.yml #402
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| --- | ||
| "@transcend-io/cli": minor | ||
| "@transcend-io/sdk": major | ||
| --- | ||
|
|
||
| Support per-workflow deletion dependencies in `transcend.yml`. Use a list of titles for the global configuration only, or a list of objects when any per-workflow override is present (`{ titles }` for global, `{ workflow, titles }` or `{ workflow, reset-to-global: true }` for overrides). Mixing titles and objects in the same list is not allowed. | ||
|
|
||
| `syncDataSiloDependencies` now takes `[dataSiloId, DependedOnDataSiloInput[]][]` instead of `[dataSiloId, string[]][]` and pushes through `dependedOnDataSilos` rather than the deprecated `dependedOnDataSiloTitles`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ A command line interface that allows you to programatically interact with the Tr | |
| - [Changelog](#changelog) | ||
| - [Installation](#installation) | ||
| - [transcend.yml](#transcendyml) | ||
| - [Deletion dependencies](#deletion-dependencies) | ||
| - [Usage](#usage) | ||
| - [`transcend request approve`](#transcend-request-approve) | ||
| - [`transcend request upload`](#transcend-request-upload) | ||
|
|
@@ -168,7 +169,12 @@ data-silos: | |
| - userId | ||
| deletion-dependencies: | ||
| - Identity Service | ||
| - titles: | ||
| - Identity Service | ||
| - workflow: GDPR Erasure | ||
| titles: | ||
| - Identity Service | ||
| - CRM Warehouse | ||
| owners: | ||
| - alice@transcend.io | ||
| datapoints: | ||
|
|
@@ -192,6 +198,50 @@ data-silos: | |
| description: The email address of the user | ||
| ``` | ||
|
|
||
| ### Deletion dependencies | ||
|
|
||
| When an erasure request runs, `deletion-dependencies` holds off deleting from a data silo until the data silos it lists have finished deleting. | ||
|
|
||
| Use a list of titles when there are no per-workflow overrides: | ||
|
|
||
| ```yaml | ||
| data-silos: | ||
| - title: Salesforce | ||
| integrationName: server | ||
| deletion-dependencies: | ||
| - Identity Service | ||
| - CRM Warehouse | ||
| ``` | ||
|
|
||
| Once any override is present, use a list of objects for the whole field (global deps as `{ titles }`, overrides as `{ workflow, titles }` or `{ workflow, reset-to-global: true }`). Mixing titles and objects in the same list is not allowed: | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't phrase this as "Once any override is present" - this will be the new way going forward and we want to phrase it as the proper way to use the CLI. |
||
|
|
||
| ```yaml | ||
| data-silos: | ||
| - title: Salesforce | ||
| integrationName: server | ||
| deletion-dependencies: | ||
| # Global configuration | ||
| - titles: | ||
| - Identity Service | ||
| # Overrides the global configuration for the "GDPR Erasure" workflow only | ||
| - workflow: GDPR Erasure | ||
| titles: | ||
| - Identity Service | ||
| - CRM Warehouse | ||
| # Runs with no dependencies at all in the "CCPA Delete" workflow | ||
| - workflow: CCPA Delete | ||
| titles: [] | ||
| # Removes a previously configured override so the workflow uses the global configuration again | ||
| - workflow: Legacy Erasure | ||
| reset-to-global: true | ||
| ``` | ||
|
|
||
| `workflow` is the internal name of an erasure workflow, which you can find under [DSR Automation -> Workflows](https://app.transcend.io/privacy-requests/workflows). Overrides are only supported on erasure workflows, and the data silo and everything it depends on must already be part of that workflow. | ||
|
|
||
| A workflow that is not listed keeps whatever configuration it already has, so pushing a config that only lists global dependencies never removes existing overrides. Use `reset-to-global: true` to remove one. | ||
|
|
||
| Omitting `deletion-dependencies` entirely clears the global configuration, matching how the rest of `transcend.yml` treats omitted fields. | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Not for reviewers, not for Cursor] Even though it says this matches "how the rest of |
||
|
|
||
| ## Usage | ||
|
|
||
| <!-- COMMANDS_START --> | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -1301,6 +1301,72 @@ export const IntlMessageInput = t.intersection([ | |||||
| /** Type override */ | ||||||
| export type IntlMessageInput = t.TypeOf<typeof IntlMessageInput>; | ||||||
|
|
||||||
| /** | ||||||
| * A set of deletion dependencies, either global (when `workflow` is omitted) | ||||||
| * or scoped to a single DSR workflow. | ||||||
| * | ||||||
| * An empty `titles` list scoped to a workflow is an explicit override, meaning | ||||||
| * that workflow runs the data silo with no dependencies at all. | ||||||
| */ | ||||||
| export const DeletionDependencyGroup = t.intersection([ | ||||||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's call this |
||||||
| t.type({ | ||||||
| /** | ||||||
| * The titles of the data silos that must be deleted from first. This list can contain | ||||||
| * other internal systems defined in this file, as well as any of the SaaS tools connected | ||||||
| * in your Transcend instance. | ||||||
| */ | ||||||
| titles: t.array(t.string), | ||||||
| }), | ||||||
| t.partial({ | ||||||
| /** | ||||||
| * The internal name of the DSR workflow that these dependencies override the global | ||||||
| * configuration for. Omit to declare the global configuration. | ||||||
| */ | ||||||
| workflow: t.string, | ||||||
| }), | ||||||
| ]); | ||||||
|
|
||||||
| /** Type override */ | ||||||
| export type DeletionDependencyGroup = t.TypeOf<typeof DeletionDependencyGroup>; | ||||||
|
|
||||||
| /** | ||||||
| * Removes a workflow's deletion dependency override so that the workflow falls back | ||||||
| * to the global configuration. | ||||||
| */ | ||||||
| export const DeletionDependencyReset = t.type({ | ||||||
| /** The internal name of the DSR workflow to remove the override from */ | ||||||
| workflow: t.string, | ||||||
| /** Must be `true`; declares that the override should be removed */ | ||||||
| 'reset-to-global': t.literal(true), | ||||||
| }); | ||||||
|
|
||||||
| /** Type override */ | ||||||
| export type DeletionDependencyReset = t.TypeOf<typeof DeletionDependencyReset>; | ||||||
|
|
||||||
| /** | ||||||
| * A single object entry in a data silo's `deletion-dependencies` list. | ||||||
| * Used when the list includes any per-workflow override; global dependencies | ||||||
| * are written as `{ titles: [...] }` in that form. | ||||||
| */ | ||||||
| export const DeletionDependencyObject = t.union([DeletionDependencyGroup, DeletionDependencyReset]); | ||||||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| /** Type override */ | ||||||
| export type DeletionDependencyObject = t.TypeOf<typeof DeletionDependencyObject>; | ||||||
|
|
||||||
| /** | ||||||
| * The `deletion-dependencies` field for a data silo. | ||||||
| * | ||||||
| * Use a list of titles when there are no per-workflow overrides. Once any | ||||||
| * override is present, use a list of objects instead (global deps as | ||||||
| * `{ titles: [...] }`, overrides as `{ workflow, titles }` or | ||||||
| * `{ workflow, reset-to-global: true }`). Mixing strings and objects in the | ||||||
| * same list is not allowed. | ||||||
| */ | ||||||
| export const DeletionDependencies = t.union([t.array(t.string), t.array(DeletionDependencyObject)]); | ||||||
|
|
||||||
| /** Type override */ | ||||||
| export type DeletionDependencies = t.TypeOf<typeof DeletionDependencies>; | ||||||
|
|
||||||
| /** | ||||||
| * Input to define a data silo | ||||||
| * | ||||||
|
|
@@ -1350,8 +1416,13 @@ export const DataSiloInput = t.intersection([ | |||||
| * When a data erasure request is being performed, this data silo should not be deleted from | ||||||
| * until all of the following data silos were deleted first. This list can contain other internal | ||||||
| * systems defined in this file, as well as any of the SaaS tools connected in your Transcend instance. | ||||||
| * | ||||||
| * A list of titles sets the global configuration only. To include per-workflow overrides, | ||||||
| * use a list of objects instead: `{ titles: [...] }` for the global configuration and | ||||||
| * `{ workflow, titles }` (or `{ workflow, reset-to-global: true }`) for each override. | ||||||
| * Workflows that are not listed keep whatever configuration they already have. | ||||||
| */ | ||||||
| 'deletion-dependencies': t.array(t.string), | ||||||
| 'deletion-dependencies': DeletionDependencies, | ||||||
| /** | ||||||
| * The email addresses of the employees within your company that are the go-to individuals | ||||||
| * for managing this data silo | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we note this as deprecated? Follow other examples in the README for deprecated fields. If there are none, let me know.