# BW Update Server — Claude Development Guide

**Version:** 0.1.0 | **Last Updated:** 2026-04-10

## What this plugin does

Serves update manifests to client WordPress sites and logs every update check. Lives only on the `plugins.bowden.works` dist host.

## Critical notes

- This plugin is **load-bearing** — every BW plugin on every client site polls its REST endpoint.
- A bug here breaks update checks for every client. Test thoroughly.
- It is NOT distributed to client sites. It only runs on the dist host.
- It is NOT released via `tools/release.sh` — it's site infrastructure.

## Architecture

- `bw-update-server.php` — main bootstrap.
- `includes/class-bw-update-server-installer.php` — creates/upgrades the DB table on activation.
- `includes/class-bw-update-server-repository.php` — DB access (log_check, recent_checks).
- `includes/class-bw-update-server-manifest.php` — reads `.meta.json` sidecars from `wp-content/uploads/plugin-updates/`.
- `includes/class-bw-update-server-rest.php` — REST routes under `/wp-json/bw/v1/`.
- `uninstall.php` — drops the table and options.

## REST API

- `GET /wp-json/bw/v1/update-check?slug=bw-<slug>` → manifest for the latest version of `slug`, and logs the check.
- `GET /wp-json/bw/v1/plugins` → list of all slugs with manifests on this host.
- `GET /wp-json/bw/v1/health` → simple health check.

## Database

Table: `{prefix}bw_update_log` — logs every update check. Indexed on plugin_slug, site_url, checked_at.

## Where manifests come from

The release script `tools/release.sh` (on the bw-plugins dev host at `/srv/apps/bw-plugins/tools/release.sh`) writes `.meta.json` files directly into `wp-content/uploads/plugin-updates/` on the dist host. This plugin only reads them.

Manifest filename format: `<slug>-<version>.meta.json`
Zip filename format: `<slug>-<version>.zip`

## Testing locally

```bash
# Health check
curl https://plugins.bowden.works/wp-json/bw/v1/health

# List plugins
curl https://plugins.bowden.works/wp-json/bw/v1/plugins

# Get a manifest
curl 'https://plugins.bowden.works/wp-json/bw/v1/update-check?slug=bw-source-capture'
```

## What NOT to do

- Never add features that rely on state from client sites (not covered by security model).
- Never add endpoints that execute arbitrary code or file operations.
- Never log site content or user data — only plugin/WP/site metadata.
- Never change the URL structure of REST routes without a major version bump and coordinated release.

## Version bumps

This plugin is updated in-place on the dist host. When changing:
1. Bump `Version:` in header and `BW_UPDATE_SERVER_VERSION` constant.
2. Update `CHANGELOG.md`.
3. Deactivate/reactivate if there's a DB schema change (so `activate()` runs).
4. Verify REST endpoints still respond.

## Phase 3b (upcoming)

Admin dashboard at WP Admin → BW Plugins → Installs:
- List of all installs, filterable by plugin
- Version distribution chart
- Stale install detection (no check > 30 days)
- CSV export
- Dashboard widget
