mirror of
https://github.com/twentyhq/twenty
synced 2026-04-21 13:37:22 +00:00
add workspaceId to indirect entities (#19522)
Required for `workspace:export` command --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
parent
7ef80dd238
commit
8a10071253
38 changed files with 439 additions and 15 deletions
|
|
@ -36,6 +36,12 @@ ruleTester.run(RULE_NAME, rule, {
|
|||
'1-22/1-22-instance-command-fast-1780000000000-create-task-table.ts',
|
||||
),
|
||||
},
|
||||
{
|
||||
code: DUMMY_CODE,
|
||||
filename: filename(
|
||||
'1-22/1-22-instance-command-slow-1775758621018-backfill-workspace-id.ts',
|
||||
),
|
||||
},
|
||||
{
|
||||
code: DUMMY_CODE,
|
||||
filename: filename('1-21/1-21-upgrade-version-command.module.ts'),
|
||||
|
|
@ -75,7 +81,7 @@ ruleTester.run(RULE_NAME, rule, {
|
|||
filename: filename(
|
||||
'1-21/1-21-instance-command-fast-add-column.ts',
|
||||
),
|
||||
errors: [{ messageId: 'invalidInstanceCommandFilename' }],
|
||||
errors: [{ messageId: 'invalidInstanceCommandFastFilename' }],
|
||||
},
|
||||
{
|
||||
code: DUMMY_CODE,
|
||||
|
|
|
|||
|
|
@ -5,9 +5,12 @@ export const RULE_NAME = 'upgrade-command-filename';
|
|||
const WORKSPACE_COMMAND_REGEX =
|
||||
/^\d+-\d+-workspace-command-\d{13,}-[a-z0-9]+(?:-[a-z0-9]+)*\.command\.ts$/;
|
||||
|
||||
const INSTANCE_COMMAND_REGEX =
|
||||
const INSTANCE_COMMAND_FAST_REGEX =
|
||||
/^\d+-\d+-instance-command-fast-\d{13,}-[a-z0-9]+(?:-[a-z0-9]+)*\.ts$/;
|
||||
|
||||
const INSTANCE_COMMAND_SLOW_REGEX =
|
||||
/^\d+-\d+-instance-command-slow-\d{13,}-[a-z0-9]+(?:-[a-z0-9]+)*\.ts$/;
|
||||
|
||||
const SKIPPED_FILE_REGEX =
|
||||
/\.(module|spec|test|snap)\.ts$|__tests__|__mocks__|__snapshots__/;
|
||||
|
||||
|
|
@ -37,10 +40,12 @@ export const rule = defineRule({
|
|||
messages: {
|
||||
invalidWorkspaceCommandFilename:
|
||||
"Workspace command filename '{{ name }}' must match pattern: {major}-{minor}-workspace-command-{timestamp}-{description}.command.ts (e.g. '1-21-workspace-command-1775500001000-add-feature.command.ts')",
|
||||
invalidInstanceCommandFilename:
|
||||
invalidInstanceCommandFastFilename:
|
||||
"Instance command filename '{{ name }}' must match pattern: {major}-{minor}-instance-command-fast-{timestamp}-{description}.ts (e.g. '1-21-instance-command-fast-1775500001000-add-column.ts')",
|
||||
invalidInstanceCommandSlowFilename:
|
||||
"Instance command filename '{{ name }}' must match pattern: {major}-{minor}-instance-command-slow-{timestamp}-{description}.ts (e.g. '1-22-instance-command-slow-1775500001000-backfill-data.ts')",
|
||||
invalidUpgradeCommandFilename:
|
||||
"Upgrade command filename '{{ name }}' does not match any recognized pattern. Expected workspace-command or instance-command-fast format.",
|
||||
"Upgrade command filename '{{ name }}' does not match any recognized pattern. Expected workspace-command, instance-command-fast, or instance-command-slow format.",
|
||||
},
|
||||
},
|
||||
create: (context) => {
|
||||
|
|
@ -78,10 +83,22 @@ export const rule = defineRule({
|
|||
}
|
||||
|
||||
if (basename.includes('instance-command-fast-')) {
|
||||
if (!INSTANCE_COMMAND_REGEX.test(basename)) {
|
||||
if (!INSTANCE_COMMAND_FAST_REGEX.test(basename)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'invalidInstanceCommandFilename',
|
||||
messageId: 'invalidInstanceCommandFastFilename',
|
||||
data: { name: basename },
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (basename.includes('instance-command-slow-')) {
|
||||
if (!INSTANCE_COMMAND_SLOW_REGEX.test(basename)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'invalidInstanceCommandSlowFilename',
|
||||
data: { name: basename },
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decor
|
|||
import { FastInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/fast-instance-command.interface';
|
||||
|
||||
@RegisteredInstanceCommand('1.22.0', 1775749486425)
|
||||
export class AutoGeneratedFastInstanceCommand implements FastInstanceCommand {
|
||||
export class AddPermissionFlagRoleIdIndexFastInstanceCommand
|
||||
implements FastInstanceCommand
|
||||
{
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "IDX_PERMISSION_FLAG_ROLE_ID" ON "core"."permissionFlag" ("roleId") ',
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import { QueryRunner } from 'typeorm';
|
||||
|
||||
import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator';
|
||||
import { FastInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/fast-instance-command.interface';
|
||||
|
||||
const TABLES = [
|
||||
'applicationVariable',
|
||||
'indexFieldMetadata',
|
||||
'twoFactorAuthenticationMethod',
|
||||
'agentMessagePart',
|
||||
'agentTurnEvaluation',
|
||||
'agentChatThread',
|
||||
'agentTurn',
|
||||
'agentMessage',
|
||||
];
|
||||
|
||||
@RegisteredInstanceCommand('1.22.0', 1775758621017)
|
||||
export class AddWorkspaceIdToIndirectEntitiesFastInstanceCommand
|
||||
implements FastInstanceCommand
|
||||
{
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
for (const table of TABLES) {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."${table}" ADD "workspaceId" uuid`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
for (const table of TABLES) {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."${table}" DROP COLUMN "workspaceId"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
import { QueryRunner } from 'typeorm';
|
||||
|
||||
import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator';
|
||||
import { FastInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/fast-instance-command.interface';
|
||||
|
||||
@RegisteredInstanceCommand('1.22.0', 1775761294897)
|
||||
export class AddWorkspaceIdIndexesAndFksFastInstanceCommand
|
||||
implements FastInstanceCommand
|
||||
{
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "IDX_78ae6cfe5f49a76c4bf842ad58" ON "core"."applicationVariable" ("workspaceId") ',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "IDX_d8cf7f15cf6466ac0e3b443b3d" ON "core"."indexFieldMetadata" ("workspaceId") ',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "IDX_b8282d1e10fbb7856950f86c61" ON "core"."twoFactorAuthenticationMethod" ("workspaceId") ',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "IDX_70b398dc45219db8f3e36b3a07" ON "core"."agentMessagePart" ("workspaceId") ',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "IDX_c81d8fabdda94b7fa86fb6f1e7" ON "core"."agentTurnEvaluation" ("workspaceId") ',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "IDX_3d097ed53841d80904ed02c837" ON "core"."agentChatThread" ("workspaceId") ',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "IDX_a4bb3c6176c2607693a6756ff6" ON "core"."agentTurn" ("workspaceId") ',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'CREATE INDEX "IDX_75db4f2e80922078e8171ae130" ON "core"."agentMessage" ("workspaceId") ',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."applicationVariable" ADD CONSTRAINT "FK_78ae6cfe5f49a76c4bf842ad58b" FOREIGN KEY ("workspaceId") REFERENCES "core"."workspace"("id") ON DELETE CASCADE ON UPDATE NO ACTION',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."indexFieldMetadata" ADD CONSTRAINT "FK_d8cf7f15cf6466ac0e3b443b3d2" FOREIGN KEY ("workspaceId") REFERENCES "core"."workspace"("id") ON DELETE CASCADE ON UPDATE NO ACTION',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."twoFactorAuthenticationMethod" ADD CONSTRAINT "FK_b8282d1e10fbb7856950f86c616" FOREIGN KEY ("workspaceId") REFERENCES "core"."workspace"("id") ON DELETE CASCADE ON UPDATE NO ACTION',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."agentMessagePart" ADD CONSTRAINT "FK_70b398dc45219db8f3e36b3a078" FOREIGN KEY ("workspaceId") REFERENCES "core"."workspace"("id") ON DELETE CASCADE ON UPDATE NO ACTION',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."agentTurnEvaluation" ADD CONSTRAINT "FK_c81d8fabdda94b7fa86fb6f1e70" FOREIGN KEY ("workspaceId") REFERENCES "core"."workspace"("id") ON DELETE CASCADE ON UPDATE NO ACTION',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."agentChatThread" ADD CONSTRAINT "FK_3d097ed53841d80904ed02c8373" FOREIGN KEY ("workspaceId") REFERENCES "core"."workspace"("id") ON DELETE CASCADE ON UPDATE NO ACTION',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."agentTurn" ADD CONSTRAINT "FK_a4bb3c6176c2607693a6756ff6c" FOREIGN KEY ("workspaceId") REFERENCES "core"."workspace"("id") ON DELETE CASCADE ON UPDATE NO ACTION',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."agentMessage" ADD CONSTRAINT "FK_75db4f2e80922078e8171ae130a" FOREIGN KEY ("workspaceId") REFERENCES "core"."workspace"("id") ON DELETE CASCADE ON UPDATE NO ACTION',
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."agentMessage" DROP CONSTRAINT "FK_75db4f2e80922078e8171ae130a"',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."agentTurn" DROP CONSTRAINT "FK_a4bb3c6176c2607693a6756ff6c"',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."agentChatThread" DROP CONSTRAINT "FK_3d097ed53841d80904ed02c8373"',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."agentTurnEvaluation" DROP CONSTRAINT "FK_c81d8fabdda94b7fa86fb6f1e70"',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."agentMessagePart" DROP CONSTRAINT "FK_70b398dc45219db8f3e36b3a078"',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."twoFactorAuthenticationMethod" DROP CONSTRAINT "FK_b8282d1e10fbb7856950f86c616"',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."indexFieldMetadata" DROP CONSTRAINT "FK_d8cf7f15cf6466ac0e3b443b3d2"',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "core"."applicationVariable" DROP CONSTRAINT "FK_78ae6cfe5f49a76c4bf842ad58b"',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'DROP INDEX "core"."IDX_75db4f2e80922078e8171ae130"',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'DROP INDEX "core"."IDX_a4bb3c6176c2607693a6756ff6"',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'DROP INDEX "core"."IDX_3d097ed53841d80904ed02c837"',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'DROP INDEX "core"."IDX_c81d8fabdda94b7fa86fb6f1e7"',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'DROP INDEX "core"."IDX_70b398dc45219db8f3e36b3a07"',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'DROP INDEX "core"."IDX_b8282d1e10fbb7856950f86c61"',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'DROP INDEX "core"."IDX_d8cf7f15cf6466ac0e3b443b3d"',
|
||||
);
|
||||
await queryRunner.query(
|
||||
'DROP INDEX "core"."IDX_78ae6cfe5f49a76c4bf842ad58"',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
import { DataSource, QueryRunner } from 'typeorm';
|
||||
|
||||
import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator';
|
||||
import { SlowInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/slow-instance-command.interface';
|
||||
|
||||
type BackfillDefinition = {
|
||||
table: string;
|
||||
parentTable: string;
|
||||
foreignKey: string;
|
||||
};
|
||||
|
||||
// Order matters: parents must be backfilled before children
|
||||
const BACKFILL_DEFINITIONS: BackfillDefinition[] = [
|
||||
{
|
||||
table: 'twoFactorAuthenticationMethod',
|
||||
parentTable: 'userWorkspace',
|
||||
foreignKey: 'userWorkspaceId',
|
||||
},
|
||||
{
|
||||
table: 'agentChatThread',
|
||||
parentTable: 'userWorkspace',
|
||||
foreignKey: 'userWorkspaceId',
|
||||
},
|
||||
{
|
||||
table: 'agentTurn',
|
||||
parentTable: 'agentChatThread',
|
||||
foreignKey: 'threadId',
|
||||
},
|
||||
{
|
||||
table: 'agentMessage',
|
||||
parentTable: 'agentChatThread',
|
||||
foreignKey: 'threadId',
|
||||
},
|
||||
{
|
||||
table: 'agentTurnEvaluation',
|
||||
parentTable: 'agentTurn',
|
||||
foreignKey: 'turnId',
|
||||
},
|
||||
{
|
||||
table: 'agentMessagePart',
|
||||
parentTable: 'agentMessage',
|
||||
foreignKey: 'messageId',
|
||||
},
|
||||
{
|
||||
table: 'indexFieldMetadata',
|
||||
parentTable: 'indexMetadata',
|
||||
foreignKey: 'indexMetadataId',
|
||||
},
|
||||
{
|
||||
table: 'applicationVariable',
|
||||
parentTable: 'application',
|
||||
foreignKey: 'applicationId',
|
||||
},
|
||||
];
|
||||
|
||||
const TABLES = BACKFILL_DEFINITIONS.map((definition) => definition.table);
|
||||
|
||||
@RegisteredInstanceCommand('1.22.0', 1775758621018, { type: 'slow' })
|
||||
export class BackfillWorkspaceIdOnIndirectEntitiesSlowInstanceCommand
|
||||
implements SlowInstanceCommand
|
||||
{
|
||||
async runDataMigration(dataSource: DataSource): Promise<void> {
|
||||
for (const { table, parentTable, foreignKey } of BACKFILL_DEFINITIONS) {
|
||||
await dataSource.query(
|
||||
`UPDATE "core"."${table}" t
|
||||
SET "workspaceId" = p."workspaceId"
|
||||
FROM "core"."${parentTable}" p
|
||||
WHERE t."${foreignKey}" = p."id"
|
||||
AND t."workspaceId" IS NULL`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
for (const table of TABLES) {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."${table}" ALTER COLUMN "workspaceId" SET NOT NULL`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
for (const table of TABLES) {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."${table}" ALTER COLUMN "workspaceId" DROP NOT NULL`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,11 +3,17 @@
|
|||
import { AddViewFieldGroupIdIndexOnViewFieldFastInstanceCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-instance-command-fast-1775129420309-add-view-field-group-id-index-on-view-field';
|
||||
import { MigrateMessagingCalendarToCoreFastInstanceCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-instance-command-fast-1775165049548-migrate-messaging-calendar-to-core';
|
||||
import { AddEmailThreadWidgetTypeFastInstanceCommand } from 'src/database/commands/upgrade-version-command/1-21/1-21-instance-command-fast-1775200000000-add-email-thread-widget-type';
|
||||
import { AutoGeneratedFastInstanceCommand } from 'src/database/commands/upgrade-version-command/1-22/1-22-instance-command-fast-1775749486425-auto-generated';
|
||||
import { AddPermissionFlagRoleIdIndexFastInstanceCommand } from 'src/database/commands/upgrade-version-command/1-22/1-22-instance-command-fast-1775749486425-add-permission-flag-role-id-index';
|
||||
import { AddWorkspaceIdToIndirectEntitiesFastInstanceCommand } from 'src/database/commands/upgrade-version-command/1-22/1-22-instance-command-fast-1775758621017-add-workspace-id-to-indirect-entities';
|
||||
import { BackfillWorkspaceIdOnIndirectEntitiesSlowInstanceCommand } from 'src/database/commands/upgrade-version-command/1-22/1-22-instance-command-slow-1775758621018-backfill-workspace-id-on-indirect-entities';
|
||||
import { AddWorkspaceIdIndexesAndFksFastInstanceCommand } from 'src/database/commands/upgrade-version-command/1-22/1-22-instance-command-fast-1775761294897-add-workspace-id-indexes-and-fks-to-indirect-entities';
|
||||
|
||||
export const INSTANCE_COMMANDS = [
|
||||
AddViewFieldGroupIdIndexOnViewFieldFastInstanceCommand,
|
||||
MigrateMessagingCalendarToCoreFastInstanceCommand,
|
||||
AddEmailThreadWidgetTypeFastInstanceCommand,
|
||||
AutoGeneratedFastInstanceCommand,
|
||||
AddPermissionFlagRoleIdIndexFastInstanceCommand,
|
||||
AddWorkspaceIdToIndirectEntitiesFastInstanceCommand,
|
||||
BackfillWorkspaceIdOnIndirectEntitiesSlowInstanceCommand,
|
||||
AddWorkspaceIdIndexesAndFksFastInstanceCommand,
|
||||
];
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ describe('ApplicationVariableEntityService', () => {
|
|||
description: 'A secret key',
|
||||
isSecret: true,
|
||||
applicationId: mockApplicationId,
|
||||
workspaceId: mockWorkspaceId,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
|
@ -216,6 +217,7 @@ describe('ApplicationVariableEntityService', () => {
|
|||
description: 'Public URL',
|
||||
isSecret: false,
|
||||
applicationId: mockApplicationId,
|
||||
workspaceId: mockWorkspaceId,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import {
|
|||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
Index,
|
||||
JoinColumn,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
|
|
@ -14,6 +15,7 @@ import {
|
|||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
|
||||
import type { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { EntityRelation } from 'src/engine/workspace-manager/workspace-migration/types/entity-relation.interface';
|
||||
|
||||
@Entity({
|
||||
|
|
@ -30,6 +32,14 @@ export class ApplicationVariableEntity {
|
|||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
@Index()
|
||||
workspaceId: string;
|
||||
|
||||
@ManyToOne('WorkspaceEntity', { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'workspaceId' })
|
||||
workspace: EntityRelation<WorkspaceEntity>;
|
||||
|
||||
@Column({ nullable: false, type: 'text' })
|
||||
key: string;
|
||||
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ export class ApplicationVariableEntityService {
|
|||
description: description ?? '',
|
||||
isSecret: isSecretValue,
|
||||
applicationId,
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ export const fromApplicationVariableEntityToFlatApplicationVariable = (
|
|||
description: entity.description,
|
||||
isSecret: entity.isSecret,
|
||||
applicationId: entity.applicationId,
|
||||
workspaceId: entity.workspaceId,
|
||||
createdAt: entity.createdAt.toISOString(),
|
||||
updatedAt: entity.updatedAt.toISOString(),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ export class BillingWebhookSubscriptionService {
|
|||
await this.updateBillingSubscriptionItems(
|
||||
updatedBillingSubscription.id,
|
||||
event,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
const shouldSuspend = this.shouldSuspendWorkspace(data);
|
||||
|
|
@ -224,6 +225,7 @@ export class BillingWebhookSubscriptionService {
|
|||
| Stripe.CustomerSubscriptionUpdatedEvent
|
||||
| Stripe.CustomerSubscriptionCreatedEvent
|
||||
| Stripe.CustomerSubscriptionDeletedEvent,
|
||||
workspaceId: string,
|
||||
) {
|
||||
const deletedSubscriptionItemIds =
|
||||
getDeletedStripeSubscriptionItemIdsFromStripeSubscriptionEvent(event);
|
||||
|
|
@ -239,6 +241,7 @@ export class BillingWebhookSubscriptionService {
|
|||
transformStripeSubscriptionEventToDatabaseSubscriptionItem(
|
||||
subscriptionId,
|
||||
event.data,
|
||||
workspaceId,
|
||||
),
|
||||
{
|
||||
conflictPaths: ['stripeSubscriptionItemId'],
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@ export const transformStripeSubscriptionEventToDatabaseSubscriptionItem = (
|
|||
| Stripe.CustomerSubscriptionUpdatedEvent.Data
|
||||
| Stripe.CustomerSubscriptionCreatedEvent.Data
|
||||
| Stripe.CustomerSubscriptionDeletedEvent.Data,
|
||||
workspaceId: string,
|
||||
) => {
|
||||
return data.object.items.data.map((item) => {
|
||||
return {
|
||||
billingSubscriptionId,
|
||||
workspaceId,
|
||||
stripeSubscriptionId: data.object.id,
|
||||
stripeProductId: String(item.price.product),
|
||||
stripePriceId: item.price.id,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import {
|
|||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
Index,
|
||||
JoinColumn,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
|
|
@ -16,6 +17,7 @@ import {
|
|||
import { BillingProductEntity } from 'src/engine/core-modules/billing/entities/billing-product.entity';
|
||||
import { BillingSubscriptionEntity } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
|
||||
import { BillingSubscriptionItemMetadata } from 'src/engine/core-modules/billing/types/billing-subscription-item-metadata.type';
|
||||
import type { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
@Entity({ name: 'billingSubscriptionItem', schema: 'core' })
|
||||
@Unique(
|
||||
'IDX_BILLING_SUBSCRIPTION_ITEM_BILLING_SUBSCRIPTION_ID_STRIPE_PRODUCT_ID_UNIQUE',
|
||||
|
|
@ -25,6 +27,14 @@ export class BillingSubscriptionItemEntity {
|
|||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
@Index()
|
||||
workspaceId: string;
|
||||
|
||||
@ManyToOne('WorkspaceEntity', { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'workspaceId' })
|
||||
workspace: Relation<WorkspaceEntity>;
|
||||
|
||||
@Column({ nullable: true, type: 'timestamptz' })
|
||||
deletedAt?: Date;
|
||||
|
||||
|
|
|
|||
|
|
@ -348,6 +348,7 @@ export class BillingSubscriptionService {
|
|||
{
|
||||
object: subscription,
|
||||
},
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
const meterBillingSubscriptionItem = findOrThrow(
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ describe('buildEnvVar', () => {
|
|||
description: 'Public URL',
|
||||
isSecret: false,
|
||||
applicationId: 'app-1',
|
||||
workspaceId: '00000000-0000-0000-0000-000000000000',
|
||||
createdAt: '2024-01-01T00:00:00.000Z',
|
||||
updatedAt: '2024-01-01T00:00:00.000Z',
|
||||
},
|
||||
|
|
@ -37,6 +38,7 @@ describe('buildEnvVar', () => {
|
|||
description: 'API secret',
|
||||
isSecret: true,
|
||||
applicationId: 'app-1',
|
||||
workspaceId: '00000000-0000-0000-0000-000000000000',
|
||||
createdAt: '2024-01-01T00:00:00.000Z',
|
||||
updatedAt: '2024-01-01T00:00:00.000Z',
|
||||
},
|
||||
|
|
@ -47,6 +49,7 @@ describe('buildEnvVar', () => {
|
|||
description: 'Debug flag',
|
||||
isSecret: false,
|
||||
applicationId: 'app-1',
|
||||
workspaceId: '00000000-0000-0000-0000-000000000000',
|
||||
createdAt: '2024-01-01T00:00:00.000Z',
|
||||
updatedAt: '2024-01-01T00:00:00.000Z',
|
||||
},
|
||||
|
|
@ -74,6 +77,7 @@ describe('buildEnvVar', () => {
|
|||
description: '',
|
||||
isSecret: false,
|
||||
applicationId: 'app-1',
|
||||
workspaceId: '00000000-0000-0000-0000-000000000000',
|
||||
createdAt: '2024-01-01T00:00:00.000Z',
|
||||
updatedAt: '2024-01-01T00:00:00.000Z',
|
||||
},
|
||||
|
|
@ -84,6 +88,7 @@ describe('buildEnvVar', () => {
|
|||
description: '',
|
||||
isSecret: false,
|
||||
applicationId: 'app-1',
|
||||
workspaceId: '00000000-0000-0000-0000-000000000000',
|
||||
createdAt: '2024-01-01T00:00:00.000Z',
|
||||
updatedAt: '2024-01-01T00:00:00.000Z',
|
||||
},
|
||||
|
|
@ -106,6 +111,7 @@ describe('buildEnvVar', () => {
|
|||
description: '',
|
||||
isSecret: false,
|
||||
applicationId: 'app-1',
|
||||
workspaceId: '00000000-0000-0000-0000-000000000000',
|
||||
createdAt: '2024-01-01T00:00:00.000Z',
|
||||
updatedAt: '2024-01-01T00:00:00.000Z',
|
||||
},
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {
|
|||
|
||||
import { OTPStatus } from 'src/engine/core-modules/two-factor-authentication/strategies/otp/otp.constants';
|
||||
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||
import type { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
||||
@Index(['userWorkspaceId', 'strategy'], { unique: true })
|
||||
@Entity({ name: 'twoFactorAuthenticationMethod', schema: 'core' })
|
||||
|
|
@ -20,6 +21,14 @@ export class TwoFactorAuthenticationMethodEntity {
|
|||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
@Index()
|
||||
workspaceId: string;
|
||||
|
||||
@ManyToOne('WorkspaceEntity', { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'workspaceId' })
|
||||
workspace: Relation<WorkspaceEntity>;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
userWorkspaceId: string;
|
||||
|
||||
|
|
|
|||
|
|
@ -191,6 +191,7 @@ describe('TwoFactorAuthenticationService', () => {
|
|||
);
|
||||
expect(repository.save).toHaveBeenCalledWith({
|
||||
id: undefined,
|
||||
workspaceId: workspace.id,
|
||||
userWorkspace: mockUserWorkspace,
|
||||
secret: encryptedSecret,
|
||||
status: 'PENDING',
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ export class TwoFactorAuthenticationService {
|
|||
|
||||
await this.twoFactorAuthenticationMethodRepository.save({
|
||||
id: existing2FAMethod?.id,
|
||||
workspaceId,
|
||||
userWorkspace: userWorkspace,
|
||||
secret: encryptedSecret,
|
||||
status: context.status,
|
||||
|
|
|
|||
|
|
@ -12,12 +12,21 @@ import {
|
|||
|
||||
import { FileEntity } from 'src/engine/core-modules/file/entities/file.entity';
|
||||
import { AgentMessageEntity } from 'src/engine/metadata-modules/ai/ai-agent-execution/entities/agent-message.entity';
|
||||
import type { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
||||
@Entity('agentMessagePart')
|
||||
@Entity({ name: 'agentMessagePart', schema: 'core' })
|
||||
export class AgentMessagePartEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
@Index()
|
||||
workspaceId: string;
|
||||
|
||||
@ManyToOne('WorkspaceEntity', { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'workspaceId' })
|
||||
workspace: Relation<WorkspaceEntity>;
|
||||
|
||||
@Column('uuid')
|
||||
@Index()
|
||||
messageId: string;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {
|
|||
import { AgentMessagePartEntity } from 'src/engine/metadata-modules/ai/ai-agent-execution/entities/agent-message-part.entity';
|
||||
import { AgentTurnEntity } from 'src/engine/metadata-modules/ai/ai-agent-execution/entities/agent-turn.entity';
|
||||
import { AgentChatThreadEntity } from 'src/engine/metadata-modules/ai/ai-chat/entities/agent-chat-thread.entity';
|
||||
import type { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
||||
export enum AgentMessageRole {
|
||||
SYSTEM = 'system',
|
||||
|
|
@ -25,11 +26,19 @@ export enum AgentMessageStatus {
|
|||
SENT = 'sent',
|
||||
}
|
||||
|
||||
@Entity('agentMessage')
|
||||
@Entity({ name: 'agentMessage', schema: 'core' })
|
||||
export class AgentMessageEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
@Index()
|
||||
workspaceId: string;
|
||||
|
||||
@ManyToOne('WorkspaceEntity', { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'workspaceId' })
|
||||
workspace: Relation<WorkspaceEntity>;
|
||||
|
||||
@Column('uuid')
|
||||
@Index()
|
||||
threadId: string;
|
||||
|
|
|
|||
|
|
@ -13,12 +13,21 @@ import {
|
|||
import { AgentMessageEntity } from 'src/engine/metadata-modules/ai/ai-agent-execution/entities/agent-message.entity';
|
||||
import { AgentTurnEvaluationEntity } from 'src/engine/metadata-modules/ai/ai-agent-monitor/entities/agent-turn-evaluation.entity';
|
||||
import { AgentChatThreadEntity } from 'src/engine/metadata-modules/ai/ai-chat/entities/agent-chat-thread.entity';
|
||||
import type { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
||||
@Entity('agentTurn')
|
||||
@Entity({ name: 'agentTurn', schema: 'core' })
|
||||
export class AgentTurnEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
@Index()
|
||||
workspaceId: string;
|
||||
|
||||
@ManyToOne('WorkspaceEntity', { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'workspaceId' })
|
||||
workspace: Relation<WorkspaceEntity>;
|
||||
|
||||
@Column('uuid')
|
||||
@Index()
|
||||
threadId: string;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ const isToolPart = (part: ExtendedUIMessagePart): part is ToolUIPart => {
|
|||
export const mapUIMessagePartsToDBParts = (
|
||||
uiMessageParts: ExtendedUIMessagePart[],
|
||||
messageId: string,
|
||||
workspaceId: string,
|
||||
): Partial<AgentMessagePartEntity>[] => {
|
||||
return uiMessageParts
|
||||
.map((part, index) => {
|
||||
|
|
@ -20,6 +21,7 @@ export const mapUIMessagePartsToDBParts = (
|
|||
messageId,
|
||||
orderIndex: index,
|
||||
type: part.type,
|
||||
workspaceId,
|
||||
};
|
||||
|
||||
switch (part.type) {
|
||||
|
|
|
|||
|
|
@ -10,12 +10,21 @@ import {
|
|||
} from 'typeorm';
|
||||
|
||||
import { AgentTurnEntity } from 'src/engine/metadata-modules/ai/ai-agent-execution/entities/agent-turn.entity';
|
||||
import type { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
||||
@Entity('agentTurnEvaluation')
|
||||
@Entity({ name: 'agentTurnEvaluation', schema: 'core' })
|
||||
export class AgentTurnEvaluationEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
@Index()
|
||||
workspaceId: string;
|
||||
|
||||
@ManyToOne('WorkspaceEntity', { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'workspaceId' })
|
||||
workspace: Relation<WorkspaceEntity>;
|
||||
|
||||
@Column('uuid')
|
||||
@Index()
|
||||
turnId: string;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ export class RunEvaluationInputJob {
|
|||
role: 'user',
|
||||
parts: [{ type: 'text', text: data.input }],
|
||||
},
|
||||
workspaceId: data.workspaceId,
|
||||
});
|
||||
|
||||
const agent = await this.agentRepository.findOne({
|
||||
|
|
@ -72,6 +73,7 @@ export class RunEvaluationInputJob {
|
|||
},
|
||||
],
|
||||
},
|
||||
workspaceId: data.workspaceId,
|
||||
});
|
||||
|
||||
await this.messageQueueService.add<{
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ export class AgentTurnResolver {
|
|||
): Promise<AgentTurnEntity> {
|
||||
const thread = this.threadRepository.create({
|
||||
userWorkspaceId,
|
||||
workspaceId: workspace.id,
|
||||
title: `Eval: ${input.substring(0, 50)}...`,
|
||||
});
|
||||
const savedThread = await this.threadRepository.save(thread);
|
||||
|
|
@ -75,6 +76,7 @@ export class AgentTurnResolver {
|
|||
const turn = this.turnRepository.create({
|
||||
threadId: savedThread.id,
|
||||
agentId,
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
const savedTurn = await this.turnRepository.save(turn);
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ export class AgentTurnGraderService {
|
|||
|
||||
const evaluation = this.evaluationRepository.create({
|
||||
turnId,
|
||||
workspaceId: turn.workspaceId,
|
||||
score,
|
||||
comment,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,13 +13,22 @@ import {
|
|||
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||
import { AgentMessageEntity } from 'src/engine/metadata-modules/ai/ai-agent-execution/entities/agent-message.entity';
|
||||
import { AgentTurnEntity } from 'src/engine/metadata-modules/ai/ai-agent-execution/entities/agent-turn.entity';
|
||||
import type { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { EntityRelation } from 'src/engine/workspace-manager/workspace-migration/types/entity-relation.interface';
|
||||
|
||||
@Entity('agentChatThread')
|
||||
@Entity({ name: 'agentChatThread', schema: 'core' })
|
||||
export class AgentChatThreadEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
@Index()
|
||||
workspaceId: string;
|
||||
|
||||
@ManyToOne('WorkspaceEntity', { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'workspaceId' })
|
||||
workspace: EntityRelation<WorkspaceEntity>;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
@Index()
|
||||
userWorkspaceId: string;
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ export class StreamAgentChatJob {
|
|||
part.type === 'text' || part.type === 'file',
|
||||
),
|
||||
},
|
||||
workspaceId: data.workspaceId,
|
||||
});
|
||||
|
||||
userMessagePromise.catch(() => {});
|
||||
|
|
@ -271,6 +272,7 @@ export class StreamAgentChatJob {
|
|||
await this.handleStreamFinish({
|
||||
responseMessage,
|
||||
threadId: data.threadId,
|
||||
workspaceId: data.workspaceId,
|
||||
streamUsage,
|
||||
lastStepConversationSize,
|
||||
modelConfig,
|
||||
|
|
@ -410,6 +412,7 @@ export class StreamAgentChatJob {
|
|||
private async handleStreamFinish({
|
||||
responseMessage,
|
||||
threadId,
|
||||
workspaceId,
|
||||
streamUsage,
|
||||
lastStepConversationSize,
|
||||
modelConfig,
|
||||
|
|
@ -417,6 +420,7 @@ export class StreamAgentChatJob {
|
|||
}: {
|
||||
responseMessage: Omit<ExtendedUIMessage, 'id'>;
|
||||
threadId: string;
|
||||
workspaceId: string;
|
||||
streamUsage: {
|
||||
inputTokens: number;
|
||||
outputTokens: number;
|
||||
|
|
@ -437,6 +441,7 @@ export class StreamAgentChatJob {
|
|||
threadId,
|
||||
uiMessage: responseMessage,
|
||||
turnId: userMessage.turnId ?? undefined,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
await this.threadRepository.update(threadId, {
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ export class AgentChatResolver {
|
|||
threadId,
|
||||
text,
|
||||
id: messageId,
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
|
||||
await this.eventPublisherService.publish({
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ export class AgentChatStreamingService {
|
|||
role: AgentMessageRole.USER,
|
||||
parts: [{ type: 'text' as const, text }],
|
||||
},
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
|
||||
const previousMessages = await this.loadMessagesFromDB(
|
||||
|
|
@ -138,6 +139,7 @@ export class AgentChatStreamingService {
|
|||
const turnId = await this.agentChatService.promoteQueuedMessage(
|
||||
nextQueued.id,
|
||||
threadId,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
if (turnId === null) {
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ export class AgentChatService {
|
|||
}) {
|
||||
const thread = this.threadRepository.create({
|
||||
userWorkspaceId,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const savedThread = await this.threadRepository.save(thread);
|
||||
|
|
@ -105,6 +106,7 @@ export class AgentChatService {
|
|||
agentId,
|
||||
turnId,
|
||||
id,
|
||||
workspaceId,
|
||||
}: {
|
||||
threadId: string;
|
||||
uiMessage: Omit<ExtendedUIMessage, 'id'>;
|
||||
|
|
@ -112,6 +114,7 @@ export class AgentChatService {
|
|||
agentId?: string;
|
||||
turnId?: string;
|
||||
id?: string;
|
||||
workspaceId: string;
|
||||
}) {
|
||||
let actualTurnId = turnId;
|
||||
|
||||
|
|
@ -119,6 +122,7 @@ export class AgentChatService {
|
|||
const turn = this.turnRepository.create({
|
||||
threadId,
|
||||
agentId: agentId ?? null,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const savedTurn = await this.turnRepository.save(turn);
|
||||
|
|
@ -133,6 +137,7 @@ export class AgentChatService {
|
|||
role: uiMessage.role as AgentMessageRole,
|
||||
agentId: agentId ?? null,
|
||||
processedAt: new Date(),
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const savedMessage = await this.messageRepository.save(message);
|
||||
|
|
@ -141,6 +146,7 @@ export class AgentChatService {
|
|||
const dbParts = mapUIMessagePartsToDBParts(
|
||||
uiMessage.parts,
|
||||
savedMessage.id,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
await this.messagePartRepository.save(dbParts);
|
||||
|
|
@ -175,10 +181,12 @@ export class AgentChatService {
|
|||
threadId,
|
||||
text,
|
||||
id,
|
||||
workspaceId,
|
||||
}: {
|
||||
threadId: string;
|
||||
text: string;
|
||||
id?: string;
|
||||
workspaceId: string;
|
||||
}): Promise<AgentMessageEntity> {
|
||||
const message = this.messageRepository.create({
|
||||
...(id ? { id } : {}),
|
||||
|
|
@ -187,6 +195,7 @@ export class AgentChatService {
|
|||
role: AgentMessageRole.USER,
|
||||
agentId: null,
|
||||
status: AgentMessageStatus.QUEUED,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const savedMessage = await this.messageRepository.save(message);
|
||||
|
|
@ -196,6 +205,7 @@ export class AgentChatService {
|
|||
orderIndex: 0,
|
||||
type: 'text',
|
||||
textContent: text,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
await this.messagePartRepository.save(part);
|
||||
|
|
@ -234,10 +244,12 @@ export class AgentChatService {
|
|||
async promoteQueuedMessage(
|
||||
messageId: string,
|
||||
threadId: string,
|
||||
workspaceId: string,
|
||||
): Promise<string | null> {
|
||||
const turn = this.turnRepository.create({
|
||||
threadId,
|
||||
agentId: null,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const savedTurn = await this.turnRepository.save(turn);
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ export const fromIndexMetadataEntityToFlatIndexMetadata = ({
|
|||
]),
|
||||
createdAt: indexFieldMetadata.createdAt.toISOString(),
|
||||
updatedAt: indexFieldMetadata.updatedAt.toISOString(),
|
||||
workspaceId: indexFieldMetadata.workspaceId,
|
||||
}),
|
||||
),
|
||||
universalFlatIndexFieldMetadatas:
|
||||
|
|
|
|||
|
|
@ -12,14 +12,23 @@ import {
|
|||
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
|
||||
import type { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
||||
@Entity('indexFieldMetadata')
|
||||
@Entity({ name: 'indexFieldMetadata', schema: 'core' })
|
||||
export class IndexFieldMetadataEntity
|
||||
implements Required<IndexFieldMetadataEntity>
|
||||
{
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
@Index()
|
||||
workspaceId: string;
|
||||
|
||||
@ManyToOne('WorkspaceEntity', { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'workspaceId' })
|
||||
workspace: Relation<WorkspaceEntity>;
|
||||
|
||||
@Column({ nullable: false })
|
||||
indexMetadataId: string;
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ const seedChatThreads = async ({
|
|||
.insert()
|
||||
.into(`${schemaName}.${agentChatThreadTableName}`, [
|
||||
'id',
|
||||
'workspaceId',
|
||||
'userWorkspaceId',
|
||||
'createdAt',
|
||||
'updatedAt',
|
||||
|
|
@ -85,6 +86,7 @@ const seedChatThreads = async ({
|
|||
.values([
|
||||
{
|
||||
id: threadId,
|
||||
workspaceId,
|
||||
userWorkspaceId,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
|
|
@ -113,6 +115,7 @@ const seedChatMessages = async ({
|
|||
let turnIds: string[];
|
||||
let messages: Array<{
|
||||
id: string;
|
||||
workspaceId: string;
|
||||
threadId: string;
|
||||
turnId: string;
|
||||
role: AgentMessageRole;
|
||||
|
|
@ -120,6 +123,7 @@ const seedChatMessages = async ({
|
|||
}>;
|
||||
let messageParts: Array<{
|
||||
id: string;
|
||||
workspaceId: string;
|
||||
messageId: string;
|
||||
orderIndex: number;
|
||||
type: string;
|
||||
|
|
@ -150,6 +154,7 @@ const seedChatMessages = async ({
|
|||
messages = [
|
||||
{
|
||||
id: messageIds[0],
|
||||
workspaceId,
|
||||
threadId,
|
||||
turnId: turnIds[0],
|
||||
role: AgentMessageRole.USER,
|
||||
|
|
@ -157,6 +162,7 @@ const seedChatMessages = async ({
|
|||
},
|
||||
{
|
||||
id: messageIds[1],
|
||||
workspaceId,
|
||||
threadId,
|
||||
turnId: turnIds[0],
|
||||
role: AgentMessageRole.ASSISTANT,
|
||||
|
|
@ -164,6 +170,7 @@ const seedChatMessages = async ({
|
|||
},
|
||||
{
|
||||
id: messageIds[2],
|
||||
workspaceId,
|
||||
threadId,
|
||||
turnId: turnIds[1],
|
||||
role: AgentMessageRole.USER,
|
||||
|
|
@ -171,6 +178,7 @@ const seedChatMessages = async ({
|
|||
},
|
||||
{
|
||||
id: messageIds[3],
|
||||
workspaceId,
|
||||
threadId,
|
||||
turnId: turnIds[1],
|
||||
role: AgentMessageRole.ASSISTANT,
|
||||
|
|
@ -180,6 +188,7 @@ const seedChatMessages = async ({
|
|||
messageParts = [
|
||||
{
|
||||
id: partIds[0],
|
||||
workspaceId,
|
||||
messageId: messageIds[0],
|
||||
orderIndex: 0,
|
||||
type: 'text',
|
||||
|
|
@ -189,6 +198,7 @@ const seedChatMessages = async ({
|
|||
},
|
||||
{
|
||||
id: partIds[1],
|
||||
workspaceId,
|
||||
messageId: messageIds[1],
|
||||
orderIndex: 0,
|
||||
type: 'text',
|
||||
|
|
@ -198,6 +208,7 @@ const seedChatMessages = async ({
|
|||
},
|
||||
{
|
||||
id: partIds[2],
|
||||
workspaceId,
|
||||
messageId: messageIds[2],
|
||||
orderIndex: 0,
|
||||
type: 'text',
|
||||
|
|
@ -207,6 +218,7 @@ const seedChatMessages = async ({
|
|||
},
|
||||
{
|
||||
id: partIds[3],
|
||||
workspaceId,
|
||||
messageId: messageIds[3],
|
||||
orderIndex: 0,
|
||||
type: 'text',
|
||||
|
|
@ -235,6 +247,7 @@ const seedChatMessages = async ({
|
|||
messages = [
|
||||
{
|
||||
id: messageIds[0],
|
||||
workspaceId,
|
||||
threadId,
|
||||
turnId: turnIds[0],
|
||||
role: AgentMessageRole.USER,
|
||||
|
|
@ -242,6 +255,7 @@ const seedChatMessages = async ({
|
|||
},
|
||||
{
|
||||
id: messageIds[1],
|
||||
workspaceId,
|
||||
threadId,
|
||||
turnId: turnIds[0],
|
||||
role: AgentMessageRole.ASSISTANT,
|
||||
|
|
@ -249,6 +263,7 @@ const seedChatMessages = async ({
|
|||
},
|
||||
{
|
||||
id: messageIds[2],
|
||||
workspaceId,
|
||||
threadId,
|
||||
turnId: turnIds[1],
|
||||
role: AgentMessageRole.USER,
|
||||
|
|
@ -256,6 +271,7 @@ const seedChatMessages = async ({
|
|||
},
|
||||
{
|
||||
id: messageIds[3],
|
||||
workspaceId,
|
||||
threadId,
|
||||
turnId: turnIds[1],
|
||||
role: AgentMessageRole.ASSISTANT,
|
||||
|
|
@ -265,6 +281,7 @@ const seedChatMessages = async ({
|
|||
messageParts = [
|
||||
{
|
||||
id: partIds[0],
|
||||
workspaceId,
|
||||
messageId: messageIds[0],
|
||||
orderIndex: 0,
|
||||
type: 'text',
|
||||
|
|
@ -274,6 +291,7 @@ const seedChatMessages = async ({
|
|||
},
|
||||
{
|
||||
id: partIds[1],
|
||||
workspaceId,
|
||||
messageId: messageIds[1],
|
||||
orderIndex: 0,
|
||||
type: 'text',
|
||||
|
|
@ -283,6 +301,7 @@ const seedChatMessages = async ({
|
|||
},
|
||||
{
|
||||
id: partIds[2],
|
||||
workspaceId,
|
||||
messageId: messageIds[2],
|
||||
orderIndex: 0,
|
||||
type: 'text',
|
||||
|
|
@ -292,6 +311,7 @@ const seedChatMessages = async ({
|
|||
},
|
||||
{
|
||||
id: partIds[3],
|
||||
workspaceId,
|
||||
messageId: messageIds[3],
|
||||
orderIndex: 0,
|
||||
type: 'text',
|
||||
|
|
@ -309,6 +329,7 @@ const seedChatMessages = async ({
|
|||
// Create turns first
|
||||
const turns = turnIds.map((id, index) => ({
|
||||
id,
|
||||
workspaceId,
|
||||
threadId,
|
||||
createdAt: messages[index * 2].createdAt,
|
||||
}));
|
||||
|
|
@ -318,6 +339,7 @@ const seedChatMessages = async ({
|
|||
.insert()
|
||||
.into(`${schemaName}.${agentTurnTableName}`, [
|
||||
'id',
|
||||
'workspaceId',
|
||||
'threadId',
|
||||
'createdAt',
|
||||
])
|
||||
|
|
@ -330,6 +352,7 @@ const seedChatMessages = async ({
|
|||
.insert()
|
||||
.into(`${schemaName}.${agentMessageTableName}`, [
|
||||
'id',
|
||||
'workspaceId',
|
||||
'threadId',
|
||||
'turnId',
|
||||
'role',
|
||||
|
|
@ -344,6 +367,7 @@ const seedChatMessages = async ({
|
|||
.insert()
|
||||
.into(`${schemaName}.${agentMessagePartTableName}`, [
|
||||
'id',
|
||||
'workspaceId',
|
||||
'messageId',
|
||||
'orderIndex',
|
||||
'type',
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ export const createStandardIndexFlatMetadata = <
|
|||
indexMetadataId: indexId,
|
||||
order: index,
|
||||
updatedAt: now,
|
||||
workspaceId,
|
||||
}),
|
||||
),
|
||||
workspaceId,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ export type UniversalFlatIndexFieldMetadata = Omit<
|
|||
| 'fieldMetadataId'
|
||||
| 'fieldMetadata'
|
||||
| 'id'
|
||||
| 'workspaceId'
|
||||
| 'workspace'
|
||||
| keyof CastRecordTypeOrmDatePropertiesToString<IndexFieldMetadataEntity>
|
||||
> & {
|
||||
indexMetadataUniversalIdentifier: string;
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ export const fromUniversalFlatIndexToFlatIndex = ({
|
|||
order: universalFlatIndexFieldMetadata.order,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
workspaceId,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue