From 66cd74b039e6fab8c848a296047d1669b9c5a574 Mon Sep 17 00:00:00 2001 From: Iaroslav Gryshaiev Date: Fri, 7 Feb 2025 09:40:23 +0100 Subject: [PATCH] feat(deployment): creates setting if not exists on get refs #714 --- .../deployment-setting.controller.ts | 4 ++-- .../deployment-setting.router.ts | 2 +- .../deployment-setting.service.ts | 17 +++++++++++++-- .../functional/deployment-setting.spec.ts | 21 ++++++++++++------- apps/deploy-web/env/.env.production | 2 +- 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/apps/api/src/deployment/controllers/deployment-setting/deployment-setting.controller.ts b/apps/api/src/deployment/controllers/deployment-setting/deployment-setting.controller.ts index a0552993a..e5b78a3a6 100644 --- a/apps/api/src/deployment/controllers/deployment-setting/deployment-setting.controller.ts +++ b/apps/api/src/deployment/controllers/deployment-setting/deployment-setting.controller.ts @@ -15,8 +15,8 @@ export class DeploymentSettingController { constructor(private readonly deploymentSettingService: DeploymentSettingService) {} @Protected([{ action: "read", subject: "DeploymentSetting" }]) - async findByUserIdAndDseq(params: FindDeploymentSettingParams): Promise { - const setting = await this.deploymentSettingService.findByUserIdAndDseq(params); + async findOrCreateByUserIdAndDseq(params: FindDeploymentSettingParams): Promise { + const setting = await this.deploymentSettingService.findOrCreateByUserIdAndDseq(params); assert(setting, 404, "Deployment setting not found"); return { data: setting }; } diff --git a/apps/api/src/deployment/routes/deployment-setting/deployment-setting.router.ts b/apps/api/src/deployment/routes/deployment-setting/deployment-setting.router.ts index d531460f9..3e6185bc6 100644 --- a/apps/api/src/deployment/routes/deployment-setting/deployment-setting.router.ts +++ b/apps/api/src/deployment/routes/deployment-setting/deployment-setting.router.ts @@ -108,7 +108,7 @@ export const deploymentSettingRouter = new OpenApiHonoHandler(); deploymentSettingRouter.openapi(getRoute, async function routeGetDeploymentSettings(c) { const params = c.req.valid("param"); - const result = await container.resolve(DeploymentSettingController).findByUserIdAndDseq(params); + const result = await container.resolve(DeploymentSettingController).findOrCreateByUserIdAndDseq(params); return c.json(result, 200); }); diff --git a/apps/api/src/deployment/services/deployment-setting/deployment-setting.service.ts b/apps/api/src/deployment/services/deployment-setting/deployment-setting.service.ts index c832ce1da..9e41a576e 100644 --- a/apps/api/src/deployment/services/deployment-setting/deployment-setting.service.ts +++ b/apps/api/src/deployment/services/deployment-setting/deployment-setting.service.ts @@ -25,8 +25,21 @@ export class DeploymentSettingService { private readonly config: DeploymentConfigService ) {} - async findByUserIdAndDseq(params: FindDeploymentSettingParams): Promise { - return this.withEstimatedTopUpAmount(await this.deploymentSettingRepository.accessibleBy(this.authService.ability, "read").findOneBy(params)); + async findOrCreateByUserIdAndDseq(params: FindDeploymentSettingParams): Promise { + const setting = await this.deploymentSettingRepository.accessibleBy(this.authService.ability, "read").findOneBy(params); + + if (setting) { + return this.withEstimatedTopUpAmount(setting); + } + + try { + return await this.create(params); + } catch (error) { + if (error instanceof ForbiddenError) { + return undefined; + } + throw error; + } } async create(input: DeploymentSettingsInput): Promise { diff --git a/apps/api/test/functional/deployment-setting.spec.ts b/apps/api/test/functional/deployment-setting.spec.ts index e13f197fe..d4e8586af 100644 --- a/apps/api/test/functional/deployment-setting.spec.ts +++ b/apps/api/test/functional/deployment-setting.spec.ts @@ -32,21 +32,28 @@ describe("Deployment Settings", () => { expect(response.status).toBe(401); }); - it("should return 404 if deployment settings not found", async () => { - const { token } = await walletService.createUserAndWallet(); - const userId = faker.string.uuid(); + it("should return a new deployment setting if not found", async () => { + const { token, user } = await walletService.createUserAndWallet(); const dseq = faker.string.numeric(); - const response = await app.request(`/v1/deployment-settings/${userId}/${dseq}`, { + const response = await app.request(`/v1/deployment-settings/${user.id}/${dseq}`, { headers: { authorization: `Bearer ${token}` } }); - expect(response.status).toBe(404); + expect(response.status).toBe(200); expect(await response.json()).toEqual({ - error: "NotFoundError", - message: "Deployment setting not found" + data: { + id: expect.any(String), + userId: user.id, + dseq, + autoTopUpEnabled: false, + createdAt: expect.any(String), + updatedAt: expect.any(String), + estimatedTopUpAmount: expect.any(Number), + topUpFrequencyMs: expect.any(Number) + } }); }); diff --git a/apps/deploy-web/env/.env.production b/apps/deploy-web/env/.env.production index 4e5c114ba..45cf4f48e 100644 --- a/apps/deploy-web/env/.env.production +++ b/apps/deploy-web/env/.env.production @@ -6,7 +6,7 @@ NEXT_PUBLIC_TURNSTILE_SITE_KEY=0x4AAAAAAA5Stdp3_0Q5FClX NEXT_PUBLIC_DEFAULT_NETWORK_ID=mainnet NEXT_PUBLIC_BILLING_ENABLED=true -NEXT_PUBLIC_AUTO_TOP_UP_ENABLED=false +NEXT_PUBLIC_AUTO_TOP_UP_ENABLED=true NEXT_PUBLIC_MANAGED_WALLET_NETWORK_ID=mainnet NEXT_PUBLIC_MANAGED_WALLET_DENOM=usdc NEXT_PUBLIC_MASTER_WALLET_ADDRESS=akash1p4k0jer30g25mf62h5yc42agtjeumw4gxk8z37