浏览代码

feat: add shared vaults user model. (#632)

Co-authored-by: Mo <mo@standardnotes.com>
Karol Sójko 2 年之前
父节点
当前提交
52f879f842

+ 8 - 0
packages/syncing-server/src/Domain/SharedVault/SharedVaultRepositoryInterface.ts

@@ -0,0 +1,8 @@
+import { Uuid } from '@standardnotes/domain-core'
+import { SharedVault } from './SharedVault'
+
+export interface SharedVaultRepositoryInterface {
+  findByUuid(uuid: Uuid): Promise<SharedVault | null>
+  save(sharedVault: SharedVault): Promise<void>
+  remove(sharedVault: SharedVault): Promise<void>
+}

+ 0 - 7
packages/syncing-server/src/Domain/SharedVault/SharedVaultsRepositoryInterface.ts

@@ -1,7 +0,0 @@
-import { SharedVault } from './SharedVault'
-
-export interface SharedVaultsRepositoryInterface {
-  findByUuid(uuid: string): Promise<SharedVault | null>
-  save(sharedVault: SharedVault): Promise<void>
-  remove(sharedVault: SharedVault): Promise<void>
-}

+ 17 - 0
packages/syncing-server/src/Domain/SharedVault/User/SharedVaultUser.ts

@@ -0,0 +1,17 @@
+import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
+
+import { SharedVaultUserProps } from './SharedVaultUserProps'
+
+export class SharedVaultUser extends Entity<SharedVaultUserProps> {
+  get id(): UniqueEntityId {
+    return this._id
+  }
+
+  private constructor(props: SharedVaultUserProps, id?: UniqueEntityId) {
+    super(props, id)
+  }
+
+  static create(props: SharedVaultUserProps, id?: UniqueEntityId): Result<SharedVaultUser> {
+    return Result.ok<SharedVaultUser>(new SharedVaultUser(props, id))
+  }
+}

+ 21 - 0
packages/syncing-server/src/Domain/SharedVault/User/SharedVaultUserPermission.ts

@@ -0,0 +1,21 @@
+import { Result, ValueObject } from '@standardnotes/domain-core'
+
+import { SharedVaultUserPermissionProps } from './SharedVaultUserPermissionProps'
+
+export class SharedVaultUserPermission extends ValueObject<SharedVaultUserPermissionProps> {
+  get value(): string {
+    return this.props.value
+  }
+
+  private constructor(props: SharedVaultUserPermissionProps) {
+    super(props)
+  }
+
+  static create(sharedVaultUserPermission: string): Result<SharedVaultUserPermission> {
+    if (!['read', 'write', 'admin'].includes(sharedVaultUserPermission)) {
+      return Result.fail<SharedVaultUserPermission>(`Invalid shared vault user permission ${sharedVaultUserPermission}`)
+    } else {
+      return Result.ok<SharedVaultUserPermission>(new SharedVaultUserPermission({ value: sharedVaultUserPermission }))
+    }
+  }
+}

+ 3 - 0
packages/syncing-server/src/Domain/SharedVault/User/SharedVaultUserPermissionProps.ts

@@ -0,0 +1,3 @@
+export interface SharedVaultUserPermissionProps {
+  value: string
+}

+ 10 - 0
packages/syncing-server/src/Domain/SharedVault/User/SharedVaultUserProps.ts

@@ -0,0 +1,10 @@
+import { Timestamps, Uuid } from '@standardnotes/domain-core'
+
+import { SharedVaultUserPermission } from './SharedVaultUserPermission'
+
+export interface SharedVaultUserProps {
+  sharedVaultUuid: Uuid
+  userUuid: Uuid
+  permission: SharedVaultUserPermission
+  timestamps: Timestamps
+}

+ 9 - 0
packages/syncing-server/src/Domain/SharedVault/User/SharedVaultUserRepositoryInterface.ts

@@ -0,0 +1,9 @@
+import { Uuid } from '@standardnotes/domain-core'
+
+import { SharedVaultUser } from './SharedVaultUser'
+
+export interface SharedVaultUserRepositoryInterface {
+  findByUuid(sharedVaultUserUuid: Uuid): Promise<SharedVaultUser | null>
+  save(sharedVaultUser: SharedVaultUser): Promise<void>
+  remove(sharedVault: SharedVaultUser): Promise<void>
+}

+ 5 - 5
packages/syncing-server/src/Infra/TypeORM/TypeORMSharedVaultRepository.ts

@@ -1,11 +1,11 @@
 import { Repository } from 'typeorm'
-import { MapperInterface } from '@standardnotes/domain-core'
+import { MapperInterface, Uuid } from '@standardnotes/domain-core'
 
-import { SharedVaultsRepositoryInterface } from '../../Domain/SharedVault/SharedVaultsRepositoryInterface'
+import { SharedVaultRepositoryInterface } from '../../Domain/SharedVault/SharedVaultRepositoryInterface'
 import { TypeORMSharedVault } from './TypeORMSharedVault'
 import { SharedVault } from '../../Domain/SharedVault/SharedVault'
 
-export class TypeORMSharedVaultRepository implements SharedVaultsRepositoryInterface {
+export class TypeORMSharedVaultRepository implements SharedVaultRepositoryInterface {
   constructor(
     private ormRepository: Repository<TypeORMSharedVault>,
     private mapper: MapperInterface<SharedVault, TypeORMSharedVault>,
@@ -17,11 +17,11 @@ export class TypeORMSharedVaultRepository implements SharedVaultsRepositoryInter
     await this.ormRepository.save(persistence)
   }
 
-  async findByUuid(uuid: string): Promise<SharedVault | null> {
+  async findByUuid(uuid: Uuid): Promise<SharedVault | null> {
     const persistence = await this.ormRepository
       .createQueryBuilder('shared_vault')
       .where('shared_vault.uuid = :uuid', {
-        uuid,
+        uuid: uuid.toString(),
       })
       .getOne()
 

+ 38 - 0
packages/syncing-server/src/Infra/TypeORM/TypeORMSharedVaultUser.ts

@@ -0,0 +1,38 @@
+import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'
+
+@Entity({ name: 'shared_vault_users' })
+export class TypeORMSharedVaultUser {
+  @PrimaryGeneratedColumn('uuid')
+  declare uuid: string
+
+  @Column({
+    name: 'shared_vault_uuid',
+    length: 36,
+  })
+  declare sharedVaultUuid: string
+
+  @Column({
+    name: 'user_uuid',
+    length: 36,
+  })
+  declare userUuid: string
+
+  @Column({
+    name: 'permission',
+    type: 'varchar',
+    length: 24,
+  })
+  declare permission: string
+
+  @Column({
+    name: 'created_at_timestamp',
+    type: 'bigint',
+  })
+  declare createdAtTimestamp: number
+
+  @Column({
+    name: 'updated_at_timestamp',
+    type: 'bigint',
+  })
+  declare updatedAtTimestamp: number
+}

+ 38 - 0
packages/syncing-server/src/Infra/TypeORM/TypeORMSharedVaultUserRepository.ts

@@ -0,0 +1,38 @@
+import { Repository } from 'typeorm'
+import { MapperInterface, Uuid } from '@standardnotes/domain-core'
+
+import { TypeORMSharedVaultUser } from './TypeORMSharedVaultUser'
+import { SharedVaultUser } from '../../Domain/SharedVault/User/SharedVaultUser'
+import { SharedVaultUserRepositoryInterface } from '../../Domain/SharedVault/User/SharedVaultUserRepositoryInterface'
+
+export class TypeORMSharedVaultUserRepository implements SharedVaultUserRepositoryInterface {
+  constructor(
+    private ormRepository: Repository<TypeORMSharedVaultUser>,
+    private mapper: MapperInterface<SharedVaultUser, TypeORMSharedVaultUser>,
+  ) {}
+
+  async save(sharedVaultUser: SharedVaultUser): Promise<void> {
+    const persistence = this.mapper.toProjection(sharedVaultUser)
+
+    await this.ormRepository.save(persistence)
+  }
+
+  async findByUuid(uuid: Uuid): Promise<SharedVaultUser | null> {
+    const persistence = await this.ormRepository
+      .createQueryBuilder('shared_vault_user')
+      .where('shared_vault_user.uuid = :uuid', {
+        uuid: uuid.toString(),
+      })
+      .getOne()
+
+    if (persistence === null) {
+      return null
+    }
+
+    return this.mapper.toDomain(persistence)
+  }
+
+  async remove(sharedVaultUser: SharedVaultUser): Promise<void> {
+    await this.ormRepository.remove(this.mapper.toProjection(sharedVaultUser))
+  }
+}

+ 62 - 0
packages/syncing-server/src/Mapping/SharedVaultUserPersistenceMapper.ts

@@ -0,0 +1,62 @@
+import { Timestamps, MapperInterface, UniqueEntityId, Uuid } from '@standardnotes/domain-core'
+
+import { SharedVaultUser } from '../Domain/SharedVault/User/SharedVaultUser'
+import { TypeORMSharedVaultUser } from '../Infra/TypeORM/TypeORMSharedVaultUser'
+import { SharedVaultUserPermission } from '../Domain/SharedVault/User/SharedVaultUserPermission'
+
+export class SharedVaultUserPersistenceMapper implements MapperInterface<SharedVaultUser, TypeORMSharedVaultUser> {
+  toDomain(projection: TypeORMSharedVaultUser): SharedVaultUser {
+    const userUuidOrError = Uuid.create(projection.userUuid)
+    if (userUuidOrError.isFailed()) {
+      throw new Error(`Failed to create shared vault user from projection: ${userUuidOrError.getError()}`)
+    }
+    const userUuid = userUuidOrError.getValue()
+
+    const sharedVaultUuidOrError = Uuid.create(projection.sharedVaultUuid)
+    if (sharedVaultUuidOrError.isFailed()) {
+      throw new Error(`Failed to create shared vault user from projection: ${sharedVaultUuidOrError.getError()}`)
+    }
+    const sharedVaultUuid = sharedVaultUuidOrError.getValue()
+
+    const timestampsOrError = Timestamps.create(projection.createdAtTimestamp, projection.updatedAtTimestamp)
+    if (timestampsOrError.isFailed()) {
+      throw new Error(`Failed to create shared vault user from projection: ${timestampsOrError.getError()}`)
+    }
+    const timestamps = timestampsOrError.getValue()
+
+    const permissionOrError = SharedVaultUserPermission.create(projection.permission)
+    if (permissionOrError.isFailed()) {
+      throw new Error(`Failed to create shared vault user from projection: ${permissionOrError.getError()}`)
+    }
+    const permission = permissionOrError.getValue()
+
+    const sharedVaultUserOrError = SharedVaultUser.create(
+      {
+        userUuid,
+        sharedVaultUuid,
+        permission,
+        timestamps,
+      },
+      new UniqueEntityId(projection.uuid),
+    )
+    if (sharedVaultUserOrError.isFailed()) {
+      throw new Error(`Failed to create shared vault user from projection: ${sharedVaultUserOrError.getError()}`)
+    }
+    const sharedVaultUser = sharedVaultUserOrError.getValue()
+
+    return sharedVaultUser
+  }
+
+  toProjection(domain: SharedVaultUser): TypeORMSharedVaultUser {
+    const typeorm = new TypeORMSharedVaultUser()
+
+    typeorm.uuid = domain.id.toString()
+    typeorm.sharedVaultUuid = domain.props.sharedVaultUuid.value
+    typeorm.userUuid = domain.props.userUuid.value
+    typeorm.permission = domain.props.permission.value
+    typeorm.createdAtTimestamp = domain.props.timestamps.createdAt
+    typeorm.updatedAtTimestamp = domain.props.timestamps.updatedAt
+
+    return typeorm
+  }
+}