# Unsupervised Scheduler A WordPress plugin for instructor/student lesson scheduling — private lessons and group classes — with offerings, intake questions, versioned policies, account registration, and (coming) online payments. **Version:** 1.0.0-rc.1 · **Requires:** WordPress 6.0+, PHP 8.1+ · **License:** GPL-2.0-or-later > Pre-release. The booking platform is being built feature-by-feature; see > [Implementation status](#implementation-status) below. ## Overview The plugin is organised **package-by-domain** under `src/` (PSR-4 `Unsupervised\Schedular\`). Each domain owns its value objects, repositories, REST endpoints, and admin/front-end controllers. All data access goes through repository classes against custom `{prefix}us_*` tables; permissions are enforced with WordPress **capabilities**, never role-name checks. There is no front-end build step (vanilla JS/CSS in `assets/`). Every feature has a spec in [`docs/features/`](docs/features/) describing its data model, REST API, classes, and tests. For contributor/architecture guidance see [`CLAUDE.md`](CLAUDE.md). ## Implementation status | Feature | Spec | Status | |---|---|---| | User roles & capabilities (studio admin / instructor / student) | [user-roles.md](docs/features/user-roles.md) | ✅ Implemented | | Offerings (private-lesson types & group classes) | [offerings.md](docs/features/offerings.md) | ✅ Implemented | | Availability (durations, weekly recurrence, calendar) | [availability-management.md](docs/features/availability-management.md) | ✅ Implemented | | Registration questions (per-offering intake) | [registration-questions.md](docs/features/registration-questions.md) | ✅ Implemented | | Policies (drafting, versioning, tracked acceptance) | [policies.md](docs/features/policies.md) | ✅ Implemented | | Account registration (invite-only, signup policy acceptance) | [account-registration.md](docs/features/account-registration.md) | ✅ Implemented | | Lesson booking (offering → questions → policies) | [lesson-booking.md](docs/features/lesson-booking.md) | ✅ Implemented | | Group classes (capacity-enforced enrolment) | [group-classes.md](docs/features/group-classes.md) | ✅ Implemented | | Student administration (studio-admin view) | [student-administration.md](docs/features/student-administration.md) | ✅ Implemented | | Payments (e-transfer/comp + receipts + HST; Stripe card charge pending) | [payments.md](docs/features/payments.md) | 🟡 Partial | | Payment reporting (monthly per-instructor + HST + CSV) | [payment-reporting.md](docs/features/payment-reporting.md) | ✅ Implemented | > Payments are deliberately deferred to the end: booking and enrolment ship with a > clean seam (a lesson lands `pending`, an enrolment `active`, with `payment_id` > null) into which the pay→confirm + receipt step plugs later. ## Shortcodes | Shortcode | Purpose | |---|---| | `[us_booking]` | Student calendar + private-lesson registration flow | | `[us_group_classes]` | Browse and enrol in group classes | | `[us_student_login]` | Front-end student login | | `[us_student_register]` | Invite-based account registration (accepts signup policies) | ## REST API All endpoints live under `/wp-json/us-scheduler/v1/` (e.g. `/offerings`, `/availability`, `/bookings`, `/enrollments`, `/policies`, `/questions`). Permissions are enforced via `permission_callback` capability checks. See each feature doc for the routes and required capabilities. ## Roles & capabilities Three custom roles — **Studio Admin** (`us_studio_admin`), **Instructor** (`us_instructor`), and **Student** (`us_student`) — plus a `user_has_cap` filter that grants every studio-admin capability to WordPress administrators, so the site owner runs the studio without a separate role. Full capability matrix in [user-roles.md](docs/features/user-roles.md). ## Installation 1. Build a distributable zip (see [Development](#development)): ```bash composer build # -> dist/unsupervised-schedular-.zip ``` 2. In wp-admin: **Plugins → Add New → Upload Plugin**, choose the zip, install, and activate. Activation creates the `us_*` database tables and registers the roles. CI also publishes an installable zip artifact on every merge to `main`. ## Development ```bash composer install # install dependencies composer test # PHPUnit (run after every change) composer lint # PHPStan (level 6) composer cs # PHPCS (WordPress coding standards) composer cs:fix # auto-fix coding standards composer build # build the plugin zip into dist/ # a single test file / single test ./vendor/bin/phpunit tests/Unit/Offering/OfferingRepositoryTest.php ./vendor/bin/phpunit --filter testInsertReturnsId ``` Tests use [Brain\Monkey](https://brain-wp.github.io/BrainMonkey/) and Mockery to stub WordPress and `$wpdb` without a full WP install. To run the plugin in a real WordPress without Docker, `wp-now` works well: `npx @wp-now/cli@latest start`. ## CI Gitea Actions (`.gitea/workflows/ci.yml`) runs on every push and pull request: **lint** (PHPCS), **static-analysis** (PHPStan), **test** (PHPUnit on PHP 8.1/8.2/8.3), and **no-debug** (rejects debug statements in `src/`). On merge to `main` a **build** job publishes the installable plugin zip as an artifact. ## License GPL-2.0-or-later.