o2o-site-AEO/solution/backend/services/prompts/section_prompts.json
Mina Choi f0c4d5f413 [fix] solution: 엽서·가요 다방 손질 — 재굽기 전 사이트도 공유되게 사진을 중계한다
배포 뒤 대표 지적 넷을 한 번에 고친다.

- 사진 중계(`backend/router/v1/media/relay.py`, `/v1/image/relay`) — 굽는 쪽이 사진을
  우리 자리로 옮기는 건 **다시 굽는 사이트에만** 적용된다. 아직 재발행 안 한 사이트는
  캔버스가 오염된 채라 저장·공유가 막혀 있다. 같은 오리진으로 바이트를 흘려보내 그 사이를
  메운다. `postcard-canvas.loadImage` 가 CORS 실패 때만 두 번째로 탄다 —
  이미 우리 자리에 있는 사진은 첫 시도에서 끝난다.
  ★ 열린 프록시가 되지 않게: https · 호스트 allowlist · 이미지 타입 · 8MB ·
    리다이렉트 후 호스트 재검사 · IP 주소 거절. 실측: pstatic 사진 158KB 통과,
    http·목록 밖·127.0.0.1·169.254.169.254 전부 거절
- 엽서 미리보기 360px (320 → 240 은 작다 하셔서 그 사이로)
- 엽서 사진 목록에 슬라이더가 없던 것 — `.slider-viewport` 마크업만 손으로 찍어서
  embla 가 안 붙어 있었다(그건 스크립트 붙기 전의 기본 상태다). 진짜 `Carousel` 로 바꾼다
- 가요 다방 판이 전부 주朱색이던 것 — **실측 67곡 중 63곡에 `labelColor` 가 없다.**
  모델이 공통 규칙 2("확인 안 된 값은 뺀다")를 색에까지 적용한다. 색은 사실이 아니라
  디자인 값이다: 프롬프트에 그렇게 못 박고, 비었을 때는 제목 해시로 레코드 라벨색 8종에서
  고른다(무작위가 아니다 — 하이드레이션이 어긋나면 안 되고, 새로고침마다 바뀌어도 안 된다)

tsc·eslint 통과(site), site 79 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 09:51:53 +09:00

56 lines
10 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"_generated": "npm run export:prompts — 손으로 고치지 않는다",
"rules": "\n[공통 규칙]\n1. JSON 하나만 출력한다. 인사말·설명·코드펜스를 붙이지 않는다.\n2. 확인되지 않은 값은 필드를 통째로 뺀다. 빈 문자열로 채우거나 지어내지 않는다.\n3. source.url 은 실제로 열리는 공식·기관·언론 페이지여야 한다. 검색 결과 주소는 쓰지 않는다.\n4. 근거가 확실하면 verified 를 \"확인\", 애매하면 \"확인필요\" 로 적는다. 애매한 걸 \"확인\" 으로 올리지 않는다.\n5. 가사·시·소설의 원문을 한 줄도 옮기지 않는다. 제목과 배경만 쓴다.\n6. 설명 문장은 항목당 두 문장을 넘기지 않는다.\n7. 이미지 주소는 만들지 않는다. 필요하면 imageQuery 에 검색어만 적는다.\n",
"specs": {
"songs": {
"kind": "songs",
"label": "가요 다방",
"maxItems": 8,
"task": "[해야 할 일]\n[지역]을 노래한 대중가요를 8곡까지 찾아 아래 JSON 으로 정리한다.\n1960~80년대 곡을 우선하고, 지명·항구·강·다리가 제목이나 배경에 나오는 곡을 고른다.\n\n[스키마]\n{ \"kind\":\"songs\", \"version\":1, \"title\":\"가요 다방\", \"subtitle\":\"...\", \"items\":[\n { \"title\":\"곡명\", \"artist\":\"가수\", \"lyricist\":\"작사\", \"composer\":\"작곡\",\n \"year\":1966, \"label\":\"음반사\", \"labelColor\":\"#d4551f\",\n \"story\":\"곡의 배경 (두 문장 이내, 가사 없이)\",\n \"connection\":\"[업소]와 이 곡을 잇는 한 문장\",\n \"verified\":\"확인|확인필요\",\n \"source\":{\"name\":\"출처명\",\"url\":\"https://...\"} } ] }",
"rules": "\n[이 아이템만의 규칙]\n· lyrics 필드는 스키마에 없다. 어떤 이유로도 만들지 마라. 가사 한 소절도 안 된다.\n· labelColor 는 레코드 라벨 색이다. 곡의 분위기에 맞춰 진한 색 하나를 hex 로 고른다.\n **이건 사실이 아니라 디자인 값이다 — 공통 규칙 2 를 적용하지 말고 곡마다 반드시 채운다.**\n 앞뒤 곡과 같은 색을 쓰지 않는다. 비워 두면 판이 전부 한 색으로 깔린다(실측 2026-09-15:\n 67곡 중 63곡이 비어 있었다).\n· 작사·작곡·발표연도를 모르면 그 필드를 뺀다. \"미상\" 이라고 쓰지 않는다.\n"
},
"daily": {
"kind": "daily",
"label": "오늘의 한 장",
"maxItems": 30,
"task": "[해야 할 일]\n[지역]의 이야깃거리를 30개 찾아, 하루에 하나씩 뜯어 보는 일력용 JSON 으로 만든다.\n같은 주제를 두 번 쓰지 않는다. 계절이 맞는 날짜에 배치한다(축제는 실제 개최 시기에).\n\n[스키마]\n{ \"kind\":\"daily\", \"version\":1, \"title\":\"오늘의 한 장\", \"items\":[\n { \"monthDay\":\"09-02\", \"category\":\"역사|인물|장소|음식|축제|바다|문학\",\n \"title\":\"제목\", \"body\":\"두 문장 이내\", \"season\":\"봄|여름|가을|겨울\",\n \"tags\":[\"#태그\"], \"verified\":\"확인|확인필요\",\n \"source\":{\"name\":\"출처명\",\"url\":\"https://...\"} } ] }",
"rules": "\n[이 아이템만의 규칙]\n· monthDay 는 MM-DD 다. 연도를 넣지 않는다 — 해마다 다시 쓰는 일력이다.\n· 30개를 억지로 채우지 마라. 확실한 것이 12개면 12개만 낸다.\n· 같은 장소를 계절만 바꿔 반복하지 않는다.\n"
},
"people": {
"kind": "people",
"label": "인물 열전",
"maxItems": 10,
"task": "[해야 할 일]\n[지역] 출신이거나 [지역]과 깊이 얽힌 인물을 10명까지 찾는다.\n문학·음악·미술·역사 인물을 고루 섞고, 생존 인물은 공개된 사실만 쓴다.\n\n[스키마]\n{ \"kind\":\"people\", \"version\":1, \"title\":\"인물 열전\", \"items\":[\n { \"name\":\"이름\", \"aka\":\"호·예명\", \"years\":\"19021950\", \"role\":\"소설가\",\n \"oneLine\":\"한 문장 소개\", \"imageQuery\":\"사진 검색어\",\n \"verified\":\"확인|확인필요\",\n \"source\":{\"name\":\"출처명\",\"url\":\"https://...\"} } ] }",
"rules": "\n[이 아이템만의 규칙]\n· \"~ 출신으로 알려진\" 처럼 근거가 전언뿐이면 verified 를 \"확인필요\" 로 한다.\n· 생존 인물의 가족·거주지·건강 같은 사생활은 쓰지 않는다.\n· 사진 URL 을 넣지 않는다. imageQuery 만 넣는다 — 초상권과 저작권은 사장님이 확인한다.\n"
},
"chronicle": {
"kind": "chronicle",
"label": "시간의 골목",
"maxItems": 14,
"task": "[해야 할 일]\n[지역]의 역사를 연도순으로 10~14개 사건으로 정리한다.\n가장 오래된 것부터 가장 최근까지 고르게 펴고, 한 시대에 몰지 않는다.\n\n[스키마]\n{ \"kind\":\"chronicle\", \"version\":1, \"title\":\"시간의 골목\", \"items\":[\n { \"year\":1899, \"title\":\"사건 이름\", \"summary\":\"두 문장 이내\",\n \"place\":\"지금 가 볼 수 있는 자리\", \"turning\":true,\n \"verified\":\"확인|확인필요\",\n \"source\":{\"name\":\"출처명\",\"url\":\"https://...\"} } ] }",
"rules": "\n[이 아이템만의 규칙]\n· turning 은 도시의 성격을 바꾼 해에만 true 다. 3~4개를 넘기지 않는다.\n· 연도가 불확실하면 그 항목을 통째로 뺀다. 연표에서 틀린 연도는 바로 들킨다.\n· place 는 지금도 찾아갈 수 있는 자리만 적는다. 없으면 필드를 뺀다.\n· 다만 **찾아갈 수 있는 자리가 있으면 반드시 적는다.** 행정 개편처럼 장소가 없어 보이는\n 사건에도 그 일이 남긴 자리가 대개 있다(개항 → 항구, 부두 건설 → 그 부두, 준공 → 그 구조물).\n 이 값으로 공공데이터에서 그 해의 사진을 찾아 붙인다 — 비면 연표가 활자만으로 선다.\n"
},
"reading": {
"kind": "reading",
"label": "지역 읽기",
"maxItems": 34,
"task": "[해야 할 일]\n[지역]을 소개하는 글 30~34꼭지를 갈래로 나눠 쓴다.\n갈래는 다섯이다 — 문학 · 섬과 바다 · 역사 · 장소 · 음식과 생활.\n한 갈래에 몰지 않되, 댈 수 있는 사실이 적은 갈래는 적게 쓴다.\n\n[스키마]\n{ \"kind\":\"reading\", \"version\":1, \"title\":\"[지역] 읽기\",\n \"subtitle\":\"문학 · 섬과 바다 · 역사 · 장소 · 음식과 생활 — 올 때마다 다른 몇 가지\",\n \"items\":[\n { \"group\":\"문학|섬과 바다|역사|장소|음식과 생활\",\n \"title\":\"꼭지 제목\", \"body\":\"서너 문장\", \"year\":1937 } ] }",
"rules": "\n[이 아이템만의 규칙]\n· body 는 **서너 문장**이다. 두 문장이면 카드가 한 줄로 접혀 빈 카드처럼 보인다.\n 다만 문장을 늘리려고 없는 숫자·연도·거리를 지어내지 않는다 — 널리 알려진 배경만 보탠다.\n· **이미 다른 자리에 선 것은 쓰지 않는다.** 인물·대중가요·축제·연표 사건·주변 명소·맛집은\n 각자 섹션이 있다. 같은 것을 두 번 세우면 페이지만 길어지고 손님은 같은 말을 두 번 읽는다.\n· year 는 연도를 댈 수 있는 꼭지에만 쓴다. 짐작해서 넣지 않는다.\n· source 와 verified 를 적지 않는다. **주소를 짐작해 적으면 없는 문서로 이어진다** —\n 제목으로 찾아가는 검색 링크를 서버가 붙인다(2026-09-14 대표 지시).\n· 시·소설·가사의 원문을 한 줄도 옮기지 않는다. 제목과 배경만 쓴다.\n· 부제에 전체 개수를 적지 않는다. 화면은 이 중 5~6개만 매번 무작위로 보여준다 —\n 숫자를 박으면 보이는 개수와 어긋난다.\n"
},
"postcard": {
"kind": "postcard",
"label": "오늘의 엽서",
"maxItems": 12,
"task": "[해야 할 일]\n[지역]에 대해 손님이 자기 SNS 에 그대로 붙여 쓸 만한 한 문장을 12개 쓴다.\n사실 하나가 반드시 들어가되, 설명하지 말고 툭 던지는 문장으로 쓴다.\n\n[스키마]\n{ \"kind\":\"postcard\", \"version\":1, \"title\":\"오늘의 엽서\", \"items\":[\n { \"line\":\"한 문장\", \"hashtags\":[\"#태그\"], \"place\":\"장소\",\n \"postmark\":\"소인에 찍을 짧은 지명\",\n \"verified\":\"확인|확인필요\",\n \"source\":{\"name\":\"출처명\",\"url\":\"https://...\"} } ] }",
"rules": "\n[이 아이템만의 규칙]\n· 한 문장은 40자 안쪽이다. 두 문장으로 쓰지 않는다.\n· 느낌표와 이모지를 쓰지 않는다. 광고 문구처럼 들리면 실패다.\n· 해시태그는 3개까지. 지역명 하나는 반드시 넣는다.\n· **같은 대상을 두 번 쓰지 않는다.** 열두 장이 전부 다른 곳·다른 이야기여야 한다 —\n 한 시설의 주소·휴관일·운영시간을 나눠 적으면 엽서가 아니라 안내문 열두 장이 된다\n (실측 2026-09-10: 네 장이 같은 박물관의 관람안내였다).\n· 운영시간·휴관일·주소·요금은 엽서에 적지 않는다. 그건 이용 정보지 엽서 문장이 아니다.\n· place 는 사진을 찾는 열쇠다. **찾아갈 수 있는 곳 이름을 정확히** 적는다 —\n 이 값으로 공공데이터에서 앞면 사진을 찾고, 못 찾으면 그 엽서는 실리지 않는다.\n"
},
"quiz": {
"kind": "quiz",
"label": "뒤집어 보는 질문",
"maxItems": 12,
"task": "[해야 할 일]\n[지역]을 소재로, 아이와 어른이 함께 생각해 볼 질문을 12개 만든다.\n질문은 검색하면 바로 나오는 단답형이 아니라 \"왜\" 와 \"어떻게\" 를 묻는 것으로 한다.\n\n[스키마]\n{ \"kind\":\"quiz\", \"version\":1, \"title\":\"뒤집어 보는 질문\", \"items\":[\n { \"question\":\"질문 한 문장\", \"hint\":\"두 문장 이내 힌트\",\n \"topic\":\"관련 장소·주제\", \"level\":\"초등|중등|어른\",\n \"verified\":\"확인|확인필요\",\n \"source\":{\"name\":\"출처명\",\"url\":\"https://...\"} } ] }",
"rules": "\n[이 아이템만의 규칙]\n· answer 필드는 스키마에 없다. 정답을 단정하지 않는다 — 힌트까지만 준다.\n· 힌트에 사실을 넣되, 확실하지 않으면 그 항목을 통째로 뺀다.\n· 질문에 지역 이름을 넣어 어디 이야기인지 알 수 있게 한다.\n"
}
}
}