feat(backend): 축제·공연·행사 동기화와 조회 API 추가

홈 '이번 주말 축제·행사'와 장소 상세 '근처 축제·행사'에 쓸 데이터를 채운다.

- place:sync -- event: 관광공사 searchFestival2 를 오늘~90일 기간으로 받아
  festival_event 에 upsert(서버는 기간이 겹치는 행사를 준다). 지역 조건을 보내고
  응답에서도 다른 지역 행사는 거른다. 상세(소개·요금·공연 시간·장소)는 새로 생기거나
  수정된 행사만 받는다. 기간 안에서 목록에 없는 행사는 숨긴다
- GET /api/events: 기간(기본 오늘~30일, 최대 92일)·근처(좌표+반경)·분류·커서.
  60일 넘는 상시 프로그램과 숨김 행사는 뺀다. 항목에 오늘 진행 중 여부
- GET /api/events/{id}: 소개·공연 시간·요금·장소·홈페이지·출처
- 마이그레이션: festival_event 에 분류 코드·지역 코드·장소명·전화·홈페이지·
  작은 사진·원본 수정일·상세 수신 시각 추가

e2e(test/festival.e2e-spec.ts)는 2030년 날짜·동해 좌표 픽스처라 실행 날짜와 무관하다.
2026-11-03 실측: 앞으로 90일 관광공사 행사는 전국 106건, 대구 1건, 경북 7건.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-03 19:30:08 +09:00
parent 55f10c5c7a
commit 295d74f4d3
16 changed files with 1437 additions and 14 deletions
+16 -1
View File
@@ -1,4 +1,9 @@
import { kstClock, kstStartOfDay, parseKstTimestamp } from './kst';
import {
kstClock,
kstDateString,
kstStartOfDay,
parseKstTimestamp,
} from './kst';
describe('kstStartOfDay', () => {
it('한국 날짜의 0시를 돌려준다', () => {
@@ -46,3 +51,13 @@ describe('kstClock', () => {
});
});
});
describe('kstDateString', () => {
it('한국 날짜를 돌려주고 날짜를 더할 수 있다', () => {
// 2026-11-02 23:30 UTC = 2026-11-03 08:30 KST
const now = new Date('2026-11-02T23:30:00Z');
expect(kstDateString(now)).toBe('2026-11-03');
expect(kstDateString(now, 90)).toBe('2027-02-01');
expect(kstDateString(now, -1)).toBe('2026-11-02');
});
});
+6
View File
@@ -43,3 +43,9 @@ export function kstClock(now: Date): { weekday: number; minutes: number } {
minutes: kst.getUTCHours() * 60 + kst.getUTCMinutes(),
};
}
/** 한국 날짜 'YYYY-MM-DD' — addDays 만큼 더하거나 뺀 날 */
export function kstDateString(now: Date, addDays = 0): string {
const kst = new Date(now.getTime() + KST_OFFSET_MS + addDays * 86_400_000);
return kst.toISOString().slice(0, 10);
}