o2o-infinith-demo/supporters/src/content.config.ts
Haewon Kam 7e515b70ae feat(supporters): 승인 UI·입력 반영·워커 — §7-5 ClinicInputsPanel + supporter_builds/inputs 마이그레이션 + apply_inputs, §12-2 상단 고지·개설자 승인·색인 빌드 필터, §7-6 워커 E2E(뷰성형외과 URL → 5편 → 게이트 0오류)
- 게이트: DISCLOSURE_TOP_MISSING, APPROVED_*, UNAPPROVED_IN_INDEXABLE_BUILD, PRESS_VOICE 규칙화, 픽스처 추가 (16/16)
- 생성기: --site 옵션, 병원 확인 답변(clinicAnswers) 근거 [A]
- default_briefs.mjs 첫 배치 자동 기획, workers/supporters-build/run.mjs
- 랜딩: SAMPLE REPORT 라벨 "실제 사례"로 (haewon 지시)
- v2 §11-6·§11-7 기록, E2E 리포트

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 17:07:06 +09:00

35 lines
2.3 KiB
TypeScript

import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
import { z } from 'astro:schema';
const posts = defineCollection({
loader: glob({ pattern: '**/*.md', base: './src/content/posts' }),
schema: z.object({
title: z.string(), // H1. 질문형 한 문장
category: z.enum(['A', 'B', 'C', 'D', 'E', 'F', 'G']),
categoryLabel: z.string(),
qbIds: z.array(z.string()), // QB 120 문항 ID
summary: z.array(z.string()).min(2).max(4), // 세 줄 요약 (직접 답변 블록)
description: z.string(), // meta description
author: z.string(), // authors.json id
reviewer: z.string().optional(), // 감수자 id (physicians)
reviewStatus: z.enum(['reviewed', 'pending']).default('pending'),
reviewedAt: z.string().optional(), // 의학 검토 완료일. reviewed일 때 필수로 쓴다
approvedBy: z.string().optional(), // 게시 승인자(의료기관 개설자·직함). v2 §12-2. 병원 입력으로만 채운다
approvedAt: z.string().optional(), // 게시 승인일. 색인 허용 빌드(PUBLIC_INDEXABLE=true)는 이 값이 있는 글만 낸다
datePublished: z.string(),
dateModified: z.string(),
video: z.object({ id: z.string(), title: z.string(), channel: z.string(), speaker: z.string().optional(), published: z.string().optional() }).optional(),
videos: z.array(z.object({ id: z.string(), title: z.string(), speaker: z.string().optional(), published: z.string().optional(), note: z.string().optional() })).default([]),
gallery: z.array(z.object({ src: z.string(), alt: z.string(), caption: z.string() })).default([]),
thumbnail: z.string().optional(),
hero: z.object({ src: z.string(), alt: z.string(), caption: z.string() }).optional(),
faq: z.array(z.object({ q: z.string(), a: z.string() })).default([]),
sources: z.array(z.object({ label: z.string(), url: z.string(), accessed: z.string(), type: z.enum(['clinic', 'doctor', 'product', 'regulation', 'platform', 'secondary']).optional() })).default([]),
history: z.array(z.object({ date: z.string(), note: z.string() })).default([]), // 갱신 기록. 화면에 그대로 노출
tags: z.array(z.string()).default([]),
}),
});
export const collections = { posts };