> ## Documentation Index
> Fetch the complete documentation index at: https://chariow.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# CLAUDE

# CLAUDE.md

Guidance for Claude Code and other AI agents working in this repository.

## Project overview

This repo is the official developer documentation site for Chariow, a platform for selling digital products, managing customers, processing payments, and handling license keys. It is built with Mintlify and published as a bilingual (English and French) docs site targeting developers who integrate with the Chariow API. The site covers guides, an OpenAPI-backed API reference, and integration docs for MCP and n8n.

## Tech stack

* Node.js >= 18.0.0
* Mintlify ^4.2.577 (docs framework)
* pnpm (lockfile present; npm also supported per README)
* OpenAPI 3.x spec (`api-reference/openapi.json`) — source of truth for the API reference
* Chariow REST API base URL: `https://api.chariow.com/v1` (bearer auth)

## Getting started

```bash theme={null}
npm install
# or
pnpm install

# Start local dev server (http://localhost:3000)
npm run dev
```

## Common commands

| Task                | Command           |
| ------------------- | ----------------- |
| Dev / serve         | `npm run dev`     |
| Preview (port 3333) | `npm run preview` |
| Build               | `npm run build`   |
| Lint (broken links) | `npm run lint`    |

## Architecture

* `docs.json` — Mintlify site configuration: theme, navigation tree, API settings, localization, integrations (GA4, telemetry).
* `en/` — English MDX content pages (introduction, guides, resources, mcp/, n8n/).
* `fr/` — French MDX content pages mirroring the English structure.
* `api-reference/` — Auto-generated API pages driven by `openapi.json`; shared between both language tabs.
* `images/` — Static assets referenced in docs pages.
* `umami.js` — Custom analytics script injected into the site.

All navigation is declared in `docs.json` under `navigation.languages`; adding a new page requires both creating the MDX file and registering it in the relevant language tab's group array.

## Conventions

* Content is written in MDX; Mintlify-specific components (`<Card>`, `<CodeGroup>`, etc.) are available.
* Both `en/` and `fr/` must stay structurally in sync — new guides should be added to both language trees.
* API reference pages are generated from `api-reference/openapi.json`; update the spec rather than hand-editing generated pages.
* No test framework is present; `npm run lint` (Mintlify broken-links check) is the only automated quality gate.
* Use `pnpm` for dependency management to stay consistent with the checked-in `pnpm-lock.yaml`.

## Git Conventions

### 1. Branch names

Enforced regex (`branch_name_pattern`):

```
^(feature|fix|hotfix|chore|docs|refactor|test|ci|perf|build|style)/[a-z0-9._-]+$
```

* Lowercase only, kebab-case after the prefix, **max 50 characters** total.
* Use the full word `feature/` — **never** `feat/` (the short `feat` form is only for commit message types).
* Include the ticket id when relevant: `feature/AXA-123-add-stripe` (the ticket id is lowercased to satisfy the pattern — e.g. `feature/axa-123-add-stripe`).
* **Never** use a `claude/` prefix or any prefix outside the allowed set.
* `main`, `release`, `staging` are permanent protected branches — never push to them directly.
* If a branch is misnamed, rename it before pushing: `git branch -m <old> <new>`.

### 2. Commit messages

Enforced regex (`commit_message_pattern`), applied to **every** commit:

```
^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([^)]+\))?!?: .+
```

* Lowercase type, optional scope in parens, optional `!` for breaking changes, subject after `: `.
* Subject starts with a lowercase letter and has no trailing period.
* Examples: `feat(checkout): add Apple Pay support`, `fix(api): handle expired tokens`, `chore(deps): bump axios from 1.7.2 to 1.15.2`, `refactor!: drop Node 18 support`.
* Do not rewrite Dependabot commits — `chore(deps): bump X from a to b` is already enforced via `.github/dependabot.yml`.

### 3. Files that are always rejected

Never stage or commit:

* `.env`, `.env.*` (only `.env.example` and `.env.sample` are allowed), `**/.env`, `**/.env.*`
* Private keys: `**/id_rsa{,.pub}`, `**/id_dsa`, `**/id_ecdsa`, `**/id_ed25519`, `**/.ssh/id_*`
* Credentials: `**/.aws/credentials`, `**/credentials.json`, `**/service-account.json`, `**/firebase-adminsdk-*.json`, `**/secrets.{yml,yaml}`
* Extensions: `*.pem`, `*.key`, `*.p12`, `*.pfx`, `*.jks`, `*.keystore`, `*.ppk`, `*.asc`, `*.gpg`
* Any file larger than 100 MB (use git LFS)
  If a secret is needed, use `.env.example` for env vars and an external secret manager for credentials.

### Pull requests targeting `main`, `release`, `staging`

All three are protected — a PR is required (direct push blocked):

* 1 approval, all conversations resolved, **squash or rebase merge only** (linear history enforced — no merge commits).
* Commits must be GPG- or SSH-signed. Signing is required for `main` (`required-signatures-main` ruleset).
* The PR **title** becomes the squash commit message and must match the commit-message regex above (enforced on all three branches).

**Required workflows run on PRs whose base is `main` only** (not `release`/`staging`): `Branch naming convention`, `PR title — Conventional Commits`, and `PR size labeler`.
If a check shows `Waiting for workflow to run` for over a minute, the third-party action is likely missing from the enterprise allowlist.

When the branch-naming or PR-title check fails, the baseline bot auto-posts rename/title suggestions, following the enforced regex patterns.
If the bot's suggestions are incorrect, edit the PR title or branch name to match the required format.

### Pre-push checklist

Before running `git push`:

1. Branch name matches the regex.
2. Every commit in `origin/main..HEAD` matches the commit pattern (`git log --format=%s origin/main..HEAD`).
3. No staged file is in the blocked paths/extensions list.
4. Commits are signed if the target is `main`.

If any check fails, fix it locally rather than letting the server reject the push.
