|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code when working with the SourceMedium documentation repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +This is a **Mintlify documentation site** for SourceMedium, a data analytics platform for e-commerce brands. The docs cover: |
| 8 | +- Platform integrations (Shopify, Meta, Google Ads, Klaviyo, etc.) |
| 9 | +- Data transformation and activation |
| 10 | +- Dashboard/BI usage guides |
| 11 | +- Attribution and analytics concepts |
| 12 | + |
| 13 | +**Tech Stack:** Mintlify (MDX-based docs framework), GitHub Actions for CI/CD |
| 14 | + |
| 15 | +## Essential Commands |
| 16 | + |
| 17 | +```bash |
| 18 | +# Local development |
| 19 | +mintlify dev # Start local dev server (requires npm install -g mintlify) |
| 20 | + |
| 21 | +# Validation (run before committing) |
| 22 | +python3 -m json.tool docs.json # Validate JSON syntax |
| 23 | + |
| 24 | +# Navigation validation script (from CI workflow) |
| 25 | +python3 << 'EOF' |
| 26 | +import json, os, sys |
| 27 | +def extract_refs(obj, refs=[]): |
| 28 | + if isinstance(obj, str) and not obj.startswith('http'): refs.append(obj) |
| 29 | + elif isinstance(obj, list): [extract_refs(i, refs) for i in obj] |
| 30 | + elif isinstance(obj, dict): [extract_refs(v, refs) for k,v in obj.items() if k in ('tabs','pages','navigation','groups')] |
| 31 | + return refs |
| 32 | +refs = extract_refs(json.load(open('docs.json'))) |
| 33 | +missing = [f"{r}.mdx" for r in refs if not os.path.exists(f"{r}.mdx")] |
| 34 | +if missing: print(f"Missing: {missing[:10]}"); sys.exit(1) |
| 35 | +print(f"✅ All {len(refs)} nav refs valid") |
| 36 | +EOF |
| 37 | +``` |
| 38 | + |
| 39 | +## Directory Structure |
| 40 | + |
| 41 | +``` |
| 42 | +sourcemedium-docs/ |
| 43 | +├── docs.json # Main navigation config (Mintlify) |
| 44 | +├── help-center/ # FAQs, guides, troubleshooting |
| 45 | +│ ├── faq/ |
| 46 | +│ │ ├── account-management-faqs/ |
| 47 | +│ │ ├── dashboard-functionality-faqs/ |
| 48 | +│ │ ├── data-faqs/ |
| 49 | +│ │ └── configuration-sheet-faqs/ |
| 50 | +│ └── core-concepts/ |
| 51 | +├── data-inputs/ # Integration guides |
| 52 | +│ ├── platform-integration-instructions/ # Setup guides per platform |
| 53 | +│ ├── platform-supporting-resources/ # Platform-specific deep dives |
| 54 | +│ ├── configuration-sheet/ # Config sheet docs |
| 55 | +│ └── attribution-health/ # Attribution improvement guides |
| 56 | +├── data-transformations/ # How SM transforms data |
| 57 | +│ └── naming-conventions/ # Column/table naming standards |
| 58 | +├── data-activation/ # Using SM data |
| 59 | +│ ├── managed-data-warehouse/ |
| 60 | +│ ├── managed-bi-v1/modules/ |
| 61 | +│ ├── data-tables/ # Table documentation |
| 62 | +│ └── template-resources/ # Looker Studio templates |
| 63 | +├── onboarding/ # Getting started content |
| 64 | +│ ├── getting-started/ |
| 65 | +│ └── analytics-tools/ |
| 66 | +├── mta/ # Multi-Touch Attribution docs |
| 67 | +├── snippets/ # Reusable MDX snippets |
| 68 | +├── images/ # All images (article-imgs/, platform-logos/) |
| 69 | +└── .github/workflows/ # CI/CD (docs-quality.yml) |
| 70 | +``` |
| 71 | + |
| 72 | +## docs.json Navigation Structure |
| 73 | + |
| 74 | +The navigation uses a `tabs > groups > pages` hierarchy: |
| 75 | + |
| 76 | +```json |
| 77 | +{ |
| 78 | + "navigation": { |
| 79 | + "tabs": [ |
| 80 | + { |
| 81 | + "tab": "Tab Name", |
| 82 | + "groups": [ |
| 83 | + { |
| 84 | + "group": "Group Name", |
| 85 | + "pages": [ |
| 86 | + "path/to/page", // Simple page reference |
| 87 | + { // Nested group |
| 88 | + "group": "Nested Group", |
| 89 | + "pages": ["path/to/nested-page"] |
| 90 | + } |
| 91 | + ] |
| 92 | + } |
| 93 | + ] |
| 94 | + } |
| 95 | + ] |
| 96 | + } |
| 97 | +} |
| 98 | +``` |
| 99 | + |
| 100 | +**Current Tabs:** |
| 101 | +- What Is SourceMedium (help-center) |
| 102 | +- Onboarding |
| 103 | +- Data Integrations & Inputs |
| 104 | +- Data Transformation |
| 105 | +- Data Activation |
| 106 | +- MTA |
| 107 | + |
| 108 | +**Important:** Page references are paths WITHOUT `.mdx` extension. They must match actual file paths. |
| 109 | + |
| 110 | +## MDX Components |
| 111 | + |
| 112 | +Mintlify provides these components (use them for consistent formatting): |
| 113 | + |
| 114 | +### Callouts |
| 115 | +```mdx |
| 116 | +<Info>Informational note</Info> |
| 117 | +<Tip>Helpful suggestion</Tip> |
| 118 | +<Note>Important callout</Note> |
| 119 | +<Warning>Caution or gotcha</Warning> |
| 120 | +``` |
| 121 | + |
| 122 | +### Cards & Groups |
| 123 | +```mdx |
| 124 | +<CardGroup cols={2}> |
| 125 | + <Card title="Card Title" icon="icon-name" href="/path/to/page"> |
| 126 | + Card description |
| 127 | + </Card> |
| 128 | +</CardGroup> |
| 129 | +``` |
| 130 | + |
| 131 | +### Tabs |
| 132 | +```mdx |
| 133 | +<Tabs> |
| 134 | + <Tab title="First Tab">Content for first tab</Tab> |
| 135 | + <Tab title="Second Tab">Content for second tab</Tab> |
| 136 | +</Tabs> |
| 137 | +``` |
| 138 | + |
| 139 | +### Accordions |
| 140 | +```mdx |
| 141 | +<Accordion title="Expandable Section"> |
| 142 | + Hidden content revealed on click |
| 143 | +</Accordion> |
| 144 | + |
| 145 | +<AccordionGroup> |
| 146 | + <Accordion title="Item 1">Content 1</Accordion> |
| 147 | + <Accordion title="Item 2">Content 2</Accordion> |
| 148 | +</AccordionGroup> |
| 149 | +``` |
| 150 | + |
| 151 | +### Steps |
| 152 | +```mdx |
| 153 | +<Steps> |
| 154 | + <Step title="Step 1">First step content</Step> |
| 155 | + <Step title="Step 2">Second step content</Step> |
| 156 | +</Steps> |
| 157 | +``` |
| 158 | + |
| 159 | +### Tooltips & Snippets |
| 160 | +```mdx |
| 161 | +<Tooltip tip="Explanation text">Term</Tooltip> |
| 162 | + |
| 163 | +{/* Include reusable snippet */} |
| 164 | +<Snippet file="snippet-name.mdx" /> |
| 165 | +``` |
| 166 | + |
| 167 | +## Frontmatter |
| 168 | + |
| 169 | +Every `.mdx` file needs frontmatter: |
| 170 | + |
| 171 | +```yaml |
| 172 | +--- |
| 173 | +title: "Page Title" # Required |
| 174 | +sidebarTitle: "Short Nav Title" # Optional - shorter title for sidebar |
| 175 | +description: "SEO description" # Optional but recommended |
| 176 | +icon: 'icon-name' # Optional - Font Awesome icon |
| 177 | +--- |
| 178 | +``` |
| 179 | + |
| 180 | +Common icons: `plug`, `chart-line`, `question-mark`, `book`, `gear`, `heart-pulse`, `tags` |
| 181 | + |
| 182 | +## CI/CD Quality Checks |
| 183 | + |
| 184 | +PRs trigger `.github/workflows/docs-quality.yml` which validates: |
| 185 | + |
| 186 | +1. **Spell Check** (codespell) - Catches typos |
| 187 | +2. **Link Check** (lychee) - Validates internal/external URLs |
| 188 | +3. **JSON Validation** - Ensures docs.json is valid |
| 189 | +4. **Navigation Validation** - All page refs point to existing files |
| 190 | + |
| 191 | +**Ignored terms** (add to workflow if needed): smcid, sourcemedium, hdyhau, utm, cogs, ltv, roas, aov, klaviyo, shopify, etc. |
| 192 | + |
| 193 | +## Writing Guidelines |
| 194 | + |
| 195 | +### Terminology |
| 196 | +- **SMCID** - SourceMedium Customer ID (unique identifier) |
| 197 | +- **HDYHAU** - "How Did You Hear About Us?" (post-purchase survey) |
| 198 | +- **MTA** - Multi-Touch Attribution |
| 199 | +- **LTV** - Lifetime Value |
| 200 | +- **ROAS** - Return on Ad Spend |
| 201 | +- **AOV** - Average Order Value |
| 202 | +- **Zero-party data** - Customer-provided info (surveys) |
| 203 | +- **First-party data** - Tracking-based data (UTMs, GA4) |
| 204 | + |
| 205 | +### Style |
| 206 | +- Use sentence case for headings |
| 207 | +- Prefer active voice |
| 208 | +- Keep paragraphs short (3-4 sentences max) |
| 209 | +- Use tables for comparisons and reference info |
| 210 | +- Use CardGroups for related links/resources |
| 211 | +- Use Tabs for alternative approaches or platform-specific content |
| 212 | + |
| 213 | +### Links |
| 214 | +- **Internal:** Use relative paths `/data-inputs/platform-integration-instructions/shopify-integration` |
| 215 | +- **External:** Full URLs `https://example.com` |
| 216 | +- **Never:** Use old `help.sourcemedium.com` URLs (these are deprecated) |
| 217 | + |
| 218 | +## Common Tasks |
| 219 | + |
| 220 | +### Adding a new integration guide |
| 221 | +1. Create file: `data-inputs/platform-integration-instructions/<platform>-integration.mdx` |
| 222 | +2. Add to `docs.json` navigation under appropriate group |
| 223 | +3. Optionally create supporting resources in `data-inputs/platform-supporting-resources/<platform>/` |
| 224 | + |
| 225 | +### Adding a new FAQ |
| 226 | +1. Create file in appropriate `help-center/faq/<category>/` folder |
| 227 | +2. Add to `docs.json` under "What Is SourceMedium" tab > FAQs group |
| 228 | + |
| 229 | +### Adding images |
| 230 | +1. Place in `images/article-imgs/` (or `platform-logos/` for logos) |
| 231 | +2. Reference as `/images/article-imgs/filename.png` |
| 232 | + |
| 233 | +### Creating reusable content |
| 234 | +1. Create snippet in `snippets/snippet-name.mdx` |
| 235 | +2. Use with `<Snippet file="snippet-name.mdx" />` |
| 236 | + |
| 237 | +## Troubleshooting |
| 238 | + |
| 239 | +### "Page not found" in local dev |
| 240 | +- Check file path matches docs.json reference exactly |
| 241 | +- Ensure `.mdx` extension exists on file but NOT in docs.json |
| 242 | + |
| 243 | +### CI failing on spell check |
| 244 | +- Add legitimate terms to `ignore_words_list` in `.github/workflows/docs-quality.yml` |
| 245 | + |
| 246 | +### CI failing on link check |
| 247 | +- Fix broken internal links (check file exists) |
| 248 | +- For flaky external links, add to `--exclude` in lychee args |
| 249 | + |
| 250 | +### Navigation not updating |
| 251 | +- Ensure valid JSON in docs.json (run `python3 -m json.tool docs.json`) |
| 252 | +- Check page path exists as `.mdx` file |
0 commit comments