Remove redundant .js extensions from import paths.
- TypeScript 소스 파일 내 모든 import 구문에서 불필요한 `.js` 확장자를 제거하여 모듈 참조 방식을 표준화했습니다. - 핸들러, 서비스, 리포지토리 및 테스트 코드를 포함한 프로젝트 전반의 import 경로를 일관성 있게 정리했습니다.
This commit is contained in:
parent
7496cb7de7
commit
c94ce69e4f
@ -1,4 +1,4 @@
|
|||||||
import type { DailyJudgment } from "../types/panit.js";
|
import type { DailyJudgment } from "../types/panit";
|
||||||
|
|
||||||
export interface Thresholds {
|
export interface Thresholds {
|
||||||
success: number;
|
success: number;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { TierName } from "../types/panit.js";
|
import type { TierName } from "../types/panit";
|
||||||
|
|
||||||
interface TierStep {
|
interface TierStep {
|
||||||
name: TierName;
|
name: TierName;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { onRequest } from "firebase-functions/https";
|
import { onRequest } from "firebase-functions/https";
|
||||||
import { requireAdmin } from "../middleware/admin.js";
|
import { requireAdmin } from "../middleware/admin";
|
||||||
import { sendError } from "../middleware/errors.js";
|
import { sendError } from "../middleware/errors";
|
||||||
import { markGameEnded } from "../services/gameResultService.js";
|
import { markGameEnded } from "../services/gameResultService";
|
||||||
|
|
||||||
export const admin = onRequest(async (req, res) => {
|
export const admin = onRequest(async (req, res) => {
|
||||||
const segs = req.path.replace(/^\/+|\/+$/g, "").split("/");
|
const segs = req.path.replace(/^\/+|\/+$/g, "").split("/");
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { onRequest } from "firebase-functions/https";
|
import { onRequest } from "firebase-functions/https";
|
||||||
import { logger } from "firebase-functions";
|
import { logger } from "firebase-functions";
|
||||||
import { runDailyArchive } from "../scheduled/dailyArchive.js";
|
import { runDailyArchive } from "../scheduled/dailyArchive";
|
||||||
import { syncYesterdayFromLive } from "../services/gameSyncService.js";
|
import { syncYesterdayFromLive } from "../services/gameSyncService";
|
||||||
import { sendError } from "../middleware/errors.js";
|
import { sendError } from "../middleware/errors";
|
||||||
import { daysAgoKst, parseDateString } from "../types/dateString.js";
|
import { daysAgoKst, parseDateString } from "../types/dateString";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 임시 디버그 핸들러. 인증 없음 — 운영 안정화 후 제거할 것.
|
* 임시 디버그 핸들러. 인증 없음 — 운영 안정화 후 제거할 것.
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { onRequest } from "firebase-functions/https";
|
import { onRequest } from "firebase-functions/https";
|
||||||
import { getRank } from "../services/rankService.js";
|
import { getRank } from "../services/rankService";
|
||||||
import { getSchedule } from "../services/scheduleService.js";
|
import { getSchedule } from "../services/scheduleService";
|
||||||
import { getPlayerStats, getValidPlayerTypes } from "../services/playerService.js";
|
import { getPlayerStats, getValidPlayerTypes } from "../services/playerService";
|
||||||
import { getGameList } from "../services/gameListService.js";
|
import { getGameList } from "../services/gameListService";
|
||||||
import { getGameDetail } from "../services/gameDetailService.js";
|
import { getGameDetail } from "../services/gameDetailService";
|
||||||
import { TeamCode } from "../types/panit.js";
|
import { TeamCode } from "../types/panit";
|
||||||
|
|
||||||
enum KboPath {
|
enum KboPath {
|
||||||
Rank = "rank",
|
Rank = "rank",
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
import { onRequest } from "firebase-functions/https";
|
import { onRequest } from "firebase-functions/https";
|
||||||
import { requireAuth } from "../middleware/auth.js";
|
import { requireAuth } from "../middleware/auth";
|
||||||
import { HttpError, sendError } from "../middleware/errors.js";
|
import { HttpError, sendError } from "../middleware/errors";
|
||||||
import {
|
import {
|
||||||
createPrediction,
|
createPrediction,
|
||||||
updatePrediction,
|
updatePrediction,
|
||||||
getMyVotes,
|
getMyVotes,
|
||||||
getSummary,
|
getSummary,
|
||||||
listGamesByDate,
|
listGamesByDate,
|
||||||
} from "../services/predictionService.js";
|
} from "../services/predictionService";
|
||||||
import { getScoreboard } from "../services/scoreboardService.js";
|
import { getScoreboard } from "../services/scoreboardService";
|
||||||
|
|
||||||
export const prediction = onRequest(async (req, res) => {
|
export const prediction = onRequest(async (req, res) => {
|
||||||
const segs = req.path.replace(/^\/+|\/+$/g, "").split("/");
|
const segs = req.path.replace(/^\/+|\/+$/g, "").split("/");
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { onRequest } from "firebase-functions/https";
|
import { onRequest } from "firebase-functions/https";
|
||||||
import { requireAuth } from "../middleware/auth.js";
|
import { requireAuth } from "../middleware/auth";
|
||||||
import { sendError } from "../middleware/errors.js";
|
import { sendError } from "../middleware/errors";
|
||||||
import { getStats, getHistory } from "../services/statsService.js";
|
import { getStats, getHistory } from "../services/statsService";
|
||||||
|
|
||||||
export const stats = onRequest(async (req, res) => {
|
export const stats = onRequest(async (req, res) => {
|
||||||
const segs = req.path.replace(/^\/+|\/+$/g, "").split("/");
|
const segs = req.path.replace(/^\/+|\/+$/g, "").split("/");
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import { onRequest } from "firebase-functions/https";
|
import { onRequest } from "firebase-functions/https";
|
||||||
import { requireAuthToken } from "../middleware/auth.js";
|
import { requireAuthToken } from "../middleware/auth";
|
||||||
import { sendError } from "../middleware/errors.js";
|
import { sendError } from "../middleware/errors";
|
||||||
import {
|
import {
|
||||||
checkNickname,
|
checkNickname,
|
||||||
createMe,
|
createMe,
|
||||||
deleteMe,
|
deleteMe,
|
||||||
getMe,
|
getMe,
|
||||||
updateMe,
|
updateMe,
|
||||||
} from "../services/userService.js";
|
} from "../services/userService";
|
||||||
|
|
||||||
export const user = onRequest(async (req, res) => {
|
export const user = onRequest(async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { extractHiddenField } from "./html-utils.js";
|
import { extractHiddenField } from "./html-utils";
|
||||||
|
|
||||||
export const PREFIX =
|
export const PREFIX =
|
||||||
"ctl00$ctl00$ctl00$cphContents$cphContents$cphContents$";
|
"ctl00$ctl00$ctl00$cphContents$cphContents$cphContents$";
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
* --series=값 시리즈 필터 (schedule: 정규/시범/포스트)
|
* --series=값 시리즈 필터 (schedule: 정규/시범/포스트)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { padCell } from "./html-utils.js";
|
import { padCell } from "./html-utils";
|
||||||
import {
|
import {
|
||||||
fetchTeamRankInitial,
|
fetchTeamRankInitial,
|
||||||
fetchTeamRank,
|
fetchTeamRank,
|
||||||
@ -22,7 +22,7 @@ import {
|
|||||||
type TeamVsRecord,
|
type TeamVsRecord,
|
||||||
type TeamRankResult,
|
type TeamRankResult,
|
||||||
type WinLossDraw,
|
type WinLossDraw,
|
||||||
} from "./team-rank.js";
|
} from "./team-rank";
|
||||||
import {
|
import {
|
||||||
fetchPlayerStatsInitial,
|
fetchPlayerStatsInitial,
|
||||||
fetchPlayerStats,
|
fetchPlayerStats,
|
||||||
@ -31,25 +31,25 @@ import {
|
|||||||
type PlayerPageConfig,
|
type PlayerPageConfig,
|
||||||
type PlayerFilters,
|
type PlayerFilters,
|
||||||
type PlayerStatsResult,
|
type PlayerStatsResult,
|
||||||
} from "./player/common.js";
|
} from "./player/common";
|
||||||
import { HITTER_CONFIG } from "./player/hitter.js";
|
import { HITTER_CONFIG } from "./player/hitter";
|
||||||
import { PITCHER_CONFIG } from "./player/pitcher.js";
|
import { PITCHER_CONFIG } from "./player/pitcher";
|
||||||
import { DEFENSE_CONFIG } from "./player/defense.js";
|
import { DEFENSE_CONFIG } from "./player/defense";
|
||||||
import { RUNNER_CONFIG } from "./player/runner.js";
|
import { RUNNER_CONFIG } from "./player/runner";
|
||||||
import {
|
import {
|
||||||
fetchSchedule,
|
fetchSchedule,
|
||||||
SERIES_CODES,
|
SERIES_CODES,
|
||||||
type ScheduleGame,
|
type ScheduleGame,
|
||||||
type ScheduleResult,
|
type ScheduleResult,
|
||||||
} from "./schedule.js";
|
} from "./schedule";
|
||||||
import {
|
import {
|
||||||
fetchGameList,
|
fetchGameList,
|
||||||
LEAGUE_CODES,
|
LEAGUE_CODES,
|
||||||
LeagueCode,
|
LeagueCode,
|
||||||
type GameListRecord,
|
type GameListRecord,
|
||||||
type GameListResult,
|
type GameListResult,
|
||||||
} from "./game-list.js";
|
} from "./game-list";
|
||||||
import { fetchGameDetail, type GameDetail } from "./game-detail.js";
|
import { fetchGameDetail, type GameDetail } from "./game-detail";
|
||||||
|
|
||||||
const PLAYER_CONFIGS: Record<string, PlayerPageConfig> = {
|
const PLAYER_CONFIGS: Record<string, PlayerPageConfig> = {
|
||||||
hitter: HITTER_CONFIG,
|
hitter: HITTER_CONFIG,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { stripTags, decodeHtmlEntities } from "./html-utils.js";
|
import { stripTags, decodeHtmlEntities } from "./html-utils";
|
||||||
import { LeagueCode, LEAGUE_CODES } from "./game-list.js";
|
import { LeagueCode, LEAGUE_CODES } from "./game-list";
|
||||||
import { SERIES_ID } from "./schedule.js";
|
import { SERIES_ID } from "./schedule";
|
||||||
import { fetchScoringPlays, type GameScoringPlays } from "./play-by-play.js";
|
import { fetchScoringPlays, type GameScoringPlays } from "./play-by-play";
|
||||||
|
|
||||||
const BASE_URL = "https://www.koreabaseball.com/ws/Schedule.asmx";
|
const BASE_URL = "https://www.koreabaseball.com/ws/Schedule.asmx";
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { SERIES_CODES } from "./schedule.js";
|
import { SERIES_CODES } from "./schedule";
|
||||||
|
|
||||||
export { SERIES_CODES };
|
export { SERIES_CODES };
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { stripTags, decodeHtmlEntities } from "../html-utils.js";
|
import { stripTags, decodeHtmlEntities } from "../html-utils";
|
||||||
import {
|
import {
|
||||||
PREFIX,
|
PREFIX,
|
||||||
postback,
|
postback,
|
||||||
getInitialPageState,
|
getInitialPageState,
|
||||||
type PageState,
|
type PageState,
|
||||||
type PostbackResponse,
|
type PostbackResponse,
|
||||||
} from "../aspnet-client.js";
|
} from "../aspnet-client";
|
||||||
|
|
||||||
const SM_KEY = `${PREFIX}smData`;
|
const SM_KEY = `${PREFIX}smData`;
|
||||||
const UPDATE_PANEL = `${PREFIX}udpContent`;
|
const UPDATE_PANEL = `${PREFIX}udpContent`;
|
||||||
@ -39,7 +39,7 @@ export interface PlayerPageConfig {
|
|||||||
* 구체적인 컬럼 타입이 필요하면 각 페이지 모듈의 타입으로 캐스팅한다.
|
* 구체적인 컬럼 타입이 필요하면 각 페이지 모듈의 타입으로 캐스팅한다.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* import type { HitterStats } from "./hitter.js";
|
* import type { HitterStats } from "./hitter";
|
||||||
* const hitter = record as HitterStats;
|
* const hitter = record as HitterStats;
|
||||||
* console.log(hitter.avg, hitter.hr);
|
* console.log(hitter.avg, hitter.hr);
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { PlayerPageConfig, PlayerValue } from "./common.js";
|
import type { PlayerPageConfig, PlayerValue } from "./common";
|
||||||
|
|
||||||
export const DEFENSE_COLUMNS = [
|
export const DEFENSE_COLUMNS = [
|
||||||
"rank", "player", "team", "pos", "games", "gs", "ip",
|
"rank", "player", "team", "pos", "games", "gs", "ip",
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { PlayerPageConfig, PlayerValue } from "./common.js";
|
import type { PlayerPageConfig, PlayerValue } from "./common";
|
||||||
|
|
||||||
export const HITTER_COLUMNS = [
|
export const HITTER_COLUMNS = [
|
||||||
"rank", "player", "team", "avg", "games", "pa", "ab",
|
"rank", "player", "team", "avg", "games", "pa", "ab",
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { PlayerPageConfig, PlayerValue } from "./common.js";
|
import type { PlayerPageConfig, PlayerValue } from "./common";
|
||||||
|
|
||||||
export const PITCHER_COLUMNS = [
|
export const PITCHER_COLUMNS = [
|
||||||
"rank", "player", "team", "era", "games", "wins", "losses",
|
"rank", "player", "team", "era", "games", "wins", "losses",
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { PlayerPageConfig, PlayerValue } from "./common.js";
|
import type { PlayerPageConfig, PlayerValue } from "./common";
|
||||||
|
|
||||||
export const RUNNER_COLUMNS = [
|
export const RUNNER_COLUMNS = [
|
||||||
"rank", "player", "team", "games", "sba", "sb", "cs",
|
"rank", "player", "team", "games", "sba", "sb", "cs",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { stripTags, decodeHtmlEntities } from "./html-utils.js";
|
import { stripTags, decodeHtmlEntities } from "./html-utils";
|
||||||
import { TEAM_CODES } from "./player/common.js";
|
import { TEAM_CODES } from "./player/common";
|
||||||
import { fetchGameList, type PersonRef } from "./game-list.js";
|
import { fetchGameList, type PersonRef } from "./game-list";
|
||||||
|
|
||||||
function toTeamCode(name: string): string {
|
function toTeamCode(name: string): string {
|
||||||
return TEAM_CODES[name] ?? name;
|
return TEAM_CODES[name] ?? name;
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { stripTags, decodeHtmlEntities } from "./html-utils.js";
|
import { stripTags, decodeHtmlEntities } from "./html-utils";
|
||||||
import {
|
import {
|
||||||
PREFIX,
|
PREFIX,
|
||||||
postback,
|
postback,
|
||||||
getInitialPageState,
|
getInitialPageState,
|
||||||
type PageState,
|
type PageState,
|
||||||
type PostbackResponse,
|
type PostbackResponse,
|
||||||
} from "./aspnet-client.js";
|
} from "./aspnet-client";
|
||||||
|
|
||||||
const PAGE_URL =
|
const PAGE_URL =
|
||||||
"https://www.koreabaseball.com/Record/TeamRank/TeamRank.aspx";
|
"https://www.koreabaseball.com/Record/TeamRank/TeamRank.aspx";
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import type { Request } from "firebase-functions/https";
|
import type { Request } from "firebase-functions/https";
|
||||||
import { auth } from "../firebase.js";
|
import { auth } from "../firebase";
|
||||||
import { HttpError } from "./errors.js";
|
import { HttpError } from "./errors";
|
||||||
|
|
||||||
export async function requireAdmin(req: Request): Promise<string> {
|
export async function requireAdmin(req: Request): Promise<string> {
|
||||||
const header = req.get("authorization") ?? req.get("Authorization");
|
const header = req.get("authorization") ?? req.get("Authorization");
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import type { Request } from "firebase-functions/https";
|
import type { Request } from "firebase-functions/https";
|
||||||
import type { DecodedIdToken } from "firebase-admin/auth";
|
import type { DecodedIdToken } from "firebase-admin/auth";
|
||||||
import { auth } from "../firebase.js";
|
import { auth } from "../firebase";
|
||||||
import { HttpError } from "./errors.js";
|
import { HttpError } from "./errors";
|
||||||
|
|
||||||
export async function requireAuthToken(req: Request): Promise<DecodedIdToken> {
|
export async function requireAuthToken(req: Request): Promise<DecodedIdToken> {
|
||||||
const header = req.get("authorization") ?? req.get("Authorization");
|
const header = req.get("authorization") ?? req.get("Authorization");
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { Timestamp } from "firebase-admin/firestore";
|
import { Timestamp } from "firebase-admin/firestore";
|
||||||
import { firestore } from "../firebase.js";
|
import { firestore } from "../firebase";
|
||||||
import type { Game } from "../types/panit.js";
|
import type { Game } from "../types/panit";
|
||||||
import { startOfDayKst, type DateString } from "../types/dateString.js";
|
import { startOfDayKst, type DateString } from "../types/dateString";
|
||||||
|
|
||||||
const COLLECTION = "games";
|
const COLLECTION = "games";
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { FieldValue } from "firebase-admin/firestore";
|
import { FieldValue } from "firebase-admin/firestore";
|
||||||
import { firestore } from "../firebase.js";
|
import { firestore } from "../firebase";
|
||||||
|
|
||||||
const CACHE_COLLECTION = "kboCache";
|
const CACHE_COLLECTION = "kboCache";
|
||||||
const LOCK_COLLECTION = "kboLocks";
|
const LOCK_COLLECTION = "kboLocks";
|
||||||
|
|||||||
@ -2,14 +2,14 @@ import {
|
|||||||
fetchTeamRankInitial,
|
fetchTeamRankInitial,
|
||||||
fetchTeamRank,
|
fetchTeamRank,
|
||||||
type TeamRankResult,
|
type TeamRankResult,
|
||||||
} from "../kbo/team-rank.js";
|
} from "../kbo/team-rank";
|
||||||
import {
|
import {
|
||||||
fetchSchedule,
|
fetchSchedule,
|
||||||
type ScheduleFilters,
|
type ScheduleFilters,
|
||||||
type ScheduleResult,
|
type ScheduleResult,
|
||||||
type ScheduleGame,
|
type ScheduleGame,
|
||||||
type GameStatus,
|
type GameStatus,
|
||||||
} from "../kbo/schedule.js";
|
} from "../kbo/schedule";
|
||||||
import {
|
import {
|
||||||
fetchPlayerStatsInitial,
|
fetchPlayerStatsInitial,
|
||||||
fetchPlayerStats,
|
fetchPlayerStats,
|
||||||
@ -17,17 +17,17 @@ import {
|
|||||||
type PlayerPageConfig,
|
type PlayerPageConfig,
|
||||||
type PlayerFilters,
|
type PlayerFilters,
|
||||||
type PlayerStatsResult,
|
type PlayerStatsResult,
|
||||||
} from "../kbo/player/common.js";
|
} from "../kbo/player/common";
|
||||||
import {
|
import {
|
||||||
encodeKey,
|
encodeKey,
|
||||||
getOrFetch,
|
getOrFetch,
|
||||||
setCached,
|
setCached,
|
||||||
acquireLock,
|
acquireLock,
|
||||||
releaseLock,
|
releaseLock,
|
||||||
} from "./kboCacheRepository.js";
|
} from "./kboCacheRepository";
|
||||||
import { firestore } from "../firebase.js";
|
import { firestore } from "../firebase";
|
||||||
import { getGameList } from "../services/gameListService.js";
|
import { getGameList } from "../services/gameListService";
|
||||||
import type { GameListRecord } from "../kbo/game-list.js";
|
import type { GameListRecord } from "../kbo/game-list";
|
||||||
|
|
||||||
const TTL_MS = 60 * 60 * 1000; // 1 hour
|
const TTL_MS = 60 * 60 * 1000; // 1 hour
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { rtdb } from "../firebase.js";
|
import { rtdb } from "../firebase";
|
||||||
import { HttpError } from "../middleware/errors.js";
|
import { HttpError } from "../middleware/errors";
|
||||||
|
|
||||||
export const RESERVATION_TTL_MS = 10 * 60 * 1000;
|
export const RESERVATION_TTL_MS = 10 * 60 * 1000;
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { rtdb } from "../firebase.js";
|
import { rtdb } from "../firebase";
|
||||||
import type { DateString } from "../types/dateString.js";
|
import type { DateString } from "../types/dateString";
|
||||||
import type { TeamCode } from "../types/panit.js";
|
import type { TeamCode } from "../types/panit";
|
||||||
import type { ScoreboardScopeCache } from "../types/scoreboard.js";
|
import type { ScoreboardScopeCache } from "../types/scoreboard";
|
||||||
|
|
||||||
const BASE = "/scoreboardCache";
|
const BASE = "/scoreboardCache";
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { firestore } from "../firebase.js";
|
import { firestore } from "../firebase";
|
||||||
import type { VoteHistoryDoc } from "../types/panit.js";
|
import type { VoteHistoryDoc } from "../types/panit";
|
||||||
import type { DateString } from "../types/dateString.js";
|
import type { DateString } from "../types/dateString";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 특정 유저의 voteHistory 서브컬렉션 레퍼런스를 반환한다.
|
* 특정 유저의 voteHistory 서브컬렉션 레퍼런스를 반환한다.
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { ServerValue } from "firebase-admin/database";
|
import { ServerValue } from "firebase-admin/database";
|
||||||
import { rtdb } from "../firebase.js";
|
import { rtdb } from "../firebase";
|
||||||
import type { VoteEntry } from "../types/panit.js";
|
import type { VoteEntry } from "../types/panit";
|
||||||
import type { DateString } from "../types/dateString.js";
|
import type { DateString } from "../types/dateString";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 특정 경기의 해당 유저 투표를 조회한다.
|
* 특정 경기의 해당 유저 투표를 조회한다.
|
||||||
|
|||||||
@ -1,23 +1,23 @@
|
|||||||
import { onSchedule } from "firebase-functions/scheduler";
|
import { onSchedule } from "firebase-functions/scheduler";
|
||||||
import { logger } from "firebase-functions";
|
import { logger } from "firebase-functions";
|
||||||
import { rtdb } from "../firebase.js";
|
import { rtdb } from "../firebase";
|
||||||
import { setDay } from "../repositories/voteHistoryRepository.js";
|
import { setDay } from "../repositories/voteHistoryRepository";
|
||||||
import { invalidateStats } from "../services/statsService.js";
|
import { invalidateStats } from "../services/statsService";
|
||||||
import { judgeDay, judgeWeekIfNeeded } from "../services/judgmentService.js";
|
import { judgeDay, judgeWeekIfNeeded } from "../services/judgmentService";
|
||||||
import {
|
import {
|
||||||
precomputeScoreboardCache,
|
precomputeScoreboardCache,
|
||||||
snapshotRankForUser,
|
snapshotRankForUser,
|
||||||
} from "../services/rankSnapshotService.js";
|
} from "../services/rankSnapshotService";
|
||||||
import { todayKst } from "../types/dateString.js";
|
import { todayKst } from "../types/dateString";
|
||||||
import { getGame } from "../repositories/gameRepository.js";
|
import { getGame } from "../repositories/gameRepository";
|
||||||
import { deleteUserVoteGame } from "../repositories/voteRepository.js";
|
import { deleteUserVoteGame } from "../repositories/voteRepository";
|
||||||
import { processGameEndWithGame } from "../services/gameResultService.js";
|
import { processGameEndWithGame } from "../services/gameResultService";
|
||||||
import type { VoteHistoryDoc } from "../types/panit.js";
|
import type { VoteHistoryDoc } from "../types/panit";
|
||||||
import {
|
import {
|
||||||
dayOfWeekKst,
|
dayOfWeekKst,
|
||||||
daysAgoKst,
|
daysAgoKst,
|
||||||
type DateString,
|
type DateString,
|
||||||
} from "../types/dateString.js";
|
} from "../types/dateString";
|
||||||
|
|
||||||
interface RawVote {
|
interface RawVote {
|
||||||
team: string;
|
team: string;
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
import { onSchedule } from "firebase-functions/scheduler";
|
import { onSchedule } from "firebase-functions/scheduler";
|
||||||
import { logger } from "firebase-functions";
|
import { logger } from "firebase-functions";
|
||||||
import { firestore } from "../firebase.js";
|
import { firestore } from "../firebase";
|
||||||
import {
|
import {
|
||||||
fetchRankFromKbo,
|
fetchRankFromKbo,
|
||||||
fetchScheduleFromKbo,
|
fetchScheduleFromKbo,
|
||||||
} from "../repositories/kboRepository.js";
|
} from "../repositories/kboRepository";
|
||||||
import {
|
import {
|
||||||
syncGamesForMonth,
|
syncGamesForMonth,
|
||||||
syncYesterdayFromLive,
|
syncYesterdayFromLive,
|
||||||
} from "../services/gameSyncService.js";
|
} from "../services/gameSyncService";
|
||||||
import { daysAgoKst } from "../types/dateString.js";
|
import { daysAgoKst } from "../types/dateString";
|
||||||
|
|
||||||
const CACHE_COLLECTION = "kboCache";
|
const CACHE_COLLECTION = "kboCache";
|
||||||
|
|
||||||
|
|||||||
@ -3,14 +3,14 @@ import {
|
|||||||
type GameDetail,
|
type GameDetail,
|
||||||
type GameDetailFilters,
|
type GameDetailFilters,
|
||||||
type ScoreBoardMeta,
|
type ScoreBoardMeta,
|
||||||
} from "../kbo/game-detail.js";
|
} from "../kbo/game-detail";
|
||||||
import {
|
import {
|
||||||
encodeKey,
|
encodeKey,
|
||||||
getCached,
|
getCached,
|
||||||
setCached,
|
setCached,
|
||||||
acquireLock,
|
acquireLock,
|
||||||
releaseLock,
|
releaseLock,
|
||||||
} from "../repositories/kboCacheRepository.js";
|
} from "../repositories/kboCacheRepository";
|
||||||
|
|
||||||
const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;
|
const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;
|
||||||
const ONE_HOUR_MS = 60 * 60 * 1000;
|
const ONE_HOUR_MS = 60 * 60 * 1000;
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import {
|
|||||||
LeagueCode,
|
LeagueCode,
|
||||||
SERIES_CODES,
|
SERIES_CODES,
|
||||||
type GameListResult,
|
type GameListResult,
|
||||||
} from "../kbo/game-list.js";
|
} from "../kbo/game-list";
|
||||||
import { MemCache } from "../lib/memCache.js";
|
import { MemCache } from "../lib/memCache";
|
||||||
|
|
||||||
// 게임센터(GetKboGameList)는 다른 KBO 데이터와 달리 Firestore 공유 캐시
|
// 게임센터(GetKboGameList)는 다른 KBO 데이터와 달리 Firestore 공유 캐시
|
||||||
// (kboCacheRepository) 대신 인스턴스 단위 인메모리 캐시를 쓴다.
|
// (kboCacheRepository) 대신 인스턴스 단위 인메모리 캐시를 쓴다.
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import { FieldValue } from "firebase-admin/firestore";
|
import { FieldValue } from "firebase-admin/firestore";
|
||||||
import { logger } from "firebase-functions";
|
import { logger } from "firebase-functions";
|
||||||
import { firestore, rtdb } from "../firebase.js";
|
import { firestore, rtdb } from "../firebase";
|
||||||
import { HttpError } from "../middleware/errors.js";
|
import { HttpError } from "../middleware/errors";
|
||||||
import { getGame } from "../repositories/gameRepository.js";
|
import { getGame } from "../repositories/gameRepository";
|
||||||
import { getAllUserVotes, deleteGameVotes } from "../repositories/voteRepository.js";
|
import { getAllUserVotes, deleteGameVotes } from "../repositories/voteRepository";
|
||||||
import { invalidateStats } from "./statsService.js";
|
import { invalidateStats } from "./statsService";
|
||||||
import { fromTimestamp } from "../types/dateString.js";
|
import { fromTimestamp } from "../types/dateString";
|
||||||
import type { Game } from "../types/panit.js";
|
import type { Game } from "../types/panit";
|
||||||
|
|
||||||
export async function processGameEnd(gameId: string): Promise<{ processed: number }> {
|
export async function processGameEnd(gameId: string): Promise<{ processed: number }> {
|
||||||
const game = await getGame(gameId);
|
const game = await getGame(gameId);
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import { Timestamp } from "firebase-admin/firestore";
|
import { Timestamp } from "firebase-admin/firestore";
|
||||||
import { firestore } from "../firebase.js";
|
import { firestore } from "../firebase";
|
||||||
import {
|
import {
|
||||||
fetchScheduleFromKbo,
|
fetchScheduleFromKbo,
|
||||||
statusFromRecord,
|
statusFromRecord,
|
||||||
} from "../repositories/kboRepository.js";
|
} from "../repositories/kboRepository";
|
||||||
import { getGameList } from "./gameListService.js";
|
import { getGameList } from "./gameListService";
|
||||||
import type { GameListRecord } from "../kbo/game-list.js";
|
import type { GameListRecord } from "../kbo/game-list";
|
||||||
import type { ScheduleGame, GameStatus } from "../kbo/schedule.js";
|
import type { ScheduleGame, GameStatus } from "../kbo/schedule";
|
||||||
import type { Game } from "../types/panit.js";
|
import type { Game } from "../types/panit";
|
||||||
|
|
||||||
const COLLECTION = "games";
|
const COLLECTION = "games";
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
import { logger } from "firebase-functions";
|
import { logger } from "firebase-functions";
|
||||||
import { listByDate } from "../repositories/gameRepository.js";
|
import { listByDate } from "../repositories/gameRepository";
|
||||||
import { getRange, setDay } from "../repositories/voteHistoryRepository.js";
|
import { getRange, setDay } from "../repositories/voteHistoryRepository";
|
||||||
import {
|
import {
|
||||||
applyDailyJudgmentTx,
|
applyDailyJudgmentTx,
|
||||||
applyWeeklyMasterTx,
|
applyWeeklyMasterTx,
|
||||||
getUser,
|
getUser,
|
||||||
} from "../repositories/userRepository.js";
|
} from "../repositories/userRepository";
|
||||||
import {
|
import {
|
||||||
judgeByCounts,
|
judgeByCounts,
|
||||||
streakBonus,
|
streakBonus,
|
||||||
thresholdsFor,
|
thresholdsFor,
|
||||||
} from "../constants/judgment.js";
|
} from "../constants/judgment";
|
||||||
import type { DailyJudgment, VoteHistoryDoc } from "../types/panit.js";
|
import type { DailyJudgment, VoteHistoryDoc } from "../types/panit";
|
||||||
import { addDaysKst, tuesdayOf, type DateString } from "../types/dateString.js";
|
import { addDaysKst, tuesdayOf, type DateString } from "../types/dateString";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `(lastJudged, upTo)` 구간(양 끝 제외)에 **실제 판정 가능한 경기일**(=`thresholdsFor`가
|
* `(lastJudged, upTo)` 구간(양 끝 제외)에 **실제 판정 가능한 경기일**(=`thresholdsFor`가
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { fetchPlayerFromKbo } from "../repositories/kboRepository.js";
|
import { fetchPlayerFromKbo } from "../repositories/kboRepository";
|
||||||
import type { PlayerFilters, PlayerPageConfig, PlayerStatsResult } from "../types/kbo.js";
|
import type { PlayerFilters, PlayerPageConfig, PlayerStatsResult } from "../types/kbo";
|
||||||
import { TeamCode } from "../types/panit.js";
|
import { TeamCode } from "../types/panit";
|
||||||
import { HITTER_CONFIG } from "../kbo/player/hitter.js";
|
import { HITTER_CONFIG } from "../kbo/player/hitter";
|
||||||
import { PITCHER_CONFIG } from "../kbo/player/pitcher.js";
|
import { PITCHER_CONFIG } from "../kbo/player/pitcher";
|
||||||
import { DEFENSE_CONFIG } from "../kbo/player/defense.js";
|
import { DEFENSE_CONFIG } from "../kbo/player/defense";
|
||||||
import { RUNNER_CONFIG } from "../kbo/player/runner.js";
|
import { RUNNER_CONFIG } from "../kbo/player/runner";
|
||||||
|
|
||||||
const PLAYER_CONFIGS: Record<string, PlayerPageConfig> = {
|
const PLAYER_CONFIGS: Record<string, PlayerPageConfig> = {
|
||||||
hitter: HITTER_CONFIG,
|
hitter: HITTER_CONFIG,
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
import { HttpError } from "../middleware/errors.js";
|
import { HttpError } from "../middleware/errors";
|
||||||
import { getGame, listByDate, type GameWithId } from "../repositories/gameRepository.js";
|
import { getGame, listByDate, type GameWithId } from "../repositories/gameRepository";
|
||||||
import {
|
import {
|
||||||
getUserVote,
|
getUserVote,
|
||||||
submitVote,
|
submitVote,
|
||||||
changeVote,
|
changeVote,
|
||||||
getCounts,
|
getCounts,
|
||||||
getUserDateVotes,
|
getUserDateVotes,
|
||||||
} from "../repositories/voteRepository.js";
|
} from "../repositories/voteRepository";
|
||||||
import type { Game, VoteEntry } from "../types/panit.js";
|
import type { Game, VoteEntry } from "../types/panit";
|
||||||
import { fromTimestamp, parseDateString, type DateString } from "../types/dateString.js";
|
import { fromTimestamp, parseDateString, type DateString } from "../types/dateString";
|
||||||
import { MemCache } from "../lib/memCache.js";
|
import { MemCache } from "../lib/memCache";
|
||||||
|
|
||||||
type SummaryCounts = { homeCount: number; awayCount: number };
|
type SummaryCounts = { homeCount: number; awayCount: number };
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { fetchRankFromKbo } from "../repositories/kboRepository.js";
|
import { fetchRankFromKbo } from "../repositories/kboRepository";
|
||||||
import type { TeamRankResult } from "../types/kbo.js";
|
import type { TeamRankResult } from "../types/kbo";
|
||||||
|
|
||||||
export async function getRank(years: number[]): Promise<TeamRankResult[]> {
|
export async function getRank(years: number[]): Promise<TeamRankResult[]> {
|
||||||
return fetchRankFromKbo(years);
|
return fetchRankFromKbo(years);
|
||||||
|
|||||||
@ -1,20 +1,20 @@
|
|||||||
import { logger } from "firebase-functions";
|
import { logger } from "firebase-functions";
|
||||||
import { firestore } from "../firebase.js";
|
import { firestore } from "../firebase";
|
||||||
import {
|
import {
|
||||||
countRankedUsers,
|
countRankedUsers,
|
||||||
countUsersAboveTierPoints,
|
countUsersAboveTierPoints,
|
||||||
getUser,
|
getUser,
|
||||||
listTopByTierPoints,
|
listTopByTierPoints,
|
||||||
type ScoreboardUserEntry,
|
type ScoreboardUserEntry,
|
||||||
} from "../repositories/userRepository.js";
|
} from "../repositories/userRepository";
|
||||||
import { writeScope, type Scope } from "../repositories/scoreboardCacheRepository.js";
|
import { writeScope, type Scope } from "../repositories/scoreboardCacheRepository";
|
||||||
import { computePercentile, deltaFor } from "./scoreboardHelpers.js";
|
import { computePercentile, deltaFor } from "./scoreboardHelpers";
|
||||||
import type { DateString } from "../types/dateString.js";
|
import type { DateString } from "../types/dateString";
|
||||||
import { TeamCode, type RankSnapshot } from "../types/panit.js";
|
import { TeamCode, type RankSnapshot } from "../types/panit";
|
||||||
import type {
|
import type {
|
||||||
ScoreboardEntry,
|
ScoreboardEntry,
|
||||||
ScoreboardScopeCache,
|
ScoreboardScopeCache,
|
||||||
} from "../types/scoreboard.js";
|
} from "../types/scoreboard";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 유저 1명의 현재 `tierPoints` 기반 rank를 count aggregation으로 계산해
|
* 유저 1명의 현재 `tierPoints` 기반 rank를 count aggregation으로 계산해
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { fetchScheduleFromKbo } from "../repositories/kboRepository.js";
|
import { fetchScheduleFromKbo } from "../repositories/kboRepository";
|
||||||
import { SERIES_CODES } from "../types/kbo.js";
|
import { SERIES_CODES } from "../types/kbo";
|
||||||
import type { ScheduleResult } from "../types/kbo.js";
|
import type { ScheduleResult } from "../types/kbo";
|
||||||
import type { TeamCode } from "../types/panit.js";
|
import type { TeamCode } from "../types/panit";
|
||||||
|
|
||||||
export async function getSchedule(
|
export async function getSchedule(
|
||||||
year: number,
|
year: number,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import type { Scope } from "../repositories/scoreboardCacheRepository.js";
|
import type { Scope } from "../repositories/scoreboardCacheRepository";
|
||||||
import type { RankSnapshot } from "../types/panit.js";
|
import type { RankSnapshot } from "../types/panit";
|
||||||
|
|
||||||
export function computePercentile(rank: number, totalCount: number): number {
|
export function computePercentile(rank: number, totalCount: number): number {
|
||||||
if (totalCount <= 0) return 0;
|
if (totalCount <= 0) return 0;
|
||||||
|
|||||||
@ -1,22 +1,22 @@
|
|||||||
import { MemCache } from "../lib/memCache.js";
|
import { MemCache } from "../lib/memCache";
|
||||||
import {
|
import {
|
||||||
countUsersAboveTierPoints,
|
countUsersAboveTierPoints,
|
||||||
getUser,
|
getUser,
|
||||||
} from "../repositories/userRepository.js";
|
} from "../repositories/userRepository";
|
||||||
import {
|
import {
|
||||||
readScope,
|
readScope,
|
||||||
type Scope,
|
type Scope,
|
||||||
} from "../repositories/scoreboardCacheRepository.js";
|
} from "../repositories/scoreboardCacheRepository";
|
||||||
import { HttpError } from "../middleware/errors.js";
|
import { HttpError } from "../middleware/errors";
|
||||||
import { computePercentile, deltaFor } from "./scoreboardHelpers.js";
|
import { computePercentile, deltaFor } from "./scoreboardHelpers";
|
||||||
import { todayKst } from "../types/dateString.js";
|
import { todayKst } from "../types/dateString";
|
||||||
import { type TeamCode } from "../types/panit.js";
|
import { type TeamCode } from "../types/panit";
|
||||||
import type {
|
import type {
|
||||||
ScoreboardEntry,
|
ScoreboardEntry,
|
||||||
ScoreboardResponse,
|
ScoreboardResponse,
|
||||||
ScoreboardScopeCache,
|
ScoreboardScopeCache,
|
||||||
ScoreboardType,
|
ScoreboardType,
|
||||||
} from "../types/scoreboard.js";
|
} from "../types/scoreboard";
|
||||||
|
|
||||||
const BURST_TTL_MS = 30_000;
|
const BURST_TTL_MS = 30_000;
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import {rtdb} from "../firebase.js";
|
import {rtdb} from "../firebase";
|
||||||
import {HttpError} from "../middleware/errors.js";
|
import {HttpError} from "../middleware/errors";
|
||||||
import {computeLevel} from "../constants/levels.js";
|
import {computeLevel} from "../constants/levels";
|
||||||
import {tierOf} from "../constants/tiers.js";
|
import {tierOf} from "../constants/tiers";
|
||||||
import {getAll, getDay} from "../repositories/voteHistoryRepository.js";
|
import {getAll, getDay} from "../repositories/voteHistoryRepository";
|
||||||
import {getUser} from "../repositories/userRepository.js";
|
import {getUser} from "../repositories/userRepository";
|
||||||
import {hasMissedGameDayBetween} from "./judgmentService.js";
|
import {hasMissedGameDayBetween} from "./judgmentService";
|
||||||
import type {DailyJudgment, StatsResponse, VoteHistoryDoc} from "../types/panit.js";
|
import type {DailyJudgment, StatsResponse, VoteHistoryDoc} from "../types/panit";
|
||||||
import {
|
import {
|
||||||
addDaysKst,
|
addDaysKst,
|
||||||
parseDateString,
|
parseDateString,
|
||||||
@ -14,7 +14,7 @@ import {
|
|||||||
todayKst,
|
todayKst,
|
||||||
tuesdayOf as tuesdayOfUtil,
|
tuesdayOf as tuesdayOfUtil,
|
||||||
type DateString,
|
type DateString,
|
||||||
} from "../types/dateString.js";
|
} from "../types/dateString";
|
||||||
|
|
||||||
type Period =
|
type Period =
|
||||||
| "current"
|
| "current"
|
||||||
|
|||||||
@ -1,27 +1,27 @@
|
|||||||
import type { DecodedIdToken } from "firebase-admin/auth";
|
import type { DecodedIdToken } from "firebase-admin/auth";
|
||||||
import { FieldValue } from "firebase-admin/firestore";
|
import { FieldValue } from "firebase-admin/firestore";
|
||||||
import { HttpError } from "../middleware/errors.js";
|
import { HttpError } from "../middleware/errors";
|
||||||
import { auth } from "../firebase.js";
|
import { auth } from "../firebase";
|
||||||
import {
|
import {
|
||||||
createUser,
|
createUser,
|
||||||
deleteUser,
|
deleteUser,
|
||||||
findUidByDisplayName,
|
findUidByDisplayName,
|
||||||
getUser,
|
getUser,
|
||||||
updateUser,
|
updateUser,
|
||||||
} from "../repositories/userRepository.js";
|
} from "../repositories/userRepository";
|
||||||
import {
|
import {
|
||||||
deleteReservation,
|
deleteReservation,
|
||||||
releaseReservation,
|
releaseReservation,
|
||||||
reserveNickname,
|
reserveNickname,
|
||||||
verifyReservation,
|
verifyReservation,
|
||||||
} from "../repositories/nicknameRepository.js";
|
} from "../repositories/nicknameRepository";
|
||||||
import {
|
import {
|
||||||
KnowledgeLevel,
|
KnowledgeLevel,
|
||||||
TeamCode,
|
TeamCode,
|
||||||
type Provider,
|
type Provider,
|
||||||
type User,
|
type User,
|
||||||
type UserProfile,
|
type UserProfile,
|
||||||
} from "../types/panit.js";
|
} from "../types/panit";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 내부 User 문서를 클라이언트 응답용 프로필로 변환한다.
|
* 내부 User 문서를 클라이언트 응답용 프로필로 변환한다.
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
import {onDocumentUpdated} from "firebase-functions/firestore";
|
import {onDocumentUpdated} from "firebase-functions/firestore";
|
||||||
import {logger} from "firebase-functions";
|
import {logger} from "firebase-functions";
|
||||||
import {rtdb} from "../firebase.js";
|
import {rtdb} from "../firebase";
|
||||||
import {processGameEndWithGame} from "../services/gameResultService.js";
|
import {processGameEndWithGame} from "../services/gameResultService";
|
||||||
import {
|
import {
|
||||||
getAllUserVotes,
|
getAllUserVotes,
|
||||||
deleteGameVotes,
|
deleteGameVotes,
|
||||||
} from "../repositories/voteRepository.js";
|
} from "../repositories/voteRepository";
|
||||||
import {invalidateStats} from "../services/statsService.js";
|
import {invalidateStats} from "../services/statsService";
|
||||||
import {fromTimestamp} from "../types/dateString.js";
|
import {fromTimestamp} from "../types/dateString";
|
||||||
import type {Game} from "../types/panit.js";
|
import type {Game} from "../types/panit";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `games/{gameId}` 문서 업데이트를 받아 유저 투표를 정리하는 Firestore 트리거.
|
* `games/{gameId}` 문서 업데이트를 받아 유저 투표를 정리하는 Firestore 트리거.
|
||||||
|
|||||||
@ -6,32 +6,32 @@ export type {
|
|||||||
WinLossDraw,
|
WinLossDraw,
|
||||||
TeamVsRecord,
|
TeamVsRecord,
|
||||||
TeamRankResult,
|
TeamRankResult,
|
||||||
} from "../kbo/team-rank.js";
|
} from "../kbo/team-rank";
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
GameStatus,
|
GameStatus,
|
||||||
ScheduleGame,
|
ScheduleGame,
|
||||||
ScheduleFilters,
|
ScheduleFilters,
|
||||||
ScheduleResult,
|
ScheduleResult,
|
||||||
} from "../kbo/schedule.js";
|
} from "../kbo/schedule";
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
PlayerPageConfig,
|
PlayerPageConfig,
|
||||||
PlayerRecord,
|
PlayerRecord,
|
||||||
PlayerFilters,
|
PlayerFilters,
|
||||||
PlayerStatsResult,
|
PlayerStatsResult,
|
||||||
} from "../kbo/player/common.js";
|
} from "../kbo/player/common";
|
||||||
|
|
||||||
export { SERIES_CODES } from "../kbo/schedule.js";
|
export { SERIES_CODES } from "../kbo/schedule";
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
GameListFilters,
|
GameListFilters,
|
||||||
GameListRecord,
|
GameListRecord,
|
||||||
GameListResult,
|
GameListResult,
|
||||||
PersonRef,
|
PersonRef,
|
||||||
} from "../kbo/game-list.js";
|
} from "../kbo/game-list";
|
||||||
|
|
||||||
export { LeagueCode, LEAGUE_CODES } from "../kbo/game-list.js";
|
export { LeagueCode, LEAGUE_CODES } from "../kbo/game-list";
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
GameDetail,
|
GameDetail,
|
||||||
@ -50,7 +50,7 @@ export type {
|
|||||||
KeyPlayerRanking,
|
KeyPlayerRanking,
|
||||||
KeyPlayerItem,
|
KeyPlayerItem,
|
||||||
KeyPlayerGroup,
|
KeyPlayerGroup,
|
||||||
} from "../kbo/game-detail.js";
|
} from "../kbo/game-detail";
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
GameScoringPlays,
|
GameScoringPlays,
|
||||||
@ -61,6 +61,6 @@ export type {
|
|||||||
ScoringOutcome,
|
ScoringOutcome,
|
||||||
BaseState,
|
BaseState,
|
||||||
BaseRunner,
|
BaseRunner,
|
||||||
} from "../kbo/play-by-play.js";
|
} from "../kbo/play-by-play";
|
||||||
|
|
||||||
export { SERIES_ID } from "../kbo/schedule.js";
|
export { SERIES_ID } from "../kbo/schedule";
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import type { Timestamp } from "firebase-admin/firestore";
|
import type { Timestamp } from "firebase-admin/firestore";
|
||||||
import type { DateString } from "./dateString.js";
|
import type { DateString } from "./dateString";
|
||||||
|
|
||||||
export type Provider = "google" | "apple";
|
export type Provider = "google" | "apple";
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { TeamCode } from "./panit.js";
|
import type { TeamCode } from "./panit";
|
||||||
|
|
||||||
export interface ScoreboardEntry {
|
export interface ScoreboardEntry {
|
||||||
uid: string;
|
uid: string;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { beforeEach, describe, expect, it } from "vitest";
|
import { beforeEach, describe, expect, it } from "vitest";
|
||||||
import { Timestamp } from "firebase-admin/firestore";
|
import { Timestamp } from "firebase-admin/firestore";
|
||||||
import { firestore } from "../../src/firebase.js";
|
import { firestore } from "../../src/firebase";
|
||||||
import { getGame, listByDate } from "../../src/repositories/gameRepository.js";
|
import { getGame, listByDate } from "../../src/repositories/gameRepository";
|
||||||
import type { DateString } from "../../src/types/dateString.js";
|
import type { DateString } from "../../src/types/dateString";
|
||||||
|
|
||||||
describe("gameRepository", () => {
|
describe("gameRepository", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { beforeEach, describe, expect, it } from "vitest";
|
import { beforeEach, describe, expect, it } from "vitest";
|
||||||
import { firestore } from "../../src/firebase.js";
|
import { firestore } from "../../src/firebase";
|
||||||
import {
|
import {
|
||||||
fetchRankFromKbo,
|
fetchRankFromKbo,
|
||||||
fetchScheduleFromKbo,
|
fetchScheduleFromKbo,
|
||||||
} from "../../src/repositories/kboRepository.js";
|
} from "../../src/repositories/kboRepository";
|
||||||
|
|
||||||
describe("kboRepository (실제 KBO 사이트 호출)", () => {
|
describe("kboRepository (실제 KBO 사이트 호출)", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import { beforeEach, describe, expect, it } from "vitest";
|
import { beforeEach, describe, expect, it } from "vitest";
|
||||||
import { firestore } from "../../src/firebase.js";
|
import { firestore } from "../../src/firebase";
|
||||||
import {
|
import {
|
||||||
getAll,
|
getAll,
|
||||||
getDay,
|
getDay,
|
||||||
getRange,
|
getRange,
|
||||||
setDay,
|
setDay,
|
||||||
} from "../../src/repositories/voteHistoryRepository.js";
|
} from "../../src/repositories/voteHistoryRepository";
|
||||||
import type { DateString } from "../../src/types/dateString.js";
|
import type { DateString } from "../../src/types/dateString";
|
||||||
import type { VoteHistoryDoc } from "../../src/types/panit.js";
|
import type { VoteHistoryDoc } from "../../src/types/panit";
|
||||||
|
|
||||||
const uid = "test-uid-1";
|
const uid = "test-uid-1";
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { beforeEach, describe, expect, it } from "vitest";
|
import { beforeEach, describe, expect, it } from "vitest";
|
||||||
import { rtdb } from "../../src/firebase.js";
|
import { rtdb } from "../../src/firebase";
|
||||||
import {
|
import {
|
||||||
changeVote,
|
changeVote,
|
||||||
deleteGameVotes,
|
deleteGameVotes,
|
||||||
@ -8,8 +8,8 @@ import {
|
|||||||
getUserDateVotes,
|
getUserDateVotes,
|
||||||
getUserVote,
|
getUserVote,
|
||||||
submitVote,
|
submitVote,
|
||||||
} from "../../src/repositories/voteRepository.js";
|
} from "../../src/repositories/voteRepository";
|
||||||
import type { DateString } from "../../src/types/dateString.js";
|
import type { DateString } from "../../src/types/dateString";
|
||||||
|
|
||||||
const gameId = "20260412HTLG0";
|
const gameId = "20260412HTLG0";
|
||||||
const gameId2 = "20260412WOSK0";
|
const gameId2 = "20260412WOSK0";
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { beforeEach, describe, expect, it } from "vitest";
|
import { beforeEach, describe, expect, it } from "vitest";
|
||||||
import { firestore } from "../../src/firebase.js";
|
import { firestore } from "../../src/firebase";
|
||||||
import { getGameDetail } from "../../src/services/gameDetailService.js";
|
import { getGameDetail } from "../../src/services/gameDetailService";
|
||||||
|
|
||||||
// 실제 KBO 게임센터 + Firestore 에뮬레이터를 함께 사용한다.
|
// 실제 KBO 게임센터 + Firestore 에뮬레이터를 함께 사용한다.
|
||||||
// nested-array Firestore 거부, parseGameStartTs NPE 등 회귀를 잡기 위함.
|
// nested-array Firestore 거부, parseGameStartTs NPE 등 회귀를 잡기 위함.
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import { beforeEach, describe, expect, it } from "vitest";
|
import { beforeEach, describe, expect, it } from "vitest";
|
||||||
import { firestore } from "../../src/firebase.js";
|
import { firestore } from "../../src/firebase";
|
||||||
import {
|
import {
|
||||||
toGameDoc,
|
toGameDoc,
|
||||||
toTime,
|
toTime,
|
||||||
syncGamesForMonth,
|
syncGamesForMonth,
|
||||||
gameUpdateFromRecord,
|
gameUpdateFromRecord,
|
||||||
} from "../../src/services/gameSyncService.js";
|
} from "../../src/services/gameSyncService";
|
||||||
import type { ScheduleGame } from "../../src/kbo/schedule.js";
|
import type { ScheduleGame } from "../../src/kbo/schedule";
|
||||||
import type { GameListRecord } from "../../src/kbo/game-list.js";
|
import type { GameListRecord } from "../../src/kbo/game-list";
|
||||||
|
|
||||||
function baseGame(overrides: Partial<ScheduleGame> = {}): ScheduleGame {
|
function baseGame(overrides: Partial<ScheduleGame> = {}): ScheduleGame {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -1,19 +1,19 @@
|
|||||||
import { beforeEach, describe, expect, it } from "vitest";
|
import { beforeEach, describe, expect, it } from "vitest";
|
||||||
import { Timestamp } from "firebase-admin/firestore";
|
import { Timestamp } from "firebase-admin/firestore";
|
||||||
import { firestore } from "../../src/firebase.js";
|
import { firestore } from "../../src/firebase";
|
||||||
import {
|
import {
|
||||||
judgeDay,
|
judgeDay,
|
||||||
judgeWeekIfNeeded,
|
judgeWeekIfNeeded,
|
||||||
} from "../../src/services/judgmentService.js";
|
} from "../../src/services/judgmentService";
|
||||||
import { setDay } from "../../src/repositories/voteHistoryRepository.js";
|
import { setDay } from "../../src/repositories/voteHistoryRepository";
|
||||||
import type { DateString } from "../../src/types/dateString.js";
|
import type { DateString } from "../../src/types/dateString";
|
||||||
import type {
|
import type {
|
||||||
DailyJudgment,
|
DailyJudgment,
|
||||||
Game,
|
Game,
|
||||||
GameStatus,
|
GameStatus,
|
||||||
User,
|
User,
|
||||||
VoteHistoryDoc,
|
VoteHistoryDoc,
|
||||||
} from "../../src/types/panit.js";
|
} from "../../src/types/panit";
|
||||||
|
|
||||||
const uid = "judge-uid";
|
const uid = "judge-uid";
|
||||||
|
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
import { beforeEach, describe, expect, it } from "vitest";
|
import { beforeEach, describe, expect, it } from "vitest";
|
||||||
import { firestore, rtdb } from "../../src/firebase.js";
|
import { firestore, rtdb } from "../../src/firebase";
|
||||||
import {
|
import {
|
||||||
__resetScoreboardCaches,
|
__resetScoreboardCaches,
|
||||||
getScoreboard,
|
getScoreboard,
|
||||||
} from "../../src/services/scoreboardService.js";
|
} from "../../src/services/scoreboardService";
|
||||||
import {
|
import {
|
||||||
precomputeScoreboardCache,
|
precomputeScoreboardCache,
|
||||||
snapshotRankForUser,
|
snapshotRankForUser,
|
||||||
} from "../../src/services/rankSnapshotService.js";
|
} from "../../src/services/rankSnapshotService";
|
||||||
import { todayKst } from "../../src/types/dateString.js";
|
import { todayKst } from "../../src/types/dateString";
|
||||||
import { TeamCode, type RankSnapshot } from "../../src/types/panit.js";
|
import { TeamCode, type RankSnapshot } from "../../src/types/panit";
|
||||||
|
|
||||||
interface SeedUser {
|
interface SeedUser {
|
||||||
uid: string;
|
uid: string;
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
import { beforeEach, describe, expect, it } from "vitest";
|
import { beforeEach, describe, expect, it } from "vitest";
|
||||||
import { Timestamp } from "firebase-admin/firestore";
|
import { Timestamp } from "firebase-admin/firestore";
|
||||||
import { firestore, rtdb } from "../../src/firebase.js";
|
import { firestore, rtdb } from "../../src/firebase";
|
||||||
import { getStats } from "../../src/services/statsService.js";
|
import { getStats } from "../../src/services/statsService";
|
||||||
import {
|
import {
|
||||||
addDaysKst,
|
addDaysKst,
|
||||||
todayKst,
|
todayKst,
|
||||||
type DateString,
|
type DateString,
|
||||||
} from "../../src/types/dateString.js";
|
} from "../../src/types/dateString";
|
||||||
import type {
|
import type {
|
||||||
Game,
|
Game,
|
||||||
GameStatus,
|
GameStatus,
|
||||||
StatsResponse,
|
StatsResponse,
|
||||||
User,
|
User,
|
||||||
} from "../../src/types/panit.js";
|
} from "../../src/types/panit";
|
||||||
|
|
||||||
const uid = "stats-uid";
|
const uid = "stats-uid";
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
import { beforeEach, describe, expect, it } from "vitest";
|
import { beforeEach, describe, expect, it } from "vitest";
|
||||||
import type { DecodedIdToken } from "firebase-admin/auth";
|
import type { DecodedIdToken } from "firebase-admin/auth";
|
||||||
import { firestore, rtdb } from "../../src/firebase.js";
|
import { firestore, rtdb } from "../../src/firebase";
|
||||||
import {
|
import {
|
||||||
checkNickname,
|
checkNickname,
|
||||||
createMe,
|
createMe,
|
||||||
deleteMe,
|
deleteMe,
|
||||||
getMe,
|
getMe,
|
||||||
updateMe,
|
updateMe,
|
||||||
} from "../../src/services/userService.js";
|
} from "../../src/services/userService";
|
||||||
import { HttpError } from "../../src/middleware/errors.js";
|
import { HttpError } from "../../src/middleware/errors";
|
||||||
import {
|
import {
|
||||||
RESERVATION_TTL_MS,
|
RESERVATION_TTL_MS,
|
||||||
reserveNickname,
|
reserveNickname,
|
||||||
} from "../../src/repositories/nicknameRepository.js";
|
} from "../../src/repositories/nicknameRepository";
|
||||||
|
|
||||||
const uid = "user-1";
|
const uid = "user-1";
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user