Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ The main HTTP client for communicating with the Hellotext API.
Makes an HTTP request to the Hellotext API.

**Parameters:**

- `$method` - HTTP method (GET, POST, PATCH, PUT, DELETE)
- `$path` - API endpoint path
- `$data` - Request payload

**Returns:**

```php
[
'request' => [
Expand All @@ -61,6 +63,7 @@ Makes an HTTP request to the Hellotext API.
```

**Example:**

```php
use Hellotext\Api\Client;
use Hellotext\Constants;
Expand All @@ -85,6 +88,7 @@ $response = Client::post(Constants::API_ENDPOINT_PROFILES, [
Creates a client instance with a custom API suffix. Useful for testing.

**Example:**

```php
$client = Client::with_sufix('/v2');
```
Expand All @@ -110,10 +114,12 @@ Creates a new event tracker. If no session is provided, it attempts to retrieve
Tracks an event with the given action and payload.

**Parameters:**

- `$action` - Event action name (use constants from `Constants::EVENT_*`)
- `$payload` - Event data

**Example:**

```php
use Hellotext\Api\Event;
use Hellotext\Constants;
Expand Down Expand Up @@ -151,6 +157,7 @@ Accepts either a product ID or a `WC_Product` instance.
Returns the adapted product payload.

**Returns:**

```php
[
'reference' => int, // Product ID
Expand All @@ -168,6 +175,7 @@ Returns the adapted product payload.
```

**Example:**

```php
use Hellotext\Adapters\ProductAdapter;

Expand All @@ -192,6 +200,7 @@ public function __construct(\WC_Order $order)
Returns the adapted order payload.

**Returns:**

```php
[
'reference' => int, // Order ID
Expand Down Expand Up @@ -240,6 +249,7 @@ public function __construct(float|string|null $price)
Returns price in cents with currency.

**Returns:**

```php
[
'amount' => int, // Price in cents
Expand All @@ -260,6 +270,7 @@ public function __construct(?int $user_id, array $billing = [])
```

**Parameters:**

- `$user_id` - WordPress user ID (null for guest checkout)
- `$billing` - Billing data from checkout

Expand All @@ -268,12 +279,14 @@ public function __construct(?int $user_id, array $billing = [])
##### `process(): void`

Executes the profile creation/association flow:

1. Checks if profile exists
2. Creates new profile if needed
3. Associates profile with session
4. Updates session metadata

**Example:**

```php
use Hellotext\Services\CreateProfile;

Expand Down Expand Up @@ -315,6 +328,7 @@ Decrypts an encrypted session string.
Sets the `hello_session` cookie with proper expiration and security flags.

**Example:**

```php
use Hellotext\Services\Session;

Expand Down Expand Up @@ -384,16 +398,51 @@ Constants::EVENT_COUPON_REDEEMED // 'coupon.redeemed'

## WordPress Hooks

The plugin registers these WooCommerce and WordPress hooks:

| Hook | Handler | Purpose |
| --------------------------------------------- | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `woocommerce_after_single_product` | `hellotext_product_viewed` | Track `product.viewed` |
| `woocommerce_after_cart` | `hellotext_trigger_cart_updated` | Compare current and previous cart state |
| `woocommerce_add_to_cart` | `hellotext_trigger_cart_updated` | Compare current and previous cart state |
| `woocommerce_cart_item_removed` | `hellotext_trigger_cart_updated` | Compare current and previous cart state |
| `woocommerce_after_cart_item_quantity_update` | `hellotext_trigger_cart_updated` | Compare current and previous cart state |
| `woocommerce_applied_coupon` | `hellotext_coupon_redeemed` | Track valid `coupon.redeemed` events |
| `woocommerce_after_order_details` | `hellotext_order_placed` | Track `order.placed` and persist encrypted session metadata on the order; render-based hook, so duplicate prevention is required |
| `woocommerce_order_status_changed` | `track_order_status` | Track `order.confirmed`, `order.cancelled`, and `order.delivered` |
| `woocommerce_order_refunded` | `hellotext_refund_created` | Track `refund.received` |
| `user_register` | `hellotext_user_registered` | Track customer registration/profile flow |
| `hellotext_woocommerce_cart_updated` | `hellotext_cart_updated` | Track `cart.added` and `cart.removed` |
| `update_option` | `custom_field_updated` | Recreate integration after Business ID changes |
| `admin_init` | `hellotext_settings_init` | Register plugin settings |
| `admin_head` / `wp_head` | `hellotext_script` | Inject frontend/admin scripts |

## WooCommerce Compatibility

Compatibility posture as of 2026-06-11. See [WooCommerce Compatibility and API Audit](docs/WOOCOMMERCE-AUDIT.md) for the full hook/API audit, HPOS assessment, compatibility matrix, and release recommendations.

| Area | Status | Notes |
| ------------------------------ | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| WooCommerce order metadata | HPOS-aligned metadata access | Uses `WC_Order` metadata CRUD for Hellotext session metadata. |
| Order status and refund events | HPOS-aligned metadata access | Reads session metadata from the order object instead of `get_post_meta()`. |
| Product, cart, coupon events | Public hook/API usage | Uses WooCommerce hooks and objects, not order storage internals. |
| Automated tests | Mock-backed unit coverage | Event tests cover outbound payloads without real WordPress/WooCommerce runtime or HPOS datastore coverage. |
| Runtime verification | Required before declaration | Test with HPOS enabled and disabled in a real WooCommerce site before declaring formal compatibility in the plugin header/runtime. |

Do not add a formal HPOS compatibility declaration until the release candidate has passed runtime checks on WooCommerce with HPOS enabled and disabled.

### Actions

#### `hellotext_create_profile`

Triggers profile creation/association.

**Parameters:**

- `$payload` - Either user ID (int) or billing data (array)

**Usage:**

```php
// For logged-in user
do_action('hellotext_create_profile', $user_id);
Expand Down Expand Up @@ -431,6 +480,7 @@ The plugin respects the following environment variables:
- `HELLOTEXT_API_URL` - Override API URL (development only)

**Example (.htaccess):**

```apache
SetEnv APP_ENV development
SetEnv HELLOTEXT_API_URL https://api-dev.hellotext.com
Expand All @@ -454,6 +504,7 @@ try {
### Authentication

All API requests include an `Authorization: Bearer` header with either:

- **Business ID** for event tracking
- **Access Token** for profile/session management

Expand Down
105 changes: 82 additions & 23 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ composer install
```

This installs:

- Pest (testing framework)
- Mockery (mocking library)
- WordPress & WooCommerce stubs (for IDE autocomplete)
Expand Down Expand Up @@ -177,6 +178,35 @@ The project uses [Pest](https://pestphp.com/) for testing.
./vendor/bin/paratest
```

The Composer aliases used by CI and maintainers are:

```bash
composer install
composer test
composer format:check
composer build
```

`composer build` installs production dependencies with `--no-dev --optimize-autoloader`. Do not use the build output for local development without reinstalling dev dependencies afterward.

### Verified Local Flow

Last verified: 2026-06-11

| Command | Result | Notes |
| ----------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `composer install` | Passed | Requires PHP 8.2+ and Composer 2. The local system Composer emitted PHP deprecation notices under PHP 8.4; dependencies still installed correctly. |
| `composer test` | Passed | Pest suite runs against WordPress/WooCommerce mocks, not a real WordPress install. |
| `composer format:check` | Passed | PHP CS Fixer warned when run under PHP 8.4 because the Composer platform is PHP 8.2.12. CI runs the style check on PHP 8.2. |
| `composer build` | Passed | Runs `composer install --no-dev --optimize-autoloader` and removes dev tooling from `vendor/`. Run `composer install` again afterward before continuing local development. |

Setup assumptions:

- PHP 8.2 or newer is available locally.
- Composer can install from the checked-in `composer.lock`.
- Tests do not require a real WordPress, WooCommerce, database, or Hellotext API connection.
- Outbound HTTP in tests is mocked through WordPress HTTP function stubs.

### Writing Tests

#### Unit Tests
Expand Down Expand Up @@ -312,60 +342,84 @@ add_action('all', function($hook) {

### Pre-Release Checklist

- [ ] Run all tests: `./vendor/bin/pest`
- [ ] Check for PHP errors/warnings
- [ ] Test on fresh WordPress installation
- [ ] Test with WooCommerce latest version
- [ ] Verify settings page functionality
- [ ] Test event tracking in Hellotext dashboard
- [ ] Update documentation if API changed
- [ ] Update changelog.txt
- [ ] Confirm the version in `hellotext.php` matches the release tag.
- [ ] Update `changelog.txt` with user-facing changes, compatibility notes, and any known limitations.
- [ ] Review open dependency PRs and confirm there are no urgent security/runtime updates pending.
- [ ] Run `composer install` from a clean checkout.
- [ ] Run `composer test` and confirm all tests pass.
- [ ] Run `composer format:check` and confirm no style diff is reported.
- [ ] Run `composer build` and confirm production dependencies install with `--no-dev --optimize-autoloader`.
- [ ] Inspect the production `vendor/` tree enough to confirm dev-only packages such as Pest, Mockery, stubs, PHPUnit, and PHP CS Fixer are not included in the release build.
- [ ] Verify `.distignore` excludes development files from the release zip: `.github/`, `tests/`, `composer.json`, `composer.lock`, `DEVELOPMENT.md`, and `API.md`.
- [ ] Smoke test the plugin zip in a clean WordPress/WooCommerce site.
- [ ] Confirm settings save correctly: Business ID, access token, webchat ID, placement, and behavior.
- [ ] Confirm script/webchat injection renders on the storefront when configured.
- [ ] Smoke test tracking for product view, cart add/remove, coupon redemption, checkout/order placement, order status change, refund, user registration, plugin activation, and plugin deactivation.
- [ ] Smoke test classic template pages and WooCommerce Cart/Checkout blocks separately for product, cart, and checkout coverage.
- [ ] Smoke test order placement, order status, and refund flows with WooCommerce HPOS enabled and disabled.
- [ ] Record WooCommerce API/HPOS compatibility notes in the release description if anything changed.
- [ ] Run `composer install` again after build validation to restore dev dependencies before more local work.

### Creating a Release

1. **Tag the release:**

```bash
git tag -a v1.3.0 -m "Release version 1.3.0"
git push origin v1.3.0
```

2. **Build release package:**
```bash

````bash
# Remove dev dependencies
composer install --no-dev

# Create zip
cd ..
zip -r hellotext-wordpress-1.3.0.zip hellotext-wordpress \
-x "hellotext-wordpress/.git/*" \
-x "hellotext-wordpress/tests/*" \
-x "hellotext-wordpress/node_modules/*"
```

3. **Create GitHub release:**
- Go to Releases → Draft new release
- Select the tag
- Upload the zip file
- Add release notes from changelog
3. **Verify the generated release:**
- Download the release zip from GitHub.
- Confirm files excluded by `.distignore` are not included: `.github/`, `tests/`, `composer.json`, `composer.lock`, `DEVELOPMENT.md`, and `API.md`.
- Confirm runtime files are included: `hellotext.php`, `src/`, `vendor/`, `README.md`, and `changelog.txt` if present.
- Install the zip in a clean WordPress/WooCommerce site.
- Confirm the release asset installs and activates without PHP warnings in `debug.log`.

### Post-Release

1. Reinstall dev dependencies: `composer install`
2. Announce release to team
3. Monitor error logs for issues

### Dependency Update Triage

Use this checklist before merging dependency-only PRs:

- Confirm the diff is limited to dependency metadata or the expected workflow file.
- Confirm GitHub reports the PR as mergeable.
- Confirm required CI checks pass.
- Prefer merging patch/minor test stub updates independently from runtime code changes.
- For GitHub Action major updates, inspect the action release notes before merging.

Dependency PRs reviewed during this maintenance pass:

- Keep dependency-only lockfile refreshes separate from runtime compatibility changes.
- Prefer one broad lock refresh over multiple older overlapping Dependabot PRs when it carries newer compatible versions and CI passes.
- For GitHub Action major updates, inspect the action release notes and verify the generated zip on the next tagged release because release publishing only runs on tags.

See also [WooCommerce Compatibility and API Audit](docs/WOOCOMMERCE-AUDIT.md) for hook, HPOS, and release compatibility notes.

## Contributing

### Workflow

1. **Fork & Clone**

```bash
git clone https://github.com/YOUR_USERNAME/hellotext-wordpress.git
cd hellotext-wordpress
composer install
```
````

2. **Create Feature Branch**

```bash
git checkout -b feature/my-new-feature
```
Expand All @@ -376,24 +430,28 @@ git checkout -b feature/my-new-feature
- Update documentation

4. **Run Tests**

```bash
./vendor/bin/pest
```

5. **Commit**

```bash
git add .
git commit -m "feat: add new feature"
```

Use [Conventional Commits](https://www.conventionalcommits.org/):

- `feat:` - New feature
- `fix:` - Bug fix
- `docs:` - Documentation
- `test:` - Tests
- `refactor:` - Code refactoring

6. **Push & PR**

```bash
git push origin feature/my-new-feature
```
Expand Down Expand Up @@ -458,6 +516,7 @@ function hellotext_track_new_action($data): void {
**Issue**: Mockery errors or WordPress function not found

**Solution**: Ensure WordPress and WooCommerce stubs are installed:

```bash
composer require --dev php-stubs/wordpress-stubs php-stubs/woocommerce-stubs
```
Expand Down
Loading