diff --git a/apps/bff/src/subscriptions/sim-management.service.ts b/apps/bff/src/subscriptions/sim-management.service.ts index 0a961b1b..8a69ab6c 100644 --- a/apps/bff/src/subscriptions/sim-management.service.ts +++ b/apps/bff/src/subscriptions/sim-management.service.ts @@ -580,15 +580,18 @@ export class SimManagementService { throw new BadRequestException("Invalid plan code"); } - // TESTING: schedule for immediate execution (today) - const now = new Date(); + // Automatically set to 1st of next month + const nextMonth = new Date(); + nextMonth.setMonth(nextMonth.getMonth() + 1); + nextMonth.setDate(1); // Set to 1st of the month + // Format as YYYYMMDD for Freebit API - const year = now.getFullYear(); - const month = String(now.getMonth() + 1).padStart(2, "0"); - const day = String(now.getDate()).padStart(2, "0"); + const year = nextMonth.getFullYear(); + const month = String(nextMonth.getMonth() + 1).padStart(2, "0"); + const day = String(nextMonth.getDate()).padStart(2, "0"); const scheduledAt = `${year}${month}${day}`; - this.logger.log(`Scheduled plan change for testing (immediate): ${scheduledAt}`, { + this.logger.log(`Auto-scheduled plan change to 1st of next month: ${scheduledAt}`, { userId, subscriptionId, account, diff --git a/apps/bff/src/subscriptions/sim-usage-store.service.ts b/apps/bff/src/subscriptions/sim-usage-store.service.ts index 1487dc0d..a9ca410e 100644 --- a/apps/bff/src/subscriptions/sim-usage-store.service.ts +++ b/apps/bff/src/subscriptions/sim-usage-store.service.ts @@ -9,6 +9,11 @@ export class SimUsageStoreService { @Inject(Logger) private readonly logger: Logger ) {} + private get store(): any | null { + const s = (this.prisma as any)?.simUsageDaily; + return s && typeof s === 'object' ? s : null; + } + private normalizeDate(date?: Date): Date { const d = date ? new Date(date) : new Date(); // strip time to YYYY-MM-DD @@ -19,7 +24,12 @@ export class SimUsageStoreService { async upsertToday(account: string, usageMb: number, date?: Date): Promise { const day = this.normalizeDate(date); try { - await (this.prisma as any).simUsageDaily.upsert({ + const store = this.store; + if (!store) { + this.logger.debug('SIM usage store not configured; skipping persist'); + return; + } + await store.upsert({ where: { account_date: { account, date: day } }, update: { usageMb }, create: { account, date: day, usageMb }, @@ -37,7 +47,9 @@ export class SimUsageStoreService { const end = this.normalizeDate(); const start = new Date(end); start.setUTCDate(end.getUTCDate() - (days - 1)); - const rows = (await (this.prisma as any).simUsageDaily.findMany({ + const store = this.store; + if (!store) return []; + const rows = (await store.findMany({ where: { account, date: { gte: start, lte: end } }, orderBy: { date: "desc" }, })) as Array<{ date: Date; usageMb: number }>; @@ -47,7 +59,9 @@ export class SimUsageStoreService { async cleanupPreviousMonths(): Promise { const now = new Date(); const firstOfMonth = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1)); - const result = (await (this.prisma as any).simUsageDaily.deleteMany({ + const store = this.store; + if (!store) return 0; + const result = (await store.deleteMany({ where: { date: { lt: firstOfMonth } }, })) as { count: number }; return result.count; diff --git a/scripts/dev/manage.sh b/scripts/dev/manage.sh index 4002d97b..bde9eaa1 100755 --- a/scripts/dev/manage.sh +++ b/scripts/dev/manage.sh @@ -215,20 +215,31 @@ start_services() { local next="${NEXT_PORT:-$NEXT_PORT_DEFAULT}" local bff="${BFF_PORT:-$BFF_PORT_DEFAULT}" - # Auto-pick free ports if occupied - local next_free - next_free="$(find_free_port "$next")" - if [ "$next_free" != "$next" ]; then - warn "Port $next in use; assigning NEXT_PORT=$next_free" - export NEXT_PORT="$next_free" - next="$next_free" + # Ensure desired ports are free; kill any listeners + kill_by_port "$next" + kill_by_port "$bff" + # If still busy, either auto-shift (if allowed) or fail + if ! is_port_free "$next"; then + if [ "${ALLOW_PORT_SHIFT:-0}" = "1" ]; then + local next_free + next_free="$(find_free_port "$next")" + warn "Port $next in use; assigning NEXT_PORT=$next_free" + export NEXT_PORT="$next_free" + next="$next_free" + else + fail "Port $next is in use. Stop the process or run '$0 cleanup'. Set ALLOW_PORT_SHIFT=1 to auto-assign another port." + fi fi - local bff_free - bff_free="$(find_free_port "$bff")" - if [ "$bff_free" != "$bff" ]; then - warn "Port $bff in use; assigning BFF_PORT=$bff_free" - export BFF_PORT="$bff_free" - bff="$bff_free" + if ! is_port_free "$bff"; then + if [ "${ALLOW_PORT_SHIFT:-0}" = "1" ]; then + local bff_free + bff_free="$(find_free_port "$bff")" + warn "Port $bff in use; assigning BFF_PORT=$bff_free" + export BFF_PORT="$bff_free" + bff="$bff_free" + else + fail "Port $bff is in use. Stop the process or run '$0 cleanup'. Set ALLOW_PORT_SHIFT=1 to auto-assign another port." + fi fi log "✅ Development services are running!" log "🔗 Database: postgresql://${POSTGRES_USER:-$DB_USER_DEFAULT}:${POSTGRES_PASSWORD:-${POSTGRES_PASSWORD:-dev}}@localhost:5432/${POSTGRES_DB:-$DB_NAME_DEFAULT}"