feat: bootstrap NestJS backend with auth, stations, users, health-check, now-playing

This commit is contained in:
nk
2026-06-02 13:54:00 +03:00
commit 8aadd62e3c
47 changed files with 13234 additions and 0 deletions

104
src/users/users.service.ts Normal file
View File

@@ -0,0 +1,104 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { UpdateSettingsDto } from './dto/update-settings.dto';
@Injectable()
export class UsersService {
constructor(private readonly prisma: PrismaService) {}
async findById(id: string) {
const user = await this.prisma.user.findUnique({
where: { id },
include: { settings: true },
});
if (!user) throw new NotFoundException('User not found');
return user;
}
async getSettings(userId: string) {
const settings = await this.prisma.userSettings.findUnique({
where: { userId },
});
if (!settings) {
return this.prisma.userSettings.create({
data: { userId },
});
}
return settings;
}
async updateSettings(userId: string, dto: UpdateSettingsDto) {
await this.findById(userId);
return this.prisma.userSettings.upsert({
where: { userId },
create: {
userId,
theme: dto.theme,
language: dto.language,
autoPlay: dto.autoPlay,
showOffline: dto.showOffline,
sleepTimerMinutes: dto.sleepTimerMinutes,
},
update: {
theme: dto.theme,
language: dto.language,
autoPlay: dto.autoPlay,
showOffline: dto.showOffline,
sleepTimerMinutes: dto.sleepTimerMinutes,
},
});
}
async getFavorites(userId: string) {
const favorites = await this.prisma.userFavorite.findMany({
where: { userId },
include: { station: { include: { nowPlaying: true } } },
orderBy: { createdAt: 'desc' },
});
return favorites.map((f) => f.station);
}
async addFavorite(userId: string, stationId: string) {
return this.prisma.userFavorite.create({
data: { userId, stationId },
});
}
async removeFavorite(userId: string, stationId: string) {
const favorite = await this.prisma.userFavorite.findUnique({
where: { userId_stationId: { userId, stationId } },
});
if (!favorite) throw new NotFoundException('Favorite not found');
await this.prisma.userFavorite.delete({
where: { id: favorite.id },
});
}
async getHistory(
userId: string,
pagination: { limit: number; offset: number },
) {
const [items, total] = await Promise.all([
this.prisma.playHistory.findMany({
where: { userId },
include: { station: { include: { nowPlaying: true } } },
orderBy: { playedAt: 'desc' },
skip: pagination.offset,
take: pagination.limit,
}),
this.prisma.playHistory.count({ where: { userId } }),
]);
return {
items: items.map((h) => h.station),
total,
limit: pagination.limit,
offset: pagination.offset,
};
}
async addHistory(userId: string, stationId: string) {
return this.prisma.playHistory.create({
data: { userId, stationId },
});
}
}