Refactor SIM management and usage services for improved functionality and type safety
- Updated SimManagementService to schedule plan changes for immediate execution during testing. - Enhanced type safety in SimUsageStoreService by removing unsafe type assertions and improving method calls. - Improved error handling in FreebititService by ensuring proper type handling for plan codes and sizes. - Added functionality in manage.sh to automatically find and assign free ports for development services.
This commit is contained in:
parent
f21db44611
commit
6e27d8a21e
@ -580,18 +580,15 @@ export class SimManagementService {
|
|||||||
throw new BadRequestException("Invalid plan code");
|
throw new BadRequestException("Invalid plan code");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Automatically set to 1st of next month
|
// TESTING: schedule for immediate execution (today)
|
||||||
const nextMonth = new Date();
|
const now = new Date();
|
||||||
nextMonth.setMonth(nextMonth.getMonth() + 1);
|
|
||||||
nextMonth.setDate(1); // Set to 1st of the month
|
|
||||||
|
|
||||||
// Format as YYYYMMDD for Freebit API
|
// Format as YYYYMMDD for Freebit API
|
||||||
const year = nextMonth.getFullYear();
|
const year = now.getFullYear();
|
||||||
const month = String(nextMonth.getMonth() + 1).padStart(2, "0");
|
const month = String(now.getMonth() + 1).padStart(2, "0");
|
||||||
const day = String(nextMonth.getDate()).padStart(2, "0");
|
const day = String(now.getDate()).padStart(2, "0");
|
||||||
const scheduledAt = `${year}${month}${day}`;
|
const scheduledAt = `${year}${month}${day}`;
|
||||||
|
|
||||||
this.logger.log(`Auto-scheduled plan change to 1st of next month: ${scheduledAt}`, {
|
this.logger.log(`Scheduled plan change for testing (immediate): ${scheduledAt}`, {
|
||||||
userId,
|
userId,
|
||||||
subscriptionId,
|
subscriptionId,
|
||||||
account,
|
account,
|
||||||
|
|||||||
@ -19,10 +19,8 @@ export class SimUsageStoreService {
|
|||||||
async upsertToday(account: string, usageMb: number, date?: Date): Promise<void> {
|
async upsertToday(account: string, usageMb: number, date?: Date): Promise<void> {
|
||||||
const day = this.normalizeDate(date);
|
const day = this.normalizeDate(date);
|
||||||
try {
|
try {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
await (this.prisma as any).simUsageDaily.upsert({
|
||||||
await this.prisma.simUsageDaily.upsert({
|
where: { account_date: { account, date: day } },
|
||||||
// @ts-expect-error composite unique input type depends on Prisma schema
|
|
||||||
where: { account_date: { account, date: day } as unknown },
|
|
||||||
update: { usageMb },
|
update: { usageMb },
|
||||||
create: { account, date: day, usageMb },
|
create: { account, date: day, usageMb },
|
||||||
});
|
});
|
||||||
@ -39,8 +37,7 @@ export class SimUsageStoreService {
|
|||||||
const end = this.normalizeDate();
|
const end = this.normalizeDate();
|
||||||
const start = new Date(end);
|
const start = new Date(end);
|
||||||
start.setUTCDate(end.getUTCDate() - (days - 1));
|
start.setUTCDate(end.getUTCDate() - (days - 1));
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
const rows = (await (this.prisma as any).simUsageDaily.findMany({
|
||||||
const rows = (await this.prisma.simUsageDaily.findMany({
|
|
||||||
where: { account, date: { gte: start, lte: end } },
|
where: { account, date: { gte: start, lte: end } },
|
||||||
orderBy: { date: "desc" },
|
orderBy: { date: "desc" },
|
||||||
})) as Array<{ date: Date; usageMb: number }>;
|
})) as Array<{ date: Date; usageMb: number }>;
|
||||||
@ -50,10 +47,9 @@ export class SimUsageStoreService {
|
|||||||
async cleanupPreviousMonths(): Promise<number> {
|
async cleanupPreviousMonths(): Promise<number> {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const firstOfMonth = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1));
|
const firstOfMonth = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1));
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
const result = (await (this.prisma as any).simUsageDaily.deleteMany({
|
||||||
const result = (await this.prisma.simUsageDaily.deleteMany({
|
|
||||||
where: { date: { lt: firstOfMonth } },
|
where: { date: { lt: firstOfMonth } },
|
||||||
})) as unknown as { count: number };
|
})) as { count: number };
|
||||||
return result.count;
|
return result.count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
apps/bff/src/vendors/freebit/freebit.service.ts
vendored
10
apps/bff/src/vendors/freebit/freebit.service.ts
vendored
@ -344,10 +344,16 @@ export class FreebititService {
|
|||||||
iccid: simData.iccid ? String(simData.iccid) : undefined,
|
iccid: simData.iccid ? String(simData.iccid) : undefined,
|
||||||
imsi: simData.imsi ? String(simData.imsi) : undefined,
|
imsi: simData.imsi ? String(simData.imsi) : undefined,
|
||||||
eid: simData.eid,
|
eid: simData.eid,
|
||||||
planCode: simData.planCode,
|
planCode: String(simData.planCode ?? ""),
|
||||||
status: this.mapSimStatus(String(simData.state || "pending")),
|
status: this.mapSimStatus(String(simData.state || "pending")),
|
||||||
simType: simData.eid ? "esim" : "physical",
|
simType: simData.eid ? "esim" : "physical",
|
||||||
size: simData.size,
|
size: ((): "standard" | "nano" | "micro" | "esim" => {
|
||||||
|
const sizeVal = String(simData.size ?? "").toLowerCase();
|
||||||
|
if (sizeVal === "standard" || sizeVal === "nano" || sizeVal === "micro" || sizeVal === "esim") {
|
||||||
|
return sizeVal as "standard" | "nano" | "micro" | "esim";
|
||||||
|
}
|
||||||
|
return simData.eid ? "esim" : "nano";
|
||||||
|
})(),
|
||||||
hasVoice: simData.talk === 10,
|
hasVoice: simData.talk === 10,
|
||||||
hasSms: simData.sms === 10,
|
hasSms: simData.sms === 10,
|
||||||
remainingQuotaKb: typeof simData.quota === "number" ? simData.quota : 0,
|
remainingQuotaKb: typeof simData.quota === "number" ? simData.quota : 0,
|
||||||
|
|||||||
@ -175,6 +175,30 @@ kill_by_port() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check if a port is free using Node (portable)
|
||||||
|
is_port_free() {
|
||||||
|
local port="$1"
|
||||||
|
if ! command -v node >/dev/null 2>&1; then
|
||||||
|
return 0 # assume free if node unavailable
|
||||||
|
fi
|
||||||
|
node -e "const net=require('net');const p=parseInt(process.argv[1],10);const s=net.createServer();s.once('error',()=>process.exit(1));s.once('listening',()=>s.close(()=>process.exit(0)));s.listen({port:p,host:'127.0.0.1'});" "$port"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Find a free port starting from base, up to +50
|
||||||
|
find_free_port() {
|
||||||
|
local base="$1"
|
||||||
|
local limit=$((base+50))
|
||||||
|
local p="$base"
|
||||||
|
while [ "$p" -le "$limit" ]; do
|
||||||
|
if is_port_free "$p"; then
|
||||||
|
echo "$p"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
p=$((p+1))
|
||||||
|
done
|
||||||
|
echo "$base"
|
||||||
|
}
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Commands
|
# Commands
|
||||||
########################################
|
########################################
|
||||||
@ -191,6 +215,21 @@ start_services() {
|
|||||||
|
|
||||||
local next="${NEXT_PORT:-$NEXT_PORT_DEFAULT}"
|
local next="${NEXT_PORT:-$NEXT_PORT_DEFAULT}"
|
||||||
local bff="${BFF_PORT:-$BFF_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"
|
||||||
|
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"
|
||||||
|
fi
|
||||||
log "✅ Development services are running!"
|
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}"
|
log "🔗 Database: postgresql://${POSTGRES_USER:-$DB_USER_DEFAULT}:${POSTGRES_PASSWORD:-${POSTGRES_PASSWORD:-dev}}@localhost:5432/${POSTGRES_DB:-$DB_NAME_DEFAULT}"
|
||||||
log "🔗 Redis: redis://localhost:6379"
|
log "🔗 Redis: redis://localhost:6379"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user