Assist_Design/apps/bff/src/subscriptions/sim-usage-store.service.ts
tema bccc476283 Refactor SIM management and Freebit service for improved error handling and type safety
- Consolidated error handling in SimManagementService and FreebititService to provide clearer logging and user feedback.
- Enhanced type safety in FreebititService by refining type definitions for API requests and responses.
- Updated various components to ensure consistent error handling and improved user experience during SIM management actions.
2025-09-10 18:31:16 +09:00

82 lines
2.6 KiB
TypeScript

import { Injectable, Inject } from "@nestjs/common";
import { PrismaService } from "../common/prisma/prisma.service";
import { Logger } from "nestjs-pino";
@Injectable()
export class SimUsageStoreService {
constructor(
private readonly prisma: PrismaService,
@Inject(Logger) private readonly logger: Logger
) {}
private get store(): {
upsert: (args: unknown) => Promise<unknown>;
findMany: (args: unknown) => Promise<unknown>;
deleteMany: (args: unknown) => Promise<unknown>;
} | null {
const s = (
this.prisma as {
simUsageDaily?: {
upsert: (args: unknown) => Promise<unknown>;
findMany: (args: unknown) => Promise<unknown>;
deleteMany: (args: unknown) => Promise<unknown>;
};
}
)?.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
const iso = d.toISOString().split("T")[0];
return new Date(iso + "T00:00:00.000Z");
}
async upsertToday(account: string, usageMb: number, date?: Date): Promise<void> {
const day = this.normalizeDate(date);
try {
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 },
});
} catch (e: unknown) {
const message = e instanceof Error ? e.message : String(e);
this.logger.error("Failed to upsert daily usage", { account, error: message });
}
}
async getLastNDays(
account: string,
days = 30
): Promise<Array<{ date: string; usageMb: number }>> {
const end = this.normalizeDate();
const start = new Date(end);
start.setUTCDate(end.getUTCDate() - (days - 1));
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 }>;
return rows.map(r => ({ date: r.date.toISOString().split("T")[0], usageMb: r.usageMb }));
}
async cleanupPreviousMonths(): Promise<number> {
const now = new Date();
const firstOfMonth = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1));
const store = this.store;
if (!store) return 0;
const result = (await store.deleteMany({
where: { date: { lt: firstOfMonth } },
})) as { count: number };
return result.count;
}
}