Skip to content

Commit 83a5f90

Browse files
committed
Add CLAUDE.md for Claude Code guidance
1 parent 04913b7 commit 83a5f90

1 file changed

Lines changed: 68 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Plugin Overview
6+
7+
FreemKit is a WordPress plugin (v1.0.0-beta1) that bridges Freemius software licensing with Kit (formerly ConvertKit) email marketing. It receives Freemius webhook events and subscribes customers to Kit forms/tags based on whether they are free or paid users. Namespace: `WebberZone\FreemKit`. Prefix: `freemkit_`. Requires WordPress 5.0+, PHP 7.4+.
8+
9+
## Commands
10+
11+
### PHP
12+
```bash
13+
composer phpcs # Lint PHP (WordPress coding standards)
14+
composer phpcbf # Auto-fix PHP code style
15+
composer phpstan # Static analysis (level configured in phpstan.neon.dist)
16+
composer phpcompat # Check PHP 7.4–8.5 compatibility
17+
composer test # Run all checks (phpcs + phpcompat + phpstan)
18+
composer build:vendor # Install production-only dependencies
19+
composer zip # Create distribution zip
20+
```
21+
22+
### JavaScript/CSS
23+
```bash
24+
npm run build # Build JS/CSS assets with wp-scripts
25+
npm run build:assets # Minify CSS/JS and generate RTL CSS (node build-assets.js)
26+
npm start # Watch mode
27+
npm run lint:js # ESLint
28+
npm run lint:css # Stylelint
29+
npm run format # Format with wp-scripts
30+
npm run zip # Create plugin zip via wp-scripts
31+
```
32+
33+
## Architecture
34+
35+
### Entry Point & Bootstrap
36+
`freemkit.php` defines constants (`FREEMKIT_VERSION`, `FREEMKIT_PLUGIN_FILE`, `FREEMKIT_PLUGIN_DIR`, `FREEMKIT_PLUGIN_URL`), loads Kit shared library classes from `vendor/convertkit/convertkit-wordpress-libraries/`, registers the autoloader, and calls `\WebberZone\FreemKit\load()` on `plugins_loaded`.
37+
38+
**Autoloader convention:** Namespace segments become path segments under `includes/`; underscores → hyphens, lowercase, last segment prefixed with `class-`. e.g. `WebberZone\FreemKit\Admin\Settings``includes/admin/class-settings.php`.
39+
40+
### Core Components
41+
- **`Main`** (`includes/class-main.php`) — Singleton. Instantiates `Runtime`, `Kit_Credential_Hooks`, and `Language_Handler`; registers hooks via `Hook_Registry`.
42+
- **`Runtime`** (`includes/class-runtime.php`) — Initializes `Database`, `Kit_API`, and `Webhook_Handler` on `init`. Creates the `Admin` object when in admin context.
43+
- **`Webhook_Handler`** (`includes/class-webhook-handler.php`) — Core logic. Registers a REST endpoint at `freemkit/v1/webhook` (or a query-var fallback). Validates HMAC-SHA256 signatures (`x-signature` header) and webhook freshness (15-minute window). Queues events as WP transients and processes them asynchronously via WP-Cron (`freemkit_process_webhook_event`). Includes deduplication via `freemkit_webhook_seen_*` transients, and exponential-backoff retry (max 3 attempts).
44+
- **`Database`** (`includes/class-database.php`) — Manages the `{prefix}freemkit_subscribers` custom table, which persists subscriber records locally.
45+
- **`Options_API`** (`includes/class-options-api.php`) — All settings stored as a single `freemkit_settings` array in `wp_options`. Access via `Options_API::get_option($key)` / `Options_API::get_settings()`. Sensitive keys (access/refresh tokens) are encrypted at rest using AES-256-CBC (OpenSSL) or libsodium.
46+
47+
### Kit Integration (`includes/kit/`)
48+
- **`Kit_API`** — Wraps `ConvertKit_API_V4` to subscribe users to forms and apply tags.
49+
- **`Kit_Settings`** — Manages OAuth tokens (`kit_access_token`, `kit_refresh_token`). Falls back to the official Kit WordPress plugin's stored credentials if available.
50+
- **`Kit_Credential_Hooks`** — Listens for `freemkit_api_get_access_token` / `freemkit_api_refresh_token` / `convertkit_api_access_token_invalid` actions to keep tokens in sync.
51+
- **`Kit_Audit_Log`** — Logs Kit API interactions.
52+
53+
### Admin (`includes/admin/`)
54+
- **`Admin`** — Admin menu, settings page, subscriber list screen.
55+
- **`Settings`** / **`Settings_Wizard`** — Settings pages; wizard is shown on first activation. Settings include: global Kit form/tag defaults, per-plugin overrides (free and paid form IDs, tag IDs, event types), custom field mappings, webhook endpoint type (REST vs query-var).
56+
- **`Kit_OAuth`** — OAuth flow for connecting to Kit.
57+
- **`Subscribers_List`** / **`Subscribers_List_Table`** — Admin screen displaying the local `freemkit_subscribers` table.
58+
59+
### Utilities (`includes/util/`)
60+
- **`Hook_Registry`** — Static registry for all registered actions/filters; prevents duplicates (same pattern as CRP).
61+
62+
## Key Patterns
63+
64+
- **Webhook event routing:** Freemius sends a `type` field (e.g. `install.installed`, `license.created`). Default free events: `['install.installed']`; default paid events: `['license.created']`. Both can be overridden per-plugin config or via `freemkit_default_free_event_types` / `freemkit_default_paid_event_types` filters.
65+
- **Per-plugin config:** The settings store a `plugins` array, each entry keyed by Freemius plugin ID, with separate free/paid form IDs, tag IDs, and event types. Falls back to global kit form/tag settings when per-plugin values are empty.
66+
- **Settings access:** Always use `Options_API::get_option($key)` rather than reading `freemkit_settings` directly.
67+
- **Hook registration:** Use `Hook_Registry::add_action()` / `Hook_Registry::add_filter()` rather than WordPress functions directly.
68+
- **Async processing:** Webhooks are never processed synchronously (except when WP-Cron is disabled or scheduling fails). Always go through `queue_webhook_event()``process_queued_webhook()`.

0 commit comments

Comments
 (0)