feat(stocks): discover sector — 네이버 업종 코드 직접 조회로 재설계 (v2.2.250)
[버그] discover sector 가 항상 0개 반환. 원인: sectorHint 를 통합 API 의
없는 필드(industryInfo.name)에서 읽어 전 종목이 업종 미상 → 필터 전멸.
[근본 수정] "전 종목 시총 크롤 후 sectorHint 필터" → "네이버 업종 코드로
해당 섹터 종목 직접 조회". 실측: 2차전지 1000-5000억 0개 → 36개.
- stockSectors: 친화 섹터키 → 네이버 업종코드 묶음 (업종 79개 코드표). 17개 그룹.
- naverScreener.screenIndustry(): /api/stocks/industry/{code} 직접 수집 + 시총 필터 + dedup.
- naverFundamentals: sectorHint 를 industryCode→이름 매핑으로 수정 (기술력 키워드·judge 복구).
- stockDiscovery: 섹터 모드 3키워드 게이트 완화(≥1, "섹터 내 상대 추천").
- CLI: discover sector <섹터> [min] [max] / discover sectors.
테스트 8건. 라이브 e2e 확인.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* 섹터 분류·해석 (네이버 업종 코드 기반) — 순수 로직 테스트.
|
||||
*/
|
||||
import { resolveSectorQuery, listSectorKeys, SECTOR_GROUPS, NAVER_INDUSTRY_NAMES } from '../src/features/stocks/stockSectors';
|
||||
|
||||
describe('resolveSectorQuery', () => {
|
||||
test('친화 키 직접 입력', () => {
|
||||
expect(resolveSectorQuery('반도체')?.key).toBe('반도체');
|
||||
expect(resolveSectorQuery('2차전지')?.key).toBe('2차전지');
|
||||
expect(resolveSectorQuery('금융')?.key).toBe('금융');
|
||||
});
|
||||
test('영문/대체 별칭', () => {
|
||||
expect(resolveSectorQuery('semiconductor')?.key).toBe('반도체');
|
||||
expect(resolveSectorQuery('battery')?.key).toBe('2차전지');
|
||||
expect(resolveSectorQuery('배터리')?.key).toBe('2차전지');
|
||||
expect(resolveSectorQuery('bio')?.key).toBe('바이오/제약');
|
||||
});
|
||||
test('네이버 업종명 직접 입력 → 그 코드를 가진 그룹', () => {
|
||||
expect(resolveSectorQuery('제약')?.key).toBe('바이오/제약');
|
||||
expect(resolveSectorQuery('은행')?.key).toBe('금융');
|
||||
expect(resolveSectorQuery('조선')?.key).toBe('조선/기계');
|
||||
});
|
||||
test('대소문자 무시', () => {
|
||||
expect(resolveSectorQuery('SEMICON')?.key).toBe('반도체');
|
||||
});
|
||||
test('미지원 입력 → null', () => {
|
||||
expect(resolveSectorQuery('zzzqqq')).toBeNull();
|
||||
expect(resolveSectorQuery('')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('SECTOR_GROUPS 무결성', () => {
|
||||
test('모든 그룹이 유효한 네이버 업종 코드를 가진다', () => {
|
||||
for (const g of SECTOR_GROUPS) {
|
||||
expect(g.codes.length).toBeGreaterThan(0);
|
||||
for (const c of g.codes) {
|
||||
expect(NAVER_INDUSTRY_NAMES[c]).toBeDefined(); // 코드가 실제 업종명에 존재
|
||||
}
|
||||
}
|
||||
});
|
||||
test('핵심 섹터가 올바른 대표 코드를 가진다', () => {
|
||||
const semi = SECTOR_GROUPS.find(g => g.key === '반도체')!;
|
||||
expect(semi.codes).toContain(278); // 반도체와반도체장비
|
||||
const batt = SECTOR_GROUPS.find(g => g.key === '2차전지')!;
|
||||
expect(batt.codes).toContain(283); // 전기제품(2차전지)
|
||||
});
|
||||
test('listSectorKeys 는 모든 그룹 키', () => {
|
||||
expect(listSectorKeys()).toEqual(SECTOR_GROUPS.map(g => g.key));
|
||||
expect(listSectorKeys().length).toBeGreaterThanOrEqual(15);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user