@hiai-gg/docsmint 0.4.4 → 0.4.6
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/backend/src/lib/lifecycle-service.ts +191 -0
- package/dist/backend/index.js +1 -1
- package/dist/backend-account-runtime-cleanup.d.ts +9 -0
- package/dist/backend-account-runtime-cleanup.js +2747 -0
- package/dist/lifecycle-runtime.js +88 -0
- package/package.json +9 -6
- package/packages/cli/src/index.ts +1 -1
- package/packages/mcp-server/src/index.ts +1 -1
|
@@ -538,6 +538,10 @@ function tokenHash(token) {
|
|
|
538
538
|
function subjectHash(actorUserId) {
|
|
539
539
|
return new Bun.CryptoHasher("sha256").update(actorUserId).digest("hex");
|
|
540
540
|
}
|
|
541
|
+
function lifecycleTombstoneEmail(actorUserId) {
|
|
542
|
+
const hash = new Bun.CryptoHasher("sha256").update("docsmint:privacy-tombstone:v1\x00").update(actorUserId).digest("hex");
|
|
543
|
+
return `deleted-${hash}@invalid.local`;
|
|
544
|
+
}
|
|
541
545
|
function checksumLine(hash, record) {
|
|
542
546
|
hash.update(`${JSON.stringify(record)}
|
|
543
547
|
`, "utf8");
|
|
@@ -634,6 +638,77 @@ function createPersistentLifecycleService(runtime, database, hostSteps = []) {
|
|
|
634
638
|
checksumLine(hash, manifest);
|
|
635
639
|
recordCount += 1;
|
|
636
640
|
yield manifest;
|
|
641
|
+
const actor = await withActor(ctx.actorUserId, (tx) => tx.select({
|
|
642
|
+
id: users.id,
|
|
643
|
+
email: users.email,
|
|
644
|
+
name: users.name,
|
|
645
|
+
emailVerified: users.emailVerified,
|
|
646
|
+
image: users.image,
|
|
647
|
+
createdAt: users.createdAt,
|
|
648
|
+
updatedAt: users.updatedAt
|
|
649
|
+
}).from(users).where(eq(users.id, ctx.actorUserId)).limit(1));
|
|
650
|
+
for (const profile of actor) {
|
|
651
|
+
const record = {
|
|
652
|
+
type: "data",
|
|
653
|
+
domain: "account",
|
|
654
|
+
resourceType: "user",
|
|
655
|
+
resourceId: profile.id,
|
|
656
|
+
workspaceId: null,
|
|
657
|
+
payload: {
|
|
658
|
+
email: profile.email,
|
|
659
|
+
name: profile.name,
|
|
660
|
+
emailVerified: profile.emailVerified,
|
|
661
|
+
image: profile.image,
|
|
662
|
+
createdAt: profile.createdAt,
|
|
663
|
+
updatedAt: profile.updatedAt
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
checksumLine(hash, record);
|
|
667
|
+
recordCount += 1;
|
|
668
|
+
yield record;
|
|
669
|
+
}
|
|
670
|
+
const actorFolders = await withActor(ctx.actorUserId, (tx) => tx.select().from(folders).where(eq(folders.ownerId, ctx.actorUserId)));
|
|
671
|
+
for (const folder of actorFolders) {
|
|
672
|
+
const record = {
|
|
673
|
+
type: "data",
|
|
674
|
+
domain: "folders",
|
|
675
|
+
resourceType: "folder",
|
|
676
|
+
resourceId: folder.id,
|
|
677
|
+
workspaceId: folder.workspaceId,
|
|
678
|
+
payload: folder
|
|
679
|
+
};
|
|
680
|
+
checksumLine(hash, record);
|
|
681
|
+
recordCount += 1;
|
|
682
|
+
yield record;
|
|
683
|
+
}
|
|
684
|
+
const actorTags = await withActor(ctx.actorUserId, (tx) => tx.select().from(tags).where(eq(tags.ownerId, ctx.actorUserId)));
|
|
685
|
+
for (const tag of actorTags) {
|
|
686
|
+
const record = {
|
|
687
|
+
type: "data",
|
|
688
|
+
domain: "tags",
|
|
689
|
+
resourceType: "tag",
|
|
690
|
+
resourceId: tag.id,
|
|
691
|
+
workspaceId: tag.workspaceId,
|
|
692
|
+
payload: tag
|
|
693
|
+
};
|
|
694
|
+
checksumLine(hash, record);
|
|
695
|
+
recordCount += 1;
|
|
696
|
+
yield record;
|
|
697
|
+
}
|
|
698
|
+
const actorCategories = await withActor(ctx.actorUserId, (tx) => tx.select().from(categories).where(eq(categories.ownerId, ctx.actorUserId)));
|
|
699
|
+
for (const category of actorCategories) {
|
|
700
|
+
const record = {
|
|
701
|
+
type: "data",
|
|
702
|
+
domain: "categories",
|
|
703
|
+
resourceType: "category",
|
|
704
|
+
resourceId: category.id,
|
|
705
|
+
workspaceId: category.workspaceId,
|
|
706
|
+
payload: category
|
|
707
|
+
};
|
|
708
|
+
checksumLine(hash, record);
|
|
709
|
+
recordCount += 1;
|
|
710
|
+
yield record;
|
|
711
|
+
}
|
|
637
712
|
const ownedDocuments = await withActor(ctx.actorUserId, (tx) => tx.select().from(documents).where(eq(documents.ownerId, ctx.actorUserId)));
|
|
638
713
|
for (const document of ownedDocuments) {
|
|
639
714
|
throwIfAborted(ctx.signal);
|
|
@@ -733,12 +808,24 @@ function createPersistentLifecycleService(runtime, database, hostSteps = []) {
|
|
|
733
808
|
storageKey: attachments.storageKey
|
|
734
809
|
}).from(attachments).where(inArray(attachments.documentId, documentIds))) : [];
|
|
735
810
|
await runStep(operation, ctx.actorUserId, leaseOwner, "delete_attachment_objects", deletedByDomain, () => runtime.deleteObjects(objectRows.map((row) => row.storageKey), ctx.signal));
|
|
811
|
+
await runStep(operation, ctx.actorUserId, leaseOwner, "remove_subject_folders", deletedByDomain, () => dbDelete((tx) => tx.delete(folders).where(eq(folders.ownerId, ctx.actorUserId)).returning({ id: folders.id })));
|
|
812
|
+
await runStep(operation, ctx.actorUserId, leaseOwner, "remove_subject_tags", deletedByDomain, () => dbDelete((tx) => tx.delete(tags).where(eq(tags.ownerId, ctx.actorUserId)).returning({ id: tags.id })));
|
|
813
|
+
await runStep(operation, ctx.actorUserId, leaseOwner, "remove_subject_categories", deletedByDomain, () => dbDelete((tx) => tx.delete(categories).where(eq(categories.ownerId, ctx.actorUserId)).returning({ id: categories.id })));
|
|
736
814
|
await runStep(operation, ctx.actorUserId, leaseOwner, "remove_attachment_rows", deletedByDomain, () => objectRows.length ? dbDelete((tx) => tx.delete(attachments).where(inArray(attachments.id, objectRows.map((row) => row.id))).returning({ id: attachments.id })) : Promise.resolve(0));
|
|
737
815
|
await runStep(operation, ctx.actorUserId, leaseOwner, "remove_subject_documents", deletedByDomain, () => dbDelete((tx) => tx.delete(documents).where(eq(documents.ownerId, ctx.actorUserId)).returning({ id: documents.id })));
|
|
738
816
|
await runStep(operation, ctx.actorUserId, leaseOwner, "clear_redis_state", deletedByDomain, () => runtime.clearAccountRedisState(ctx.actorUserId, ctx.signal));
|
|
739
817
|
for (const step of orderedSteps)
|
|
740
818
|
if (step.purge)
|
|
741
819
|
await runStep(operation, ctx.actorUserId, leaseOwner, `host:${step.id}`, deletedByDomain, async () => (await step.purge?.(ctx))?.deletedCount ?? 0);
|
|
820
|
+
await runStep(operation, ctx.actorUserId, leaseOwner, "remove_auth_sessions", deletedByDomain, () => dbDelete((tx) => tx.delete(sessions).where(eq(sessions.userId, ctx.actorUserId)).returning({ id: sessions.id })));
|
|
821
|
+
await runStep(operation, ctx.actorUserId, leaseOwner, "remove_auth_accounts", deletedByDomain, () => dbDelete((tx) => tx.delete(accounts).where(eq(accounts.userId, ctx.actorUserId)).returning({ id: accounts.id })));
|
|
822
|
+
await runStep(operation, ctx.actorUserId, leaseOwner, "tombstone_subject_user", deletedByDomain, () => dbDelete((tx) => tx.update(users).set({
|
|
823
|
+
email: lifecycleTombstoneEmail(ctx.actorUserId),
|
|
824
|
+
name: null,
|
|
825
|
+
image: null,
|
|
826
|
+
emailVerified: false,
|
|
827
|
+
updatedAt: new Date
|
|
828
|
+
}).where(eq(users.id, ctx.actorUserId)).returning({ id: users.id })));
|
|
742
829
|
await runStep(operation, ctx.actorUserId, leaseOwner, "write_deletion_audit", deletedByDomain, async () => {
|
|
743
830
|
await withActor(ctx.actorUserId, (tx) => tx.insert(auditLog).values({
|
|
744
831
|
actorId: ctx.actorUserId,
|
|
@@ -803,6 +890,7 @@ function createPersistentLifecycleRuntime(options) {
|
|
|
803
890
|
}
|
|
804
891
|
export {
|
|
805
892
|
requireLeaseWrite,
|
|
893
|
+
lifecycleTombstoneEmail,
|
|
806
894
|
createPersistentLifecycleService,
|
|
807
895
|
createPersistentLifecycleRuntime,
|
|
808
896
|
bindPersistentLifecycle,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hiai-gg/docsmint",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"browser": {
|
|
6
6
|
"./dist/backend-launcher.js": false,
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"./dist/pipeline-cancellation.js": false,
|
|
11
11
|
"./dist/storage-quota.js": false,
|
|
12
12
|
"./dist/workspace.js": false,
|
|
13
|
-
"./dist/backend-pipeline-cancellation.js": false
|
|
13
|
+
"./dist/backend-pipeline-cancellation.js": false,
|
|
14
|
+
"./dist/backend-account-runtime-cleanup.js": false
|
|
14
15
|
},
|
|
15
16
|
"license": "Apache-2.0",
|
|
16
17
|
"description": "The lightweight, AI-native self-hosted knowledge base — built-in RAG, hybrid semantic search, and a clean REST API for AI agents.",
|
|
@@ -306,6 +307,11 @@
|
|
|
306
307
|
"browser": "./dist/server-only-browser-entry.js",
|
|
307
308
|
"import": "./dist/backend-pipeline-cancellation.js",
|
|
308
309
|
"types": "./dist/backend-pipeline-cancellation.d.ts"
|
|
310
|
+
},
|
|
311
|
+
"./backend/account-runtime-cleanup": {
|
|
312
|
+
"browser": "./dist/server-only-browser-entry.js",
|
|
313
|
+
"import": "./dist/backend-account-runtime-cleanup.js",
|
|
314
|
+
"types": "./dist/backend-account-runtime-cleanup.d.ts"
|
|
309
315
|
}
|
|
310
316
|
},
|
|
311
317
|
"bin": {
|
|
@@ -352,12 +358,12 @@
|
|
|
352
358
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
353
359
|
"bullmq": "^5.80.2",
|
|
354
360
|
"commander": "^13.1.0",
|
|
361
|
+
"ioredis": "^5.11.1",
|
|
355
362
|
"zod": "^4.0.0"
|
|
356
363
|
},
|
|
357
364
|
"peerDependencies": {
|
|
358
365
|
"drizzle-orm": "^0.45.2",
|
|
359
366
|
"postgres": "^3.4.9",
|
|
360
|
-
"ioredis": "^5.4.0",
|
|
361
367
|
"@aws-sdk/client-s3": "^3.0.0",
|
|
362
368
|
"pino": "^10.0.0",
|
|
363
369
|
"@sveltejs/kit": "^2.68.0",
|
|
@@ -370,9 +376,6 @@
|
|
|
370
376
|
"postgres": {
|
|
371
377
|
"optional": true
|
|
372
378
|
},
|
|
373
|
-
"ioredis": {
|
|
374
|
-
"optional": true
|
|
375
|
-
},
|
|
376
379
|
"@aws-sdk/client-s3": {
|
|
377
380
|
"optional": true
|
|
378
381
|
},
|
|
@@ -24,7 +24,7 @@ import { registerSearch } from "./commands/search.js";
|
|
|
24
24
|
import { registerSnapshot } from "./commands/snapshot.js";
|
|
25
25
|
import { registerUpdate } from "./commands/update.js";
|
|
26
26
|
|
|
27
|
-
const VERSION = "0.4.
|
|
27
|
+
const VERSION = "0.4.6";
|
|
28
28
|
|
|
29
29
|
const program = new Command();
|
|
30
30
|
program
|