Remove redundant .js extensions from import paths.

- TypeScript 소스 파일 내 모든 import 구문에서 불필요한 `.js` 확장자를 제거하여 모듈 참조 방식을 표준화했습니다.
- 핸들러, 서비스, 리포지토리 및 테스트 코드를 포함한 프로젝트 전반의 import 경로를 일관성 있게 정리했습니다.
This commit is contained in:
윤정민 2026-05-06 16:17:51 +09:00
parent 7496cb7de7
commit c94ce69e4f
58 changed files with 221 additions and 221 deletions

View File

@ -1,4 +1,4 @@
import type { DailyJudgment } from "../types/panit.js";
import type { DailyJudgment } from "../types/panit";
export interface Thresholds {
success: number;

View File

@ -1,4 +1,4 @@
import type { TierName } from "../types/panit.js";
import type { TierName } from "../types/panit";
interface TierStep {
name: TierName;

View File

@ -1,7 +1,7 @@
import { onRequest } from "firebase-functions/https";
import { requireAdmin } from "../middleware/admin.js";
import { sendError } from "../middleware/errors.js";
import { markGameEnded } from "../services/gameResultService.js";
import { requireAdmin } from "../middleware/admin";
import { sendError } from "../middleware/errors";
import { markGameEnded } from "../services/gameResultService";
export const admin = onRequest(async (req, res) => {
const segs = req.path.replace(/^\/+|\/+$/g, "").split("/");

View File

@ -1,9 +1,9 @@
import { onRequest } from "firebase-functions/https";
import { logger } from "firebase-functions";
import { runDailyArchive } from "../scheduled/dailyArchive.js";
import { syncYesterdayFromLive } from "../services/gameSyncService.js";
import { sendError } from "../middleware/errors.js";
import { daysAgoKst, parseDateString } from "../types/dateString.js";
import { runDailyArchive } from "../scheduled/dailyArchive";
import { syncYesterdayFromLive } from "../services/gameSyncService";
import { sendError } from "../middleware/errors";
import { daysAgoKst, parseDateString } from "../types/dateString";
/**
* . .

View File

@ -1,10 +1,10 @@
import { onRequest } from "firebase-functions/https";
import { getRank } from "../services/rankService.js";
import { getSchedule } from "../services/scheduleService.js";
import { getPlayerStats, getValidPlayerTypes } from "../services/playerService.js";
import { getGameList } from "../services/gameListService.js";
import { getGameDetail } from "../services/gameDetailService.js";
import { TeamCode } from "../types/panit.js";
import { getRank } from "../services/rankService";
import { getSchedule } from "../services/scheduleService";
import { getPlayerStats, getValidPlayerTypes } from "../services/playerService";
import { getGameList } from "../services/gameListService";
import { getGameDetail } from "../services/gameDetailService";
import { TeamCode } from "../types/panit";
enum KboPath {
Rank = "rank",

View File

@ -1,14 +1,14 @@
import { onRequest } from "firebase-functions/https";
import { requireAuth } from "../middleware/auth.js";
import { HttpError, sendError } from "../middleware/errors.js";
import { requireAuth } from "../middleware/auth";
import { HttpError, sendError } from "../middleware/errors";
import {
createPrediction,
updatePrediction,
getMyVotes,
getSummary,
listGamesByDate,
} from "../services/predictionService.js";
import { getScoreboard } from "../services/scoreboardService.js";
} from "../services/predictionService";
import { getScoreboard } from "../services/scoreboardService";
export const prediction = onRequest(async (req, res) => {
const segs = req.path.replace(/^\/+|\/+$/g, "").split("/");

View File

@ -1,7 +1,7 @@
import { onRequest } from "firebase-functions/https";
import { requireAuth } from "../middleware/auth.js";
import { sendError } from "../middleware/errors.js";
import { getStats, getHistory } from "../services/statsService.js";
import { requireAuth } from "../middleware/auth";
import { sendError } from "../middleware/errors";
import { getStats, getHistory } from "../services/statsService";
export const stats = onRequest(async (req, res) => {
const segs = req.path.replace(/^\/+|\/+$/g, "").split("/");

View File

@ -1,13 +1,13 @@
import { onRequest } from "firebase-functions/https";
import { requireAuthToken } from "../middleware/auth.js";
import { sendError } from "../middleware/errors.js";
import { requireAuthToken } from "../middleware/auth";
import { sendError } from "../middleware/errors";
import {
checkNickname,
createMe,
deleteMe,
getMe,
updateMe,
} from "../services/userService.js";
} from "../services/userService";
export const user = onRequest(async (req, res) => {
try {

View File

@ -1,4 +1,4 @@
import { extractHiddenField } from "./html-utils.js";
import { extractHiddenField } from "./html-utils";
export const PREFIX =
"ctl00$ctl00$ctl00$cphContents$cphContents$cphContents$";

View File

@ -14,7 +14,7 @@
* --series= (schedule: 정규//)
*/
import { padCell } from "./html-utils.js";
import { padCell } from "./html-utils";
import {
fetchTeamRankInitial,
fetchTeamRank,
@ -22,7 +22,7 @@ import {
type TeamVsRecord,
type TeamRankResult,
type WinLossDraw,
} from "./team-rank.js";
} from "./team-rank";
import {
fetchPlayerStatsInitial,
fetchPlayerStats,
@ -31,25 +31,25 @@ import {
type PlayerPageConfig,
type PlayerFilters,
type PlayerStatsResult,
} from "./player/common.js";
import { HITTER_CONFIG } from "./player/hitter.js";
import { PITCHER_CONFIG } from "./player/pitcher.js";
import { DEFENSE_CONFIG } from "./player/defense.js";
import { RUNNER_CONFIG } from "./player/runner.js";
} from "./player/common";
import { HITTER_CONFIG } from "./player/hitter";
import { PITCHER_CONFIG } from "./player/pitcher";
import { DEFENSE_CONFIG } from "./player/defense";
import { RUNNER_CONFIG } from "./player/runner";
import {
fetchSchedule,
SERIES_CODES,
type ScheduleGame,
type ScheduleResult,
} from "./schedule.js";
} from "./schedule";
import {
fetchGameList,
LEAGUE_CODES,
LeagueCode,
type GameListRecord,
type GameListResult,
} from "./game-list.js";
import { fetchGameDetail, type GameDetail } from "./game-detail.js";
} from "./game-list";
import { fetchGameDetail, type GameDetail } from "./game-detail";
const PLAYER_CONFIGS: Record<string, PlayerPageConfig> = {
hitter: HITTER_CONFIG,

View File

@ -1,7 +1,7 @@
import { stripTags, decodeHtmlEntities } from "./html-utils.js";
import { LeagueCode, LEAGUE_CODES } from "./game-list.js";
import { SERIES_ID } from "./schedule.js";
import { fetchScoringPlays, type GameScoringPlays } from "./play-by-play.js";
import { stripTags, decodeHtmlEntities } from "./html-utils";
import { LeagueCode, LEAGUE_CODES } from "./game-list";
import { SERIES_ID } from "./schedule";
import { fetchScoringPlays, type GameScoringPlays } from "./play-by-play";
const BASE_URL = "https://www.koreabaseball.com/ws/Schedule.asmx";

View File

@ -1,4 +1,4 @@
import { SERIES_CODES } from "./schedule.js";
import { SERIES_CODES } from "./schedule";
export { SERIES_CODES };

View File

@ -1,11 +1,11 @@
import { stripTags, decodeHtmlEntities } from "../html-utils.js";
import { stripTags, decodeHtmlEntities } from "../html-utils";
import {
PREFIX,
postback,
getInitialPageState,
type PageState,
type PostbackResponse,
} from "../aspnet-client.js";
} from "../aspnet-client";
const SM_KEY = `${PREFIX}smData`;
const UPDATE_PANEL = `${PREFIX}udpContent`;
@ -39,7 +39,7 @@ export interface PlayerPageConfig {
* .
*
* @example
* import type { HitterStats } from "./hitter.js";
* import type { HitterStats } from "./hitter";
* const hitter = record as HitterStats;
* console.log(hitter.avg, hitter.hr);
*/

View File

@ -1,4 +1,4 @@
import type { PlayerPageConfig, PlayerValue } from "./common.js";
import type { PlayerPageConfig, PlayerValue } from "./common";
export const DEFENSE_COLUMNS = [
"rank", "player", "team", "pos", "games", "gs", "ip",

View File

@ -1,4 +1,4 @@
import type { PlayerPageConfig, PlayerValue } from "./common.js";
import type { PlayerPageConfig, PlayerValue } from "./common";
export const HITTER_COLUMNS = [
"rank", "player", "team", "avg", "games", "pa", "ab",

View File

@ -1,4 +1,4 @@
import type { PlayerPageConfig, PlayerValue } from "./common.js";
import type { PlayerPageConfig, PlayerValue } from "./common";
export const PITCHER_COLUMNS = [
"rank", "player", "team", "era", "games", "wins", "losses",

View File

@ -1,4 +1,4 @@
import type { PlayerPageConfig, PlayerValue } from "./common.js";
import type { PlayerPageConfig, PlayerValue } from "./common";
export const RUNNER_COLUMNS = [
"rank", "player", "team", "games", "sba", "sb", "cs",

View File

@ -1,6 +1,6 @@
import { stripTags, decodeHtmlEntities } from "./html-utils.js";
import { TEAM_CODES } from "./player/common.js";
import { fetchGameList, type PersonRef } from "./game-list.js";
import { stripTags, decodeHtmlEntities } from "./html-utils";
import { TEAM_CODES } from "./player/common";
import { fetchGameList, type PersonRef } from "./game-list";
function toTeamCode(name: string): string {
return TEAM_CODES[name] ?? name;

View File

@ -1,11 +1,11 @@
import { stripTags, decodeHtmlEntities } from "./html-utils.js";
import { stripTags, decodeHtmlEntities } from "./html-utils";
import {
PREFIX,
postback,
getInitialPageState,
type PageState,
type PostbackResponse,
} from "./aspnet-client.js";
} from "./aspnet-client";
const PAGE_URL =
"https://www.koreabaseball.com/Record/TeamRank/TeamRank.aspx";

View File

@ -1,6 +1,6 @@
import type { Request } from "firebase-functions/https";
import { auth } from "../firebase.js";
import { HttpError } from "./errors.js";
import { auth } from "../firebase";
import { HttpError } from "./errors";
export async function requireAdmin(req: Request): Promise<string> {
const header = req.get("authorization") ?? req.get("Authorization");

View File

@ -1,7 +1,7 @@
import type { Request } from "firebase-functions/https";
import type { DecodedIdToken } from "firebase-admin/auth";
import { auth } from "../firebase.js";
import { HttpError } from "./errors.js";
import { auth } from "../firebase";
import { HttpError } from "./errors";
export async function requireAuthToken(req: Request): Promise<DecodedIdToken> {
const header = req.get("authorization") ?? req.get("Authorization");

View File

@ -1,7 +1,7 @@
import { Timestamp } from "firebase-admin/firestore";
import { firestore } from "../firebase.js";
import type { Game } from "../types/panit.js";
import { startOfDayKst, type DateString } from "../types/dateString.js";
import { firestore } from "../firebase";
import type { Game } from "../types/panit";
import { startOfDayKst, type DateString } from "../types/dateString";
const COLLECTION = "games";

View File

@ -1,5 +1,5 @@
import { FieldValue } from "firebase-admin/firestore";
import { firestore } from "../firebase.js";
import { firestore } from "../firebase";
const CACHE_COLLECTION = "kboCache";
const LOCK_COLLECTION = "kboLocks";

View File

@ -2,14 +2,14 @@ import {
fetchTeamRankInitial,
fetchTeamRank,
type TeamRankResult,
} from "../kbo/team-rank.js";
} from "../kbo/team-rank";
import {
fetchSchedule,
type ScheduleFilters,
type ScheduleResult,
type ScheduleGame,
type GameStatus,
} from "../kbo/schedule.js";
} from "../kbo/schedule";
import {
fetchPlayerStatsInitial,
fetchPlayerStats,
@ -17,17 +17,17 @@ import {
type PlayerPageConfig,
type PlayerFilters,
type PlayerStatsResult,
} from "../kbo/player/common.js";
} from "../kbo/player/common";
import {
encodeKey,
getOrFetch,
setCached,
acquireLock,
releaseLock,
} from "./kboCacheRepository.js";
import { firestore } from "../firebase.js";
import { getGameList } from "../services/gameListService.js";
import type { GameListRecord } from "../kbo/game-list.js";
} from "./kboCacheRepository";
import { firestore } from "../firebase";
import { getGameList } from "../services/gameListService";
import type { GameListRecord } from "../kbo/game-list";
const TTL_MS = 60 * 60 * 1000; // 1 hour

View File

@ -1,5 +1,5 @@
import { rtdb } from "../firebase.js";
import { HttpError } from "../middleware/errors.js";
import { rtdb } from "../firebase";
import { HttpError } from "../middleware/errors";
export const RESERVATION_TTL_MS = 10 * 60 * 1000;

View File

@ -1,7 +1,7 @@
import { rtdb } from "../firebase.js";
import type { DateString } from "../types/dateString.js";
import type { TeamCode } from "../types/panit.js";
import type { ScoreboardScopeCache } from "../types/scoreboard.js";
import { rtdb } from "../firebase";
import type { DateString } from "../types/dateString";
import type { TeamCode } from "../types/panit";
import type { ScoreboardScopeCache } from "../types/scoreboard";
const BASE = "/scoreboardCache";

View File

@ -1,6 +1,6 @@
import { firestore } from "../firebase.js";
import type { VoteHistoryDoc } from "../types/panit.js";
import type { DateString } from "../types/dateString.js";
import { firestore } from "../firebase";
import type { VoteHistoryDoc } from "../types/panit";
import type { DateString } from "../types/dateString";
/**
* voteHistory .

View File

@ -1,7 +1,7 @@
import { ServerValue } from "firebase-admin/database";
import { rtdb } from "../firebase.js";
import type { VoteEntry } from "../types/panit.js";
import type { DateString } from "../types/dateString.js";
import { rtdb } from "../firebase";
import type { VoteEntry } from "../types/panit";
import type { DateString } from "../types/dateString";
/**
* .

View File

@ -1,23 +1,23 @@
import { onSchedule } from "firebase-functions/scheduler";
import { logger } from "firebase-functions";
import { rtdb } from "../firebase.js";
import { setDay } from "../repositories/voteHistoryRepository.js";
import { invalidateStats } from "../services/statsService.js";
import { judgeDay, judgeWeekIfNeeded } from "../services/judgmentService.js";
import { rtdb } from "../firebase";
import { setDay } from "../repositories/voteHistoryRepository";
import { invalidateStats } from "../services/statsService";
import { judgeDay, judgeWeekIfNeeded } from "../services/judgmentService";
import {
precomputeScoreboardCache,
snapshotRankForUser,
} from "../services/rankSnapshotService.js";
import { todayKst } from "../types/dateString.js";
import { getGame } from "../repositories/gameRepository.js";
import { deleteUserVoteGame } from "../repositories/voteRepository.js";
import { processGameEndWithGame } from "../services/gameResultService.js";
import type { VoteHistoryDoc } from "../types/panit.js";
} from "../services/rankSnapshotService";
import { todayKst } from "../types/dateString";
import { getGame } from "../repositories/gameRepository";
import { deleteUserVoteGame } from "../repositories/voteRepository";
import { processGameEndWithGame } from "../services/gameResultService";
import type { VoteHistoryDoc } from "../types/panit";
import {
dayOfWeekKst,
daysAgoKst,
type DateString,
} from "../types/dateString.js";
} from "../types/dateString";
interface RawVote {
team: string;

View File

@ -1,15 +1,15 @@
import { onSchedule } from "firebase-functions/scheduler";
import { logger } from "firebase-functions";
import { firestore } from "../firebase.js";
import { firestore } from "../firebase";
import {
fetchRankFromKbo,
fetchScheduleFromKbo,
} from "../repositories/kboRepository.js";
} from "../repositories/kboRepository";
import {
syncGamesForMonth,
syncYesterdayFromLive,
} from "../services/gameSyncService.js";
import { daysAgoKst } from "../types/dateString.js";
} from "../services/gameSyncService";
import { daysAgoKst } from "../types/dateString";
const CACHE_COLLECTION = "kboCache";

View File

@ -3,14 +3,14 @@ import {
type GameDetail,
type GameDetailFilters,
type ScoreBoardMeta,
} from "../kbo/game-detail.js";
} from "../kbo/game-detail";
import {
encodeKey,
getCached,
setCached,
acquireLock,
releaseLock,
} from "../repositories/kboCacheRepository.js";
} from "../repositories/kboCacheRepository";
const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;
const ONE_HOUR_MS = 60 * 60 * 1000;

View File

@ -4,8 +4,8 @@ import {
LeagueCode,
SERIES_CODES,
type GameListResult,
} from "../kbo/game-list.js";
import { MemCache } from "../lib/memCache.js";
} from "../kbo/game-list";
import { MemCache } from "../lib/memCache";
// 게임센터(GetKboGameList)는 다른 KBO 데이터와 달리 Firestore 공유 캐시
// (kboCacheRepository) 대신 인스턴스 단위 인메모리 캐시를 쓴다.

View File

@ -1,12 +1,12 @@
import { FieldValue } from "firebase-admin/firestore";
import { logger } from "firebase-functions";
import { firestore, rtdb } from "../firebase.js";
import { HttpError } from "../middleware/errors.js";
import { getGame } from "../repositories/gameRepository.js";
import { getAllUserVotes, deleteGameVotes } from "../repositories/voteRepository.js";
import { invalidateStats } from "./statsService.js";
import { fromTimestamp } from "../types/dateString.js";
import type { Game } from "../types/panit.js";
import { firestore, rtdb } from "../firebase";
import { HttpError } from "../middleware/errors";
import { getGame } from "../repositories/gameRepository";
import { getAllUserVotes, deleteGameVotes } from "../repositories/voteRepository";
import { invalidateStats } from "./statsService";
import { fromTimestamp } from "../types/dateString";
import type { Game } from "../types/panit";
export async function processGameEnd(gameId: string): Promise<{ processed: number }> {
const game = await getGame(gameId);

View File

@ -1,13 +1,13 @@
import { Timestamp } from "firebase-admin/firestore";
import { firestore } from "../firebase.js";
import { firestore } from "../firebase";
import {
fetchScheduleFromKbo,
statusFromRecord,
} from "../repositories/kboRepository.js";
import { getGameList } from "./gameListService.js";
import type { GameListRecord } from "../kbo/game-list.js";
import type { ScheduleGame, GameStatus } from "../kbo/schedule.js";
import type { Game } from "../types/panit.js";
} from "../repositories/kboRepository";
import { getGameList } from "./gameListService";
import type { GameListRecord } from "../kbo/game-list";
import type { ScheduleGame, GameStatus } from "../kbo/schedule";
import type { Game } from "../types/panit";
const COLLECTION = "games";

View File

@ -1,18 +1,18 @@
import { logger } from "firebase-functions";
import { listByDate } from "../repositories/gameRepository.js";
import { getRange, setDay } from "../repositories/voteHistoryRepository.js";
import { listByDate } from "../repositories/gameRepository";
import { getRange, setDay } from "../repositories/voteHistoryRepository";
import {
applyDailyJudgmentTx,
applyWeeklyMasterTx,
getUser,
} from "../repositories/userRepository.js";
} from "../repositories/userRepository";
import {
judgeByCounts,
streakBonus,
thresholdsFor,
} from "../constants/judgment.js";
import type { DailyJudgment, VoteHistoryDoc } from "../types/panit.js";
import { addDaysKst, tuesdayOf, type DateString } from "../types/dateString.js";
} from "../constants/judgment";
import type { DailyJudgment, VoteHistoryDoc } from "../types/panit";
import { addDaysKst, tuesdayOf, type DateString } from "../types/dateString";
/**
* `(lastJudged, upTo)` ( ) ** **(=`thresholdsFor`

View File

@ -1,10 +1,10 @@
import { fetchPlayerFromKbo } from "../repositories/kboRepository.js";
import type { PlayerFilters, PlayerPageConfig, PlayerStatsResult } from "../types/kbo.js";
import { TeamCode } from "../types/panit.js";
import { HITTER_CONFIG } from "../kbo/player/hitter.js";
import { PITCHER_CONFIG } from "../kbo/player/pitcher.js";
import { DEFENSE_CONFIG } from "../kbo/player/defense.js";
import { RUNNER_CONFIG } from "../kbo/player/runner.js";
import { fetchPlayerFromKbo } from "../repositories/kboRepository";
import type { PlayerFilters, PlayerPageConfig, PlayerStatsResult } from "../types/kbo";
import { TeamCode } from "../types/panit";
import { HITTER_CONFIG } from "../kbo/player/hitter";
import { PITCHER_CONFIG } from "../kbo/player/pitcher";
import { DEFENSE_CONFIG } from "../kbo/player/defense";
import { RUNNER_CONFIG } from "../kbo/player/runner";
const PLAYER_CONFIGS: Record<string, PlayerPageConfig> = {
hitter: HITTER_CONFIG,

View File

@ -1,15 +1,15 @@
import { HttpError } from "../middleware/errors.js";
import { getGame, listByDate, type GameWithId } from "../repositories/gameRepository.js";
import { HttpError } from "../middleware/errors";
import { getGame, listByDate, type GameWithId } from "../repositories/gameRepository";
import {
getUserVote,
submitVote,
changeVote,
getCounts,
getUserDateVotes,
} from "../repositories/voteRepository.js";
import type { Game, VoteEntry } from "../types/panit.js";
import { fromTimestamp, parseDateString, type DateString } from "../types/dateString.js";
import { MemCache } from "../lib/memCache.js";
} from "../repositories/voteRepository";
import type { Game, VoteEntry } from "../types/panit";
import { fromTimestamp, parseDateString, type DateString } from "../types/dateString";
import { MemCache } from "../lib/memCache";
type SummaryCounts = { homeCount: number; awayCount: number };

View File

@ -1,5 +1,5 @@
import { fetchRankFromKbo } from "../repositories/kboRepository.js";
import type { TeamRankResult } from "../types/kbo.js";
import { fetchRankFromKbo } from "../repositories/kboRepository";
import type { TeamRankResult } from "../types/kbo";
export async function getRank(years: number[]): Promise<TeamRankResult[]> {
return fetchRankFromKbo(years);

View File

@ -1,20 +1,20 @@
import { logger } from "firebase-functions";
import { firestore } from "../firebase.js";
import { firestore } from "../firebase";
import {
countRankedUsers,
countUsersAboveTierPoints,
getUser,
listTopByTierPoints,
type ScoreboardUserEntry,
} from "../repositories/userRepository.js";
import { writeScope, type Scope } from "../repositories/scoreboardCacheRepository.js";
import { computePercentile, deltaFor } from "./scoreboardHelpers.js";
import type { DateString } from "../types/dateString.js";
import { TeamCode, type RankSnapshot } from "../types/panit.js";
} from "../repositories/userRepository";
import { writeScope, type Scope } from "../repositories/scoreboardCacheRepository";
import { computePercentile, deltaFor } from "./scoreboardHelpers";
import type { DateString } from "../types/dateString";
import { TeamCode, type RankSnapshot } from "../types/panit";
import type {
ScoreboardEntry,
ScoreboardScopeCache,
} from "../types/scoreboard.js";
} from "../types/scoreboard";
/**
* 1 `tierPoints` rank를 count aggregation으로

View File

@ -1,7 +1,7 @@
import { fetchScheduleFromKbo } from "../repositories/kboRepository.js";
import { SERIES_CODES } from "../types/kbo.js";
import type { ScheduleResult } from "../types/kbo.js";
import type { TeamCode } from "../types/panit.js";
import { fetchScheduleFromKbo } from "../repositories/kboRepository";
import { SERIES_CODES } from "../types/kbo";
import type { ScheduleResult } from "../types/kbo";
import type { TeamCode } from "../types/panit";
export async function getSchedule(
year: number,

View File

@ -1,5 +1,5 @@
import type { Scope } from "../repositories/scoreboardCacheRepository.js";
import type { RankSnapshot } from "../types/panit.js";
import type { Scope } from "../repositories/scoreboardCacheRepository";
import type { RankSnapshot } from "../types/panit";
export function computePercentile(rank: number, totalCount: number): number {
if (totalCount <= 0) return 0;

View File

@ -1,22 +1,22 @@
import { MemCache } from "../lib/memCache.js";
import { MemCache } from "../lib/memCache";
import {
countUsersAboveTierPoints,
getUser,
} from "../repositories/userRepository.js";
} from "../repositories/userRepository";
import {
readScope,
type Scope,
} from "../repositories/scoreboardCacheRepository.js";
import { HttpError } from "../middleware/errors.js";
import { computePercentile, deltaFor } from "./scoreboardHelpers.js";
import { todayKst } from "../types/dateString.js";
import { type TeamCode } from "../types/panit.js";
} from "../repositories/scoreboardCacheRepository";
import { HttpError } from "../middleware/errors";
import { computePercentile, deltaFor } from "./scoreboardHelpers";
import { todayKst } from "../types/dateString";
import { type TeamCode } from "../types/panit";
import type {
ScoreboardEntry,
ScoreboardResponse,
ScoreboardScopeCache,
ScoreboardType,
} from "../types/scoreboard.js";
} from "../types/scoreboard";
const BURST_TTL_MS = 30_000;

View File

@ -1,11 +1,11 @@
import {rtdb} from "../firebase.js";
import {HttpError} from "../middleware/errors.js";
import {computeLevel} from "../constants/levels.js";
import {tierOf} from "../constants/tiers.js";
import {getAll, getDay} from "../repositories/voteHistoryRepository.js";
import {getUser} from "../repositories/userRepository.js";
import {hasMissedGameDayBetween} from "./judgmentService.js";
import type {DailyJudgment, StatsResponse, VoteHistoryDoc} from "../types/panit.js";
import {rtdb} from "../firebase";
import {HttpError} from "../middleware/errors";
import {computeLevel} from "../constants/levels";
import {tierOf} from "../constants/tiers";
import {getAll, getDay} from "../repositories/voteHistoryRepository";
import {getUser} from "../repositories/userRepository";
import {hasMissedGameDayBetween} from "./judgmentService";
import type {DailyJudgment, StatsResponse, VoteHistoryDoc} from "../types/panit";
import {
addDaysKst,
parseDateString,
@ -14,7 +14,7 @@ import {
todayKst,
tuesdayOf as tuesdayOfUtil,
type DateString,
} from "../types/dateString.js";
} from "../types/dateString";
type Period =
| "current"

View File

@ -1,27 +1,27 @@
import type { DecodedIdToken } from "firebase-admin/auth";
import { FieldValue } from "firebase-admin/firestore";
import { HttpError } from "../middleware/errors.js";
import { auth } from "../firebase.js";
import { HttpError } from "../middleware/errors";
import { auth } from "../firebase";
import {
createUser,
deleteUser,
findUidByDisplayName,
getUser,
updateUser,
} from "../repositories/userRepository.js";
} from "../repositories/userRepository";
import {
deleteReservation,
releaseReservation,
reserveNickname,
verifyReservation,
} from "../repositories/nicknameRepository.js";
} from "../repositories/nicknameRepository";
import {
KnowledgeLevel,
TeamCode,
type Provider,
type User,
type UserProfile,
} from "../types/panit.js";
} from "../types/panit";
/**
* User .

View File

@ -1,14 +1,14 @@
import {onDocumentUpdated} from "firebase-functions/firestore";
import {logger} from "firebase-functions";
import {rtdb} from "../firebase.js";
import {processGameEndWithGame} from "../services/gameResultService.js";
import {rtdb} from "../firebase";
import {processGameEndWithGame} from "../services/gameResultService";
import {
getAllUserVotes,
deleteGameVotes,
} from "../repositories/voteRepository.js";
import {invalidateStats} from "../services/statsService.js";
import {fromTimestamp} from "../types/dateString.js";
import type {Game} from "../types/panit.js";
} from "../repositories/voteRepository";
import {invalidateStats} from "../services/statsService";
import {fromTimestamp} from "../types/dateString";
import type {Game} from "../types/panit";
/**
* `games/{gameId}` Firestore .

View File

@ -6,32 +6,32 @@ export type {
WinLossDraw,
TeamVsRecord,
TeamRankResult,
} from "../kbo/team-rank.js";
} from "../kbo/team-rank";
export type {
GameStatus,
ScheduleGame,
ScheduleFilters,
ScheduleResult,
} from "../kbo/schedule.js";
} from "../kbo/schedule";
export type {
PlayerPageConfig,
PlayerRecord,
PlayerFilters,
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 {
GameListFilters,
GameListRecord,
GameListResult,
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 {
GameDetail,
@ -50,7 +50,7 @@ export type {
KeyPlayerRanking,
KeyPlayerItem,
KeyPlayerGroup,
} from "../kbo/game-detail.js";
} from "../kbo/game-detail";
export type {
GameScoringPlays,
@ -61,6 +61,6 @@ export type {
ScoringOutcome,
BaseState,
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";

View File

@ -1,5 +1,5 @@
import type { Timestamp } from "firebase-admin/firestore";
import type { DateString } from "./dateString.js";
import type { DateString } from "./dateString";
export type Provider = "google" | "apple";

View File

@ -1,4 +1,4 @@
import type { TeamCode } from "./panit.js";
import type { TeamCode } from "./panit";
export interface ScoreboardEntry {
uid: string;

View File

@ -1,8 +1,8 @@
import { beforeEach, describe, expect, it } from "vitest";
import { Timestamp } from "firebase-admin/firestore";
import { firestore } from "../../src/firebase.js";
import { getGame, listByDate } from "../../src/repositories/gameRepository.js";
import type { DateString } from "../../src/types/dateString.js";
import { firestore } from "../../src/firebase";
import { getGame, listByDate } from "../../src/repositories/gameRepository";
import type { DateString } from "../../src/types/dateString";
describe("gameRepository", () => {
beforeEach(async () => {

View File

@ -1,9 +1,9 @@
import { beforeEach, describe, expect, it } from "vitest";
import { firestore } from "../../src/firebase.js";
import { firestore } from "../../src/firebase";
import {
fetchRankFromKbo,
fetchScheduleFromKbo,
} from "../../src/repositories/kboRepository.js";
} from "../../src/repositories/kboRepository";
describe("kboRepository (실제 KBO 사이트 호출)", () => {
beforeEach(async () => {

View File

@ -1,13 +1,13 @@
import { beforeEach, describe, expect, it } from "vitest";
import { firestore } from "../../src/firebase.js";
import { firestore } from "../../src/firebase";
import {
getAll,
getDay,
getRange,
setDay,
} from "../../src/repositories/voteHistoryRepository.js";
import type { DateString } from "../../src/types/dateString.js";
import type { VoteHistoryDoc } from "../../src/types/panit.js";
} from "../../src/repositories/voteHistoryRepository";
import type { DateString } from "../../src/types/dateString";
import type { VoteHistoryDoc } from "../../src/types/panit";
const uid = "test-uid-1";

View File

@ -1,5 +1,5 @@
import { beforeEach, describe, expect, it } from "vitest";
import { rtdb } from "../../src/firebase.js";
import { rtdb } from "../../src/firebase";
import {
changeVote,
deleteGameVotes,
@ -8,8 +8,8 @@ import {
getUserDateVotes,
getUserVote,
submitVote,
} from "../../src/repositories/voteRepository.js";
import type { DateString } from "../../src/types/dateString.js";
} from "../../src/repositories/voteRepository";
import type { DateString } from "../../src/types/dateString";
const gameId = "20260412HTLG0";
const gameId2 = "20260412WOSK0";

View File

@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it } from "vitest";
import { firestore } from "../../src/firebase.js";
import { getGameDetail } from "../../src/services/gameDetailService.js";
import { firestore } from "../../src/firebase";
import { getGameDetail } from "../../src/services/gameDetailService";
// 실제 KBO 게임센터 + Firestore 에뮬레이터를 함께 사용한다.
// nested-array Firestore 거부, parseGameStartTs NPE 등 회귀를 잡기 위함.

View File

@ -1,13 +1,13 @@
import { beforeEach, describe, expect, it } from "vitest";
import { firestore } from "../../src/firebase.js";
import { firestore } from "../../src/firebase";
import {
toGameDoc,
toTime,
syncGamesForMonth,
gameUpdateFromRecord,
} from "../../src/services/gameSyncService.js";
import type { ScheduleGame } from "../../src/kbo/schedule.js";
import type { GameListRecord } from "../../src/kbo/game-list.js";
} from "../../src/services/gameSyncService";
import type { ScheduleGame } from "../../src/kbo/schedule";
import type { GameListRecord } from "../../src/kbo/game-list";
function baseGame(overrides: Partial<ScheduleGame> = {}): ScheduleGame {
return {

View File

@ -1,19 +1,19 @@
import { beforeEach, describe, expect, it } from "vitest";
import { Timestamp } from "firebase-admin/firestore";
import { firestore } from "../../src/firebase.js";
import { firestore } from "../../src/firebase";
import {
judgeDay,
judgeWeekIfNeeded,
} from "../../src/services/judgmentService.js";
import { setDay } from "../../src/repositories/voteHistoryRepository.js";
import type { DateString } from "../../src/types/dateString.js";
} from "../../src/services/judgmentService";
import { setDay } from "../../src/repositories/voteHistoryRepository";
import type { DateString } from "../../src/types/dateString";
import type {
DailyJudgment,
Game,
GameStatus,
User,
VoteHistoryDoc,
} from "../../src/types/panit.js";
} from "../../src/types/panit";
const uid = "judge-uid";

View File

@ -1,15 +1,15 @@
import { beforeEach, describe, expect, it } from "vitest";
import { firestore, rtdb } from "../../src/firebase.js";
import { firestore, rtdb } from "../../src/firebase";
import {
__resetScoreboardCaches,
getScoreboard,
} from "../../src/services/scoreboardService.js";
} from "../../src/services/scoreboardService";
import {
precomputeScoreboardCache,
snapshotRankForUser,
} from "../../src/services/rankSnapshotService.js";
import { todayKst } from "../../src/types/dateString.js";
import { TeamCode, type RankSnapshot } from "../../src/types/panit.js";
} from "../../src/services/rankSnapshotService";
import { todayKst } from "../../src/types/dateString";
import { TeamCode, type RankSnapshot } from "../../src/types/panit";
interface SeedUser {
uid: string;

View File

@ -1,18 +1,18 @@
import { beforeEach, describe, expect, it } from "vitest";
import { Timestamp } from "firebase-admin/firestore";
import { firestore, rtdb } from "../../src/firebase.js";
import { getStats } from "../../src/services/statsService.js";
import { firestore, rtdb } from "../../src/firebase";
import { getStats } from "../../src/services/statsService";
import {
addDaysKst,
todayKst,
type DateString,
} from "../../src/types/dateString.js";
} from "../../src/types/dateString";
import type {
Game,
GameStatus,
StatsResponse,
User,
} from "../../src/types/panit.js";
} from "../../src/types/panit";
const uid = "stats-uid";

View File

@ -1,18 +1,18 @@
import { beforeEach, describe, expect, it } from "vitest";
import type { DecodedIdToken } from "firebase-admin/auth";
import { firestore, rtdb } from "../../src/firebase.js";
import { firestore, rtdb } from "../../src/firebase";
import {
checkNickname,
createMe,
deleteMe,
getMe,
updateMe,
} from "../../src/services/userService.js";
import { HttpError } from "../../src/middleware/errors.js";
} from "../../src/services/userService";
import { HttpError } from "../../src/middleware/errors";
import {
RESERVATION_TTL_MS,
reserveNickname,
} from "../../src/repositories/nicknameRepository.js";
} from "../../src/repositories/nicknameRepository";
const uid = "user-1";