@venturekit-pro/tenancy 0.0.37 → 0.0.39
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.
- package/README.md +23 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/lifecycle/cascade.d.ts +51 -0
- package/dist/lifecycle/cascade.d.ts.map +1 -1
- package/dist/lifecycle/cascade.js +95 -7
- package/dist/lifecycle/cascade.js.map +1 -1
- package/dist/lifecycle/index.d.ts +2 -2
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/index.js +1 -1
- package/dist/lifecycle/index.js.map +1 -1
- package/dist/middleware/runtime-tenant-middleware.d.ts +11 -3
- package/dist/middleware/runtime-tenant-middleware.d.ts.map +1 -1
- package/dist/middleware/runtime-tenant-middleware.js +1 -1
- package/dist/middleware/runtime-tenant-middleware.js.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -77,6 +77,29 @@ const tenant = getCurrentTenant(ctx);
|
|
|
77
77
|
// { id: 'acme', slug: 'acme', metadata: { ... } }
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
+
## Erasure and export
|
|
81
|
+
|
|
82
|
+
The cascade walker that backs `hardDeleteTenant` also serves the two
|
|
83
|
+
per-user obligations (GDPR art. 17 / art. 20). Both key on the column that
|
|
84
|
+
marks a row as the user's — `user_id` by default — and introspect the schema,
|
|
85
|
+
so a new table is covered the day it is added.
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { exportUserData, executeUserErasure, planUserErasure } from '@venturekit-pro/tenancy';
|
|
89
|
+
|
|
90
|
+
// Portability: every row of the user, per table, ready to redact and hand over
|
|
91
|
+
const dump = await exportUserData(query, { userId, skipTables: ['audit_events'] });
|
|
92
|
+
|
|
93
|
+
// Erasure: dry-run first, then delete FK children before parents
|
|
94
|
+
const plan = await planUserErasure(query, { column: 'member_id' });
|
|
95
|
+
await withTransaction((tx) => executeUserErasure(tx.query, { userId, column: 'member_id', skipTables: ['audit_events'] }));
|
|
96
|
+
// …then adminDeleteUser() from @venturekit/auth/server for the Cognito account.
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Rows keyed by another column (`author_id`, `created_by`) need one call per
|
|
100
|
+
column; tables in `skipTables` (an append-only ledger you must keep) are the
|
|
101
|
+
ones to anonymise instead.
|
|
102
|
+
|
|
80
103
|
## API Reference
|
|
81
104
|
|
|
82
105
|
See the [API reference](https://venturekit.dev/api-reference/tenancy) for full documentation.
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,6 @@ export { TenantContext, createTenantContext, getCurrentTenant, resolveTenant, }
|
|
|
12
12
|
export * from './middleware/index.js';
|
|
13
13
|
export { listTenants, getTenantById, getTenantBySlug, getTenantByPrimaryDomain, createTenant, updateTenant, setTenantStatus, isUniqueViolation as isTenantUniqueViolation, } from './crud/index.js';
|
|
14
14
|
export type { TenantRecord, TenantWriteFields, TenantStatus as TenantDbStatus, } from './crud/index.js';
|
|
15
|
-
export { suspendTenant, archiveTenant, restoreTenant, hardDeleteTenant, planCascade, executeCascade, } from './lifecycle/index.js';
|
|
16
|
-
export type { TenantLifecycleStatus, LifecycleArgs, LifecycleOperationArgs, HardDeleteArgs, LifecycleAuditEvent, LifecycleAuditSink, CascadePlanEntry, CascadeOptions, CascadeResult, } from './lifecycle/index.js';
|
|
15
|
+
export { suspendTenant, archiveTenant, restoreTenant, hardDeleteTenant, planCascade, executeCascade, planUserErasure, executeUserErasure, exportUserData, } from './lifecycle/index.js';
|
|
16
|
+
export type { TenantLifecycleStatus, LifecycleArgs, LifecycleOperationArgs, HardDeleteArgs, LifecycleAuditEvent, LifecycleAuditSink, CascadePlanEntry, CascadeOptions, CascadeResult, UserDataOptions, UserDataExport, } from './lifecycle/index.js';
|
|
17
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,GACd,MAAM,oBAAoB,CAAC;AAG5B,cAAc,uBAAuB,CAAC;AAGtC,OAAO,EACL,WAAW,EACX,aAAa,EACb,eAAe,EACf,wBAAwB,EACxB,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,iBAAiB,IAAI,uBAAuB,GAC7C,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,YAAY,EACZ,iBAAiB,EAGjB,YAAY,IAAI,cAAc,GAC/B,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,GACd,MAAM,oBAAoB,CAAC;AAG5B,cAAc,uBAAuB,CAAC;AAGtC,OAAO,EACL,WAAW,EACX,aAAa,EACb,eAAe,EACf,wBAAwB,EACxB,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,iBAAiB,IAAI,uBAAuB,GAC7C,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,YAAY,EACZ,iBAAiB,EAGjB,YAAY,IAAI,cAAc,GAC/B,MAAM,iBAAiB,CAAC;AASzB,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,qBAAqB,EACrB,aAAa,EACb,sBAAsB,EACtB,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -19,6 +19,7 @@ export { listTenants, getTenantById, getTenantBySlug, getTenantByPrimaryDomain,
|
|
|
19
19
|
// createRoleScopesResolver) — baseline authorization, useful without
|
|
20
20
|
// tenancy. The scopes middleware consumes it through the structural
|
|
21
21
|
// `RoleScopesLookup` type (re-exported via ./middleware above).
|
|
22
|
-
// Lifecycle (suspend / archive / restore / hard-delete + cascade walker
|
|
23
|
-
|
|
22
|
+
// Lifecycle (suspend / archive / restore / hard-delete + cascade walker,
|
|
23
|
+
// per-user erasure & export)
|
|
24
|
+
export { suspendTenant, archiveTenant, restoreTenant, hardDeleteTenant, planCascade, executeCascade, planUserErasure, executeUserErasure, exportUserData, } from './lifecycle/index.js';
|
|
24
25
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,QAAQ;AACR,cAAc,kBAAkB,CAAC;AAEjC,UAAU;AACV,OAAO,EAEL,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,GACd,MAAM,oBAAoB,CAAC;AAE5B,aAAa;AACb,cAAc,uBAAuB,CAAC;AAEtC,gEAAgE;AAChE,OAAO,EACL,WAAW,EACX,aAAa,EACb,eAAe,EACf,wBAAwB,EACxB,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,iBAAiB,IAAI,uBAAuB,GAC7C,MAAM,iBAAiB,CAAC;AASzB,oEAAoE;AACpE,qEAAqE;AACrE,oEAAoE;AACpE,gEAAgE;AAEhE,yEAAyE;AACzE,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,cAAc,GACf,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,QAAQ;AACR,cAAc,kBAAkB,CAAC;AAEjC,UAAU;AACV,OAAO,EAEL,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,GACd,MAAM,oBAAoB,CAAC;AAE5B,aAAa;AACb,cAAc,uBAAuB,CAAC;AAEtC,gEAAgE;AAChE,OAAO,EACL,WAAW,EACX,aAAa,EACb,eAAe,EACf,wBAAwB,EACxB,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,iBAAiB,IAAI,uBAAuB,GAC7C,MAAM,iBAAiB,CAAC;AASzB,oEAAoE;AACpE,qEAAqE;AACrE,oEAAoE;AACpE,gEAAgE;AAEhE,yEAAyE;AACzE,6BAA6B;AAC7B,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,cAAc,GACf,MAAM,sBAAsB,CAAC"}
|
|
@@ -96,4 +96,55 @@ export declare function planCascade(querier: Querier, options?: Pick<CascadeOpti
|
|
|
96
96
|
* querier in.
|
|
97
97
|
*/
|
|
98
98
|
export declare function executeCascade(querier: Querier, options: CascadeOptions): Promise<CascadeResult>;
|
|
99
|
+
export interface UserDataOptions {
|
|
100
|
+
/** The user's id as stored in `column` (a Cognito sub, a members.id, …). */
|
|
101
|
+
userId: string;
|
|
102
|
+
/**
|
|
103
|
+
* Column that marks a row as belonging to the user. Default `user_id`.
|
|
104
|
+
* Apps whose ownership column differs (`member_id`, `created_by`) name
|
|
105
|
+
* it here; call once per column if several apply.
|
|
106
|
+
*/
|
|
107
|
+
column?: string;
|
|
108
|
+
/** Schema to introspect. Default `public`. */
|
|
109
|
+
schema?: string;
|
|
110
|
+
/**
|
|
111
|
+
* Tables to leave alone even though they carry the column — e.g. an
|
|
112
|
+
* append-only audit log the regime requires you to KEEP, or a billing
|
|
113
|
+
* ledger. For erasure these are the tables you anonymise instead.
|
|
114
|
+
*/
|
|
115
|
+
skipTables?: string[];
|
|
116
|
+
}
|
|
117
|
+
export interface UserDataExport {
|
|
118
|
+
userId: string;
|
|
119
|
+
column: string;
|
|
120
|
+
/** Rows per schema-qualified table, in introspection order. */
|
|
121
|
+
tables: Record<string, Record<string, unknown>[]>;
|
|
122
|
+
/** Tables that were listed but skipped. */
|
|
123
|
+
skipped: string[];
|
|
124
|
+
exportedAt: string;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Plan a per-user erasure: every table in `schema` with `column`,
|
|
128
|
+
* children before parents. Same guarantees as {@link planCascade}.
|
|
129
|
+
*/
|
|
130
|
+
export declare function planUserErasure(querier: Querier, options?: Omit<UserDataOptions, 'userId'>): Promise<CascadePlanEntry[]>;
|
|
131
|
+
/**
|
|
132
|
+
* Erase one user's rows from every `column`-bearing table, leaves first.
|
|
133
|
+
* The user's Cognito account and any row keyed by a DIFFERENT column
|
|
134
|
+
* (e.g. `author_id`) are the caller's responsibility — run this once per
|
|
135
|
+
* ownership column, then `adminDeleteUser`.
|
|
136
|
+
*
|
|
137
|
+
* **Destructive.** Wrap in `withTransaction()` and pass `tx.query` for
|
|
138
|
+
* all-or-nothing semantics; otherwise re-running is idempotent.
|
|
139
|
+
*/
|
|
140
|
+
export declare function executeUserErasure(querier: Querier, options: UserDataOptions): Promise<CascadeResult>;
|
|
141
|
+
/**
|
|
142
|
+
* Export one user's rows from every `column`-bearing table — the raw
|
|
143
|
+
* material for a data-portability response. Rows come back as stored
|
|
144
|
+
* (`SELECT *`); the app decides which columns to redact (other people's
|
|
145
|
+
* identifiers, internal flags) before handing the file over.
|
|
146
|
+
*
|
|
147
|
+
* Read-only; safe to run against a replica.
|
|
148
|
+
*/
|
|
149
|
+
export declare function exportUserData(querier: Querier, options: UserDataOptions): Promise<UserDataExport>;
|
|
99
150
|
//# sourceMappingURL=cascade.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cascade.d.ts","sourceRoot":"","sources":["../../src/lifecycle/cascade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"cascade.d.ts","sourceRoot":"","sources":["../../src/lifecycle/cascade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AA4BD;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,YAAY,CAAM,GAC1D,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAS7B;AAmHD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CA8BxB;AAMD,MAAM,WAAW,eAAe;IAC9B,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IAClD,2CAA2C;IAC3C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAM,GAC5C,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAM7B;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,aAAa,CAAC,CAaxB;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAiCzB"}
|
|
@@ -31,6 +31,18 @@
|
|
|
31
31
|
* hard delete; the package doesn't enforce that delay (compliance
|
|
32
32
|
* regimes vary), but it's the recommended pattern.
|
|
33
33
|
*/
|
|
34
|
+
/**
|
|
35
|
+
* The column a cascade / export keys on is interpolated into SQL (it is a
|
|
36
|
+
* schema identifier, not a value). Restrict it to plain unquoted
|
|
37
|
+
* identifiers so a caller can never smuggle anything else in.
|
|
38
|
+
*/
|
|
39
|
+
const SAFE_IDENTIFIER = /^[a-z_][a-z0-9_]{0,62}$/;
|
|
40
|
+
function assertColumnName(column) {
|
|
41
|
+
if (!SAFE_IDENTIFIER.test(column)) {
|
|
42
|
+
throw new Error(`[tenancy/cascade] column must be a plain lowercase identifier (got ${JSON.stringify(column)})`);
|
|
43
|
+
}
|
|
44
|
+
return column;
|
|
45
|
+
}
|
|
34
46
|
/**
|
|
35
47
|
* Plan the cascade WITHOUT executing it. Useful for dry-runs in the
|
|
36
48
|
* admin UI ("about to delete N rows from M tables — confirm?").
|
|
@@ -40,18 +52,29 @@
|
|
|
40
52
|
* tenant-scoped set fail loud with a clear error.
|
|
41
53
|
*/
|
|
42
54
|
export async function planCascade(querier, options = {}) {
|
|
43
|
-
|
|
44
|
-
|
|
55
|
+
return planColumnCascade(querier, {
|
|
56
|
+
column: 'tenant_id',
|
|
57
|
+
schema: options.schema,
|
|
45
58
|
// `vk_tenants` is the root we're collapsing into; the helper deletes
|
|
46
59
|
// it separately at the very end. Including it in the cascade
|
|
47
60
|
// would cause a "depends on itself" cycle.
|
|
48
|
-
'vk_tenants',
|
|
49
|
-
|
|
50
|
-
|
|
61
|
+
skipTables: ['vk_tenants', ...(options.skipTables ?? [])],
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Shared walker: every table in `schema` with a column named `column`,
|
|
66
|
+
* ordered so that FK children come before their parents. `planCascade`
|
|
67
|
+
* (tenant erasure) and `planUserErasure` (per-user erasure) are both
|
|
68
|
+
* thin wrappers over it.
|
|
69
|
+
*/
|
|
70
|
+
async function planColumnCascade(querier, options) {
|
|
71
|
+
const schema = options.schema ?? 'public';
|
|
72
|
+
const column = assertColumnName(options.column);
|
|
73
|
+
const skip = new Set(options.skipTables ?? []);
|
|
51
74
|
const tables = await querier(`SELECT table_schema AS "schema_name", table_name
|
|
52
75
|
FROM information_schema.columns
|
|
53
76
|
WHERE table_schema = $1
|
|
54
|
-
AND column_name =
|
|
77
|
+
AND column_name = $2`, [schema, column]);
|
|
55
78
|
const tenantTables = new Set(tables.map((t) => t.table_name).filter((name) => !skip.has(name)));
|
|
56
79
|
if (tenantTables.size === 0)
|
|
57
80
|
return [];
|
|
@@ -111,7 +134,7 @@ export async function planCascade(querier, options = {}) {
|
|
|
111
134
|
}
|
|
112
135
|
if (leaves.length === 0) {
|
|
113
136
|
const remaining = Array.from(parentToChildren.keys()).sort();
|
|
114
|
-
throw new Error(`[tenancy/cascade] FK cycle detected among
|
|
137
|
+
throw new Error(`[tenancy/cascade] FK cycle detected among ${column}-scoped tables: [${remaining.join(', ')}]. ` +
|
|
115
138
|
`Add the offending tables to skipTables and delete them manually.`);
|
|
116
139
|
}
|
|
117
140
|
leaves.sort(); // deterministic order within a depth level
|
|
@@ -171,4 +194,69 @@ export async function executeCascade(querier, options) {
|
|
|
171
194
|
durationMs: Date.now() - startedAt,
|
|
172
195
|
};
|
|
173
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Plan a per-user erasure: every table in `schema` with `column`,
|
|
199
|
+
* children before parents. Same guarantees as {@link planCascade}.
|
|
200
|
+
*/
|
|
201
|
+
export async function planUserErasure(querier, options = {}) {
|
|
202
|
+
return planColumnCascade(querier, {
|
|
203
|
+
column: options.column ?? 'user_id',
|
|
204
|
+
schema: options.schema,
|
|
205
|
+
skipTables: options.skipTables,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Erase one user's rows from every `column`-bearing table, leaves first.
|
|
210
|
+
* The user's Cognito account and any row keyed by a DIFFERENT column
|
|
211
|
+
* (e.g. `author_id`) are the caller's responsibility — run this once per
|
|
212
|
+
* ownership column, then `adminDeleteUser`.
|
|
213
|
+
*
|
|
214
|
+
* **Destructive.** Wrap in `withTransaction()` and pass `tx.query` for
|
|
215
|
+
* all-or-nothing semantics; otherwise re-running is idempotent.
|
|
216
|
+
*/
|
|
217
|
+
export async function executeUserErasure(querier, options) {
|
|
218
|
+
const startedAt = Date.now();
|
|
219
|
+
const column = assertColumnName(options.column ?? 'user_id');
|
|
220
|
+
const plan = await planUserErasure(querier, { ...options, column });
|
|
221
|
+
const counts = {};
|
|
222
|
+
for (const entry of plan) {
|
|
223
|
+
const rows = await querier(`DELETE FROM ${entry.tableName} WHERE ${column} = $1 RETURNING 1 AS id`, [options.userId]);
|
|
224
|
+
counts[entry.tableName] = rows.length;
|
|
225
|
+
}
|
|
226
|
+
return { plan, counts, durationMs: Date.now() - startedAt };
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Export one user's rows from every `column`-bearing table — the raw
|
|
230
|
+
* material for a data-portability response. Rows come back as stored
|
|
231
|
+
* (`SELECT *`); the app decides which columns to redact (other people's
|
|
232
|
+
* identifiers, internal flags) before handing the file over.
|
|
233
|
+
*
|
|
234
|
+
* Read-only; safe to run against a replica.
|
|
235
|
+
*/
|
|
236
|
+
export async function exportUserData(querier, options) {
|
|
237
|
+
const schema = options.schema ?? 'public';
|
|
238
|
+
const column = assertColumnName(options.column ?? 'user_id');
|
|
239
|
+
const skip = new Set(options.skipTables ?? []);
|
|
240
|
+
const tables = await querier(`SELECT table_schema AS "schema_name", table_name
|
|
241
|
+
FROM information_schema.columns
|
|
242
|
+
WHERE table_schema = $1
|
|
243
|
+
AND column_name = $2
|
|
244
|
+
ORDER BY table_name`, [schema, column]);
|
|
245
|
+
const out = {
|
|
246
|
+
userId: options.userId,
|
|
247
|
+
column,
|
|
248
|
+
tables: {},
|
|
249
|
+
skipped: [],
|
|
250
|
+
exportedAt: new Date().toISOString(),
|
|
251
|
+
};
|
|
252
|
+
for (const t of tables) {
|
|
253
|
+
const qualified = `${schema}.${t.table_name}`;
|
|
254
|
+
if (skip.has(t.table_name)) {
|
|
255
|
+
out.skipped.push(qualified);
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
out.tables[qualified] = await querier(`SELECT * FROM ${qualified} WHERE ${column} = $1`, [options.userId]);
|
|
259
|
+
}
|
|
260
|
+
return out;
|
|
261
|
+
}
|
|
174
262
|
//# sourceMappingURL=cascade.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cascade.js","sourceRoot":"","sources":["../../src/lifecycle/cascade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAqDH;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAgB,EAChB,UAAyD,EAAE;IAE3D,
|
|
1
|
+
{"version":3,"file":"cascade.js","sourceRoot":"","sources":["../../src/lifecycle/cascade.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,6 @@
|
|
|
17
17
|
export type { Querier, TenantLifecycleStatus, LifecycleArgs, LifecycleAuditEvent, LifecycleAuditSink, } from './types.js';
|
|
18
18
|
export { suspendTenant, archiveTenant, restoreTenant, hardDeleteTenant, } from './operations.js';
|
|
19
19
|
export type { LifecycleOperationArgs, HardDeleteArgs } from './operations.js';
|
|
20
|
-
export { planCascade, executeCascade, } from './cascade.js';
|
|
21
|
-
export type { CascadePlanEntry, CascadeOptions, CascadeResult, } from './cascade.js';
|
|
20
|
+
export { planCascade, executeCascade, planUserErasure, executeUserErasure, exportUserData, } from './cascade.js';
|
|
21
|
+
export type { CascadePlanEntry, CascadeOptions, CascadeResult, UserDataOptions, UserDataExport, } from './cascade.js';
|
|
22
22
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lifecycle/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,YAAY,EACV,OAAO,EACP,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE9E,OAAO,EACL,WAAW,EACX,cAAc,GACf,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lifecycle/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,YAAY,EACV,OAAO,EACP,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE9E,OAAO,EACL,WAAW,EACX,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,cAAc,GACf,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,cAAc,CAAC"}
|
package/dist/lifecycle/index.js
CHANGED
|
@@ -15,5 +15,5 @@
|
|
|
15
15
|
* `hardDeleteTenant`).
|
|
16
16
|
*/
|
|
17
17
|
export { suspendTenant, archiveTenant, restoreTenant, hardDeleteTenant, } from './operations.js';
|
|
18
|
-
export { planCascade, executeCascade, } from './cascade.js';
|
|
18
|
+
export { planCascade, executeCascade, planUserErasure, executeUserErasure, exportUserData, } from './cascade.js';
|
|
19
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lifecycle/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAUH,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,WAAW,EACX,cAAc,GACf,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lifecycle/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAUH,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,WAAW,EACX,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,cAAc,GACf,MAAM,cAAc,CAAC"}
|
|
@@ -88,9 +88,17 @@ export interface HostPrefixDomainResolverOptions<T extends TenantContext> {
|
|
|
88
88
|
*/
|
|
89
89
|
lookup: (domain: string, ctx: RequestContext) => Promise<T | null> | T | null;
|
|
90
90
|
/**
|
|
91
|
-
* Dev-only overrides honored when `process.env.
|
|
92
|
-
*
|
|
93
|
-
*
|
|
91
|
+
* Dev-only overrides honored when `process.env.VENTURE_LOCAL === 'true'`
|
|
92
|
+
* — the marker `vk dev` injects and nothing deployed ever carries
|
|
93
|
+
* (the same switch the repo's other dev-only surfaces key on). Lets
|
|
94
|
+
* `vk dev` serve tenanted routes from `localhost:3001` by accepting an
|
|
95
|
+
* explicit slug from a header or query param.
|
|
96
|
+
*
|
|
97
|
+
* Deliberately NOT keyed on a stage name: `dev` is a deployable stage,
|
|
98
|
+
* and a deployed API that let any caller pick the tenant with a header
|
|
99
|
+
* would be a cross-tenant read. (Historically this read `STAGE=dev`,
|
|
100
|
+
* which no deploy path set — the override was dead locally and one
|
|
101
|
+
* `STAGE=dev` env var away from live in the cloud.)
|
|
94
102
|
*
|
|
95
103
|
* Defaults: header `X-Tenant-Slug`, query `tenant`. Set to `false`
|
|
96
104
|
* to disable.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-tenant-middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/runtime-tenant-middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIrF,MAAM,WAAW,qBAAqB;IACpC,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,aAAa,GAAG,IAAI,CAAC;CAC7E;AAED,MAAM,WAAW,8BAA8B;IAC7C;;;;;;;OAOG;IACH,QAAQ,EAAE,qBAAqB,CAAC;IAEhC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,8BAA8B,GACtC,UAAU,CAAC,cAAc,CAAC,CAiB5B;AAED,MAAM,WAAW,+BAA+B,CAAC,CAAC,SAAS,aAAa;IACtE;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,EAAE,CACN,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,cAAc,KAChB,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAClC
|
|
1
|
+
{"version":3,"file":"runtime-tenant-middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/runtime-tenant-middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIrF,MAAM,WAAW,qBAAqB;IACpC,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,aAAa,GAAG,IAAI,CAAC;CAC7E;AAED,MAAM,WAAW,8BAA8B;IAC7C;;;;;;;OAOG;IACH,QAAQ,EAAE,qBAAqB,CAAC;IAEhC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,8BAA8B,GACtC,UAAU,CAAC,cAAc,CAAC,CAiB5B;AAED,MAAM,WAAW,+BAA+B,CAAC,CAAC,SAAS,aAAa;IACtE;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,EAAE,CACN,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,cAAc,KAChB,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAClC;;;;;;;;;;;;;;;OAeG;IACH,YAAY,CAAC,EACT,KAAK,GACL;QACE,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,CACZ,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,cAAc,KAChB,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;KACnC,CAAC;CACP;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,SAAS,aAAa,EAC9D,OAAO,EAAE,+BAA+B,CAAC,CAAC,CAAC,GAC1C,qBAAqB,CAgCvB"}
|
|
@@ -58,7 +58,7 @@ export function hostPrefixDomainResolver(options) {
|
|
|
58
58
|
const dev = options.devOverrides;
|
|
59
59
|
return async (ctx) => {
|
|
60
60
|
const headers = ctx.rawEvent.headers ?? {};
|
|
61
|
-
if (process.env.
|
|
61
|
+
if (process.env.VENTURE_LOCAL === 'true' && dev !== false) {
|
|
62
62
|
const headerName = (dev?.headerName ?? 'x-tenant-slug').toLowerCase();
|
|
63
63
|
const queryName = dev?.queryName ?? 'tenant';
|
|
64
64
|
const headerValue = headers[headerName] ??
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-tenant-middleware.js","sourceRoot":"","sources":["../../src/middleware/runtime-tenant-middleware.ts"],"names":[],"mappings":"AA4BA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AA2B7D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,6BAA6B,CAC3C,OAAuC;IAEvC,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAC/C,OAAO;QACL,IAAI,EAAE,gBAAgB;QACtB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;YACnC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,IAAI,QAAQ,EAAE,CAAC;oBACb,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC;oBAClB,OAAO,IAAI,EAAE,CAAC;gBAChB,CAAC;gBACD,MAAM,IAAI,mBAAmB,CAAC,SAAS,CAAC,CAAC;YAC3C,CAAC;YACD,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;YACpB,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime-tenant-middleware.js","sourceRoot":"","sources":["../../src/middleware/runtime-tenant-middleware.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@venturekit-pro/tenancy",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.39",
|
|
4
4
|
"description": "Multi-tenant utilities for VentureKit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@venturekit/core": "0.0.
|
|
33
|
+
"@venturekit/core": "0.0.39"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"@venturekit/data": "0.0.
|
|
37
|
-
"@venturekit/runtime": "0.0.
|
|
36
|
+
"@venturekit/data": "0.0.39",
|
|
37
|
+
"@venturekit/runtime": "0.0.39"
|
|
38
38
|
},
|
|
39
39
|
"peerDependenciesMeta": {
|
|
40
40
|
"@venturekit/data": {
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/node": "^26.5.1",
|
|
49
|
-
"@venturekit/data": "0.0.
|
|
50
|
-
"@venturekit/runtime": "0.0.
|
|
49
|
+
"@venturekit/data": "0.0.39",
|
|
50
|
+
"@venturekit/runtime": "0.0.39",
|
|
51
51
|
"typescript": "^5.3.0"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|