From 037fd3a1ca3c450b503917591b272b2bd9705520 Mon Sep 17 00:00:00 2001 From: "Akinsuyi Philip." <91294691+Akinsuyiphilip@users.noreply.github.com> Date: Sun, 30 Aug 2026 02:34:25 +0000 Subject: [PATCH 1/2] Add price snapshot write coverage for unchanged prices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with Codebuff Co-Authored-By: Codebuff --- .../price-snapshot-debug-log.unit.test.ts | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/modules/indexer/price-snapshot-debug-log.unit.test.ts b/src/modules/indexer/price-snapshot-debug-log.unit.test.ts index c5ee457..def9dfe 100644 --- a/src/modules/indexer/price-snapshot-debug-log.unit.test.ts +++ b/src/modules/indexer/price-snapshot-debug-log.unit.test.ts @@ -16,6 +16,9 @@ jest.mock('../../utils/prisma.utils', () => ({ create: jest.fn(), update: jest.fn(), }, + creatorPriceHistory: { + create: jest.fn(), + }, }, })); @@ -34,6 +37,9 @@ const mockPrisma = prisma as unknown as { create: jest.Mock; update: jest.Mock; }; + creatorPriceHistory: { + create: jest.Mock; + }; }; const mockLogger = logger as unknown as { @@ -89,6 +95,67 @@ describe('#636 price snapshot write debug log', () => { expect(fields.previous_price).toBeNull(); }); + it('skips snapshot and history writes when the price is unchanged', async () => { + mockPrisma.creatorPriceSnapshot.findUnique.mockResolvedValue({ + creatorId: CREATOR_ID, + currentPrice: BigInt(1_000_000), + price24hAgo: BigInt(900_000), + lastTradeAt: new Date('2026-01-01T00:00:00Z'), + }); + + await upsertPriceSnapshot({ + creatorId: CREATOR_ID, + price: BigInt(1_000_000), + tradeAt: new Date('2026-01-02T00:00:00Z'), + }); + + expect(mockPrisma.creatorPriceSnapshot.update).not.toHaveBeenCalled(); + expect(mockPrisma.creatorPriceHistory.create).not.toHaveBeenCalled(); + }); + + it('writes a new snapshot and history record when the price changes', async () => { + mockPrisma.creatorPriceSnapshot.findUnique.mockResolvedValue({ + creatorId: CREATOR_ID, + currentPrice: BigInt(1_000_000), + price24hAgo: BigInt(900_000), + lastTradeAt: new Date('2026-01-01T00:00:00Z'), + }); + mockPrisma.creatorPriceSnapshot.update.mockResolvedValue({}); + mockPrisma.creatorPriceHistory.create.mockResolvedValue({}); + + const tradeAt = new Date('2026-01-02T00:00:00Z'); + await upsertPriceSnapshot({ + creatorId: CREATOR_ID, + price: BigInt(1_100_000), + tradeAt, + }); + + expect(mockPrisma.creatorPriceSnapshot.update).toHaveBeenCalledTimes(1); + expect(mockPrisma.creatorPriceHistory.create).toHaveBeenCalledTimes(1); + expect(mockPrisma.creatorPriceHistory.create).toHaveBeenCalledWith({ + data: { + creatorId: CREATOR_ID, + price: BigInt(1_100_000), + recordedAt: tradeAt, + }, + }); + }); + + it('writes the first snapshot when no previous snapshot exists', async () => { + mockPrisma.creatorPriceSnapshot.findUnique.mockResolvedValue(null); + mockPrisma.creatorPriceSnapshot.create.mockResolvedValue({}); + mockPrisma.creatorPriceHistory.create.mockResolvedValue({}); + + await upsertPriceSnapshot({ + creatorId: CREATOR_ID, + price: BigInt(1_000_000), + tradeAt: new Date('2026-01-01T00:00:00Z'), + }); + + expect(mockPrisma.creatorPriceSnapshot.create).toHaveBeenCalledTimes(1); + expect(mockPrisma.creatorPriceHistory.create).toHaveBeenCalledTimes(1); + }); + it('emits a debug log with the previous price on a subsequent (update) write', async () => { mockPrisma.creatorPriceSnapshot.findUnique.mockResolvedValue({ creatorId: CREATOR_ID, From 96a5c375951d954c88e516eb28c7672485f3f166 Mon Sep 17 00:00:00 2001 From: "Akinsuyi Philip." <91294691+Akinsuyiphilip@users.noreply.github.com> Date: Sun, 30 Aug 2026 02:54:27 +0000 Subject: [PATCH 2/2] Resolve remaining TypeScript validation errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with Codebuff Co-Authored-By: Codebuff --- src/config.schema.ts | 2 -- src/constants/error.constants.ts | 1 + src/modules/creator/creator.routes.ts | 5 +++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/config.schema.ts b/src/config.schema.ts index d474eb3..df8cc9d 100644 --- a/src/config.schema.ts +++ b/src/config.schema.ts @@ -269,8 +269,6 @@ export const envSchema = z .positive() .default(1000), - // Stellar auth challenge signing secret - STELLAR_AUTH_SECRET: optionalNonEmptyString, }) .superRefine((data, ctx) => { if (data.MODE === 'production' && data.STELLAR_NETWORK === 'testnet') { diff --git a/src/constants/error.constants.ts b/src/constants/error.constants.ts index c207198..bfee94f 100644 --- a/src/constants/error.constants.ts +++ b/src/constants/error.constants.ts @@ -4,6 +4,7 @@ */ export const ErrorCode = { VALIDATION_ERROR: 'VALIDATION_ERROR', + UNPROCESSABLE_ENTITY: 'UNPROCESSABLE_ENTITY', NOT_FOUND: 'NOT_FOUND', UNAUTHORIZED: 'UNAUTHORIZED', FORBIDDEN: 'FORBIDDEN', diff --git a/src/modules/creator/creator.routes.ts b/src/modules/creator/creator.routes.ts index dc290fa..ca419d9 100644 --- a/src/modules/creator/creator.routes.ts +++ b/src/modules/creator/creator.routes.ts @@ -74,9 +74,10 @@ creatorsRouter.post( 'capBps must be between 100 and 2500' ); return; - } + } const keyId = Array.isArray(req.params.keyId) + ? req.params.keyId[0] + : req.params.keyId; - const keyId = req.params.keyId; try { const creatorProfile = await prisma.creatorProfile.findFirst({ where: { OR: [{ id: keyId }, { handle: keyId }] },