MCPcopy Create free account
hub / github.com/cameri/nostream / UserRepository

Class UserRepository

src/repositories/user-repository.ts:10–127  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

8const logger = createLogger('user-repository')
9
10export class UserRepository implements IUserRepository {
11 public constructor(
12 private readonly dbClient: DatabaseClient,
13 private readonly eventRepository: IEventRepository,
14 ) {}
15
16 public async findByPubkey(pubkey: Pubkey, client: DatabaseClient = this.dbClient): Promise<User | undefined> {
17 logger('find by pubkey: %s', pubkey)
18 const [dbuser] = await client<DBUser>('users').where('pubkey', toBuffer(pubkey)).select()
19
20 if (!dbuser) {
21 return
22 }
23
24 return fromDBUser(dbuser)
25 }
26
27 public async upsert(user: Partial<User>, client: DatabaseClient = this.dbClient): Promise<number> {
28 logger('upsert: %o', user)
29
30 const date = new Date()
31
32 const row = applySpec<DBUser>({
33 pubkey: pipe(prop('pubkey'), toBuffer),
34 is_admitted: pipe(prop('isAdmitted'), defaultTo(false)),
35 is_vanished: pipe(prop('isVanished'), defaultTo(false)),
36 tos_accepted_at: prop('tosAcceptedAt'),
37 updated_at: always(date),
38 created_at: always(date),
39 })(user)
40
41 const query = client<DBUser>('users')
42 .insert(row)
43 .onConflict('pubkey')
44 .merge(omit(['pubkey', 'balance', 'created_at'])(row))
45
46 return {
47 then: <T1, T2>(
48 onfulfilled: (value: number) => T1 | PromiseLike<T1>,
49 onrejected: (reason: any) => T2 | PromiseLike<T2>,
50 ) => query.then(prop('rowCount') as () => number).then(onfulfilled, onrejected),
51 catch: <T>(onrejected: (reason: any) => T | PromiseLike<T>) => query.catch(onrejected),
52 toString: (): string => query.toString(),
53 } as Promise<number>
54 }
55
56 /**
57 * Returns vanish state from users.is_vanished, or lazily hydrates a user row from events once
58 * when no users row exists (single upsert; no duplicate inserts).
59 */
60 public async isVanished(pubkey: Pubkey, client: DatabaseClient = this.dbClient): Promise<boolean> {
61 const existing = await this.findByPubkey(pubkey, client)
62 if (existing) {
63 return existing.isVanished
64 }
65
66 const vanishedFromEvents = await this.eventRepository.hasActiveRequestToVanish(pubkey)
67 await this.upsertVanishState(pubkey, vanishedFromEvents, client)

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected