Skip to content

Commit 6c6fc71

Browse files
committed
blog(ops): 운영 문서 3개 신규 + 3편 frontmatter tags/내부링크
- QUALITY_STANDARDS.md: 글 단위 품질 기준 8섹션 (수치 정직성 6원칙, 자기검토 12개, 거짓 사례 회귀) - DARTLAB_USAGE.md: dartlab 데이터 cookbook 8섹션 (호출 8패턴, 분기/연간/Q4 단위표, 표 작성 규칙) - SEO_PLAYBOOK.md: 글 단위 SEO 체크리스트 12개 + GEO/SGE/LLM 친화 조치 - TOPIC_ROADMAP.md: 주제별 블로그 사상 명시, 글 추가 패턴, 발간 목록 갱신 - 3편 frontmatter: tags 신규 도입, 같은 시리즈 내부 링크 추가, 데이터 기준일 갱신
1 parent 85388f5 commit 6c6fc71

7 files changed

Lines changed: 902 additions & 15 deletions

File tree

blog/05-company-reports/01-000660-skhynix/index.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
11
---
22
title: "SK하이닉스 (000660) — 한국 반도체 30년의 미스터리, 그리고 영업이익률 58%"
33
date: 2026-04-08
4-
description: "1983 현대전자로 시작해서 1999 LG반도체 인수, 2001 채권단 관리, 2012 SK 인수, 그리고 2025 영업이익률 58.4%. 30년의 미스터리를 dartlab으로 까보는 글이다."
4+
description: "1983 현대전자로 시작해 다섯 번 망할 뻔한 회사가 2025년 4분기 영업이익률 58.40%, 사상 처음으로 모회사 삼성전자를 추월했다. 9년 사이클 + 가격결정력 + CAPEX 27조 베팅을 dartlab으로 펼친다."
55
category: company-reports
66
series: company-reports
77
seriesOrder: 1
88
stockCode: "000660"
99
corpName: "SK하이닉스"
1010
storyTemplate: "장기 사이클 + 위기 탈출"
1111
grade: "dCR-AA"
12+
tags:
13+
- SK하이닉스
14+
- "000660"
15+
- 반도체
16+
- HBM
17+
- 메모리 사이클
18+
- 가격결정력
19+
- 전자공시
1220
thumbnail: /avatar-chart.png
1321
youtubeId: ""
1422
---
1523

16-
> **장기 사이클 + 위기 탈출** | IT > 메모리반도체 | 2026-04-07 기준
17-
> 데이터: dartlab Q1 2016 ~ Q4 2025 | 엔진: dartlab review + analysis + credit + report
24+
> **장기 사이클 + 위기 탈출** | IT > 메모리반도체 | 2026-04-08 dartlab 실측
25+
> 데이터: dartlab Q1 2016 ~ Q4 2025 | 엔진: review + analysis + credit + report
26+
> 같은 시리즈: [삼양식품 (003230)](../02-003230-samyang-foods/) · [두산에너빌리티 (034020)](../03-034020-doosan-enerbility/) · [기업분석 시리즈 전체](/blog/series/company-reports)
1827
1928
---
2029

blog/05-company-reports/02-003230-samyang-foods/index.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
11
---
22
title: "삼양식품 (003230) — 라면 빅3 꼴등이 매출 2.3조 글로벌 식품 거인이 되기까지"
3-
date: 2026-04-07
4-
description: "2014년 라면 시장 꼴등 회사가 9년 만에 영업이익률 21.83%, 매출 6.1배. 그 사이 한 사람의 매운맛 베팅이 있었고, 한 부부의 횡령 판결도 있었다."
3+
date: 2026-04-08
4+
description: "2014년 라면 시장 꼴등 회사가 9년 만에 영업이익률 21.83%, 매출 5.1배. 그 사이 한 사람의 매운맛 베팅이 있었고, 호황의 정중앙에서 잉여현금이 -1,397억으로 떨어지는 공격투자 사이클이 있었다."
55
category: company-reports
66
series: company-reports
77
seriesOrder: 2
88
stockCode: "003230"
99
corpName: "삼양식품"
1010
storyTemplate: "반전 폭발"
1111
grade: "dCR-AA-"
12+
tags:
13+
- 삼양식품
14+
- "003230"
15+
- 불닭볶음면
16+
- 식품
17+
- 고정비 레버리지
18+
- 미국 수출
19+
- 전자공시
1220
thumbnail: /avatar-chart.png
1321
youtubeId: ""
1422
---
1523

16-
> **반전 폭발 + 인물 중심** | 식품 > 라면 | 2026-04-07 기준
17-
> 데이터: dartlab Q1 2016 ~ Q4 2025 | 엔진: dartlab review + analysis + credit + report.dividend
24+
> **반전 폭발 + 인물 중심** | 식품 > 라면 | 2026-04-08 dartlab 실측
25+
> 데이터: dartlab Q1 2016 ~ Q4 2025 | 엔진: review + analysis + credit + report.dividend
26+
> 같은 시리즈: [SK하이닉스 (000660)](../01-000660-skhynix/) · [두산에너빌리티 (034020)](../03-034020-doosan-enerbility/) · [기업분석 시리즈 전체](/blog/series/company-reports)
1827
1928
---
2029

blog/05-company-reports/03-034020-doosan-enerbility/index.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,21 @@ stockCode: "034020"
99
corpName: "두산에너빌리티"
1010
storyTemplate: "위기 탈출"
1111
grade: "dCR-AA+"
12+
tags:
13+
- 두산에너빌리티
14+
- "034020"
15+
- 원자력
16+
- 발전소
17+
- 부채 다이어트
18+
- 체코 두코바니
19+
- 전자공시
1220
thumbnail: /avatar-chart.png
1321
youtubeId: ""
1422
---
1523

16-
> **위기 탈출 + 장기 사이클** | 산업재 > 발전·에너지 | 2026-04-07 기준
17-
> 데이터: dartlab Q1 2016 ~ Q4 2025 | 엔진: dartlab review + analysis + credit + report.dividend
24+
> **위기 탈출 + 장기 사이클** | 산업재 > 발전·에너지 | 2026-04-08 dartlab 실측
25+
> 데이터: dartlab Q1 2016 ~ Q4 2025 | 엔진: review + analysis + credit + report.dividend
26+
> 같은 시리즈: [SK하이닉스 (000660)](../01-000660-skhynix/) · [삼양식품 (003230)](../02-003230-samyang-foods/) · [기업분석 시리즈 전체](/blog/series/company-reports)
1827
1928
---
2029

blog/DARTLAB_USAGE.md

Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
# DartLab Data Cookbook for Blog Writing
2+
3+
블로그 한 편을 쓸 때 dartlab 데이터를 최대로 뽑는 방법. 미래의 내가 펴 놓고 작업할 cookbook.
4+
5+
관련 문서:
6+
- 글 단위 품질 기준: [QUALITY_STANDARDS.md](QUALITY_STANDARDS.md)
7+
- 자산/SVG 규칙: [ASSET_POLICY.md](ASSET_POLICY.md)
8+
9+
---
10+
11+
## 1. 공통 호출 패턴 8가지
12+
13+
블로그에 자주 등장하는 dartlab 호출. 이 패턴을 그대로 본문 코드블록에 박는다 — 독자가 복사 → 실행 → 검증할 수 있어야 한다.
14+
15+
### 1) IS 9년 시계열 (1년 합산)
16+
17+
```python
18+
import dartlab
19+
c = dartlab.Company("000660") # SK하이닉스
20+
21+
c.select("IS", ["매출액","매출원가","매출총이익","판매비와관리비","영업이익","당기순이익"])
22+
```
23+
24+
dartlab은 분기 컬럼(`2025Q4`, `2025Q3`, ...)을 반환한다. 1년치 합산이 필요하면 분기를 더한다:
25+
26+
```python
27+
df = c.select("IS", ["매출액"])
28+
row = df.row(0, named=True)
29+
annual = {y: sum(row.get(f"{y}Q{q}", 0) or 0 for q in range(1, 5)) for y in range(2017, 2026)}
30+
```
31+
32+
⚠ "분기 단독값"과 "1년 합산"을 표 안에 절대 섞지 말 것.
33+
34+
### 2) BS Q4 스냅샷
35+
36+
```python
37+
c.select("BS", ["자산총계","부채총계","자본총계","현금및현금성자산","단기금융상품"])
38+
```
39+
40+
BS는 시점 데이터다. 합산하지 말고 각 연도의 Q4 컬럼만 골라낸다:
41+
42+
```python
43+
df = c.select("BS", ["자산총계"])
44+
row = df.row(0, named=True)
45+
snapshots = {y: row.get(f"{y}Q4") for y in range(2017, 2026)}
46+
```
47+
48+
### 3) CF 9년 시계열 + 잉여현금 파생행
49+
50+
```python
51+
c.select("CF", ["영업활동현금흐름","유형자산의 취득","배당금지급"])
52+
```
53+
54+
CF에 들어갈 핵심 파생행: **영업CF − CAPEX = 잉여현금 (FCF)**.
55+
56+
이 한 행이 회사가 영업으로 번 돈만큼 공장을 짓는지, 아니면 곳간까지 깎고 있는지를 한눈에 보여준다. 본문 표에 반드시 포함.
57+
58+
### 4) 비율 분기 시계열
59+
60+
```python
61+
c.select("ratios", ["영업이익률 (%)","매출총이익률 (%)","부채비율 (%)"])
62+
```
63+
64+
`ratios` 토픽은 분기 단위. 본문 표 헤더는 `(분기, %)` 또는 `(Q4, %)`로 명시.
65+
66+
⚠ 같은 비율이 `c.analysis("financial","수익성")["marginWaterfall"]`에서는 1년치로 나온다. 두 출처를 같은 표에 섞으면 거짓이 생긴다.
67+
68+
### 5) 수익성 분석 — marginWaterfall, roicTree, penmanDecomposition
69+
70+
```python
71+
prof = c.analysis("financial", "수익성")
72+
73+
prof["marginWaterfall"]["history"][0] # 가장 최근 1년치 마진 분해
74+
prof["roicTree"]["history"][0] # ROIC 트리 (marginDriver 자체 출력)
75+
prof["penmanDecomposition"]["history"] # Penman RNOA/FLEV/NBC/Spread
76+
```
77+
78+
`marginDriver`는 dartlab 자체 분류이므로 본문에 직접 인용 가능. 인용 시 코드블록으로 명시:
79+
80+
```
81+
"marginDriver": "높은 가격결정력 (매출총이익률 > 40%)"
82+
```
83+
84+
### 6) 자금조달 — capitalOverview vs notesDetail.borrowings (가장 거짓이 많이 났던 자리)
85+
86+
```python
87+
fund = c.analysis("financial", "자금조달")
88+
89+
fund["capitalOverview"] # 표시용 요약 (총자산/총부채/자기자본/순차입금만)
90+
fund["fundingSources"]["notesDetail"]["borrowings"] # 차입금 항목별 상세
91+
```
92+
93+
`capitalOverview`의 "순차입금"은 dartlab 내부 정의가 있어 그대로 인용 OK. 단 **"총 차입금"이 필요하면 반드시 `notesDetail.borrowings`의 "합계" 행**을 써야 한다.
94+
95+
지난 라운드 거짓 사례: SK하이닉스 본문 "차입금 8.16조"는 `notesDetail.borrowings`의 "소계, 유동" 행이었다. 진짜 합계는 22.25조 (소계 유동 + 비유동).
96+
97+
### 7) 자본배분 — 배당 (두 출처 차이 주의)
98+
99+
```python
100+
ca = c.analysis("financial", "자본배분")
101+
ca["dividendPolicy"]["history"] # CF dividendsPaid 1년치 합산
102+
103+
# 별도 출처
104+
c.report.dividend.dps # 주당 현금배당금 시계열 (DART 정기보고서 기반)
105+
```
106+
107+
두 출처는 다를 수 있다. CF는 자본 재구성/우선주/자기주식 매입까지 포함, report는 보통주 현금배당만. 본문에서 어느 출처를 썼는지 검증표에 명시.
108+
109+
### 8) 신용등급
110+
111+
```python
112+
cr = c.credit("등급")
113+
cr["grade"] # "dCR-AA" 등
114+
cr["score"] # 0~100 위험점수 (낮을수록 안전)
115+
cr["healthScore"] # 100 - score
116+
cr["divergenceExplanation"] # dartlab 자체 경고 (직접 인용 OK)
117+
```
118+
119+
---
120+
121+
## 2. 분기 vs 연간 vs Q4 스냅샷 — 단일 라벨 표
122+
123+
| 데이터 종류 | 단위 | 컬럼 | 표 헤더 라벨 |
124+
|---|---|---|---|
125+
| IS (매출/원가/이익) | 1년치 합산 | 연도 | `(1년치 합산, 조원)` |
126+
| IS — 단일 분기 | 분기 단독 | YYQ# | `(분기, 조)` |
127+
| BS (자산/부채/자본) | 시점 스냅샷 | 연도 Q4 | `(Q4 스냅샷, 조원)` |
128+
| CF (영업/투자/재무) | 1년치 합산 | 연도 | `(1년치 합산, 조원)` |
129+
| 비율 (`ratios`) | 분기 | YYQ# | `(분기, %)` |
130+
| marginWaterfall | 1년치 | 연도 | `(1년치 분해, %)` |
131+
| roicTree.history | 1년치 | 연도 | `(1년치, %)` |
132+
133+
**한 표 안에 여러 단위를 절대 섞지 않는다.** 분기 ratios 9개 + 연간 marginWaterfall 1개를 같은 표에 박으면 거짓이 된다.
134+
135+
---
136+
137+
## 3. 표 작성 규칙 (CSS와 정합)
138+
139+
랜딩 빌드는 `landing/src/routes/blog/[slug]/+page.svelte`의 표 CSS로 처리한다. 지난 라운드에 다음을 적용:
140+
141+
- `display: block` + `overflow-x: auto` (모바일 가로 스크롤)
142+
- `table-layout: auto` (컬럼 폭 자동)
143+
- 첫 컬럼 `white-space: nowrap` (계정명 줄바꿈 방지)
144+
145+
### 마크다운 표 규칙
146+
147+
1. **컬럼 = 시점, 좌측이 가장 최신** (예: 2025 → 2024 → ... → 2017)
148+
2. **첫 컬럼 = 항목명**, 짧고 명확하게 (`매출액`, `영업이익`, `OCF`)
149+
3. **단위는 표 헤더에 명시** (`항목 (조원)`, `항목 (억원)`, `항목 (%)`)
150+
4. **숫자 컬럼은 `---:`로 우측 정렬** — 자릿수 정렬용
151+
5. **강조는 `**굵게**`** — 정점/바닥/사상 최대 등
152+
6. **표 아래에 한 줄 풀이**`표시: **+58.40** = 사상 최대 / **-66.87** = 사상 최악`
153+
154+
### 단위 결정 기준
155+
156+
모든 행이 0.5~1000 범위에 들어가는 단위를 고른다.
157+
158+
| 회사 | 권장 단위 | 이유 |
159+
|---|---|---|
160+
| 대형 (SK하이닉스, 삼성전자, 두산) | 조원 | 매출 10조 이상 |
161+
| 중형 (삼양식품) | 억원 | 매출 0.5~3조, 조원 단위로 가면 0.X로 깔림 |
162+
| 비율 | % | 표 헤더에 `(%)` 명시 |
163+
164+
같은 글 안에서 단위 혼용 가능 (IS는 조원, 영업이익만 보조 억원 표기) — 단, 표마다 헤더에 명시.
165+
166+
---
167+
168+
## 4. 글 한 편당 최소 데이터 단위 (회사 종합편)
169+
170+
회사 종합편 한 편에 다음 6가지가 다 들어 있어야 한다. 빠지면 종합편으로 부족하다.
171+
172+
| # | 데이터 | 호출 | 본문 위치 |
173+
|---|---|---|---|
174+
| 1 | IS 9년 시계열 표 | `c.select("IS", [...])` 분기 합산 | 수익성/마진 막 시작 |
175+
| 2 | BS 9년 Q4 스냅샷 표 | `c.select("BS", [...])` Q4만 | 안정성/자금조달 막 시작 |
176+
| 3 | CF 9년 시계열 표 + 잉여현금 파생행 | `c.select("CF", [...])` 분기 합산 | 현금/자본배분 막 시작 |
177+
| 4 | 핵심 비율 분기 시계열 표 1~3개 | `c.select("ratios", [...])` | 핵심 변곡점 막 |
178+
| 5 | dartlab 자체 분석 인용 ≥1 | `c.analysis(...)` 의 marginDriver/flag/divergence | 메커니즘 막 |
179+
| 6 | 신용등급 카드 | `c.credit("등급")` | 안정성 막 |
180+
181+
주제 심화편(한 회사 한 각도)은 1·5·6만 필수, 나머지는 주제에 따라.
182+
183+
---
184+
185+
## 5. 금지 패턴 (지난 라운드 거짓 19건의 공통 원인)
186+
187+
### 패턴 A — 분기값을 연도 라벨로 표기
188+
189+
```markdown
190+
❌ 나쁨:
191+
| 연도 (Q4) | 매출 | 영업이익 |
192+
|---|---|---|
193+
| 2025 | 4.86 | 2,121 | ← Q4 단독값인데 "2025"로 라벨
194+
195+
✅ 좋음:
196+
| 항목 (Q4 단독, 조원) | 2025Q4 | 2024Q4 |
197+
|---|---|---|
198+
| 매출액 | 4.86 | 4.59 |
199+
```
200+
201+
### 패턴 B — 비율 분기값과 1년치 marginWaterfall을 같은 표에
202+
203+
```markdown
204+
❌ 나쁨:
205+
| 분기 | GP마진 |
206+
|---|---|
207+
| 2023Q1 | -32% (사상 최악)
208+
| ...
209+
| 2025 | 60.41% ← 1년치 값을 분기 표에 끼움
210+
```
211+
212+
연간 GP마진은 별도 표 또는 본문 한 줄로.
213+
214+
### 패턴 C — capitalOverview 소계를 총합으로 인용
215+
216+
`capitalOverview["순차입금"]`은 dartlab 내부 정의 (현금성자산 - 차입금).
217+
"총 차입금" 절대값이 필요하면 반드시 `fundingSources.notesDetail.borrowings`의 "합계" 행.
218+
219+
### 패턴 D — dartlab 출력을 풀어 쓰면서 단위 변환 실수
220+
221+
```python
222+
print(c.analysis("자본배분")["dividendPolicy"]["history"][0])
223+
# {'period': '2025', 'dividendsPaid': 522052000000.0, ...}
224+
```
225+
226+
→ 본문 "5,220.52억" 또는 "5,221억". 절대로 "약 2,631억" 같이 다른 숫자가 나오면 안 된다 (지난 라운드 SK 거짓).
227+
228+
### 패턴 E — 검증 안 된 외부 출처 수치
229+
230+
보도자료 수치(체코 5.6조, 사우디 3조 등)는 `c.select`로 검증 불가. 검증표에 "외부 인용"으로 명시하고 출처 링크 첨부.
231+
232+
---
233+
234+
## 6. 검증 스크립트 템플릿
235+
236+
블로그 한 편의 모든 인용 수치를 발행 직전 한 번에 dartlab으로 재호출해 비교.
237+
238+
```python
239+
# .claude/scripts/verifyBlogNumbers.py (별도 plan에서 본격 구현)
240+
import dartlab
241+
242+
def verify_skhynix():
243+
c = dartlab.Company("000660")
244+
checks = []
245+
246+
# 본문 핵심 후킹
247+
is_df = c.select("IS", ["매출액","영업이익"])
248+
rev_2025 = sum(is_df.row(0, named=True).get(f"2025Q{q}", 0) or 0 for q in range(1,5))
249+
op_2025 = sum(is_df.row(1, named=True).get(f"2025Q{q}", 0) or 0 for q in range(1,5))
250+
251+
checks.append(("매출 97.15조", abs(rev_2025/1e12 - 97.15) < 0.05))
252+
checks.append(("영업이익 47.21조", abs(op_2025/1e12 - 47.21) < 0.05))
253+
254+
# 차입금
255+
borrowings = c.analysis("financial","자금조달")["fundingSources"]["notesDetail"]["borrowings"]
256+
total = next(r["2025"] for r in borrowings if r["계정명"] == "합계")
257+
checks.append(("차입금 22.25조", abs(total/1e12 - 22.25) < 0.05))
258+
259+
# 결과
260+
for name, ok in checks:
261+
print(f"{'' if ok else '🔴'} {name}")
262+
return all(ok for _, ok in checks)
263+
264+
if __name__ == "__main__":
265+
verify_skhynix()
266+
```
267+
268+
이 스크립트를 글마다 만들어두면 데이터 갱신 후에도 회귀 검증이 가능하다.
269+
270+
---
271+
272+
## 7. 실측 한 번 더 — 분기/연간 헷갈릴 때
273+
274+
작성 중 "이 숫자가 분기인지 1년치인지" 헷갈리면:
275+
276+
```python
277+
df = c.select("IS", ["매출액"])
278+
row = df.row(0, named=True)
279+
280+
# 검증 1: 4분기 합산 vs Q4 단독값
281+
annual = sum(row.get(f"2025Q{q}", 0) for q in range(1,5))
282+
q4_only = row.get("2025Q4")
283+
print(f"2025 연간 {annual/1e12:.2f}조 / Q4 단독 {q4_only/1e12:.2f}")
284+
```
285+
286+
이 두 숫자를 본문에 박을 때 절대 한 표에 섞지 않는다.
287+
288+
---
289+
290+
## 8. 데이터 갱신 시점 처리
291+
292+
dartlab 데이터는 분기마다 새 공시가 들어오면서 갱신된다. 글 발행 시점과 검증 시점이 다를 수 있다.
293+
294+
권장:
295+
- 글 제목 옆에 "데이터 기준: 2026-04-08 dartlab" 명시
296+
- 검증표에 "📅 dartlab 실측 2026-04-08"
297+
- 큰 분기 변동(예: Q4 결산 발표) 후에는 회사 종합편 핵심 후킹 한 번 더 검증

0 commit comments

Comments
 (0)