@powerhousedao/vetra-builder-package 0.0.13 → 0.0.15
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/dist/document-models/builder-account/gen/schema/types.d.ts +1 -1
- package/dist/document-models/builder-account/gen/schema/zod.js +1 -1
- package/dist/document-models/index.d.ts +1 -0
- package/dist/document-models/index.js +1 -0
- package/dist/document-models/renown-profile/gen/actions.d.ts +5 -0
- package/dist/document-models/renown-profile/gen/actions.js +2 -0
- package/dist/document-models/renown-profile/gen/authorization/actions.d.ts +11 -0
- package/dist/document-models/renown-profile/gen/authorization/actions.js +1 -0
- package/dist/document-models/renown-profile/gen/authorization/creators.d.ts +4 -0
- package/dist/document-models/renown-profile/gen/authorization/creators.js +4 -0
- package/dist/document-models/renown-profile/gen/authorization/error.d.ts +1 -0
- package/dist/document-models/renown-profile/gen/authorization/error.js +1 -0
- package/dist/document-models/renown-profile/gen/authorization/object.d.ts +7 -0
- package/dist/document-models/renown-profile/gen/authorization/object.js +10 -0
- package/dist/document-models/renown-profile/gen/authorization/operations.d.ts +7 -0
- package/dist/document-models/renown-profile/gen/authorization/operations.js +1 -0
- package/dist/document-models/renown-profile/gen/creators.d.ts +2 -0
- package/dist/document-models/renown-profile/gen/creators.js +2 -0
- package/dist/document-models/renown-profile/gen/document-model.d.ts +2 -0
- package/dist/document-models/renown-profile/gen/document-model.js +99 -0
- package/dist/document-models/renown-profile/gen/index.d.ts +7 -0
- package/dist/document-models/renown-profile/gen/index.js +6 -0
- package/dist/document-models/renown-profile/gen/object.d.ts +16 -0
- package/dist/document-models/renown-profile/gen/object.js +30 -0
- package/dist/document-models/renown-profile/gen/ph-factories.d.ts +26 -0
- package/dist/document-models/renown-profile/gen/ph-factories.js +53 -0
- package/dist/document-models/renown-profile/gen/profile/actions.d.ts +15 -0
- package/dist/document-models/renown-profile/gen/profile/actions.js +1 -0
- package/dist/document-models/renown-profile/gen/profile/creators.d.ts +5 -0
- package/dist/document-models/renown-profile/gen/profile/creators.js +5 -0
- package/dist/document-models/renown-profile/gen/profile/error.d.ts +1 -0
- package/dist/document-models/renown-profile/gen/profile/error.js +1 -0
- package/dist/document-models/renown-profile/gen/profile/object.d.ts +8 -0
- package/dist/document-models/renown-profile/gen/profile/object.js +13 -0
- package/dist/document-models/renown-profile/gen/profile/operations.d.ts +8 -0
- package/dist/document-models/renown-profile/gen/profile/operations.js +1 -0
- package/dist/document-models/renown-profile/gen/reducer.d.ts +4 -0
- package/dist/document-models/renown-profile/gen/reducer.js +37 -0
- package/dist/document-models/renown-profile/gen/schema/index.d.ts +2 -0
- package/dist/document-models/renown-profile/gen/schema/index.js +2 -0
- package/dist/document-models/renown-profile/gen/schema/types.d.ts +174 -0
- package/dist/document-models/renown-profile/gen/schema/types.js +1 -0
- package/dist/document-models/renown-profile/gen/schema/zod.d.ts +16 -0
- package/dist/document-models/renown-profile/gen/schema/zod.js +62 -0
- package/dist/document-models/renown-profile/gen/types.d.ts +9 -0
- package/dist/document-models/renown-profile/gen/types.js +1 -0
- package/dist/document-models/renown-profile/gen/utils.d.ts +21 -0
- package/dist/document-models/renown-profile/gen/utils.js +45 -0
- package/dist/document-models/renown-profile/index.d.ts +28 -0
- package/dist/document-models/renown-profile/index.js +21 -0
- package/dist/document-models/renown-profile/src/reducers/authorization.d.ts +2 -0
- package/dist/document-models/renown-profile/src/reducers/authorization.js +8 -0
- package/dist/document-models/renown-profile/src/reducers/profile.d.ts +2 -0
- package/dist/document-models/renown-profile/src/reducers/profile.js +11 -0
- package/dist/document-models/renown-profile/src/tests/authorization.test.d.ts +5 -0
- package/dist/document-models/renown-profile/src/tests/authorization.test.js +24 -0
- package/dist/document-models/renown-profile/src/tests/document-model.test.d.ts +5 -0
- package/dist/document-models/renown-profile/src/tests/document-model.test.js +18 -0
- package/dist/document-models/renown-profile/src/tests/profile.test.d.ts +5 -0
- package/dist/document-models/renown-profile/src/tests/profile.test.js +24 -0
- package/dist/document-models/renown-profile/src/utils.d.ts +1 -0
- package/dist/document-models/renown-profile/src/utils.js +1 -0
- package/dist/editors/builder-account-editor/editor.js +2 -3
- package/dist/editors/hooks/useRenownProfileDocument.d.ts +3 -0
- package/dist/editors/hooks/useRenownProfileDocument.js +8 -0
- package/dist/editors/index.d.ts +1 -0
- package/dist/editors/index.js +1 -0
- package/dist/editors/renown-profile-editor/editor.d.ts +3 -0
- package/dist/editors/renown-profile-editor/editor.js +33 -0
- package/dist/editors/renown-profile-editor/index.d.ts +2 -0
- package/dist/editors/renown-profile-editor/index.js +11 -0
- package/dist/index.d.ts +1 -1
- package/dist/powerhouse.manifest.json +18 -1
- package/dist/processors/factory.js +2 -5
- package/dist/processors/index.d.ts +2 -0
- package/dist/processors/index.js +2 -0
- package/dist/processors/renown-profile/factory.d.ts +3 -0
- package/dist/processors/renown-profile/factory.js +22 -0
- package/dist/processors/renown-profile/index.d.ts +9 -0
- package/dist/processors/renown-profile/index.js +81 -0
- package/dist/processors/renown-profile/migrations.d.ts +3 -0
- package/dist/processors/renown-profile/migrations.js +39 -0
- package/dist/processors/renown-profile/schema.d.ts +14 -0
- package/dist/processors/renown-profile/schema.js +1 -0
- package/dist/processors/renown-read-model/migrations.d.ts +3 -0
- package/dist/processors/renown-read-model/migrations.js +55 -0
- package/dist/processors/renown-read-model/schema.d.ts +21 -0
- package/dist/processors/renown-read-model/schema.js +1 -0
- package/dist/processors/vetra-read-model/builder-account-handlers.js +7 -7
- package/dist/processors/vetra-read-model/database-helpers.d.ts +6 -1
- package/dist/processors/vetra-read-model/database-helpers.js +24 -1
- package/dist/processors/vetra-read-model/document-drive-handlers.d.ts +21 -0
- package/dist/processors/vetra-read-model/document-drive-handlers.js +77 -0
- package/dist/processors/vetra-read-model/factory.js +4 -1
- package/dist/processors/vetra-read-model/index.d.ts +2 -1
- package/dist/processors/vetra-read-model/index.js +23 -2
- package/dist/processors/vetra-read-model/migrations.js +22 -0
- package/dist/processors/vetra-read-model/schema.d.ts +7 -0
- package/dist/style.css +385 -17
- package/dist/subgraphs/index.d.ts +1 -0
- package/dist/subgraphs/index.js +2 -0
- package/dist/subgraphs/renown-profile/index.d.ts +10 -0
- package/dist/subgraphs/renown-profile/index.js +11 -0
- package/dist/subgraphs/renown-profile/resolvers.d.ts +2 -0
- package/dist/subgraphs/renown-profile/resolvers.js +151 -0
- package/dist/subgraphs/renown-profile/schema.d.ts +2 -0
- package/dist/subgraphs/renown-profile/schema.js +104 -0
- package/dist/subgraphs/renown-read-model/index.d.ts +10 -0
- package/dist/subgraphs/renown-read-model/index.js +11 -0
- package/dist/subgraphs/renown-read-model/resolvers.d.ts +2 -0
- package/dist/subgraphs/renown-read-model/resolvers.js +25 -0
- package/dist/subgraphs/renown-read-model/schema.d.ts +2 -0
- package/dist/subgraphs/renown-read-model/schema.js +16 -0
- package/dist/subgraphs/vetra-read-model/resolvers.js +31 -4
- package/package.json +3 -2
|
@@ -14,15 +14,32 @@
|
|
|
14
14
|
{
|
|
15
15
|
"id": "powerhouse/vetra/package",
|
|
16
16
|
"name": "VetraPackage"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "powerhouse/renown-profile",
|
|
20
|
+
"name": "RenownProfile"
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"editors": [
|
|
24
|
+
{
|
|
25
|
+
"id": "renown-profile-editor",
|
|
26
|
+
"name": "RenownProfileEditor",
|
|
27
|
+
"documentTypes": [
|
|
28
|
+
"powerhouse/renown-profile"
|
|
29
|
+
]
|
|
17
30
|
}
|
|
18
31
|
],
|
|
19
|
-
"editors": [],
|
|
20
32
|
"apps": [],
|
|
21
33
|
"subgraphs": [
|
|
22
34
|
{
|
|
23
35
|
"id": "vetra",
|
|
24
36
|
"name": "vetra",
|
|
25
37
|
"documentTypes": []
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "renown-read-model",
|
|
41
|
+
"name": "RenownReadModel",
|
|
42
|
+
"documentTypes": []
|
|
26
43
|
}
|
|
27
44
|
],
|
|
28
45
|
"importScripts": []
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
* This file aggregates all processor factories
|
|
3
|
-
* Auto-generated by codegen - DO NOT EDIT MANUALLY
|
|
4
|
-
*/
|
|
5
|
-
// Import other processor factories here as they are generated
|
|
1
|
+
import { renownProfileProcessorFactory } from "./renown-profile/factory.js";
|
|
6
2
|
import { vetraReadModelProcessorFactory } from "./vetra-read-model/factory.js";
|
|
7
3
|
export const processorFactory = (module) => {
|
|
8
4
|
// Initialize all processor factories once with the module
|
|
9
5
|
const factories = [];
|
|
10
6
|
// Add other processors here as they are generated
|
|
11
7
|
factories.push(vetraReadModelProcessorFactory(module));
|
|
8
|
+
factories.push(renownProfileProcessorFactory(module));
|
|
12
9
|
// Return the inner function that will be called for each drive
|
|
13
10
|
return async (driveHeader) => {
|
|
14
11
|
const processors = [];
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { VetraReadModelProcessor } from "./vetra-read-model/index.js";
|
|
2
2
|
export { vetraReadModelProcessorFactory } from "./vetra-read-model/factory.js";
|
|
3
3
|
export { processorFactory } from "./factory.js";
|
|
4
|
+
export * as RenownProfileProcessor from "./renown-profile/index.js";
|
|
5
|
+
export { renownProfileProcessorFactory } from "./renown-profile/factory.js";
|
package/dist/processors/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { VetraReadModelProcessor } from "./vetra-read-model/index.js";
|
|
2
2
|
export { vetraReadModelProcessorFactory } from "./vetra-read-model/factory.js";
|
|
3
3
|
export { processorFactory } from "./factory.js";
|
|
4
|
+
export * as RenownProfileProcessor from "./renown-profile/index.js";
|
|
5
|
+
export { renownProfileProcessorFactory } from "./renown-profile/factory.js";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type ProcessorRecord, type IProcessorHostModule } from "document-drive/processors/types";
|
|
2
|
+
import { type PHDocumentHeader } from "document-model";
|
|
3
|
+
export declare const renownProfileProcessorFactory: (module: IProcessorHostModule) => (driveHeader: PHDocumentHeader) => Promise<ProcessorRecord[]>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { RenownProfileProcessor } from "./index.js";
|
|
2
|
+
export const renownProfileProcessorFactory = (module) => async (driveHeader) => {
|
|
3
|
+
// Create a namespace for the processor and the provided drive id
|
|
4
|
+
const namespace = RenownProfileProcessor.getNamespace(driveHeader.id);
|
|
5
|
+
// Create a namespaced db for the processor
|
|
6
|
+
const store = await module.relationalDb.createNamespace(namespace);
|
|
7
|
+
// Create a filter for the processor
|
|
8
|
+
const filter = {
|
|
9
|
+
branch: ["main"],
|
|
10
|
+
documentId: ["*"],
|
|
11
|
+
documentType: ["powerhouse/renown-profile"],
|
|
12
|
+
scope: ["global"],
|
|
13
|
+
};
|
|
14
|
+
// Create the processor
|
|
15
|
+
const processor = new RenownProfileProcessor(namespace, filter, store);
|
|
16
|
+
return [
|
|
17
|
+
{
|
|
18
|
+
processor,
|
|
19
|
+
filter,
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { RelationalDbProcessor } from "document-drive/processors/relational";
|
|
2
|
+
import { type InternalTransmitterUpdate } from "document-drive/server/listener/transmitter/internal";
|
|
3
|
+
import { type DB } from "./schema.js";
|
|
4
|
+
export declare class RenownProfileProcessor extends RelationalDbProcessor<DB> {
|
|
5
|
+
static getNamespace(driveId: string): string;
|
|
6
|
+
initAndUpgrade(): Promise<void>;
|
|
7
|
+
onStrands(strands: InternalTransmitterUpdate[]): Promise<void>;
|
|
8
|
+
onDisconnect(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { RelationalDbProcessor } from "document-drive/processors/relational";
|
|
2
|
+
import { up } from "./migrations.js";
|
|
3
|
+
export class RenownProfileProcessor extends RelationalDbProcessor {
|
|
4
|
+
static getNamespace(driveId) {
|
|
5
|
+
// Default namespace: `${this.name}_${driveId.replaceAll("-", "_")}`
|
|
6
|
+
return super.getNamespace(driveId);
|
|
7
|
+
}
|
|
8
|
+
async initAndUpgrade() {
|
|
9
|
+
await up(this.relationalDb);
|
|
10
|
+
}
|
|
11
|
+
async onStrands(strands) {
|
|
12
|
+
if (strands.length === 0) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
for (const strand of strands) {
|
|
16
|
+
if (strand.operations.length === 0) {
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
const documentId = strand.documentId;
|
|
20
|
+
// Ensure the profile exists in the database
|
|
21
|
+
const existingProfile = await this.relationalDb
|
|
22
|
+
.selectFrom("renown_profile")
|
|
23
|
+
.select(["document_id"])
|
|
24
|
+
.where("document_id", "=", documentId)
|
|
25
|
+
.executeTakeFirst();
|
|
26
|
+
if (!existingProfile) {
|
|
27
|
+
// Create a new profile entry
|
|
28
|
+
await this.relationalDb
|
|
29
|
+
.insertInto("renown_profile")
|
|
30
|
+
.values({
|
|
31
|
+
document_id: documentId,
|
|
32
|
+
username: null,
|
|
33
|
+
eth_address: null,
|
|
34
|
+
user_image: null,
|
|
35
|
+
created_at: new Date(),
|
|
36
|
+
updated_at: new Date(),
|
|
37
|
+
})
|
|
38
|
+
.execute();
|
|
39
|
+
}
|
|
40
|
+
// Process each operation
|
|
41
|
+
for (const operation of strand.operations) {
|
|
42
|
+
// Update the profile based on the operation type
|
|
43
|
+
const updateData = {
|
|
44
|
+
updated_at: new Date(),
|
|
45
|
+
};
|
|
46
|
+
switch (operation.action.type) {
|
|
47
|
+
case "SET_USERNAME": {
|
|
48
|
+
const input = operation.action.input;
|
|
49
|
+
if (input?.username) {
|
|
50
|
+
updateData.username = input.username;
|
|
51
|
+
}
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
case "SET_ETH_ADDRESS": {
|
|
55
|
+
const input = operation.action.input;
|
|
56
|
+
if (input?.ethAddress) {
|
|
57
|
+
updateData.eth_address = input.ethAddress;
|
|
58
|
+
}
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
case "SET_USER_IMAGE": {
|
|
62
|
+
const input = operation.action.input;
|
|
63
|
+
if (input?.userImage !== undefined) {
|
|
64
|
+
updateData.user_image = input.userImage || null;
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Apply updates if there are any field changes
|
|
70
|
+
if (Object.keys(updateData).length > 1) {
|
|
71
|
+
await this.relationalDb
|
|
72
|
+
.updateTable("renown_profile")
|
|
73
|
+
.set(updateData)
|
|
74
|
+
.where("document_id", "=", documentId)
|
|
75
|
+
.execute();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async onDisconnect() { }
|
|
81
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export async function up(db) {
|
|
2
|
+
await down(db);
|
|
3
|
+
// Create renown_profile table
|
|
4
|
+
await db.schema
|
|
5
|
+
.createTable("renown_profile")
|
|
6
|
+
.addColumn("document_id", "varchar(255)")
|
|
7
|
+
.addColumn("username", "varchar(255)")
|
|
8
|
+
.addColumn("eth_address", "varchar(42)")
|
|
9
|
+
.addColumn("user_image", "text")
|
|
10
|
+
.addColumn("created_at", "timestamp", (col) => col.defaultTo(db.fn("now")))
|
|
11
|
+
.addColumn("updated_at", "timestamp", (col) => col.defaultTo(db.fn("now")))
|
|
12
|
+
.addPrimaryKeyConstraint("renown_profile_pkey", ["document_id"])
|
|
13
|
+
.ifNotExists()
|
|
14
|
+
.execute();
|
|
15
|
+
// Create index on username for faster lookups
|
|
16
|
+
await db.schema
|
|
17
|
+
.createIndex("idx_renown_profile_username")
|
|
18
|
+
.on("renown_profile")
|
|
19
|
+
.column("username")
|
|
20
|
+
.ifNotExists()
|
|
21
|
+
.execute();
|
|
22
|
+
// Create index on eth_address for faster lookups
|
|
23
|
+
await db.schema
|
|
24
|
+
.createIndex("idx_renown_profile_eth_address")
|
|
25
|
+
.on("renown_profile")
|
|
26
|
+
.column("eth_address")
|
|
27
|
+
.ifNotExists()
|
|
28
|
+
.execute();
|
|
29
|
+
}
|
|
30
|
+
export async function down(db) {
|
|
31
|
+
// Drop indexes
|
|
32
|
+
await db.schema
|
|
33
|
+
.dropIndex("idx_renown_profile_eth_address")
|
|
34
|
+
.ifExists()
|
|
35
|
+
.execute();
|
|
36
|
+
await db.schema.dropIndex("idx_renown_profile_username").ifExists().execute();
|
|
37
|
+
// Drop tables
|
|
38
|
+
await db.schema.dropTable("renown_profile").ifExists().execute();
|
|
39
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ColumnType } from "kysely";
|
|
2
|
+
export type Generated<T> = T extends ColumnType<infer S, infer I, infer U> ? ColumnType<S, I | undefined, U> : ColumnType<T, T | undefined, T>;
|
|
3
|
+
export type Timestamp = ColumnType<Date, Date | string, Date | string>;
|
|
4
|
+
export interface RenownProfile {
|
|
5
|
+
created_at: Generated<Timestamp | null>;
|
|
6
|
+
document_id: string;
|
|
7
|
+
eth_address: string | null;
|
|
8
|
+
updated_at: Generated<Timestamp | null>;
|
|
9
|
+
user_image: string | null;
|
|
10
|
+
username: string | null;
|
|
11
|
+
}
|
|
12
|
+
export interface DB {
|
|
13
|
+
renown_profile: RenownProfile;
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export async function up(db) {
|
|
2
|
+
if (process.env.NODE_ENV !== "production") {
|
|
3
|
+
await down(db);
|
|
4
|
+
}
|
|
5
|
+
// Create renown_profiles table
|
|
6
|
+
await db.schema
|
|
7
|
+
.createTable("renown_profiles")
|
|
8
|
+
.addColumn("id", "varchar(255)", (col) => col.primaryKey())
|
|
9
|
+
.addColumn("username", "varchar(255)")
|
|
10
|
+
.addColumn("eth_address", "varchar(42)") // Ethereum addresses are 42 chars
|
|
11
|
+
.addColumn("user_image", "text")
|
|
12
|
+
.addColumn("created_at", "timestamp", (col) => col.defaultTo("now()").notNull())
|
|
13
|
+
.addColumn("updated_at", "timestamp", (col) => col.defaultTo("now()").notNull())
|
|
14
|
+
.ifNotExists()
|
|
15
|
+
.execute();
|
|
16
|
+
// Create deleted_files table
|
|
17
|
+
await db.schema
|
|
18
|
+
.createTable("deleted_files")
|
|
19
|
+
.addColumn("id", "varchar(255)", (col) => col.primaryKey())
|
|
20
|
+
.addColumn("document_id", "varchar(255)", (col) => col.notNull())
|
|
21
|
+
.addColumn("drive_id", "varchar(255)", (col) => col.notNull())
|
|
22
|
+
.addColumn("deleted_at", "timestamp", (col) => col.defaultTo("now()").notNull())
|
|
23
|
+
.ifNotExists()
|
|
24
|
+
.execute();
|
|
25
|
+
// Create indexes for better performance
|
|
26
|
+
await db.schema
|
|
27
|
+
.createIndex("idx_renown_profiles_username")
|
|
28
|
+
.on("renown_profiles")
|
|
29
|
+
.column("username")
|
|
30
|
+
.ifNotExists()
|
|
31
|
+
.execute();
|
|
32
|
+
await db.schema
|
|
33
|
+
.createIndex("idx_renown_profiles_eth_address")
|
|
34
|
+
.on("renown_profiles")
|
|
35
|
+
.column("eth_address")
|
|
36
|
+
.ifNotExists()
|
|
37
|
+
.execute();
|
|
38
|
+
await db.schema
|
|
39
|
+
.createIndex("idx_deleted_files_document_id")
|
|
40
|
+
.on("deleted_files")
|
|
41
|
+
.column("document_id")
|
|
42
|
+
.ifNotExists()
|
|
43
|
+
.execute();
|
|
44
|
+
await db.schema
|
|
45
|
+
.createIndex("idx_deleted_files_drive_id")
|
|
46
|
+
.on("deleted_files")
|
|
47
|
+
.column("drive_id")
|
|
48
|
+
.ifNotExists()
|
|
49
|
+
.execute();
|
|
50
|
+
}
|
|
51
|
+
export async function down(db) {
|
|
52
|
+
// Drop tables in reverse order due to foreign key constraints
|
|
53
|
+
await db.schema.dropTable("deleted_files").ifExists().execute();
|
|
54
|
+
await db.schema.dropTable("renown_profiles").ifExists().execute();
|
|
55
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ColumnType } from "kysely";
|
|
2
|
+
export type Generated<T> = T extends ColumnType<infer S, infer I, infer U> ? ColumnType<S, I | undefined, U> : ColumnType<T, T | undefined, T>;
|
|
3
|
+
export type Timestamp = ColumnType<Date, Date | string, Date | string>;
|
|
4
|
+
export interface RenownProfiles {
|
|
5
|
+
id: string;
|
|
6
|
+
username: string | null;
|
|
7
|
+
eth_address: string | null;
|
|
8
|
+
user_image: string | null;
|
|
9
|
+
created_at: Generated<Timestamp>;
|
|
10
|
+
updated_at: Generated<Timestamp>;
|
|
11
|
+
}
|
|
12
|
+
export interface DeletedFiles {
|
|
13
|
+
id: string;
|
|
14
|
+
document_id: string;
|
|
15
|
+
drive_id: string;
|
|
16
|
+
deleted_at: Generated<Timestamp>;
|
|
17
|
+
}
|
|
18
|
+
export interface DB {
|
|
19
|
+
renown_profiles: RenownProfiles;
|
|
20
|
+
deleted_files: DeletedFiles;
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -68,31 +68,31 @@ export class BuilderAccountHandlers {
|
|
|
68
68
|
}
|
|
69
69
|
// Profile operations
|
|
70
70
|
async handleSetLogo(documentId, action, state) {
|
|
71
|
-
await this.dbHelpers.
|
|
71
|
+
await this.dbHelpers.ensureBuilderAccountExistsAndIsNotdeleted(documentId);
|
|
72
72
|
await this.dbHelpers.updateBuilderAccount(documentId, {
|
|
73
73
|
profile_logo: action.input.logoUrl,
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
76
|
async handleSetProfileName(documentId, action, state) {
|
|
77
|
-
await this.dbHelpers.
|
|
77
|
+
await this.dbHelpers.ensureBuilderAccountExistsAndIsNotdeleted(documentId);
|
|
78
78
|
await this.dbHelpers.updateBuilderAccount(documentId, {
|
|
79
79
|
profile_name: action.input.name,
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
async handleSetSlug(documentId, action, state) {
|
|
83
|
-
await this.dbHelpers.
|
|
83
|
+
await this.dbHelpers.ensureBuilderAccountExistsAndIsNotdeleted(documentId);
|
|
84
84
|
await this.dbHelpers.updateBuilderAccount(documentId, {
|
|
85
85
|
profile_slug: action.input.slug,
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
88
|
async handleSetProfileDescription(documentId, action, state) {
|
|
89
|
-
await this.dbHelpers.
|
|
89
|
+
await this.dbHelpers.ensureBuilderAccountExistsAndIsNotdeleted(documentId);
|
|
90
90
|
await this.dbHelpers.updateBuilderAccount(documentId, {
|
|
91
91
|
profile_description: action.input.description,
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
94
|
async handleUpdateSocials(documentId, action, state) {
|
|
95
|
-
await this.dbHelpers.
|
|
95
|
+
await this.dbHelpers.ensureBuilderAccountExistsAndIsNotdeleted(documentId);
|
|
96
96
|
await this.dbHelpers.updateBuilderAccount(documentId, {
|
|
97
97
|
profile_socials_x: action.input.x,
|
|
98
98
|
profile_socials_github: action.input.github,
|
|
@@ -101,7 +101,7 @@ export class BuilderAccountHandlers {
|
|
|
101
101
|
}
|
|
102
102
|
// Members operations
|
|
103
103
|
async handleAddMember(documentId, action, state) {
|
|
104
|
-
await this.dbHelpers.
|
|
104
|
+
await this.dbHelpers.ensureBuilderAccountExistsAndIsNotdeleted(documentId);
|
|
105
105
|
if (!action.input.ethAddress)
|
|
106
106
|
return;
|
|
107
107
|
const memberExists = await this.dbHelpers.memberExists(documentId, action.input.ethAddress);
|
|
@@ -128,7 +128,7 @@ export class BuilderAccountHandlers {
|
|
|
128
128
|
}
|
|
129
129
|
// Spaces operations
|
|
130
130
|
async handleAddSpace(documentId, action, state) {
|
|
131
|
-
await this.dbHelpers.
|
|
131
|
+
await this.dbHelpers.ensureBuilderAccountExistsAndIsNotdeleted(documentId);
|
|
132
132
|
const spaceId = toPascalCase(action.input.title);
|
|
133
133
|
await this.db
|
|
134
134
|
.insertInto("builder_spaces")
|
|
@@ -7,10 +7,15 @@ export declare class DatabaseHelpers {
|
|
|
7
7
|
* Ensures a package exists in the database, creating it if it doesn't
|
|
8
8
|
*/
|
|
9
9
|
ensurePackageExists(documentId: string, driveId: string): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Check if a document ID is marked as deleted
|
|
12
|
+
*/
|
|
13
|
+
private isDocumentDeleted;
|
|
10
14
|
/**
|
|
11
15
|
* Ensures a builder account exists in the database, creating it if it doesn't
|
|
16
|
+
* Throws an error if the document was previously deleted
|
|
12
17
|
*/
|
|
13
|
-
|
|
18
|
+
ensureBuilderAccountExistsAndIsNotdeleted(documentId: string): Promise<void>;
|
|
14
19
|
/**
|
|
15
20
|
* Updates a package with the provided data
|
|
16
21
|
*/
|
|
@@ -25,10 +25,33 @@ export class DatabaseHelpers {
|
|
|
25
25
|
.execute();
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Check if a document ID is marked as deleted
|
|
30
|
+
*/
|
|
31
|
+
async isDocumentDeleted(documentId) {
|
|
32
|
+
try {
|
|
33
|
+
const result = await this.db
|
|
34
|
+
.selectFrom("deleted_files")
|
|
35
|
+
.select("id")
|
|
36
|
+
.where("document_id", "=", documentId)
|
|
37
|
+
.executeTakeFirst();
|
|
38
|
+
return !!result;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
console.error("Error checking if document is deleted:", error);
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
28
45
|
/**
|
|
29
46
|
* Ensures a builder account exists in the database, creating it if it doesn't
|
|
47
|
+
* Throws an error if the document was previously deleted
|
|
30
48
|
*/
|
|
31
|
-
async
|
|
49
|
+
async ensureBuilderAccountExistsAndIsNotdeleted(documentId) {
|
|
50
|
+
// Check if the document was deleted
|
|
51
|
+
const isDeleted = await this.isDocumentDeleted(documentId);
|
|
52
|
+
if (isDeleted) {
|
|
53
|
+
throw new Error(`Builder account with document ID ${documentId} was previously deleted and cannot be accessed`);
|
|
54
|
+
}
|
|
32
55
|
const existing = await this.db
|
|
33
56
|
.selectFrom("builder_accounts")
|
|
34
57
|
.select("id")
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Action } from "document-model";
|
|
2
|
+
import type { DB } from "./schema.js";
|
|
3
|
+
import type { IRelationalDb } from "document-drive";
|
|
4
|
+
export type DocumentDriveAction = Action & {
|
|
5
|
+
type: "DELETE_NODE" | "ADD_FILE" | "ADD_FOLDER" | "UPDATE_FILE" | "UPDATE_NODE" | "COPY_NODE" | "MOVE_NODE";
|
|
6
|
+
input: any;
|
|
7
|
+
};
|
|
8
|
+
export declare class DocumentDriveHandlers {
|
|
9
|
+
private db;
|
|
10
|
+
constructor(db: IRelationalDb<DB>);
|
|
11
|
+
/**
|
|
12
|
+
* Check if a document ID is marked as deleted
|
|
13
|
+
*/
|
|
14
|
+
isDocumentDeleted(documentId: string): Promise<boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* Get all deleted document IDs for a specific drive
|
|
17
|
+
*/
|
|
18
|
+
getDeletedDocumentsInDrive(driveId: string): Promise<string[]>;
|
|
19
|
+
handleDocumentDriveOperation(documentId: string, action: DocumentDriveAction, driveId?: string): Promise<void>;
|
|
20
|
+
private handleDeleteNode;
|
|
21
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export class DocumentDriveHandlers {
|
|
2
|
+
db;
|
|
3
|
+
constructor(db) {
|
|
4
|
+
this.db = db;
|
|
5
|
+
console.log("DocumentDriveHandlers constructor");
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Check if a document ID is marked as deleted
|
|
9
|
+
*/
|
|
10
|
+
async isDocumentDeleted(documentId) {
|
|
11
|
+
try {
|
|
12
|
+
const result = await this.db
|
|
13
|
+
.selectFrom("deleted_files")
|
|
14
|
+
.select("id")
|
|
15
|
+
.where("document_id", "=", documentId)
|
|
16
|
+
.executeTakeFirst();
|
|
17
|
+
return !!result;
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
console.error("Error checking if document is deleted:", error);
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get all deleted document IDs for a specific drive
|
|
26
|
+
*/
|
|
27
|
+
async getDeletedDocumentsInDrive(driveId) {
|
|
28
|
+
try {
|
|
29
|
+
const results = await this.db
|
|
30
|
+
.selectFrom("deleted_files")
|
|
31
|
+
.select("document_id")
|
|
32
|
+
.where("drive_id", "=", driveId)
|
|
33
|
+
.execute();
|
|
34
|
+
return results.map((r) => r.document_id);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.error("Error getting deleted documents in drive:", error);
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async handleDocumentDriveOperation(documentId, action, driveId) {
|
|
42
|
+
console.log("Handling document drive operation:", action.type);
|
|
43
|
+
switch (action.type) {
|
|
44
|
+
case "DELETE_NODE":
|
|
45
|
+
console.log("Deleting node:", action.input.nodeId);
|
|
46
|
+
await this.handleDeleteNode(documentId, action, driveId);
|
|
47
|
+
break;
|
|
48
|
+
// Add other document-drive operations as needed
|
|
49
|
+
// case "ADD_FILE":
|
|
50
|
+
// await this.handleAddFile(documentId, action, driveId);
|
|
51
|
+
// break;
|
|
52
|
+
// case "UPDATE_FILE":
|
|
53
|
+
// await this.handleUpdateFile(documentId, action, driveId);
|
|
54
|
+
// break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async handleDeleteNode(documentId, action, driveId) {
|
|
58
|
+
try {
|
|
59
|
+
const { nodeId } = action.input;
|
|
60
|
+
// Store the deleted file/document ID in the deleted_files table
|
|
61
|
+
// documentId is the drive ID, nodeId is the specific file/node being deleted
|
|
62
|
+
await this.db
|
|
63
|
+
.insertInto("deleted_files")
|
|
64
|
+
.values({
|
|
65
|
+
id: `${documentId}-${nodeId}`, // Unique ID combining drive and node
|
|
66
|
+
document_id: nodeId, // The specific document/file that was deleted
|
|
67
|
+
drive_id: documentId, // The drive containing the deleted file
|
|
68
|
+
deleted_at: new Date(),
|
|
69
|
+
})
|
|
70
|
+
.onConflict((oc) => oc.column("id").doNothing())
|
|
71
|
+
.execute();
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error("Error handling delete node:", error);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -8,7 +8,10 @@ export const vetraReadModelProcessorFactory = (module) => async (driveHeader) =>
|
|
|
8
8
|
const filter = {
|
|
9
9
|
branch: ["main"],
|
|
10
10
|
documentId: ["*"],
|
|
11
|
-
documentType: [
|
|
11
|
+
documentType: [
|
|
12
|
+
"powerhouse/vetra/builder-account",
|
|
13
|
+
"powerhouse/document-drive",
|
|
14
|
+
],
|
|
12
15
|
scope: ["global"],
|
|
13
16
|
};
|
|
14
17
|
// Create the processor
|
|
@@ -5,7 +5,8 @@ export declare class VetraReadModelProcessor extends RelationalDbProcessor<DB> {
|
|
|
5
5
|
static getNamespace(driveId: string): string;
|
|
6
6
|
initAndUpgrade(): Promise<void>;
|
|
7
7
|
onStrands(strands: InternalTransmitterUpdate[]): Promise<void>;
|
|
8
|
-
private
|
|
8
|
+
private handleDocumentDriveOperation;
|
|
9
|
+
private handlePackageOperation;
|
|
9
10
|
private handleSetLogo;
|
|
10
11
|
private handleSetProfileName;
|
|
11
12
|
private handleSetSlug;
|
|
@@ -18,11 +18,32 @@ export class VetraReadModelProcessor extends RelationalDbProcessor {
|
|
|
18
18
|
continue;
|
|
19
19
|
}
|
|
20
20
|
for (const operation of strand.operations) {
|
|
21
|
-
|
|
21
|
+
if (strand.documentType.includes("powerhouse/document-drive")) {
|
|
22
|
+
await this.handleDocumentDriveOperation(strand.documentId, strand.driveId, operation.action, operation.state);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
await this.handlePackageOperation(strand.documentId, operation.action, operation.state);
|
|
26
|
+
}
|
|
22
27
|
}
|
|
23
28
|
}
|
|
24
29
|
}
|
|
25
|
-
async
|
|
30
|
+
async handleDocumentDriveOperation(documentId, driveId = "", action, state) {
|
|
31
|
+
switch (action.type) {
|
|
32
|
+
case "DELETE_NODE":
|
|
33
|
+
await this.relationalDb
|
|
34
|
+
.insertInto("deleted_files")
|
|
35
|
+
.values({
|
|
36
|
+
id: documentId + "-" + action.input.id,
|
|
37
|
+
document_id: action.input.id,
|
|
38
|
+
drive_id: driveId,
|
|
39
|
+
deleted_at: new Date(),
|
|
40
|
+
})
|
|
41
|
+
.onConflict((oc) => oc.column("id").doNothing())
|
|
42
|
+
.execute();
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async handlePackageOperation(documentId, action, state) {
|
|
26
47
|
switch (action.type) {
|
|
27
48
|
// Profile operations
|
|
28
49
|
case "SET_LOGO":
|
|
@@ -70,6 +70,15 @@ export async function up(db) {
|
|
|
70
70
|
.addForeignKeyConstraint("builder_package_keywords_package_fk", ["package_id"], "builder_packages", ["id"], (cb) => cb.onDelete("cascade"))
|
|
71
71
|
.ifNotExists()
|
|
72
72
|
.execute();
|
|
73
|
+
// Create deleted_files table
|
|
74
|
+
await db.schema
|
|
75
|
+
.createTable("deleted_files")
|
|
76
|
+
.addColumn("id", "varchar(255)", (col) => col.primaryKey())
|
|
77
|
+
.addColumn("document_id", "varchar(255)", (col) => col.notNull())
|
|
78
|
+
.addColumn("drive_id", "varchar(255)", (col) => col.notNull())
|
|
79
|
+
.addColumn("deleted_at", "timestamp", (col) => col.defaultTo("now()").notNull())
|
|
80
|
+
.ifNotExists()
|
|
81
|
+
.execute();
|
|
73
82
|
// Create indexes for better performance
|
|
74
83
|
await db.schema
|
|
75
84
|
.createIndex("idx_builder_accounts_slug")
|
|
@@ -119,9 +128,22 @@ export async function up(db) {
|
|
|
119
128
|
.column("package_id")
|
|
120
129
|
.ifNotExists()
|
|
121
130
|
.execute();
|
|
131
|
+
await db.schema
|
|
132
|
+
.createIndex("idx_deleted_files_document_id")
|
|
133
|
+
.on("deleted_files")
|
|
134
|
+
.column("document_id")
|
|
135
|
+
.ifNotExists()
|
|
136
|
+
.execute();
|
|
137
|
+
await db.schema
|
|
138
|
+
.createIndex("idx_deleted_files_drive_id")
|
|
139
|
+
.on("deleted_files")
|
|
140
|
+
.column("drive_id")
|
|
141
|
+
.ifNotExists()
|
|
142
|
+
.execute();
|
|
122
143
|
}
|
|
123
144
|
export async function down(db) {
|
|
124
145
|
// Drop tables in reverse order due to foreign key constraints
|
|
146
|
+
await db.schema.dropTable("deleted_files").ifExists().execute();
|
|
125
147
|
await db.schema.dropTable("builder_package_keywords").ifExists().execute();
|
|
126
148
|
await db.schema.dropTable("builder_packages").ifExists().execute();
|
|
127
149
|
await db.schema.dropTable("builder_spaces").ifExists().execute();
|