feat: multi-workspace followup (#4197)
* Seed UserWorkspace for existing demo/dev users * add workspaces field to currentUser * new token generation endpoint for switching workspace * lint fix * include dependency * requested fixes * resolver test pass * changing defaultWorkspace and workspaceMember when switching workspaces * tests fix * requested changes * delete user/workspace edge case handled * after merge * requested changes * :wq! * workspace manytoone relation * lint fix / import fix * gql codegen * Fix migrations and generateJWT * migration fix * relations fix --------- Co-authored-by: martmull <martmull@hotmail.fr>
This commit is contained in:
@ -9,6 +9,10 @@ import {
|
||||
deleteWorkspaces,
|
||||
} from 'src/database/typeorm-seeds/core/demo/workspaces';
|
||||
import { deleteFeatureFlags } from 'src/database/typeorm-seeds/core/demo/feature-flags';
|
||||
import {
|
||||
deleteUserWorkspaces,
|
||||
seedUserWorkspaces,
|
||||
} from 'src/database/typeorm-seeds/core/demo/userWorkspaces';
|
||||
|
||||
export const seedCoreSchema = async (
|
||||
workspaceDataSource: DataSource,
|
||||
@ -18,6 +22,7 @@ export const seedCoreSchema = async (
|
||||
|
||||
await seedWorkspaces(workspaceDataSource, schemaName, workspaceId);
|
||||
await seedUsers(workspaceDataSource, schemaName, workspaceId);
|
||||
await seedUserWorkspaces(workspaceDataSource, schemaName, workspaceId);
|
||||
};
|
||||
|
||||
export const deleteCoreSchema = async (
|
||||
@ -26,6 +31,7 @@ export const deleteCoreSchema = async (
|
||||
) => {
|
||||
const schemaName = 'core';
|
||||
|
||||
await deleteUserWorkspaces(workspaceDataSource, schemaName, workspaceId);
|
||||
await deleteUsersByWorkspace(workspaceDataSource, schemaName, workspaceId);
|
||||
await deleteFeatureFlags(workspaceDataSource, schemaName, workspaceId);
|
||||
// deleteWorkspaces should be last
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
|
||||
const tableName = 'userWorkspace';
|
||||
|
||||
export enum DemoSeedUserIds {
|
||||
Noah = '20202020-9e3b-46d4-a556-88b9ddc2b035',
|
||||
Hugo = '20202020-3957-4908-9c36-2929a23f8358',
|
||||
Julia = '20202020-7169-42cf-bc47-1cfef15264b9',
|
||||
}
|
||||
|
||||
export const seedUserWorkspaces = async (
|
||||
workspaceDataSource: DataSource,
|
||||
schemaName: string,
|
||||
workspaceId: string,
|
||||
) => {
|
||||
await workspaceDataSource
|
||||
.createQueryBuilder()
|
||||
.insert()
|
||||
.into(`${schemaName}.${tableName}`, ['userId', 'workspaceId'])
|
||||
.orIgnore()
|
||||
.values([
|
||||
{
|
||||
userId: DemoSeedUserIds.Noah,
|
||||
workspaceId: workspaceId,
|
||||
},
|
||||
{
|
||||
userId: DemoSeedUserIds.Hugo,
|
||||
workspaceId: workspaceId,
|
||||
},
|
||||
{
|
||||
userId: DemoSeedUserIds.Julia,
|
||||
workspaceId: workspaceId,
|
||||
},
|
||||
])
|
||||
.execute();
|
||||
};
|
||||
|
||||
export const deleteUserWorkspaces = async (
|
||||
workspaceDataSource: DataSource,
|
||||
schemaName: string,
|
||||
workspaceId: string,
|
||||
) => {
|
||||
await workspaceDataSource
|
||||
.createQueryBuilder()
|
||||
.delete()
|
||||
.from(`${schemaName}.${tableName}`)
|
||||
.where(`"${tableName}"."workspaceId" = :workspaceId`, {
|
||||
workspaceId,
|
||||
})
|
||||
.execute();
|
||||
};
|
||||
@ -12,6 +12,10 @@ import {
|
||||
seedFeatureFlags,
|
||||
deleteFeatureFlags,
|
||||
} from 'src/database/typeorm-seeds/core/feature-flags';
|
||||
import {
|
||||
deleteUserWorkspaces,
|
||||
seedUserWorkspaces,
|
||||
} from 'src/database/typeorm-seeds/core/userWorkspaces';
|
||||
|
||||
export const seedCoreSchema = async (
|
||||
workspaceDataSource: DataSource,
|
||||
@ -21,6 +25,7 @@ export const seedCoreSchema = async (
|
||||
|
||||
await seedWorkspaces(workspaceDataSource, schemaName, workspaceId);
|
||||
await seedUsers(workspaceDataSource, schemaName, workspaceId);
|
||||
await seedUserWorkspaces(workspaceDataSource, schemaName, workspaceId);
|
||||
await seedFeatureFlags(workspaceDataSource, schemaName, workspaceId);
|
||||
};
|
||||
|
||||
@ -30,6 +35,7 @@ export const deleteCoreSchema = async (
|
||||
) => {
|
||||
const schemaName = 'core';
|
||||
|
||||
await deleteUserWorkspaces(workspaceDataSource, schemaName, workspaceId);
|
||||
await deleteUsersByWorkspace(workspaceDataSource, schemaName, workspaceId);
|
||||
await deleteFeatureFlags(workspaceDataSource, schemaName, workspaceId);
|
||||
// deleteWorkspaces should be last
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
|
||||
// import { SeedWorkspaceId } from 'src/database/typeorm-seeds/core/workspaces';
|
||||
|
||||
const tableName = 'userWorkspace';
|
||||
|
||||
export enum SeedUserIds {
|
||||
Tim = '20202020-9e3b-46d4-a556-88b9ddc2b034',
|
||||
Jony = '20202020-3957-4908-9c36-2929a23f8357',
|
||||
Phil = '20202020-7169-42cf-bc47-1cfef15264b8',
|
||||
}
|
||||
|
||||
export const seedUserWorkspaces = async (
|
||||
workspaceDataSource: DataSource,
|
||||
schemaName: string,
|
||||
workspaceId: string,
|
||||
) => {
|
||||
await workspaceDataSource
|
||||
.createQueryBuilder()
|
||||
.insert()
|
||||
.into(`${schemaName}.${tableName}`, ['userId', 'workspaceId'])
|
||||
.orIgnore()
|
||||
.values([
|
||||
{
|
||||
userId: SeedUserIds.Tim,
|
||||
workspaceId,
|
||||
},
|
||||
{
|
||||
userId: SeedUserIds.Jony,
|
||||
workspaceId,
|
||||
},
|
||||
{
|
||||
userId: SeedUserIds.Phil,
|
||||
workspaceId,
|
||||
},
|
||||
])
|
||||
.execute();
|
||||
};
|
||||
|
||||
export const deleteUserWorkspaces = async (
|
||||
workspaceDataSource: DataSource,
|
||||
schemaName: string,
|
||||
workspaceId: string,
|
||||
) => {
|
||||
await workspaceDataSource
|
||||
.createQueryBuilder()
|
||||
.delete()
|
||||
.from(`${schemaName}.${tableName}`)
|
||||
.where(`"${tableName}"."workspaceId" = :workspaceId`, {
|
||||
workspaceId,
|
||||
})
|
||||
.execute();
|
||||
};
|
||||
@ -0,0 +1,28 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class UpdateUserWorkspace1709314035408 implements MigrationInterface {
|
||||
name = 'UpdateUserWorkspace1709314035408';
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE "core"."userWorkspace"
|
||||
ADD CONSTRAINT "FK_37fdc7357af701e595c5c3a9bd6"
|
||||
FOREIGN KEY ("workspaceId") REFERENCES "core"."workspace"("id")
|
||||
ON DELETE CASCADE ON UPDATE NO ACTION
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE "core"."userWorkspace"
|
||||
ADD CONSTRAINT "FK_cb488f32c6a0827b938edadf221"
|
||||
FOREIGN KEY ("userId") REFERENCES "core"."user"("id")
|
||||
ON DELETE CASCADE ON UPDATE NO ACTION
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."userWorkspace" DROP CONSTRAINT "FK_cb488f32c6a0827b938edadf221"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."userWorkspace" DROP CONSTRAINT "FK_37fdc7357af701e595c5c3a9bd6"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,7 @@ import { RefreshToken } from 'src/core/refresh-token/refresh-token.entity';
|
||||
import { FeatureFlagEntity } from 'src/core/feature-flag/feature-flag.entity';
|
||||
import { BillingSubscription } from 'src/core/billing/entities/billing-subscription.entity';
|
||||
import { BillingSubscriptionItem } from 'src/core/billing/entities/billing-subscription-item.entity';
|
||||
import { UserWorkspace } from 'src/core/user-workspace/user-workspace.entity';
|
||||
|
||||
@Injectable()
|
||||
export class TypeORMService implements OnModuleInit, OnModuleDestroy {
|
||||
@ -26,6 +27,7 @@ export class TypeORMService implements OnModuleInit, OnModuleDestroy {
|
||||
entities: [
|
||||
User,
|
||||
Workspace,
|
||||
UserWorkspace,
|
||||
RefreshToken,
|
||||
FeatureFlagEntity,
|
||||
BillingSubscription,
|
||||
|
||||
Reference in New Issue
Block a user