refactor(skills): Restructure skills to dual-platform architecture
Major refactoring of ourdigital-custom-skills with new numbering system: ## Structure Changes - Each skill now has code/ (Claude Code) and desktop/ (Claude Desktop) versions - New progressive numbering: 01-09 General, 10-19 SEO, 20-29 GTM, 30-39 OurDigital, 40-49 Jamie ## Skill Reorganization - 01-notion-organizer (from 02) - 10-18: SEO tools split into focused skills (technical, on-page, local, schema, vitals, gsc, gateway) - 20-21: GTM audit and manager - 30-32: OurDigital designer, research, presentation - 40-41: Jamie brand editor and audit ## New Files - .claude/commands/: Slash command definitions for all skills - CLAUDE.md: Updated with new skill structure documentation - REFACTORING_PLAN.md: Migration documentation - COMPATIBILITY_REPORT.md, SKILLS_COMPARISON.md: Analysis docs ## Removed - Old skill directories (02-05, 10-14, 20-21 old numbering) - Consolidated into new structure with _archive/ for reference 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
# CLAUDE.md
|
||||
|
||||
## Overview
|
||||
|
||||
Jamie Clinic content generation toolkit. Creates branded content following Jamie's voice and Korean medical advertising regulations.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Check content compliance
|
||||
python scripts/compliance_checker.py --input draft.md
|
||||
```
|
||||
|
||||
## Scripts
|
||||
|
||||
| Script | Purpose |
|
||||
|--------|---------|
|
||||
| `compliance_checker.py` | Validate content against medical ad regulations |
|
||||
|
||||
## Compliance Checker
|
||||
|
||||
```bash
|
||||
# Check draft content
|
||||
python scripts/compliance_checker.py --input draft.md
|
||||
|
||||
# With detailed report
|
||||
python scripts/compliance_checker.py --input draft.md --verbose --output report.json
|
||||
|
||||
# Batch check
|
||||
python scripts/compliance_checker.py --dir ./drafts --output compliance_report.json
|
||||
```
|
||||
|
||||
## Compliance Rules
|
||||
|
||||
Checks for Korean medical advertising regulations:
|
||||
- No exaggerated claims
|
||||
- No before/after comparison violations
|
||||
- No guarantee language
|
||||
- No competitor comparisons
|
||||
- Proper disclosure requirements
|
||||
|
||||
## Brand Voice
|
||||
|
||||
Content must follow Jamie's voice:
|
||||
- 90% 격식체 (~습니다/~입니다)
|
||||
- "환자분" for medical contexts
|
||||
- "자연스러운" as key descriptor
|
||||
- No exaggeration, realistic expectations
|
||||
|
||||
## Content Types
|
||||
|
||||
- Blog posts (블로그 포스팅)
|
||||
- Procedure pages (시술 페이지)
|
||||
- Ad copy (광고 카피)
|
||||
- Social media (SNS 콘텐츠)
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Generate content (use SKILL.md guidelines)
|
||||
2. Run compliance checker
|
||||
3. Fix flagged issues
|
||||
4. Submit to `41-jamie-brand-audit` for final review
|
||||
|
||||
## References
|
||||
|
||||
See `desktop/` for:
|
||||
- `brand_guidelines/` - Voice and tone guide
|
||||
- `regulations/` - Medical ad law summary
|
||||
- `procedures_dataset/` - Procedure information
|
||||
246
ourdigital-custom-skills/40-jamie-brand-editor/code/docs/PLAN.md
Normal file
246
ourdigital-custom-skills/40-jamie-brand-editor/code/docs/PLAN.md
Normal file
@@ -0,0 +1,246 @@
|
||||
# Jamie Brand Editor - Development Plan
|
||||
|
||||
> **Status**: Under Development
|
||||
> **Current Version**: 1.0.0
|
||||
> **Target Version**: 2.8.0 (sync with Guardian)
|
||||
> **Last Updated**: 2025-12-11
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
This document outlines the refactoring roadmap for jamie-brand-editor skill to align with jamie-brand-guardian v2.8 and establish clear role separation.
|
||||
|
||||
### Role Definition
|
||||
|
||||
| Skill | Role | Input | Output |
|
||||
|-------|------|-------|--------|
|
||||
| **jamie-brand-editor** | Content GENERATION | Topic/brief | Brand-compliant draft |
|
||||
| **jamie-brand-guardian** | Content REVIEW | Existing content | Feedback/corrections |
|
||||
|
||||
---
|
||||
|
||||
## Current State Assessment
|
||||
|
||||
### Evaluation Score (2025-12-11)
|
||||
|
||||
| Area | Score | Status |
|
||||
|------|-------|--------|
|
||||
| SKILL.md Structure | 85/100 | OK |
|
||||
| Brand Guidelines Alignment | 70/100 | Needs Work |
|
||||
| Resource Completeness | 45/100 | Critical |
|
||||
| Role Separation | 75/100 | Needs Work |
|
||||
| **Overall** | **69/100** | Refactoring Required |
|
||||
|
||||
### Existing Resources
|
||||
|
||||
```
|
||||
20-jamie-brand-editor/
|
||||
├── SKILL.md (551 lines - too long)
|
||||
├── README.md
|
||||
├── brand_guidelines/
|
||||
│ ├── brand_voice_guide_korean.md ✅
|
||||
│ └── content_examples/
|
||||
│ └── [4 PDF files] ✅
|
||||
├── procedures_schema_dataset/
|
||||
│ └── [16 JSON files] ✅
|
||||
├── regulations/
|
||||
│ └── medical_advertising_law_summary_korean.md ✅
|
||||
├── scripts/
|
||||
│ └── compliance_checker.py ✅
|
||||
├── templates/ (EMPTY) ❌
|
||||
└── docs/ (development docs, excluded from skill)
|
||||
└── PLAN.md
|
||||
```
|
||||
|
||||
### Missing Resources (Referenced in SKILL.md but don't exist)
|
||||
|
||||
```
|
||||
❌ brand_guidelines/brand_pillars_detailed.md
|
||||
❌ brand_guidelines/competitive_positioning.md
|
||||
❌ brand_guidelines/content_examples/approved_webpage_samples.md
|
||||
❌ brand_guidelines/content_examples/successful_blog_posts.md
|
||||
❌ brand_guidelines/content_examples/compliant_social_media.md
|
||||
❌ regulations/compliance_checklist.md
|
||||
❌ regulations/prohibited_content_examples.md
|
||||
❌ regulations/required_disclaimers_templates.md
|
||||
❌ templates/procedure_page_template_korean.md
|
||||
❌ templates/blog_post_template.md
|
||||
❌ templates/social_media_templates.md
|
||||
❌ templates/advertising_copy_templates.md
|
||||
❌ scripts/brand_voice_analyzer.py
|
||||
❌ scripts/content_generator.py
|
||||
❌ scripts/seo_optimizer.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Refactoring Roadmap
|
||||
|
||||
### Phase 1: SKILL.md Cleanup (Priority: Critical)
|
||||
|
||||
**Goal**: Reduce SKILL.md to <300 lines, remove non-existent features
|
||||
|
||||
**Tasks**:
|
||||
1. [ ] Remove "Content Review" sections (Guardian's role)
|
||||
2. [ ] Remove "Regulatory Compliance Checks" workflow (Guardian's role)
|
||||
3. [ ] Remove references to non-existent scripts
|
||||
4. [ ] Remove references to non-existent template files
|
||||
5. [ ] Move detailed regulations to `regulations/` folder
|
||||
6. [ ] Move usage examples to `examples/` folder
|
||||
7. [ ] Keep only: Role, Core Functions, Tone Guidelines, Content Structure, Usage
|
||||
|
||||
**Target Structure**:
|
||||
```markdown
|
||||
# Jamie Brand Editor Skill
|
||||
## Role Definition (Editor = Generation, Guardian = Review)
|
||||
## Core Functions (Content Types Supported)
|
||||
## Tone & Manner Quick Reference (sync with Guardian)
|
||||
## Content Structure Templates
|
||||
## Procedure Knowledge (reference to JSON dataset)
|
||||
## Usage Instructions
|
||||
## Available Resources
|
||||
```
|
||||
|
||||
### Phase 2: Tone & Manner Sync (Priority: High)
|
||||
|
||||
**Goal**: Sync with Guardian v2.8 tone guidelines
|
||||
|
||||
**Tasks**:
|
||||
1. [ ] Add 종결 어미 비율 (90% 격식체, 6% 서비스형, 4% 부드러운)
|
||||
2. [ ] Add 호칭 가이드 (환자분 61%, 고객님 22%, 여러분 17%)
|
||||
3. [ ] Add 권장 형용사 TOP 5
|
||||
4. [ ] Add 비유 표현 패턴 (정기호 원장 스타일)
|
||||
5. [ ] Add 브랜드 슬로건
|
||||
6. [ ] Add 제이미의 약속 4가지
|
||||
7. [ ] Add 브랜드 퍼스낼리티 5가지
|
||||
|
||||
**Source**: Copy from `../21-jamie-brand-guardian/SKILL.md` (Voice & Tone Guidelines section)
|
||||
|
||||
### Phase 3: Templates Implementation (Priority: High)
|
||||
|
||||
**Goal**: Create actual content generation templates
|
||||
|
||||
**Tasks**:
|
||||
1. [ ] Create `templates/blog-post-template.md`
|
||||
2. [ ] Create `templates/procedure-page-template.md`
|
||||
3. [ ] Create `templates/social-media-templates.md`
|
||||
4. [ ] Create `templates/ad-copy-templates.md`
|
||||
|
||||
**Template Format**:
|
||||
```markdown
|
||||
---
|
||||
name: template-name
|
||||
type: blog|procedure|social|ad
|
||||
variables:
|
||||
- procedure_name
|
||||
- target_audience
|
||||
- key_benefits
|
||||
---
|
||||
|
||||
[Template content with {{variable}} placeholders]
|
||||
```
|
||||
|
||||
### Phase 4: Script Implementation (Priority: Medium)
|
||||
|
||||
**Goal**: Implement referenced scripts or remove references
|
||||
|
||||
**Option A - Implement**:
|
||||
1. [ ] `scripts/content_generator.py` - Template-based generation using JSON data
|
||||
2. [ ] `scripts/brand_voice_analyzer.py` - Simple keyword/pattern checker
|
||||
|
||||
**Option B - Remove**:
|
||||
- Remove all script references from SKILL.md
|
||||
- Keep only `compliance_checker.py`
|
||||
|
||||
**Recommendation**: Option B for v1.x, Option A for v2.0
|
||||
|
||||
### Phase 5: Resource Organization (Priority: Medium)
|
||||
|
||||
**Tasks**:
|
||||
1. [ ] Create `examples/` folder with sample outputs
|
||||
2. [ ] Move detailed regulation content to `regulations/`
|
||||
3. [ ] Create `regulations/compliance_checklist.md`
|
||||
4. [ ] Create `regulations/required_disclaimers.md`
|
||||
|
||||
### Phase 6: Version Alignment (Priority: Low)
|
||||
|
||||
**Goal**: Sync version with Guardian
|
||||
|
||||
**Tasks**:
|
||||
1. [ ] Update version to 2.0.0 after Phase 1-3 complete
|
||||
2. [ ] Update version to 2.8.0 after full alignment with Guardian
|
||||
|
||||
---
|
||||
|
||||
## File Structure Target
|
||||
|
||||
```
|
||||
20-jamie-brand-editor/
|
||||
├── SKILL.md (<300 lines, generation-focused)
|
||||
├── brand_guidelines/
|
||||
│ ├── brand_voice_guide_korean.md
|
||||
│ ├── tone_manner_quick_reference.md (NEW - sync with Guardian)
|
||||
│ └── content_examples/
|
||||
│ └── [PDF files]
|
||||
├── procedures_schema_dataset/
|
||||
│ └── [16 JSON files]
|
||||
├── regulations/
|
||||
│ ├── medical_advertising_law_summary_korean.md
|
||||
│ ├── compliance_checklist.md (NEW)
|
||||
│ └── required_disclaimers.md (NEW)
|
||||
├── templates/ (NEW)
|
||||
│ ├── blog-post-template.md
|
||||
│ ├── procedure-page-template.md
|
||||
│ ├── social-media-templates.md
|
||||
│ └── ad-copy-templates.md
|
||||
├── examples/ (NEW)
|
||||
│ ├── sample-blog-post.md
|
||||
│ └── sample-procedure-page.md
|
||||
├── scripts/
|
||||
│ └── compliance_checker.py
|
||||
└── docs/ (excluded from skill packaging)
|
||||
├── PLAN.md
|
||||
├── EVALUATION.md
|
||||
└── CHANGELOG.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Integration Notes
|
||||
|
||||
### Guardian Reference Pattern
|
||||
|
||||
Editor should reference Guardian for:
|
||||
- Detailed brand guidelines: `See jamie-brand-guardian/guides/`
|
||||
- Visual identity: `See jamie-brand-guardian/design/`
|
||||
- Review templates: `See jamie-brand-guardian/templates/`
|
||||
|
||||
### Workflow Integration
|
||||
|
||||
```
|
||||
[User Request]
|
||||
→ jamie-brand-editor (generate draft)
|
||||
→ jamie-brand-guardian (review & correct)
|
||||
→ [Final Content]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Version History
|
||||
|
||||
| Version | Date | Changes |
|
||||
|---------|------|---------|
|
||||
| 1.0.0 | 2025-11-18 | Initial release |
|
||||
| 1.0.1 | 2025-12-10 | Role separation clarified |
|
||||
| 1.1.0 | TBD | Phase 1 complete (SKILL.md cleanup) |
|
||||
| 2.0.0 | TBD | Phase 1-3 complete (templates added) |
|
||||
| 2.8.0 | TBD | Full alignment with Guardian v2.8 |
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- `/docs` folder is excluded from skill packaging
|
||||
- Development documentation stays in `/docs`
|
||||
- Only production-ready resources go in main skill folders
|
||||
@@ -0,0 +1,273 @@
|
||||
"""
|
||||
Jamie Marketing Brand Editor - Compliance Checker
|
||||
==================================================
|
||||
|
||||
This script automatically scans marketing content for Korean medical advertising
|
||||
law violations (의료법 제56조) and flags problematic content.
|
||||
|
||||
Usage:
|
||||
python compliance_checker.py --input content.txt --output report.json
|
||||
|
||||
Or import as module:
|
||||
from compliance_checker import ComplianceChecker
|
||||
checker = ComplianceChecker()
|
||||
results = checker.check_content(content_text)
|
||||
"""
|
||||
|
||||
import re
|
||||
import json
|
||||
from typing import Dict, List, Tuple
|
||||
from dataclasses import dataclass, asdict
|
||||
|
||||
@dataclass
|
||||
class ComplianceViolation:
|
||||
"""Represents a single compliance violation found in content"""
|
||||
violation_type: str
|
||||
severity: str # 'critical', 'high', 'medium', 'low'
|
||||
location: Tuple[int, int] # (start_pos, end_pos)
|
||||
matched_text: str
|
||||
explanation_korean: str
|
||||
suggestion: str
|
||||
legal_reference: str
|
||||
|
||||
class ComplianceChecker:
|
||||
"""
|
||||
Checks marketing content for violations of Korean medical advertising law.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.prohibited_patterns = self._load_prohibited_patterns()
|
||||
self.required_disclaimers = self._load_required_disclaimers()
|
||||
|
||||
def _load_prohibited_patterns(self) -> Dict[str, List[str]]:
|
||||
"""
|
||||
Load regex patterns for prohibited content types.
|
||||
"""
|
||||
return {
|
||||
'effect_guarantee': [
|
||||
r'100[%%]\s*(?:만족|효과|성공)',
|
||||
r'반드시\s+(?:효과|개선|만족)',
|
||||
r'완벽한?\s+결과',
|
||||
r'보장합니다',
|
||||
r'확실한?\s+효과',
|
||||
],
|
||||
'comparative_superiority': [
|
||||
r'최고의?',
|
||||
r'1위',
|
||||
r'(?:압구정|강남|서울|국내)\s*(?:최고|1위)',
|
||||
r'타\s*병원보다',
|
||||
r'다른\s*(?:병원|의원)보다\s*우수',
|
||||
],
|
||||
'safety_guarantee': [
|
||||
r'부작용\s*(?:없|無)',
|
||||
r'(?:100[%%]|완전히?|절대)\s*안전',
|
||||
r'위험\s*(?:없|無)',
|
||||
],
|
||||
'patient_testimonial': [
|
||||
r'(?:환자|고객)\s*[A-Z가-힣]+\s*(?:씨|님)의?\s*(?:후기|경험)',
|
||||
r'실제\s*(?:환자|고객)\s*(?:후기|리뷰|경험담)',
|
||||
r'[""]\s*(?:정말|너무|진짜)\s+(?:만족|좋아요|감사)', # Quoted testimonials
|
||||
r'수술\s*후\s*[0-9]+\s*(?:개월|주일|년)\s*(?:만족|경과)',
|
||||
],
|
||||
'exaggeration': [
|
||||
r'(?:놀라운|대박|극적인)\s*(?:변화|효과|결과)',
|
||||
r'마법같은?',
|
||||
r'기적적인?',
|
||||
],
|
||||
}
|
||||
|
||||
def _load_required_disclaimers(self) -> Dict[str, str]:
|
||||
"""
|
||||
Load templates for required disclaimers.
|
||||
"""
|
||||
return {
|
||||
'general_surgery': '※ 모든 수술 및 시술은 개인에 따라 붓기, 멍, 염증 등의 부작용이 발생할 수 있습니다.',
|
||||
'individual_variation': '※ 수술 결과는 개인의 특성에 따라 차이가 있을 수 있습니다.',
|
||||
'consultation_required': '※ 수술 전 반드시 전문의와 충분한 상담을 통해 결정하시기 바랍니다.',
|
||||
}
|
||||
|
||||
def check_content(self, content: str) -> Dict:
|
||||
"""
|
||||
Main method to check content for compliance violations.
|
||||
|
||||
Args:
|
||||
content: Korean text content to check
|
||||
|
||||
Returns:
|
||||
Dictionary containing violations and recommendations
|
||||
"""
|
||||
violations = []
|
||||
|
||||
# Check for prohibited patterns
|
||||
for violation_type, patterns in self.prohibited_patterns.items():
|
||||
for pattern in patterns:
|
||||
for match in re.finditer(pattern, content, re.IGNORECASE):
|
||||
violation = self._create_violation(
|
||||
violation_type=violation_type,
|
||||
match=match,
|
||||
content=content
|
||||
)
|
||||
violations.append(violation)
|
||||
|
||||
# Check for missing required disclaimers
|
||||
disclaimer_issues = self._check_disclaimers(content)
|
||||
violations.extend(disclaimer_issues)
|
||||
|
||||
# Generate compliance report
|
||||
report = {
|
||||
'is_compliant': len(violations) == 0,
|
||||
'total_violations': len(violations),
|
||||
'violations_by_severity': self._count_by_severity(violations),
|
||||
'violations': [asdict(v) for v in violations],
|
||||
'recommendations': self._generate_recommendations(violations),
|
||||
'required_disclaimers': list(self.required_disclaimers.values())
|
||||
}
|
||||
|
||||
return report
|
||||
|
||||
def _create_violation(self, violation_type: str, match, content: str) -> ComplianceViolation:
|
||||
"""
|
||||
Create a ComplianceViolation object from a regex match.
|
||||
"""
|
||||
explanations = {
|
||||
'effect_guarantee': '효과를 보장하는 표현은 의료법 제56조 제2항 제2호 위반입니다.',
|
||||
'comparative_superiority': '타 의료기관과의 비교 우위 주장은 의료법 제56조 제2항 제4호 위반입니다.',
|
||||
'safety_guarantee': '안전성을 보장하거나 부작용이 없다는 표현은 의료법 제56조 제2항 제7호 위반입니다.',
|
||||
'patient_testimonial': '환자 치료경험담은 의료법 제56조 제2항 제2호 위반입니다.',
|
||||
'exaggeration': '과장된 표현은 객관적 사실과 다른 내용으로 의료법 제56조 제2항 제3호 위반 가능성이 있습니다.',
|
||||
}
|
||||
|
||||
suggestions = {
|
||||
'effect_guarantee': '"개선에 도움을 줄 수 있습니다" 또는 "개인에 따라 결과가 다를 수 있습니다"와 같은 표현으로 변경하세요.',
|
||||
'comparative_superiority': '"풍부한 경험을 보유한" 또는 "전문적인"과 같은 객관적 표현으로 변경하세요.',
|
||||
'safety_guarantee': '부작용 가능성을 명시하고 "안전한 수술을 위해 최선을 다합니다"와 같은 표현으로 변경하세요.',
|
||||
'patient_testimonial': '개인 환자 경험담 대신 통계적 데이터나 일반적인 수술 과정 설명으로 대체하세요.',
|
||||
'exaggeration': '객관적이고 절제된 표현으로 변경하세요. 예: "자연스러운 개선", "점진적인 효과"',
|
||||
}
|
||||
|
||||
severity_map = {
|
||||
'effect_guarantee': 'critical',
|
||||
'comparative_superiority': 'critical',
|
||||
'safety_guarantee': 'critical',
|
||||
'patient_testimonial': 'critical',
|
||||
'exaggeration': 'high',
|
||||
}
|
||||
|
||||
return ComplianceViolation(
|
||||
violation_type=violation_type,
|
||||
severity=severity_map.get(violation_type, 'medium'),
|
||||
location=(match.start(), match.end()),
|
||||
matched_text=match.group(),
|
||||
explanation_korean=explanations.get(violation_type, ''),
|
||||
suggestion=suggestions.get(violation_type, ''),
|
||||
legal_reference='의료법 제56조'
|
||||
)
|
||||
|
||||
def _check_disclaimers(self, content: str) -> List[ComplianceViolation]:
|
||||
"""
|
||||
Check if required disclaimers are present in content.
|
||||
"""
|
||||
violations = []
|
||||
|
||||
# Check if content discusses surgery/procedures
|
||||
procedure_keywords = ['수술', '시술', '이마거상', '쌍꺼풀', '리프팅', '보톡스', '필러']
|
||||
has_procedure_content = any(keyword in content for keyword in procedure_keywords)
|
||||
|
||||
if has_procedure_content:
|
||||
# Check for required disclaimers
|
||||
has_side_effect_notice = any(term in content for term in ['부작용', '합병증', '붓기', '멍'])
|
||||
has_individual_variation = '개인' in content and any(term in content for term in ['차이', '다를 수'])
|
||||
|
||||
if not has_side_effect_notice:
|
||||
violations.append(ComplianceViolation(
|
||||
violation_type='missing_disclaimer',
|
||||
severity='high',
|
||||
location=(-1, -1),
|
||||
matched_text='',
|
||||
explanation_korean='부작용 가능성에 대한 고지가 누락되었습니다.',
|
||||
suggestion='페이지 하단에 "※ 모든 수술 및 시술은 개인에 따라 붓기, 멍, 염증 등의 부작용이 발생할 수 있습니다." 문구를 추가하세요.',
|
||||
legal_reference='의료법 제56조 제2항 제7호'
|
||||
))
|
||||
|
||||
if not has_individual_variation:
|
||||
violations.append(ComplianceViolation(
|
||||
violation_type='missing_disclaimer',
|
||||
severity='medium',
|
||||
location=(-1, -1),
|
||||
matched_text='',
|
||||
explanation_korean='개인차에 대한 고지가 누락되었습니다.',
|
||||
suggestion='"개인에 따라 결과가 다를 수 있습니다" 문구를 추가하세요.',
|
||||
legal_reference='의료법 시행령 제23조'
|
||||
))
|
||||
|
||||
return violations
|
||||
|
||||
def _count_by_severity(self, violations: List[ComplianceViolation]) -> Dict[str, int]:
|
||||
"""Count violations by severity level."""
|
||||
counts = {'critical': 0, 'high': 0, 'medium': 0, 'low': 0}
|
||||
for v in violations:
|
||||
counts[v.severity] += 1
|
||||
return counts
|
||||
|
||||
def _generate_recommendations(self, violations: List[ComplianceViolation]) -> List[str]:
|
||||
"""Generate actionable recommendations based on violations found."""
|
||||
recommendations = []
|
||||
|
||||
if any(v.violation_type == 'patient_testimonial' for v in violations):
|
||||
recommendations.append('환자 후기를 제거하고 통계적 만족도 데이터로 대체하세요.')
|
||||
|
||||
if any(v.violation_type in ['effect_guarantee', 'safety_guarantee'] for v in violations):
|
||||
recommendations.append('절대적인 보장 표현을 가능성 표현으로 변경하세요. 예: "도움을 줄 수 있습니다"')
|
||||
|
||||
if any(v.violation_type == 'comparative_superiority' for v in violations):
|
||||
recommendations.append('비교 우위 표현을 제거하고 객관적 사실(경력, 경험)로 대체하세요.')
|
||||
|
||||
if any(v.violation_type == 'missing_disclaimer' for v in violations):
|
||||
recommendations.append('페이지 하단에 필수 고지사항을 추가하세요.')
|
||||
|
||||
return recommendations
|
||||
|
||||
def main():
|
||||
"""Command-line interface for compliance checker."""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='Check medical marketing content for compliance')
|
||||
parser.add_argument('--input', '-i', required=True, help='Input content file')
|
||||
parser.add_argument('--output', '-o', default='compliance_report.json', help='Output report file')
|
||||
parser.add_argument('--verbose', '-v', action='store_true', help='Print detailed output')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Read input content
|
||||
with open(args.input, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
# Run compliance check
|
||||
checker = ComplianceChecker()
|
||||
report = checker.check_content(content)
|
||||
|
||||
# Save report
|
||||
with open(args.output, 'w', encoding='utf-8') as f:
|
||||
json.dump(report, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# Print summary
|
||||
print(f"Compliance Check Complete")
|
||||
print(f"==========================================")
|
||||
print(f"Compliant: {'YES ✓' if report['is_compliant'] else 'NO ✗'}")
|
||||
print(f"Total Violations: {report['total_violations']}")
|
||||
print(f" - Critical: {report['violations_by_severity']['critical']}")
|
||||
print(f" - High: {report['violations_by_severity']['high']}")
|
||||
print(f" - Medium: {report['violations_by_severity']['medium']}")
|
||||
print(f" - Low: {report['violations_by_severity']['low']}")
|
||||
print(f"\nReport saved to: {args.output}")
|
||||
|
||||
if args.verbose and report['violations']:
|
||||
print(f"\nViolations Found:")
|
||||
for v in report['violations']:
|
||||
print(f"\n Type: {v['violation_type']}")
|
||||
print(f" Severity: {v['severity']}")
|
||||
print(f" Text: '{v['matched_text']}'")
|
||||
print(f" Explanation: {v['explanation_korean']}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,4 @@
|
||||
# 40-jamie-brand-editor dependencies
|
||||
python-dotenv>=1.0.0
|
||||
rich>=13.7.0
|
||||
typer>=0.9.0
|
||||
Reference in New Issue
Block a user