This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

semble / src / modules / user / infrastructure / repositories / DrizzleFollowsRepository.ts
4.1 kB 145 lines
1import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; 2import { eq, and, sql } from 'drizzle-orm'; 3import { IFollowsRepository } from '../../domain/repositories/IFollowsRepository'; 4import { Follow } from '../../domain/Follow'; 5import { DID } from '../../domain/value-objects/DID'; 6import { 7 FollowTargetType, 8 FollowTargetTypeEnum, 9} from '../../domain/value-objects/FollowTargetType'; 10import { follows } from './schema/follows.sql'; 11import { UniqueEntityID } from 'src/shared/domain/UniqueEntityID'; 12import { err, ok, Result } from 'src/shared/core/Result'; 13 14export class DrizzleFollowsRepository implements IFollowsRepository { 15 constructor(private db: PostgresJsDatabase) {} 16 17 async getFollowers( 18 targetId: string, 19 targetType: FollowTargetType, 20 ): Promise<Result<Follow[]>> { 21 try { 22 const results = await this.db 23 .select() 24 .from(follows) 25 .where( 26 and( 27 eq(follows.targetId, targetId), 28 eq(follows.targetType, targetType.value), 29 ), 30 ); 31 32 const followEntities: Follow[] = []; 33 34 for (const row of results) { 35 const followerDIDResult = DID.create(row.followerId); 36 if (followerDIDResult.isErr()) { 37 console.error( 38 `Invalid follower DID: ${row.followerId}`, 39 followerDIDResult.error, 40 ); 41 continue; 42 } 43 44 const targetTypeResult = FollowTargetType.create( 45 row.targetType as FollowTargetTypeEnum, 46 ); 47 if (targetTypeResult.isErr()) { 48 console.error( 49 `Invalid target type: ${row.targetType}`, 50 targetTypeResult.error, 51 ); 52 continue; 53 } 54 55 const followResult = Follow.create( 56 { 57 followerId: followerDIDResult.value, 58 targetId: row.targetId, 59 targetType: targetTypeResult.value, 60 createdAt: row.createdAt, 61 }, 62 new UniqueEntityID( 63 `${row.followerId}:${row.targetId}:${row.targetType}`, 64 ), 65 ); 66 67 if (followResult.isOk()) { 68 followEntities.push(followResult.value); 69 } else { 70 console.error('Failed to create Follow entity:', followResult.error); 71 } 72 } 73 74 return ok(followEntities); 75 } catch (error: any) { 76 return err(error); 77 } 78 } 79 80 async getFollowersOfCollections( 81 collectionIds: string[], 82 ): Promise<Result<Follow[]>> { 83 try { 84 if (collectionIds.length === 0) { 85 return ok([]); 86 } 87 88 const results = await this.db 89 .select() 90 .from(follows) 91 .where( 92 and( 93 sql`${follows.targetId} = ANY(${collectionIds}::text[])`, 94 eq(follows.targetType, FollowTargetTypeEnum.COLLECTION), 95 ), 96 ); 97 98 const followEntities: Follow[] = []; 99 100 for (const row of results) { 101 const followerDIDResult = DID.create(row.followerId); 102 if (followerDIDResult.isErr()) { 103 console.error( 104 `Invalid follower DID: ${row.followerId}`, 105 followerDIDResult.error, 106 ); 107 continue; 108 } 109 110 const targetTypeResult = FollowTargetType.create( 111 row.targetType as FollowTargetTypeEnum, 112 ); 113 if (targetTypeResult.isErr()) { 114 console.error( 115 `Invalid target type: ${row.targetType}`, 116 targetTypeResult.error, 117 ); 118 continue; 119 } 120 121 const followResult = Follow.create( 122 { 123 followerId: followerDIDResult.value, 124 targetId: row.targetId, 125 targetType: targetTypeResult.value, 126 createdAt: row.createdAt, 127 }, 128 new UniqueEntityID( 129 `${row.followerId}:${row.targetId}:${row.targetType}`, 130 ), 131 ); 132 133 if (followResult.isOk()) { 134 followEntities.push(followResult.value); 135 } else { 136 console.error('Failed to create Follow entity:', followResult.error); 137 } 138 } 139 140 return ok(followEntities); 141 } catch (error: any) { 142 return err(error); 143 } 144 } 145}