Appearance
Project guidance for Claude / AI assistants
Customer knowledge base for docs.captifi.io. Every customer-facing change in captifi-portal or captifi-dashboard must update the matching page(s) here plus whats-new.md in the same piece of work (full rule: workspace-root CLAUDE.md).
Before you finish a change
- Run the project's tests and linter/static analysis. Do not claim a change works without verifying.
- Match the existing patterns, naming, and style of the file you are editing.
Security (non-negotiable, see SECURITY-CHECKLIST.md in this repo)
- Authorize every action against the authenticated user. Never trust a client-supplied ID for ownership (IDOR).
- The server is the source of truth for prices, limits, balances, and statuses. Enforce limits atomically (locks or DB unique constraints), never a count-then-insert race.
- No secrets in the repo, including as config defaults. Read them through the config layer. Keep test and prod keys distinct.
- Parameterize all queries. Escape output; emit raw HTML only on sanitized content.
- Throttle auth and API routes. Verify and de-duplicate webhooks (signature + idempotency).
- Whitelist writable fields; never bind a raw request body to a model.
Writing / copy
- No em dashes or en dashes anywhere (docs, copy, comments). Use commas, periods, colons. Hyphens are fine.
Project specifics
- Stack: VitePress 1.6 static site. Content = markdown with YAML frontmatter (
title+descriptionrequired). Nav/sidebar in.vitepress/config.mts. - Run / build:
npm run docs:dev; verify withnpm run docs:build(fails on dead links). CI runs the same build on every push/PR. - Deploy: push to
master, thenssh root@captifi-server /usr/local/bin/deploy-captifi-docs(pull, npm ci, build, rsync into /var/www/captifi-docs). Public-IP SSH is firewalled — always go via Tailscale hostcaptifi-server. - Canonical facts (do not contradict): see README.md "Content Guidelines" — pricing/trial/extra-site numbers, portal IP 46.62.168.7, WireGuard UDP 51820, 8-digit device activation PIN entered on the device's own setup page.
- Gotchas: docs describe the NEW dashboard (my.captifi.io) — app.captifi.io is the "classic dashboard"; never document a UI flow without checking the captifi-dashboard source; screenshots live in public/images/dashboard/ and were captured from a locally seeded demo stack (no real customer data).