init: scaffold complet Sakuin — backend NestJS + frontend SvelteKit + CI/CD + deploy VPS
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 29s
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 29s
Backend: 5 modules (auth, user, work, list, health), AniList GraphQL proxy, SuperOAuth PKCE introspection, XP system, migrations TypeORM. Frontend: SvelteKit adapter-node, PWA manifest, dark theme, pages home/search/list/profile/callback. Infra: CI/CD Gitea vps-runner, Apache vhost SSL, pm2 sakuin-backend + sakuin-frontend, port 4002. License: BSL 1.1 (Apache 2.0 en 2028).
This commit is contained in:
105
backend/src/list/list.controller.ts
Normal file
105
backend/src/list/list.controller.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
Req,
|
||||
UseGuards,
|
||||
ParseIntPipe,
|
||||
} from '@nestjs/common';
|
||||
import { ListService } from './list.service';
|
||||
import { ListStatus } from './user-work.entity';
|
||||
import { AuthGuard } from '../auth/auth.guard';
|
||||
import { UserService } from '../user/user.service';
|
||||
|
||||
@Controller('api/list')
|
||||
@UseGuards(AuthGuard)
|
||||
export class ListController {
|
||||
constructor(
|
||||
private readonly listService: ListService,
|
||||
private readonly userService: UserService,
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
async getList(@Req() req: any, @Query('status') status?: ListStatus) {
|
||||
const user = await this.userService.findOrCreate({
|
||||
id: req.user.id,
|
||||
nickname: req.user.nickname,
|
||||
avatar: req.user.avatar,
|
||||
});
|
||||
return this.listService.getUserList(user.id, status);
|
||||
}
|
||||
|
||||
@Post()
|
||||
async addToList(
|
||||
@Req() req: any,
|
||||
@Body() body: { anilistId: number; status: ListStatus },
|
||||
) {
|
||||
const user = await this.userService.findOrCreate({
|
||||
id: req.user.id,
|
||||
nickname: req.user.nickname,
|
||||
avatar: req.user.avatar,
|
||||
});
|
||||
return this.listService.addToList(user.id, body.anilistId, body.status);
|
||||
}
|
||||
|
||||
@Put(':id/progress')
|
||||
async updateProgress(
|
||||
@Req() req: any,
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
@Body() body: { progress: number },
|
||||
) {
|
||||
const user = await this.userService.findOrCreate({
|
||||
id: req.user.id,
|
||||
nickname: req.user.nickname,
|
||||
avatar: req.user.avatar,
|
||||
});
|
||||
return this.listService.updateProgress(user.id, id, body.progress);
|
||||
}
|
||||
|
||||
@Put(':id/status')
|
||||
async updateStatus(
|
||||
@Req() req: any,
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
@Body() body: { status: ListStatus },
|
||||
) {
|
||||
const user = await this.userService.findOrCreate({
|
||||
id: req.user.id,
|
||||
nickname: req.user.nickname,
|
||||
avatar: req.user.avatar,
|
||||
});
|
||||
return this.listService.updateStatus(user.id, id, body.status);
|
||||
}
|
||||
|
||||
@Put(':id/score')
|
||||
async setScore(
|
||||
@Req() req: any,
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
@Body() body: { score: number },
|
||||
) {
|
||||
const user = await this.userService.findOrCreate({
|
||||
id: req.user.id,
|
||||
nickname: req.user.nickname,
|
||||
avatar: req.user.avatar,
|
||||
});
|
||||
return this.listService.setScore(user.id, id, body.score);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
async remove(
|
||||
@Req() req: any,
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
) {
|
||||
const user = await this.userService.findOrCreate({
|
||||
id: req.user.id,
|
||||
nickname: req.user.nickname,
|
||||
avatar: req.user.avatar,
|
||||
});
|
||||
await this.listService.removeFromList(user.id, id);
|
||||
return { deleted: true };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user