Public Source Viewer
비나래아카이브 개발자 포털
실제 서비스 구조를 살펴볼 수 있는 공개용 코드 뷰어입니다. 인증, 세션, 외부 연동, 토큰, 관리자 식별 등 보안상 민감한 구현은 파일 단위 또는 줄 단위로 검열됩니다.
src/routes/train.routes.ts
공개 가능
1
import { Router, Request, Response } from 'express';
2
import fs from 'fs';
3
import path from 'path';
4
import { PUBLIC_DIR } from '../utils/paths';
5
import { getBookmarks, spendBookmarks } from '../services/bookmark.service';
6
7
const router = Router();
8
9
router.get('/hinana/train', function(req: Request, res: Response) {
10
const imageDir = path.join(PUBLIC_DIR, 'image');
11
12
let totalScenery = 0;
13
14
try {
15
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
16
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
17
totalScenery = files.filter(file => /^scenery\d+\.png$/.test(file)).length;
18
} else {
19
console.error("이미지 폴더가 존재하지 않습니다:", imageDir);
20
totalScenery = 8;
21
}
22
} catch (err) {
23
console.error("이미지 폴더 읽기 실패:", err);
24
totalScenery = 8;
25
}
26
27
const username = req.session.username || null;
28
const trainType = (req.query.type as string) || 'hinana';
29
30
res.render('hinana/train', {
31
totalScenery: totalScenery,
32
username: username,
33
bookmarks: username ? getBookmarks(username) : 0,
34
trainType: trainType
35
});
36
});
37
38
router.post('/hinana/train/spend-bookmark', function(req: Request, res: Response) {
39
const username = req.session.username;
40
if (!username) {
41
return res.json({ success: false, needLogin: true });
42
}
43
44
const result = spendBookmarks(username, 1);
45
if (!result.success) {
46
return res.json({ success: false, insufficient: true, remaining: result.remaining });
47
}
48
49
return res.json({ success: true, remaining: result.remaining });
50
});
51
52
export default router;
53