Files
unsupervised-scheduler/docs/features/policies.md
T
thatguygriff d3a2767976
CI / Coding Standards (push) Successful in 2m23s
CI / PHPStan (push) Successful in 59s
CI / Tests (PHP 8.1) (push) Successful in 50s
CI / Tests (PHP 8.2) (push) Successful in 51s
CI / Tests (PHP 8.3) (push) Successful in 48s
CI / No Debug Code (push) Successful in 3s
Add feature specs for booking platform requirements
Update availability, lesson-booking, and user-roles docs and add specs
for offerings, group classes, registration questions, versioned policies,
Stripe payments (with e-transfer/comp overrides and receipts), and
monthly per-instructor payment reporting. Tracked in issues #1-#9.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 09:58:50 -03:00

5.1 KiB

Feature: Policies

Overview

The studio admin drafts, versions, and publishes policies (e.g. cancellation, payment, code of conduct). Registrants must read and accept the current published version of every policy before they can book. Acceptance is recorded against the specific version, so when a policy is updated students must re-accept it at their next booking.

Data Model — {prefix}us_policies

Column Type Notes
id BIGINT UNSIGNED Primary key
title VARCHAR(191) Display name
slug VARCHAR(191) Unique key, e.g. cancellation
current_version_id BIGINT UNSIGNED Nullable FK → us_policy_versions.id (published)
created_at DATETIME Insertion time

Data Model — {prefix}us_policy_versions

Column Type Notes
id BIGINT UNSIGNED Primary key
policy_id BIGINT UNSIGNED FK → us_policies.id
version_number INT Increments per policy, starting at 1
body LONGTEXT The policy text (HTML/markdown)
status VARCHAR(20) draft / published / archived
published_at DATETIME When published; NULL for drafts
created_at DATETIME Insertion time

Data Model — {prefix}us_policy_acceptances

Column Type Notes
id BIGINT UNSIGNED Primary key
policy_version_id BIGINT UNSIGNED FK → us_policy_versions.id (the exact version accepted)
student_id BIGINT UNSIGNED WordPress user ID
registration_type VARCHAR(20) lesson or enrollment
registration_id BIGINT UNSIGNED FK → us_lessons.id or us_group_enrollments.id
accepted_at DATETIME Timestamp of acceptance
ip_address VARCHAR(45) IP captured at acceptance (audit trail)

Versioning & Acceptance Rules

  • Editing a published policy creates a new draft version; the old version stays published until the draft is published.
  • Publishing a draft sets it published, stamps published_at, archives the prior version, and points us_policies.current_version_id at it.
  • The registration gate requires acceptance of the current_version_id of every policy. Because acceptance is tied to policy_version_id, a newly published version is unaccepted and must be re-accepted at the student's next booking.

Admin Interface

Policies in wp-admin (manage_policies, studio admin only):

  • Create a policy; draft and edit version bodies
  • Publish a draft version; view acceptance history per version

REST API

Method Endpoint Permission
GET /wp-json/us-scheduler/v1/policies Public (current published versions)
POST /wp-json/us-scheduler/v1/policies manage_policies
POST /wp-json/us-scheduler/v1/policies/{id}/versions manage_policies
PATCH /wp-json/us-scheduler/v1/policies/{id}/versions/{vid} manage_policies
POST /wp-json/us-scheduler/v1/policies/{id}/versions/{vid}/publish manage_policies

Acceptances are not posted directly — they are written as part of POST /bookings and POST /enrollments via the accepted_policy_version_ids[] field, which must cover every policy's current version or the registration is rejected.

Implementation

  • Repositories: Unsupervised\Schedular\Policy\PolicyRepository, Unsupervised\Schedular\Policy\PolicyVersionRepository, Unsupervised\Schedular\Policy\AcceptanceRepository
  • Models: Unsupervised\Schedular\Policy\Policy, Unsupervised\Schedular\Policy\PolicyVersion, Unsupervised\Schedular\Policy\PolicyAcceptance
  • Admin controller: Unsupervised\Schedular\Policy\PolicyController
  • REST endpoint: Unsupervised\Schedular\Policy\PolicyEndpoint

Tests

  • tests/Unit/Policy/PolicyRepositoryTest.php
  • tests/Unit/Policy/PolicyVersionRepositoryTest.php
  • tests/Unit/Policy/AcceptanceRepositoryTest.php