import { Inject, Injectable } from '@nestjs/common'; import type { Kysely } from 'kysely'; import { KYSELY_DB } from '../../database/src'; import type { Database } from '../../database/src'; import type { CreateTripInvitationFields, TripInvitation } from './trip.types'; function toTripInvitation(row: { id: string; trip_id: string; email: string; invited_by_user_id: string; token_hash: string; expires_at: Date; accepted_at: Date | null; created_at: Date; updated_at: Date; }): TripInvitation { return { id: row.id, tripId: row.trip_id, email: row.email, invitedByUserId: row.invited_by_user_id, tokenHash: row.token_hash, expiresAt: row.expires_at, acceptedAt: row.accepted_at, createdAt: row.created_at, updatedAt: row.updated_at, }; } @Injectable() export class TripInvitationsRepository { constructor(@Inject(KYSELY_DB) private readonly db: Kysely) {} async create( tripId: string, fields: CreateTripInvitationFields, ): Promise { const row = await this.db .insertInto('trip_invitations') .values({ trip_id: tripId, email: fields.email, invited_by_user_id: fields.invitedByUserId, token_hash: fields.tokenHash, expires_at: fields.expiresAt.toISOString(), }) .returningAll() .executeTakeFirstOrThrow(); return toTripInvitation(row); } async findByTokenHash( tokenHash: string, ): Promise { const row = await this.db .selectFrom('trip_invitations') .selectAll() .where('token_hash', '=', tokenHash) .executeTakeFirst(); return row ? toTripInvitation(row) : undefined; } async listByTrip(tripId: string): Promise { const rows = await this.db .selectFrom('trip_invitations') .selectAll() .where('trip_id', '=', tripId) .execute(); return rows.map(toTripInvitation); } async markAccepted(invitationId: string): Promise { await this.db .updateTable('trip_invitations') .set({ accepted_at: new Date().toISOString(), updated_at: new Date().toISOString(), }) .where('id', '=', invitationId) .execute(); } async remove(tripId: string, invitationId: string): Promise { await this.db .deleteFrom('trip_invitations') .where('trip_id', '=', tripId) .where('id', '=', invitationId) .execute(); } }