* use lower case db column names
* fix signup workspaceId
This commit is contained in:
Philipinho
2024-03-29 16:25:42 +00:00
parent 82da4ffdc2
commit b241523ff6
25 changed files with 248 additions and 407 deletions

View File

@ -23,7 +23,7 @@
"migration:down": "tsx ./src/kysely/migrate.ts down",
"migration:latest": "tsx ./src/kysely/migrate.ts latest",
"migration:redo": "tsx ./src/kysely/migrate.ts redo",
"migration:codegen": "kysely-codegen --dialect=postgres --env-file=../../.env --out-file=./src/kysely/types/db.d.ts"
"migration:codegen": "kysely-codegen --dialect=postgres --camel-case --env-file=../../.env --out-file=./src/kysely/types/db.d.ts"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.540.0",

View File

@ -39,7 +39,13 @@ export class SignupService {
this.db,
async (trx) => {
// create user
const user = await this.userRepo.insertUser(createUserDto, trx);
const user = await this.userRepo.insertUser(
{
...createUserDto,
workspaceId: workspaceId,
},
trx,
);
// add user to workspace
await this.workspaceService.addUserToWorkspace(
@ -88,7 +94,13 @@ export class SignupService {
async (trx) => {
// create user
const user = await this.userRepo.insertUser(createAdminUserDto, trx);
await this.createWorkspace(user, createAdminUserDto.workspaceName, trx);
const workspace = await this.createWorkspace(
user,
createAdminUserDto.workspaceName,
trx,
);
user.workspaceId = workspace.id;
return user;
},
trx,

View File

@ -64,7 +64,7 @@ export async function removeFromArrayAndSave(
if (index > -1) {
array.splice(index, 1);
await trx
.updateTable('page_ordering')
.updateTable('pageOrdering')
.set(entity)
.where('id', '=', entity.id)
.execute();

View File

@ -62,7 +62,7 @@ export class PageOrderingService {
// it should save or update right?
// await manager.save(spaceOrdering); //TODO: to update or create new record? pretty confusing
await trx
.updateTable('page_ordering')
.updateTable('pageOrdering')
.set(spaceOrdering)
.where('id', '=', spaceOrdering.id)
.execute();
@ -109,7 +109,7 @@ export class PageOrderingService {
// Modify the children list of the new parentPage and save
orderPageList(parentPageOrdering.childrenIds, dto);
await trx
.updateTable('page_ordering')
.updateTable('pageOrdering')
.set(parentPageOrdering)
.where('id', '=', parentPageOrdering.id)
.execute();
@ -238,7 +238,7 @@ export class PageOrderingService {
if (!ordering.childrenIds.includes(childId)) {
ordering.childrenIds.unshift(childId);
await trx
.updateTable('page_ordering')
.updateTable('pageOrdering')
.set(ordering)
.where('id', '=', ordering.id)
.execute();
@ -252,7 +252,7 @@ export class PageOrderingService {
trx: KyselyTransaction,
): Promise<PageOrdering> {
return trx
.selectFrom('page_ordering')
.selectFrom('pageOrdering')
.selectAll()
.where('entityId', '=', entityId)
.where('entityType', '=', entityType)
@ -267,7 +267,7 @@ export class PageOrderingService {
trx: KyselyTransaction,
): Promise<PageOrdering> {
await trx
.insertInto('page_ordering')
.insertInto('pageOrdering')
.values({
entityId,
entityType,
@ -285,7 +285,7 @@ export class PageOrderingService {
spaceId: string,
): Promise<{ id: string; childrenIds: string[]; spaceId: string }> {
return await this.db
.selectFrom('page_ordering')
.selectFrom('pageOrdering')
.select(['id', 'childrenIds', 'spaceId'])
.where('entityId', '=', spaceId)
.where('entityType', '=', OrderingEntity.SPACE)

View File

@ -56,7 +56,6 @@ export class WorkspaceService {
name: createWorkspaceDto.name,
hostname: createWorkspaceDto.hostname,
description: createWorkspaceDto.description,
creatorId: user.id,
},
trx,
);
@ -77,9 +76,10 @@ export class WorkspaceService {
})
.execute();
// add user to default group
await this.groupUserService.addUserToDefaultGroup(
// add user to default group created above
await this.groupUserService.addUserToGroup(
user.id,
group.id,
workspace.id,
trx,
);

View File

@ -1,7 +1,7 @@
import { Global, Module } from '@nestjs/common';
import { KyselyModule } from 'nestjs-kysely';
import { EnvironmentService } from '../integrations/environment/environment.service';
import { LogEvent, PostgresDialect } from 'kysely';
import { CamelCasePlugin, LogEvent, PostgresDialect } from 'kysely';
import { Pool } from 'pg';
import { GroupRepo } from '@docmost/db/repos/group/group.repo';
import { WorkspaceRepo } from '@docmost/db/repos/workspace/workspace.repo';
@ -25,8 +25,9 @@ import { AttachmentRepo } from './repos/attachment/attachment.repo';
dialect: new PostgresDialect({
pool: new Pool({
connectionString: environmentService.getDatabaseURL(),
}) as any,
}),
}),
plugins: [new CamelCasePlugin()],
log: (event: LogEvent) => {
if (environmentService.getEnv() !== 'development') return;
if (event.level === 'query') {

View File

@ -11,26 +11,27 @@ export async function up(db: Kysely<any>): Promise<void> {
.addColumn('description', 'text', (col) => col)
.addColumn('logo', 'varchar', (col) => col)
.addColumn('hostname', 'varchar', (col) => col)
.addColumn('customDomain', 'varchar', (col) => col)
.addColumn('enableInvite', 'boolean', (col) =>
.addColumn('custom_domain', 'varchar', (col) => col)
.addColumn('enable_invite', 'boolean', (col) =>
col.defaultTo(true).notNull(),
)
.addColumn('inviteCode', 'varchar', (col) => col)
.addColumn('invite_code', 'varchar', (col) =>
col.defaultTo(sql`gen_random_uuid()`),
)
.addColumn('settings', 'jsonb', (col) => col)
.addColumn('defaultRole', 'varchar', (col) =>
.addColumn('default_role', 'varchar', (col) =>
col.defaultTo(UserRole.MEMBER).notNull(),
)
.addColumn('creatorId', 'uuid', (col) => col)
.addColumn('defaultSpaceId', 'uuid', (col) => col)
.addColumn('createdAt', 'timestamp', (col) =>
.addColumn('default_space_id', 'uuid', (col) => col)
.addColumn('created_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('updatedAt', 'timestamp', (col) =>
.addColumn('updated_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('deletedAt', 'timestamp', (col) => col)
.addColumn('deleted_at', 'timestamptz', (col) => col)
.addUniqueConstraint('workspaces_hostname_unique', ['hostname'])
.addUniqueConstraint('workspaces_inviteCode_unique', ['inviteCode'])
.addUniqueConstraint('workspaces_invite_code_unique', ['invite_code'])
.execute();
}

View File

@ -8,38 +8,32 @@ export async function up(db: Kysely<any>): Promise<void> {
)
.addColumn('name', 'varchar', (col) => col)
.addColumn('email', 'varchar', (col) => col.notNull())
.addColumn('emailVerifiedAt', 'timestamp', (col) => col)
.addColumn('email_verified_at', 'timestamptz', (col) => col)
.addColumn('password', 'varchar', (col) => col.notNull())
.addColumn('avatarUrl', 'varchar', (col) => col)
.addColumn('avatar_url', 'varchar', (col) => col)
.addColumn('role', 'varchar', (col) => col)
.addColumn('status', 'varchar', (col) => col)
.addColumn('workspaceId', 'uuid', (col) =>
.addColumn('workspace_id', 'uuid', (col) =>
col.references('workspaces.id').onDelete('cascade'),
)
.addColumn('locale', 'varchar', (col) => col)
.addColumn('timezone', 'varchar', (col) => col)
.addColumn('settings', 'jsonb', (col) => col)
.addColumn('lastActiveAt', 'timestamp', (col) => col)
.addColumn('lastLoginAt', 'timestamp', (col) => col)
.addColumn('lastLoginIp', 'varchar', (col) => col)
.addColumn('createdAt', 'timestamp', (col) =>
.addColumn('last_active_at', 'timestamptz', (col) => col)
.addColumn('last_login_at', 'timestamptz', (col) => col)
.addColumn('created_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('updatedAt', 'timestamp', (col) =>
.addColumn('updated_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addUniqueConstraint('users_email_workspaceId_unique', [
.addUniqueConstraint('users_email_workspace_id_unique', [
'email',
'workspaceId',
'workspace_id',
])
.execute();
}
export async function down(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('users')
.dropConstraint('users_workspaceId_fkey')
.execute();
await db.schema.dropTable('users').execute();
}

View File

@ -8,35 +8,49 @@ export async function up(db: Kysely<any>): Promise<void> {
)
.addColumn('name', 'varchar', (col) => col.notNull())
.addColumn('description', 'text', (col) => col)
.addColumn('isDefault', 'boolean', (col) => col.notNull())
.addColumn('workspaceId', 'uuid', (col) =>
.addColumn('is_default', 'boolean', (col) => col.notNull())
.addColumn('workspace_id', 'uuid', (col) =>
col.references('workspaces.id').onDelete('cascade').notNull(),
)
.addColumn('creatorId', 'uuid', (col) => col.references('users.id'))
.addColumn('createdAt', 'timestamp', (col) =>
.addColumn('creator_id', 'uuid', (col) => col.references('users.id'))
.addColumn('created_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('updatedAt', 'timestamp', (col) =>
.addColumn('updated_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addUniqueConstraint('groups_name_workspaceId_unique', [
.addUniqueConstraint('groups_name_workspace_id_unique', [
'name',
'workspaceId',
'workspace_id',
])
.execute();
await db.schema
.createTable('group_users')
.addColumn('id', 'uuid', (col) =>
col.primaryKey().defaultTo(sql`gen_random_uuid()`),
)
.addColumn('user_id', 'uuid', (col) =>
col.references('users.id').onDelete('cascade').notNull(),
)
.addColumn('group_id', 'uuid', (col) =>
col.references('groups.id').onDelete('cascade').notNull(),
)
.addColumn('created_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('updated_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addUniqueConstraint('group_users_group_id_user_id_unique', [
'group_id',
'user_id',
])
.execute();
}
export async function down(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('groups')
.dropConstraint('groups_workspaceId_fkey')
.execute();
await db.schema
.alterTable('groups')
.dropConstraint('groups_creatorId_fkey')
.execute();
await db.schema.dropTable('group_users').execute();
await db.schema.dropTable('groups').execute();
}

View File

@ -1,40 +0,0 @@
import { Kysely, sql } from 'kysely';
export async function up(db: Kysely<any>): Promise<void> {
await db.schema
.createTable('group_users')
.addColumn('id', 'uuid', (col) =>
col.primaryKey().defaultTo(sql`gen_random_uuid()`),
)
.addColumn('userId', 'uuid', (col) =>
col.references('users.id').onDelete('cascade').notNull(),
)
.addColumn('groupId', 'uuid', (col) =>
col.references('groups.id').onDelete('cascade').notNull(),
)
.addColumn('createdAt', 'timestamp', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('updatedAt', 'timestamp', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addUniqueConstraint('group_users_groupId_userId_unique', [
'groupId',
'userId',
])
.execute();
}
export async function down(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('group_users')
.dropConstraint('group_users_userId_fkey')
.execute();
await db.schema
.alterTable('group_users')
.dropConstraint('group_users_groupId_fkey')
.execute();
await db.schema.dropTable('group_users').execute();
}

View File

@ -14,36 +14,64 @@ export async function up(db: Kysely<any>): Promise<void> {
.addColumn('visibility', 'varchar', (col) =>
col.defaultTo(SpaceVisibility.OPEN).notNull(),
)
.addColumn('defaultRole', 'varchar', (col) =>
.addColumn('default_role', 'varchar', (col) =>
col.defaultTo(SpaceRole.WRITER).notNull(),
)
.addColumn('creatorId', 'uuid', (col) => col.references('users.id'))
.addColumn('workspaceId', 'uuid', (col) =>
.addColumn('creator_id', 'uuid', (col) => col.references('users.id'))
.addColumn('workspace_id', 'uuid', (col) =>
col.references('workspaces.id').onDelete('cascade').notNull(),
)
.addColumn('createdAt', 'timestamp', (col) =>
.addColumn('created_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('updatedAt', 'timestamp', (col) =>
.addColumn('updated_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addUniqueConstraint('spaces_slug_workspaceId_unique', [
.addColumn('deleted_at', 'timestamptz', (col) => col)
.addUniqueConstraint('spaces_slug_workspace_id_unique', [
'slug',
'workspaceId',
'workspace_id',
])
.execute();
await db.schema
.createTable('space_members')
.addColumn('id', 'uuid', (col) =>
col.primaryKey().defaultTo(sql`gen_random_uuid()`),
)
.addColumn('user_id', 'uuid', (col) =>
col.references('users.id').onDelete('cascade'),
)
.addColumn('group_id', 'uuid', (col) =>
col.references('groups.id').onDelete('cascade'),
)
.addColumn('space_id', 'uuid', (col) =>
col.references('spaces.id').onDelete('cascade').notNull(),
)
.addColumn('role', 'varchar', (col) => col.notNull())
.addColumn('creator_id', 'uuid', (col) => col.references('users.id'))
.addColumn('created_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('updated_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addUniqueConstraint('space_members_space_id_user_id_unique', [
'space_id',
'user_id',
])
.addUniqueConstraint('space_members_space_id_group_id_unique', [
'space_id',
'group_id',
])
.addCheckConstraint(
'allow_either_user_id_or_group_id_check',
sql`(("user_id" IS NOT NULL AND "group_id" IS NULL) OR ("user_id" IS NULL AND "group_id" IS NOT NULL))`,
)
.execute();
}
export async function down(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('spaces')
.dropConstraint('spaces_creatorId_fkey')
.execute();
await db.schema
.alterTable('spaces')
.dropConstraint('spaces_workspaceId_fkey')
.execute();
await db.schema.dropTable('space_members').execute();
await db.schema.dropTable('spaces').execute();
}

View File

@ -1,62 +0,0 @@
import { Kysely, sql } from 'kysely';
export async function up(db: Kysely<any>): Promise<void> {
await db.schema
.createTable('space_members')
.addColumn('id', 'uuid', (col) =>
col.primaryKey().defaultTo(sql`gen_random_uuid()`),
)
.addColumn('userId', 'uuid', (col) =>
col.references('users.id').onDelete('cascade'),
)
.addColumn('groupId', 'uuid', (col) =>
col.references('groups.id').onDelete('cascade'),
)
.addColumn('spaceId', 'uuid', (col) =>
col.references('spaces.id').onDelete('cascade').notNull(),
)
.addColumn('role', 'varchar', (col) => col.notNull())
.addColumn('creatorId', 'uuid', (col) => col.references('users.id'))
.addColumn('createdAt', 'timestamp', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('updatedAt', 'timestamp', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addUniqueConstraint('space_members_spaceId_userId_unique', [
'spaceId',
'userId',
])
.addUniqueConstraint('space_members_spaceId_groupId_unique', [
'spaceId',
'groupId',
])
.addCheckConstraint(
'allow_either_userId_or_groupId_check',
sql`(("userId" IS NOT NULL AND "groupId" IS NULL) OR ("userId" IS NULL AND "groupId" IS NOT NULL))`,
)
.execute();
}
export async function down(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('space_members')
.dropConstraint('space_members_userId_fkey')
.execute();
await db.schema
.alterTable('space_members')
.dropConstraint('space_members_groupId_fkey')
.execute();
await db.schema
.alterTable('space_members')
.dropConstraint('space_members_spaceId_fkey')
.execute();
await db.schema
.alterTable('space_members')
.dropConstraint('space_members_creatorId_fkey')
.execute();
await db.schema.dropTable('space_members').execute();
}

View File

@ -4,18 +4,8 @@ export async function up(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('workspaces')
.addForeignKeyConstraint(
'workspaces_creatorId_fkey',
['creatorId'],
'users',
['id'],
)
.execute();
await db.schema
.alterTable('workspaces')
.addForeignKeyConstraint(
'workspaces_defaultSpaceId_fkey',
['defaultSpaceId'],
'workspaces_default_space_id_fkey',
['default_space_id'],
'spaces',
['id'],
)
@ -26,11 +16,6 @@ export async function up(db: Kysely<any>): Promise<void> {
export async function down(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('workspaces')
.dropConstraint('workspaces_creatorId_fkey')
.execute();
await db.schema
.alterTable('workspaces')
.dropConstraint('workspaces_defaultSpaceId_fkey')
.dropConstraint('workspaces_default_space_id_fkey')
.execute();
}

View File

@ -6,31 +6,22 @@ export async function up(db: Kysely<any>): Promise<void> {
.addColumn('id', 'uuid', (col) =>
col.primaryKey().defaultTo(sql`gen_random_uuid()`),
)
.addColumn('workspaceId', 'uuid', (col) =>
.addColumn('workspace_id', 'uuid', (col) =>
col.references('workspaces.id').onDelete('cascade').notNull(),
)
.addColumn('invitedById', 'uuid', (col) => col.references('users.id'))
.addColumn('invited_by_id', 'uuid', (col) => col.references('users.id'))
.addColumn('email', 'varchar', (col) => col.notNull())
.addColumn('role', 'varchar', (col) => col.notNull())
.addColumn('status', 'varchar', (col) => col)
.addColumn('createdAt', 'timestamp', (col) =>
.addColumn('created_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('updatedAt', 'timestamp', (col) =>
.addColumn('updated_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.execute();
}
export async function down(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('workspace_invitations')
.dropConstraint('workspace_invitations_workspaceId_fkey')
.execute();
await db.schema
.alterTable('workspace_invitations')
.dropConstraint('workspace_invitations_invitedById_fkey')
.execute();
await db.schema.dropTable('workspace_invitations').execute();
}

View File

@ -8,37 +8,39 @@ export async function up(db: Kysely<any>): Promise<void> {
)
.addColumn('title', 'varchar', (col) => col)
.addColumn('icon', 'varchar', (col) => col)
.addColumn('key', 'varchar', (col) => col)
.addColumn('content', 'jsonb', (col) => col)
.addColumn('html', 'text', (col) => col)
.addColumn('textContent', 'text', (col) => col)
.addColumn('text_content', 'text', (col) => col)
.addColumn('tsv', sql`tsvector`, (col) => col)
.addColumn('ydoc', 'bytea', (col) => col)
.addColumn('slug', 'varchar', (col) => col)
.addColumn('coverPhoto', 'varchar', (col) => col)
.addColumn('cover_photo', 'varchar', (col) => col)
.addColumn('editor', 'varchar', (col) => col)
.addColumn('shareId', 'varchar', (col) => col)
.addColumn('parentPageId', 'uuid', (col) =>
.addColumn('parent_page_id', 'uuid', (col) =>
col.references('pages.id').onDelete('cascade'),
)
.addColumn('creatorId', 'uuid', (col) => col.references('users.id'))
.addColumn('lastUpdatedById', 'uuid', (col) => col.references('users.id'))
.addColumn('deletedById', 'uuid', (col) => col.references('users.id'))
.addColumn('spaceId', 'uuid', (col) =>
.addColumn('creator_id', 'uuid', (col) => col.references('users.id'))
.addColumn('last_updated_by_id', 'uuid', (col) =>
col.references('users.id'),
)
.addColumn('deleted_by_id', 'uuid', (col) => col.references('users.id'))
.addColumn('space_id', 'uuid', (col) =>
col.references('spaces.id').onDelete('cascade').notNull(),
)
.addColumn('workspaceId', 'uuid', (col) =>
.addColumn('workspace_id', 'uuid', (col) =>
col.references('workspaces.id').onDelete('cascade').notNull(),
)
.addColumn('isLocked', 'boolean', (col) => col.defaultTo(false).notNull())
.addColumn('is_locked', 'boolean', (col) => col.defaultTo(false).notNull())
.addColumn('status', 'varchar', (col) => col)
.addColumn('publishedAt', 'date', (col) => col)
.addColumn('createdAt', 'timestamp', (col) =>
.addColumn('published_at', 'date', (col) => col)
.addColumn('created_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('updatedAt', 'timestamp', (col) =>
.addColumn('updated_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('deletedAt', 'timestamp', (col) => col)
.addColumn('deleted_at', 'timestamptz', (col) => col)
.execute();
await db.schema
@ -52,32 +54,32 @@ export async function up(db: Kysely<any>): Promise<void> {
export async function down(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('pages')
.dropConstraint('pages_creatorId_fkey')
.dropConstraint('pages_creator_id_fkey')
.execute();
await db.schema
.alterTable('pages')
.dropConstraint('pages_lastUpdatedById_fkey')
.dropConstraint('pages_last_updated_by_id_fkey')
.execute();
await db.schema
.alterTable('pages')
.dropConstraint('pages_deletedById_fkey')
.dropConstraint('pages_deleted_by_id_fkey')
.execute();
await db.schema
.alterTable('pages')
.dropConstraint('pages_spaceId_fkey')
.dropConstraint('pages_space_id_fkey')
.execute();
await db.schema
.alterTable('pages')
.dropConstraint('pages_workspaceId_fkey')
.dropConstraint('pages_workspace_id_fkey')
.execute();
await db.schema
.alterTable('pages')
.dropConstraint('pages_parentPageId_fkey')
.dropConstraint('pages_parent_page_id_fkey')
.execute();
await db.schema.dropTable('pages').execute();

View File

@ -6,51 +6,33 @@ export async function up(db: Kysely<any>): Promise<void> {
.addColumn('id', 'uuid', (col) =>
col.primaryKey().defaultTo(sql`gen_random_uuid()`),
)
.addColumn('pageId', 'uuid', (col) =>
.addColumn('page_id', 'uuid', (col) =>
col.references('pages.id').onDelete('cascade').notNull(),
)
.addColumn('title', 'varchar', (col) => col)
.addColumn('content', 'jsonb', (col) => col)
.addColumn('slug', 'varchar', (col) => col)
.addColumn('icon', 'varchar', (col) => col)
.addColumn('coverPhoto', 'varchar', (col) => col)
.addColumn('cover_photo', 'varchar', (col) => col)
.addColumn('version', 'int4', (col) => col.notNull())
.addColumn('lastUpdatedById', 'uuid', (col) => col.references('users.id'))
.addColumn('spaceId', 'uuid', (col) =>
.addColumn('last_updated_by_id', 'uuid', (col) =>
col.references('users.id'),
)
.addColumn('space_id', 'uuid', (col) =>
col.references('spaces.id').onDelete('cascade').notNull(),
)
.addColumn('workspaceId', 'uuid', (col) =>
.addColumn('workspace_id', 'uuid', (col) =>
col.references('workspaces.id').onDelete('cascade').notNull(),
)
.addColumn('createdAt', 'timestamp', (col) =>
.addColumn('created_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('updatedAt', 'timestamp', (col) =>
.addColumn('updated_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.execute();
}
export async function down(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('page_history')
.dropConstraint('page_history_pageId_fkey')
.execute();
await db.schema
.alterTable('page_history')
.dropConstraint('page_history_lastUpdatedById_fkey')
.execute();
await db.schema
.alterTable('page_history')
.dropConstraint('page_history_spaceId_fkey')
.execute();
await db.schema
.alterTable('page_history')
.dropConstraint('page_history_workspaceId_fkey')
.execute();
await db.schema.dropTable('page_history').execute();
}

View File

@ -6,39 +6,29 @@ export async function up(db: Kysely<any>): Promise<void> {
.addColumn('id', 'uuid', (col) =>
col.primaryKey().defaultTo(sql`gen_random_uuid()`),
)
.addColumn('entityId', 'uuid', (col) => col.notNull())
.addColumn('entityType', 'varchar', (col) => col.notNull())
.addColumn('childrenIds', sql`uuid[]`, (col) => col.notNull())
.addColumn('spaceId', 'uuid', (col) =>
.addColumn('entity_id', 'uuid', (col) => col.notNull())
.addColumn('entity_type', 'varchar', (col) => col.notNull()) // can be page or space
.addColumn('children_ids', sql`uuid[]`, (col) => col.notNull())
.addColumn('space_id', 'uuid', (col) =>
col.references('spaces.id').onDelete('cascade').notNull(),
)
.addColumn('workspaceId', 'uuid', (col) =>
.addColumn('workspace_id', 'uuid', (col) =>
col.references('workspaces.id').onDelete('cascade').notNull(),
)
.addColumn('createdAt', 'timestamp', (col) =>
.addColumn('created_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('updatedAt', 'timestamp', (col) =>
.addColumn('updated_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('deletedAt', 'timestamp', (col) => col)
.addUniqueConstraint('page_ordering_entityId_entityType_unique', [
'entityId',
'entityType',
.addColumn('deleted_at', 'timestamptz', (col) => col)
.addUniqueConstraint('page_ordering_entity_id_entity_type_unique', [
'entity_id',
'entity_type',
])
.execute();
}
export async function down(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('page_ordering')
.dropConstraint('page_ordering_spaceId_fkey')
.execute();
await db.schema
.alterTable('page_ordering')
.dropConstraint('page_ordering_workspaceId_fkey')
.execute();
await db.schema.dropTable('page_ordering').execute();
}

View File

@ -9,44 +9,24 @@ export async function up(db: Kysely<any>): Promise<void> {
.addColumn('content', 'jsonb', (col) => col)
.addColumn('selection', 'varchar', (col) => col)
.addColumn('type', 'varchar', (col) => col)
.addColumn('creatorId', 'uuid', (col) => col.references('users.id'))
.addColumn('pageId', 'uuid', (col) =>
.addColumn('creator_id', 'uuid', (col) => col.references('users.id'))
.addColumn('page_id', 'uuid', (col) =>
col.references('pages.id').onDelete('cascade').notNull(),
)
.addColumn('parentCommentId', 'uuid', (col) =>
.addColumn('parent_comment_id', 'uuid', (col) =>
col.references('comments.id').onDelete('cascade'),
)
.addColumn('workspaceId', 'uuid', (col) =>
.addColumn('workspace_id', 'uuid', (col) =>
col.references('workspaces.id').notNull(),
)
.addColumn('createdAt', 'timestamp', (col) =>
.addColumn('created_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('editedAt', 'timestamp', (col) => col)
.addColumn('deletedAt', 'timestamp', (col) => col)
.addColumn('edited_at', 'timestamptz', (col) => col)
.addColumn('deleted_at', 'timestamptz', (col) => col)
.execute();
}
export async function down(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('comments')
.dropConstraint('comments_creatorId_fkey')
.execute();
await db.schema
.alterTable('comments')
.dropConstraint('comments_pageId_fkey')
.execute();
await db.schema
.alterTable('comments')
.dropConstraint('comments_parentCommentId_fkey')
.execute();
await db.schema
.alterTable('comments')
.dropConstraint('comments_workspaceId_fkey')
.execute();
await db.schema.dropTable('comments').execute();
}

View File

@ -6,50 +6,28 @@ export async function up(db: Kysely<any>): Promise<void> {
.addColumn('id', 'uuid', (col) =>
col.primaryKey().defaultTo(sql`gen_random_uuid()`),
)
.addColumn('fileName', 'varchar', (col) => col.notNull())
.addColumn('filePath', 'varchar', (col) => col.notNull())
.addColumn('fileSize', 'int8', (col) => col)
.addColumn('fileExt', 'varchar', (col) => col.notNull())
.addColumn('mimeType', 'varchar', (col) => col)
.addColumn('file_name', 'varchar', (col) => col.notNull())
.addColumn('file_path', 'varchar', (col) => col.notNull())
.addColumn('file_size', 'int8', (col) => col)
.addColumn('file_ext', 'varchar', (col) => col.notNull())
.addColumn('mime_type', 'varchar', (col) => col)
.addColumn('type', 'varchar', (col) => col)
.addColumn('creatorId', 'uuid', (col) =>
.addColumn('creator_id', 'uuid', (col) =>
col.references('users.id').notNull(),
)
.addColumn('pageId', 'uuid', (col) => col.references('pages.id'))
.addColumn('spaceId', 'uuid', (col) => col.references('spaces.id'))
.addColumn('workspaceId', 'uuid', (col) =>
col.references('workspaces.id').onDelete('cascade').notNull(),
)
.addColumn('createdAt', 'timestamp', (col) =>
.addColumn('page_id', 'uuid', (col) => col.references('pages.id'))
.addColumn('space_id', 'uuid', (col) => col.references('spaces.id'))
.addColumn('workspace_id', 'uuid', (col) => col.references('workspaces.id'))
.addColumn('created_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('updatedAt', 'timestamp', (col) =>
.addColumn('updated_at', 'timestamptz', (col) =>
col.notNull().defaultTo(sql`now()`),
)
.addColumn('deletedAt', 'timestamp', (col) => col)
.addColumn('deleted_at', 'timestamptz', (col) => col)
.execute();
}
export async function down(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('attachments')
.dropConstraint('attachments_creatorId_fkey')
.execute();
await db.schema
.alterTable('attachments')
.dropConstraint('attachments_pageId_fkey')
.execute();
await db.schema
.alterTable('attachments')
.dropConstraint('attachments_spaceId_fkey')
.execute();
await db.schema
.alterTable('attachments')
.dropConstraint('attachments_workspaceId_fkey')
.execute();
await db.schema.dropTable('attachments').execute();
}

View File

@ -5,7 +5,7 @@ export async function up(db: Kysely<any>): Promise<void> {
begin
new.tsv :=
setweight(to_tsvector('english', coalesce(new.title, '')), 'A') ||
setweight(to_tsvector('english', coalesce(new.\"textContent\", '')), 'B');
setweight(to_tsvector('english', coalesce(new.text_content, '')), 'B');
return new;
end;
$$ LANGUAGE plpgsql;`.execute(db);

View File

@ -23,7 +23,7 @@ export class GroupUserRepo {
this.db,
async (trx) => {
return await trx
.selectFrom('group_users')
.selectFrom('groupUsers')
.selectAll()
.where('userId', '=', userId)
.where('groupId', '=', groupId)
@ -41,7 +41,7 @@ export class GroupUserRepo {
this.db,
async (trx) => {
return await trx
.insertInto('group_users')
.insertInto('groupUsers')
.values(insertableGroupUser)
.returningAll()
.executeTakeFirst();
@ -57,8 +57,8 @@ export class GroupUserRepo {
// todo add group member count
return executeTx(this.db, async (trx) => {
const groupUsers = (await trx
.selectFrom('group_users')
.innerJoin('users', 'users.id', 'group_users.userId')
.selectFrom('groupUsers')
.innerJoin('users', 'users.id', 'groupUsers.userId')
.select(sql<User>`users.*` as any)
.where('groupId', '=', groupId)
.limit(paginationOptions.limit)
@ -71,7 +71,7 @@ export class GroupUserRepo {
});
let { count } = await trx
.selectFrom('group_users')
.selectFrom('groupUsers')
.select((eb) => eb.fn.count('id').as('count'))
.where('groupId', '=', groupId)
.executeTakeFirst();
@ -84,7 +84,7 @@ export class GroupUserRepo {
async delete(userId: string, groupId: string): Promise<void> {
await this.db
.deleteFrom('group_users')
.deleteFrom('groupUsers')
.where('userId', '=', userId)
.where('groupId', '=', groupId)
.execute();

View File

@ -15,7 +15,7 @@ export class PageHistoryRepo {
async findById(pageHistoryId: string): Promise<PageHistory> {
return await this.db
.selectFrom('page_history')
.selectFrom('pageHistory')
.selectAll()
.where('id', '=', pageHistoryId)
.executeTakeFirst();
@ -30,7 +30,7 @@ export class PageHistoryRepo {
this.db,
async (trx) => {
return await trx
.updateTable('page_history')
.updateTable('pageHistory')
.set(updatablePageHistory)
.where('id', '=', pageHistoryId)
.execute();
@ -47,7 +47,7 @@ export class PageHistoryRepo {
this.db,
async (trx) => {
return await trx
.insertInto('page_history')
.insertInto('pageHistory')
.values(insertablePageHistory)
.returningAll()
.executeTakeFirst();
@ -62,7 +62,7 @@ export class PageHistoryRepo {
) {
return executeTx(this.db, async (trx) => {
const pageHistory = await trx
.selectFrom('page_history as history')
.selectFrom('pageHistory as history')
.innerJoin('users as user', 'user.id', 'history.lastUpdatedById')
.select([
'history.id',
@ -87,7 +87,7 @@ export class PageHistoryRepo {
.execute();
let { count } = await trx
.selectFrom('page_history')
.selectFrom('pageHistory')
.select((eb) => eb.fn.count('id').as('count'))
.where('pageId', '=', pageId)
.executeTakeFirst();

View File

@ -10,7 +10,6 @@ import {
import { sql } from 'kysely';
import { PaginationOptions } from 'src/helpers/pagination/pagination-options';
import { OrderingEntity } from 'src/core/page/page.util';
import { PageWithOrderingDto } from 'src/core/page/dto/page-with-ordering.dto';
// TODO: scope to space/workspace
@Injectable()
@ -23,7 +22,7 @@ export class PageRepo {
'slug',
'icon',
'coverPhoto',
'shareId',
'key',
'parentPageId',
'creatorId',
'lastUpdatedById',
@ -126,7 +125,7 @@ export class PageRepo {
async getSpaceSidebarPages(spaceId: string, limit: number) {
const pages = await this.db
.selectFrom('pages as page')
.innerJoin('page_ordering as ordering', 'ordering.entityId', 'page.id')
.innerJoin('pageOrdering as ordering', 'ordering.entityId', 'page.id')
.where('ordering.entityType', '=', OrderingEntity.PAGE)
.where('page.spaceId', '=', spaceId)
.select([

View File

@ -22,7 +22,7 @@ export class SpaceMemberRepo {
this.db,
async (trx) => {
return await trx
.insertInto('space_members')
.insertInto('spaceMembers')
.values(insertableSpaceMember)
.returningAll()
.executeTakeFirst();
@ -37,9 +37,9 @@ export class SpaceMemberRepo {
) {
return executeTx(this.db, async (trx) => {
const spaceMembers = await trx
.selectFrom('space_members')
.leftJoin('users', 'users.id', 'space_members.userId')
.leftJoin('groups', 'groups.id', 'space_members.groupId')
.selectFrom('spaceMembers')
.leftJoin('users', 'users.id', 'spaceMembers.userId')
.leftJoin('groups', 'groups.id', 'spaceMembers.groupId')
.select([
'groups.id as group_id',
'groups.name as group_name',
@ -51,10 +51,10 @@ export class SpaceMemberRepo {
'users.name as user_name',
'users.avatarUrl as user_avatarUrl',
'users.email as user_email',
'space_members.role',
'spaceMembers.role',
])
.where('spaceId', '=', spaceId)
.orderBy('space_members.createdAt', 'asc')
.orderBy('spaceMembers.createdAt', 'asc')
.limit(paginationOptions.limit)
.offset(paginationOptions.offset)
.execute();
@ -87,7 +87,7 @@ export class SpaceMemberRepo {
});
let { count } = await trx
.selectFrom('space_members')
.selectFrom('spaceMembers')
.select((eb) => eb.fn.count('id').as('count'))
.where('spaceId', '=', spaceId)
.executeTakeFirst();
@ -106,7 +106,7 @@ export class SpaceMemberRepo {
* Todo: needs more work. this is a draft
*/
async getUserSpaces(userId: string, workspaceId: string) {
const rolePriority = sql`CASE "space_members"."role"
const rolePriority = sql`CASE "spaceMembers"."role"
WHEN 'owner' THEN 3
WHEN 'writer' THEN 2
WHEN 'reader' THEN 1
@ -114,35 +114,31 @@ export class SpaceMemberRepo {
const subquery = this.db
.selectFrom('spaces')
.innerJoin('space_members', 'spaces.id', 'space_members.spaceId')
.innerJoin('spaceMembers', 'spaces.id', 'spaceMembers.spaceId')
.select([
'spaces.id',
'spaces.name',
'spaces.slug',
'spaces.icon',
'space_members.role',
'spaceMembers.role',
rolePriority,
])
.where('space_members.userId', '=', userId)
.where('spaceMembers.userId', '=', userId)
.where('spaces.workspaceId', '=', workspaceId)
.unionAll(
this.db
.selectFrom('spaces')
.innerJoin('space_members', 'spaces.id', 'space_members.spaceId')
.innerJoin(
'group_users',
'space_members.groupId',
'group_users.groupId',
)
.innerJoin('spaceMembers', 'spaces.id', 'spaceMembers.spaceId')
.innerJoin('groupUsers', 'spaceMembers.groupId', 'groupUsers.groupId')
.select([
'spaces.id',
'spaces.name',
'spaces.slug',
'spaces.icon',
'space_members.role',
'spaceMembers.role',
rolePriority,
])
.where('group_users.userId', '=', userId),
.where('groupUsers.userId', '=', userId),
)
.as('membership');
@ -194,7 +190,7 @@ export class SpaceMemberRepo {
spaceId: string,
workspaceId: string,
) {
const rolePriority = sql`CASE "space_members"."role"
const rolePriority = sql`CASE "spaceMembers"."role"
WHEN 'owner' THEN 3
WHEN 'writer' THEN 2
WHEN 'reader' THEN 1
@ -202,36 +198,32 @@ export class SpaceMemberRepo {
const subquery = this.db
.selectFrom('spaces')
.innerJoin('space_members', 'spaces.id', 'space_members.spaceId')
.innerJoin('spaceMembers', 'spaces.id', 'spaceMembers.spaceId')
.select([
'spaces.id',
'spaces.name',
'space_members.role',
'space_members.userId',
'spaceMembers.role',
'spaceMembers.userId',
rolePriority,
])
.where('space_members.userId', '=', userId)
.where('spaceMembers.userId', '=', userId)
.where('spaces.id', '=', spaceId)
.where('spaces.workspaceId', '=', workspaceId)
.unionAll(
this.db
.selectFrom('spaces')
.innerJoin('space_members', 'spaces.id', 'space_members.spaceId')
.innerJoin(
'group_users',
'space_members.groupId',
'group_users.groupId',
)
.innerJoin('spaceMembers', 'spaces.id', 'spaceMembers.spaceId')
.innerJoin('groupUsers', 'spaceMembers.groupId', 'groupUsers.groupId')
.select([
'spaces.id',
'spaces.name',
'space_members.role',
'space_members.userId',
'spaceMembers.role',
'spaceMembers.userId',
rolePriority,
])
.where('spaces.id', '=', spaceId)
.where('spaces.workspaceId', '=', workspaceId)
.where('group_users.userId', '=', userId),
.where('groupUsers.userId', '=', userId),
)
.as('membership');
@ -275,7 +267,7 @@ export class SpaceMemberRepo {
this.db,
async (trx) => {
return await trx
.selectFrom('space_members')
.selectFrom('spaceMembers')
.selectAll()
.where('userId', '=', userId)
.where('groupId', '=', groupId)
@ -287,7 +279,7 @@ export class SpaceMemberRepo {
async removeUser(userId: string, spaceId: string): Promise<void> {
await this.db
.deleteFrom('space_members')
.deleteFrom('spaceMembers')
.where('userId', '=', userId)
.where('spaceId', '=', spaceId)
.execute();
@ -295,7 +287,7 @@ export class SpaceMemberRepo {
async removeGroup(groupId: string, spaceId: string): Promise<void> {
await this.db
.deleteFrom('space_members')
.deleteFrom('spaceMembers')
.where('userId', '=', groupId)
.where('spaceId', '=', spaceId)
.execute();

View File

@ -1,15 +1,10 @@
import type { ColumnType } from 'kysely';
import type { ColumnType } from "kysely";
export type Generated<T> =
T extends ColumnType<infer S, infer I, infer U>
? ColumnType<S, I | undefined, U>
: ColumnType<T, T | undefined, T>;
export type Generated<T> = T extends ColumnType<infer S, infer I, infer U>
? ColumnType<S, I | undefined, U>
: ColumnType<T, T | undefined, T>;
export type Int8 = ColumnType<
string,
bigint | number | string,
bigint | number | string
>;
export type Int8 = ColumnType<string, bigint | number | string, bigint | number | string>;
export type Json = JsonValue;
@ -39,7 +34,7 @@ export interface Attachments {
spaceId: string | null;
type: string | null;
updatedAt: Generated<Timestamp>;
workspaceId: string;
workspaceId: string | null;
}
export interface Comments {
@ -115,10 +110,10 @@ export interface Pages {
icon: string | null;
id: Generated<string>;
isLocked: Generated<boolean>;
key: string | null;
lastUpdatedById: string | null;
parentPageId: string | null;
publishedAt: Timestamp | null;
shareId: string | null;
slug: string | null;
spaceId: string;
status: string | null;
@ -145,6 +140,7 @@ export interface Spaces {
createdAt: Generated<Timestamp>;
creatorId: string | null;
defaultRole: Generated<string>;
deletedAt: Timestamp | null;
description: string | null;
icon: string | null;
id: Generated<string>;
@ -163,7 +159,6 @@ export interface Users {
id: Generated<string>;
lastActiveAt: Timestamp | null;
lastLoginAt: Timestamp | null;
lastLoginIp: string | null;
locale: string | null;
name: string | null;
password: string;
@ -188,7 +183,6 @@ export interface WorkspaceInvitations {
export interface Workspaces {
createdAt: Generated<Timestamp>;
creatorId: string | null;
customDomain: string | null;
defaultRole: Generated<string>;
defaultSpaceId: string | null;
@ -197,7 +191,7 @@ export interface Workspaces {
enableInvite: Generated<boolean>;
hostname: string | null;
id: Generated<string>;
inviteCode: string | null;
inviteCode: Generated<string | null>;
logo: string | null;
name: string | null;
settings: Json | null;
@ -207,14 +201,14 @@ export interface Workspaces {
export interface DB {
attachments: Attachments;
comments: Comments;
group_users: GroupUsers;
groups: Groups;
page_history: PageHistory;
page_ordering: PageOrdering;
groupUsers: GroupUsers;
pageHistory: PageHistory;
pageOrdering: PageOrdering;
pages: Pages;
space_members: SpaceMembers;
spaceMembers: SpaceMembers;
spaces: Spaces;
users: Users;
workspace_invitations: WorkspaceInvitations;
workspaceInvitations: WorkspaceInvitations;
workspaces: Workspaces;
}