From c84c4e92b75863e0df82d813fdaec6d9fe1b8947 Mon Sep 17 00:00:00 2001 From: Dorian Date: Fri, 13 Feb 2026 21:30:29 +0000 Subject: [PATCH] fix: widen rents.usd_amount column, add webhook alias, silence cron spam - Migration to ALTER rents.usd_amount from numeric(5,2) to numeric(15,2) which was causing "numeric field overflow" 500 errors when saving rental prices >= 1000 sats (e.g. 1200 sats) - Also widen season_rents.usd_amount for consistency - Add /webhooks/btcpay route alias (BTCPay was posting to /btcpay but the endpoint was /btcpay-webhook, causing 404s on payment callbacks) - Skip ECS autoscaling cron when TRANSCODING_API_URL is not set (eliminates "security token invalid" error spam every minute) - Reduce payment cron from EVERY_MINUTE to EVERY_10_MINUTES to avoid 429 rate limiting on the BTC price API - Bump API CACHEBUST to 10 Co-authored-by: Cursor --- .../1776300000000-widen-usd-amount-columns.ts | 34 +++++++++++++++++++ .../src/payment/services/payment.service.ts | 2 +- .../transcoding-server.service.ts | 4 ++- backend/src/webhooks/webhooks.controller.ts | 8 +++++ docker-compose.yml | 2 +- 5 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 backend/src/database/migrations/1776300000000-widen-usd-amount-columns.ts diff --git a/backend/src/database/migrations/1776300000000-widen-usd-amount-columns.ts b/backend/src/database/migrations/1776300000000-widen-usd-amount-columns.ts new file mode 100644 index 0000000..f0e074c --- /dev/null +++ b/backend/src/database/migrations/1776300000000-widen-usd-amount-columns.ts @@ -0,0 +1,34 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +/** + * Widen the usd_amount columns in rents and season_rents tables. + * + * The original migration (1711564180593) created rents.usd_amount as + * numeric(5,2), which caps at 999.99. Rental prices are stored in + * satoshis (e.g. 1200 sats) and easily exceed 999. The entity definition + * specifies precision 15, scale 2 — this migration aligns the database. + * + * season_rents.usd_amount (created in 1755016652731) has the same + * narrow precision and is updated here for consistency. + */ +export class WidenUsdAmountColumns1776300000000 implements MigrationInterface { + name = 'WidenUsdAmountColumns1776300000000'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "rents" ALTER COLUMN "usd_amount" TYPE numeric(15,2)`, + ); + await queryRunner.query( + `ALTER TABLE "season_rents" ALTER COLUMN "usd_amount" TYPE numeric(15,2)`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "rents" ALTER COLUMN "usd_amount" TYPE numeric(5,2)`, + ); + await queryRunner.query( + `ALTER TABLE "season_rents" ALTER COLUMN "usd_amount" TYPE numeric(5,2)`, + ); + } +} diff --git a/backend/src/payment/services/payment.service.ts b/backend/src/payment/services/payment.service.ts index cbd7cb3..a76e9e7 100644 --- a/backend/src/payment/services/payment.service.ts +++ b/backend/src/payment/services/payment.service.ts @@ -159,7 +159,7 @@ export class PaymentService { }; } - @Cron(CronExpression.EVERY_MINUTE) + @Cron(CronExpression.EVERY_10_MINUTES) async handlePaymentsCron() { await Promise.all([ this.handlePayment('watch'), diff --git a/backend/src/transcoding-server/transcoding-server.service.ts b/backend/src/transcoding-server/transcoding-server.service.ts index 4a6d57f..d6d05e3 100644 --- a/backend/src/transcoding-server/transcoding-server.service.ts +++ b/backend/src/transcoding-server/transcoding-server.service.ts @@ -102,10 +102,12 @@ export class TranscodingServerService { Logger.log(`Auto Scaling group scaled to ${desiredCount} instances`); } - // Run the autoscaling logic every hour + // Run the autoscaling logic every hour (AWS ECS only). + // Skip when using the local FFmpeg worker (no TRANSCODING_API_URL). @Cron(CronExpression.EVERY_MINUTE) async autoscaleEcsService() { if (process.env.ENVIRONMENT !== 'production') return; + if (!process.env.TRANSCODING_API_URL) return; try { const queueSize = await this.getQueueSize(); const currentTaskCount = await this.describeService( diff --git a/backend/src/webhooks/webhooks.controller.ts b/backend/src/webhooks/webhooks.controller.ts index 93dc0a2..49bb7df 100644 --- a/backend/src/webhooks/webhooks.controller.ts +++ b/backend/src/webhooks/webhooks.controller.ts @@ -13,6 +13,8 @@ import type { BTCPayWebhookEvent } from 'src/payment/providers/dto/btcpay/btcpay export class WebhooksController { constructor(private readonly webhooksService: WebhooksService) {} + // Accept both /webhooks/btcpay-webhook (original) and /webhooks/btcpay + // so the webhook works regardless of which URL is configured in BTCPay. @Post('btcpay-webhook') @UseGuards(BTCPayGuard) async btcpayPayment(@Body() body: BTCPayWebhookEvent) { @@ -22,4 +24,10 @@ export class WebhooksController { throw new BadRequestException(error.message); } } + + @Post('btcpay') + @UseGuards(BTCPayGuard) + async btcpayPaymentAlias(@Body() body: BTCPayWebhookEvent) { + return this.btcpayPayment(body); + } } diff --git a/docker-compose.yml b/docker-compose.yml index 2a5da8e..7561bd1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -47,7 +47,7 @@ services: context: ./backend dockerfile: Dockerfile args: - CACHEBUST: "9" + CACHEBUST: "10" restart: unless-stopped environment: # ── Core ─────────────────────────────────────────────