ekyc

Electronic KYC process with uploading ID document using OAuth 2.1 (experimental)
Log | Files | Refs | README | LICENSE

phone.ts (4080B)


      1 import { PhoneRepository } from "#core/application/phone/phone_repository.ts";
      2 import {
      3   EntityLocked,
      4   EntityNotFound,
      5 } from "#core/application/repository_error.ts";
      6 import { PhoneEKYC } from "#core/domain/phone_ekyc.ts";
      7 import { InvalidUUID, UUID } from "#core/domain/uuid.ts";
      8 import {
      9   mapFromPhoneEKYC,
     10   mapToPhoneEKYC,
     11   PhoneEKYCDto,
     12 } from "#infrastructure/memory/mapper/phone.ts";
     13 import { mapError } from "#infrastructure/postgres/error.ts";
     14 import { Pool } from "$postgres";
     15 
     16 export class PostgresPhoneRepositoryAdapter implements PhoneRepository {
     17   constructor(readonly pool: Pool) {
     18   }
     19 
     20   async findOrCreate(id: UUID): Promise<PhoneEKYC> {
     21     try {
     22       const connection = await this.pool.connect();
     23       try {
     24         const result = await connection.queryObject<PhoneEKYCDto>`
     25           select "uuid", "phoneNumber", "phoneNumberVerified",
     26                  "phoneNumberCode", "phoneNumberCodeExpire",
     27                  "phoneNumberChallengeRequest", "phoneNumberChallengeRequestExpire",
     28                  "phoneNumberChallengeAttempt", "phoneNumberChallengeAttemptExpire",
     29                  "version"
     30           from "phone"
     31           where uuid = ${id.toString()}
     32           limit 1;
     33         `;
     34         if (result.rowCount !== 1) {
     35           return new PhoneEKYC(id);
     36         }
     37         return mapToPhoneEKYC(result.rows[0]);
     38       } finally {
     39         connection.release();
     40       }
     41     } catch (error) {
     42       if (error instanceof InvalidUUID) {
     43         throw new EntityNotFound(id.toString());
     44       }
     45       throw mapError(error);
     46     }
     47   }
     48 
     49   async store(phoneEKYC: PhoneEKYC): Promise<void> {
     50     try {
     51       const dto = mapFromPhoneEKYC(phoneEKYC);
     52       const connection = await this.pool.connect();
     53       const transaction = connection.createTransaction(
     54         `txn_${dto.uuid}_${dto.version}`,
     55       );
     56       try {
     57         await transaction.begin();
     58         dto.version++;
     59         if (dto.version === 1) {
     60           await transaction.queryArray`
     61             insert into "phone" (
     62               "uuid", "phoneNumber", "phoneNumberVerified",
     63               "phoneNumberCode", "phoneNumberCodeExpire",
     64               "phoneNumberChallengeRequest", "phoneNumberChallengeRequestExpire",
     65               "phoneNumberChallengeAttempt", "phoneNumberChallengeAttemptExpire",
     66               "version"
     67             ) values (
     68               ${dto.uuid}, ${dto.phoneNumber}, ${dto.phoneNumberVerified},
     69               ${dto.phoneNumberCode}, ${dto.phoneNumberCodeExpire},
     70               ${dto.phoneNumberChallengeRequest}, ${dto.phoneNumberChallengeRequestExpire},
     71               ${dto.phoneNumberChallengeAttempt}, ${dto.phoneNumberChallengeAttemptExpire},
     72               ${dto.version}
     73             );
     74           `;
     75           await transaction.commit();
     76           phoneEKYC.version = dto.version;
     77           return;
     78         }
     79         const result = await transaction.queryObject<{ version: number }>`
     80           update "phone" set
     81             "phoneNumber" = ${dto.phoneNumber}, "phoneNumberVerified" = ${dto.phoneNumberVerified}, 
     82             "phoneNumberCode" = ${dto.phoneNumberCode}, "phoneNumberCodeExpire" = ${dto.phoneNumberCodeExpire},
     83             "phoneNumberChallengeRequest" = ${dto.phoneNumberChallengeRequest},
     84             "phoneNumberChallengeRequestExpire" = ${dto.phoneNumberChallengeRequestExpire},
     85             "phoneNumberChallengeAttempt" = ${dto.phoneNumberChallengeAttempt},
     86             "phoneNumberChallengeAttemptExpire" = ${dto.phoneNumberChallengeAttemptExpire},
     87             "version" = "version" + 1
     88           where uuid = ${dto.uuid}
     89           returning version;
     90         `;
     91         if (result.rowCount !== 1) {
     92           transaction.rollback();
     93           throw new EntityNotFound(dto.uuid);
     94         }
     95         if (result.rows[0].version === dto.version) {
     96           await transaction.commit();
     97           phoneEKYC.version = dto.version;
     98           return;
     99         }
    100         transaction.rollback();
    101         throw new EntityLocked();
    102       } finally {
    103         connection.release();
    104       }
    105     } catch (error) {
    106       throw mapError(error);
    107     }
    108   }
    109 }