9148c358d0
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를 Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류. - 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로 자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거, 동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거. - 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming, Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business, Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로, 나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는 title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백). 원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지. - 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서. - 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는 지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지. - Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경. - 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
5.9 KiB
5.9 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | tags | raw_sources | last_reinforced | github_commit | tech_stack | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| wiki-2026-0508-설정-객체-및-룩업-테이블-설계-configuration- | 설정 객체 및 룩업 테이블 설계(Configuration Objects and Lookup Tables) | 10_Wiki/Topics | verified | self |
|
none | A | 0.92 | applied |
|
2026-05-10 | pending |
|
설정 객체 및 룩업 테이블 설계(Configuration Objects and Lookup Tables)
매 한 줄
"매 if/switch chain 의 data structure (Map/Record) 의 substitute". 매 control flow 의 data 로 transform — 매 add/modify 의 O(1) extension, 매 type-safe (TS Record), 매 testable. Refactoring catalog (Fowler) 의 "Replace Conditional with Polymorphism" 의 lightweight variant.
매 핵심
매 substitute targets
- 매 Long if/else if chain.
- 매 Switch with simple return.
- 매 Magic-number/string branching.
- 매 Strategy pattern (lightweight).
매 lookup table 의 structure
- Map / Record: key → value/handler.
- Default fallback:
??or explicit default key. - Type-safe key: TypeScript
keyof/ discriminated union. - Frozen at module load:
as const/Object.freeze.
💻 패턴
Before (if-chain) → After (lookup)
// X — 매 add 의 매 modification 의 source
function getDiscount(tier: string): number {
if (tier === 'bronze') return 0.05;
else if (tier === 'silver') return 0.10;
else if (tier === 'gold') return 0.15;
else if (tier === 'platinum') return 0.20;
else return 0;
}
// O — data-driven, type-safe, O(1) lookup
const DISCOUNT = {
bronze: 0.05,
silver: 0.10,
gold: 0.15,
platinum: 0.20,
} as const satisfies Record<string, number>;
type Tier = keyof typeof DISCOUNT;
const getDiscount = (tier: Tier): number => DISCOUNT[tier] ?? 0;
Dispatch table (handler map)
type Action = 'create' | 'update' | 'delete';
const handlers: Record<Action, (id: string) => Promise<void>> = {
create: async (id) => api.create(id),
update: async (id) => api.update(id),
delete: async (id) => api.delete(id),
};
async function dispatch(action: Action, id: string) {
await handlers[action](id);
}
Discriminated union + exhaustive check
type Event =
| { type: 'click'; x: number; y: number }
| { type: 'key'; code: string }
| { type: 'scroll'; delta: number };
const reducer: { [K in Event['type']]: (e: Extract<Event, { type: K }>) => void } = {
click: (e) => console.log('click', e.x, e.y),
key: (e) => console.log('key', e.code),
scroll:(e) => console.log('scroll', e.delta),
};
function handle(e: Event) {
(reducer[e.type] as (e: Event) => void)(e);
}
Config object (UI variants)
const BUTTON_STYLE = {
primary: 'bg-blue-600 text-white hover:bg-blue-700',
secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300',
danger: 'bg-red-600 text-white hover:bg-red-700',
ghost: 'bg-transparent text-blue-600 hover:bg-blue-50',
} as const;
type Variant = keyof typeof BUTTON_STYLE;
export function Button({ variant = 'primary', children, ...rest }:
{ variant?: Variant; children: React.ReactNode } & React.ComponentProps<'button'>) {
return <button className={BUTTON_STYLE[variant]} {...rest}>{children}</button>;
}
Validation rule registry
const VALIDATORS = {
email: (v: string) => /^[^@]+@[^@]+\.[^@]+$/.test(v) || 'invalid email',
phone: (v: string) => /^\+?[\d\s-]{10,}$/.test(v) || 'invalid phone',
required: (v: string) => v.trim().length > 0 || 'required',
} as const;
function validate(field: keyof typeof VALIDATORS, value: string) {
return VALIDATORS[field](value);
}
Status code → message
const HTTP_MESSAGE: Record<number, string> = {
200: 'OK',
400: 'Bad Request',
401: 'Unauthorized',
403: 'Forbidden',
404: 'Not Found',
500: 'Server Error',
};
const messageFor = (code: number) => HTTP_MESSAGE[code] ?? 'Unknown';
i18n table
const I18N = {
en: { hello: 'Hello', bye: 'Bye' },
ko: { hello: '안녕', bye: '안녕히' },
ja: { hello: 'こんにちは', bye: 'さようなら' },
} as const;
type Lang = keyof typeof I18N;
type Key = keyof typeof I18N[Lang];
const t = (lang: Lang, key: Key) => I18N[lang][key];
매 결정 기준
| 상황 | Approach |
|---|---|
| 단순 mapping (key → value) | 매 plain Record |
| Behavior dispatch | 매 handler Map |
| Behavior + state | 매 Strategy class (full polymorphism) |
| 매 2-3 case | 매 if/ternary 의 OK — over-engineering 의 avoid |
| 매 5+ case | 매 lookup table 의 prefer |
| Runtime extension | 매 Map (mutable) |
| Compile-time freeze | as const satisfies Record<...> |
기본값: 매 5+ branch + simple value/handler → lookup. 매 type-safe as const satisfies.
🔗 Graph
- 부모: Refactoring Catalog · Clean Code
- 변형: Replace Conditional with Polymorphism
- Adjacent: Discriminated Union
🤖 LLM 활용
언제: 긴 if/switch chain 의 detect, refactor 의 propose, type 의 tighten. 언제 X: 매 stateful behavior — Strategy class 의 use.
❌ 안티패턴
- Mutable global table: 매 race + test pollution —
as const의 freeze. - Stringly-typed key:
Record<string, T>만 —keyof의 narrow. - Default 누락:
obj[key]의 undefined access —??의 add. - Side effect 의 handler: 매 lookup map 의 pure function 의 keep.
🧪 검증 / 중복
- Verified (Refactoring 2/e Fowler — "Replace Conditional with Polymorphism", Clean Code Martin Ch.6, TypeScript handbook Record).
- 신뢰도 A.
🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — lookup/dispatch/config 7 patterns 의 정리 |