fix(reporting-service): use findFirst + update instead of upsert for realtimeStats
Replace upsert with findFirst + create/update pattern to avoid Prisma unique constraint syntax issues. The @@unique constraint with a custom name doesn't allow direct field-based queries in findUnique/upsert. This approach maintains the same behavior without schema changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
2d9d6ceed7
commit
4e201d3a66
|
|
@ -15,8 +15,8 @@ export class RealtimeStatsRepository implements IRealtimeStatsRepository {
|
||||||
async getOrCreateByDate(date: Date): Promise<RealtimeStatsData> {
|
async getOrCreateByDate(date: Date): Promise<RealtimeStatsData> {
|
||||||
const statsDate = this.normalizeDate(date);
|
const statsDate = this.normalizeDate(date);
|
||||||
|
|
||||||
const existing = await this.prisma.realtimeStats.findUnique({
|
const existing = await this.prisma.realtimeStats.findFirst({
|
||||||
where: { uk_realtime_stats_date: { statsDate } },
|
where: { statsDate },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (existing) {
|
if (existing) {
|
||||||
|
|
@ -33,8 +33,8 @@ export class RealtimeStatsRepository implements IRealtimeStatsRepository {
|
||||||
async findByDate(date: Date): Promise<RealtimeStatsData | null> {
|
async findByDate(date: Date): Promise<RealtimeStatsData | null> {
|
||||||
const statsDate = this.normalizeDate(date);
|
const statsDate = this.normalizeDate(date);
|
||||||
|
|
||||||
const found = await this.prisma.realtimeStats.findUnique({
|
const found = await this.prisma.realtimeStats.findFirst({
|
||||||
where: { uk_realtime_stats_date: { statsDate } },
|
where: { statsDate },
|
||||||
});
|
});
|
||||||
|
|
||||||
return found ? this.toDomain(found) : null;
|
return found ? this.toDomain(found) : null;
|
||||||
|
|
@ -54,57 +54,85 @@ export class RealtimeStatsRepository implements IRealtimeStatsRepository {
|
||||||
`Incrementing planting: date=${statsDate.toISOString()}, trees=${safeTreeCount}, amount=${safeAmount}`,
|
`Incrementing planting: date=${statsDate.toISOString()}, trees=${safeTreeCount}, amount=${safeAmount}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
const result = await this.prisma.realtimeStats.upsert({
|
// 使用 findFirst + create/update 替代 upsert,避免 Prisma 唯一约束语法问题
|
||||||
where: { uk_realtime_stats_date: { statsDate } },
|
const existing = await this.prisma.realtimeStats.findFirst({
|
||||||
create: {
|
where: { statsDate },
|
||||||
statsDate,
|
|
||||||
dailyPlantingCount: safeTreeCount,
|
|
||||||
dailyOrderCount: 1,
|
|
||||||
dailyPlantingAmount: safeAmount,
|
|
||||||
},
|
|
||||||
update: {
|
|
||||||
dailyPlantingCount: { increment: safeTreeCount },
|
|
||||||
dailyOrderCount: { increment: 1 },
|
|
||||||
dailyPlantingAmount: { increment: safeAmount },
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.toDomain(result);
|
if (existing) {
|
||||||
|
const result = await this.prisma.realtimeStats.update({
|
||||||
|
where: { id: existing.id },
|
||||||
|
data: {
|
||||||
|
dailyPlantingCount: { increment: safeTreeCount },
|
||||||
|
dailyOrderCount: { increment: 1 },
|
||||||
|
dailyPlantingAmount: { increment: safeAmount },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return this.toDomain(result);
|
||||||
|
} else {
|
||||||
|
const result = await this.prisma.realtimeStats.create({
|
||||||
|
data: {
|
||||||
|
statsDate,
|
||||||
|
dailyPlantingCount: safeTreeCount,
|
||||||
|
dailyOrderCount: 1,
|
||||||
|
dailyPlantingAmount: safeAmount,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return this.toDomain(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async incrementOrder(date: Date): Promise<RealtimeStatsData> {
|
async incrementOrder(date: Date): Promise<RealtimeStatsData> {
|
||||||
const statsDate = this.normalizeDate(date);
|
const statsDate = this.normalizeDate(date);
|
||||||
|
|
||||||
const result = await this.prisma.realtimeStats.upsert({
|
const existing = await this.prisma.realtimeStats.findFirst({
|
||||||
where: { uk_realtime_stats_date: { statsDate } },
|
where: { statsDate },
|
||||||
create: {
|
|
||||||
statsDate,
|
|
||||||
dailyOrderCount: 1,
|
|
||||||
},
|
|
||||||
update: {
|
|
||||||
dailyOrderCount: { increment: 1 },
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.toDomain(result);
|
if (existing) {
|
||||||
|
const result = await this.prisma.realtimeStats.update({
|
||||||
|
where: { id: existing.id },
|
||||||
|
data: {
|
||||||
|
dailyOrderCount: { increment: 1 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return this.toDomain(result);
|
||||||
|
} else {
|
||||||
|
const result = await this.prisma.realtimeStats.create({
|
||||||
|
data: {
|
||||||
|
statsDate,
|
||||||
|
dailyOrderCount: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return this.toDomain(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async incrementNewUser(date: Date): Promise<RealtimeStatsData> {
|
async incrementNewUser(date: Date): Promise<RealtimeStatsData> {
|
||||||
const statsDate = this.normalizeDate(date);
|
const statsDate = this.normalizeDate(date);
|
||||||
this.logger.debug(`Incrementing new user: date=${statsDate.toISOString()}`);
|
this.logger.debug(`Incrementing new user: date=${statsDate.toISOString()}`);
|
||||||
|
|
||||||
const result = await this.prisma.realtimeStats.upsert({
|
const existing = await this.prisma.realtimeStats.findFirst({
|
||||||
where: { uk_realtime_stats_date: { statsDate } },
|
where: { statsDate },
|
||||||
create: {
|
|
||||||
statsDate,
|
|
||||||
dailyNewUserCount: 1,
|
|
||||||
},
|
|
||||||
update: {
|
|
||||||
dailyNewUserCount: { increment: 1 },
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.toDomain(result);
|
if (existing) {
|
||||||
|
const result = await this.prisma.realtimeStats.update({
|
||||||
|
where: { id: existing.id },
|
||||||
|
data: {
|
||||||
|
dailyNewUserCount: { increment: 1 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return this.toDomain(result);
|
||||||
|
} else {
|
||||||
|
const result = await this.prisma.realtimeStats.create({
|
||||||
|
data: {
|
||||||
|
statsDate,
|
||||||
|
dailyNewUserCount: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return this.toDomain(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async incrementProvinceAuth(date: Date): Promise<RealtimeStatsData> {
|
async incrementProvinceAuth(date: Date): Promise<RealtimeStatsData> {
|
||||||
|
|
@ -113,36 +141,54 @@ export class RealtimeStatsRepository implements IRealtimeStatsRepository {
|
||||||
`Incrementing province auth: date=${statsDate.toISOString()}`,
|
`Incrementing province auth: date=${statsDate.toISOString()}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
const result = await this.prisma.realtimeStats.upsert({
|
const existing = await this.prisma.realtimeStats.findFirst({
|
||||||
where: { uk_realtime_stats_date: { statsDate } },
|
where: { statsDate },
|
||||||
create: {
|
|
||||||
statsDate,
|
|
||||||
dailyProvinceAuthCount: 1,
|
|
||||||
},
|
|
||||||
update: {
|
|
||||||
dailyProvinceAuthCount: { increment: 1 },
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.toDomain(result);
|
if (existing) {
|
||||||
|
const result = await this.prisma.realtimeStats.update({
|
||||||
|
where: { id: existing.id },
|
||||||
|
data: {
|
||||||
|
dailyProvinceAuthCount: { increment: 1 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return this.toDomain(result);
|
||||||
|
} else {
|
||||||
|
const result = await this.prisma.realtimeStats.create({
|
||||||
|
data: {
|
||||||
|
statsDate,
|
||||||
|
dailyProvinceAuthCount: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return this.toDomain(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async incrementCityAuth(date: Date): Promise<RealtimeStatsData> {
|
async incrementCityAuth(date: Date): Promise<RealtimeStatsData> {
|
||||||
const statsDate = this.normalizeDate(date);
|
const statsDate = this.normalizeDate(date);
|
||||||
this.logger.debug(`Incrementing city auth: date=${statsDate.toISOString()}`);
|
this.logger.debug(`Incrementing city auth: date=${statsDate.toISOString()}`);
|
||||||
|
|
||||||
const result = await this.prisma.realtimeStats.upsert({
|
const existing = await this.prisma.realtimeStats.findFirst({
|
||||||
where: { uk_realtime_stats_date: { statsDate } },
|
where: { statsDate },
|
||||||
create: {
|
|
||||||
statsDate,
|
|
||||||
dailyCityAuthCount: 1,
|
|
||||||
},
|
|
||||||
update: {
|
|
||||||
dailyCityAuthCount: { increment: 1 },
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.toDomain(result);
|
if (existing) {
|
||||||
|
const result = await this.prisma.realtimeStats.update({
|
||||||
|
where: { id: existing.id },
|
||||||
|
data: {
|
||||||
|
dailyCityAuthCount: { increment: 1 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return this.toDomain(result);
|
||||||
|
} else {
|
||||||
|
const result = await this.prisma.realtimeStats.create({
|
||||||
|
data: {
|
||||||
|
statsDate,
|
||||||
|
dailyCityAuthCount: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return this.toDomain(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async findRecentDays(days: number): Promise<RealtimeStatsData[]> {
|
async findRecentDays(days: number): Promise<RealtimeStatsData[]> {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue