9c900d6553
CI / Tests (PHP 8.1) (pull_request) Successful in 47s
CI / No Debug Code (pull_request) Successful in 2s
CI / Build Plugin Zip (pull_request) Has been skipped
CI / Coding Standards (pull_request) Successful in 52s
CI / PHPStan (pull_request) Successful in 1m1s
CI / Tests (PHP 8.2) (pull_request) Successful in 48s
CI / Tests (PHP 8.3) (pull_request) Successful in 45s
Implements #16: invite-only student self-registration through a front-end page, accepting signup-scoped policies at account creation. Policy domain: - us_policies.acceptance_scope (signup/booking/both); Policy::appliesTo(); PolicyRepository::findForScope(); scope threaded through PolicyService, the REST create, the admin controller, and the Policies form. - PolicyAcceptance::REG_ACCOUNT (registration_id = the new user's ID). Auth: - Invite value object + InviteRepository; us_invites table. - RegistrationController + Invites admin page (manage_students): invite an email, share the registration link, revoke. - RegistrationPage ([us_student_register] shortcode): validates the invite token, collects name/password, renders signup-scoped published policies with required acceptance, creates the us_student user, records account-type acceptances, marks the invite accepted, and logs the user in. - RoleManager: manage_students cap added to STUDIO_ADMIN_CAPS. Invite-only is implemented; the us_registration_mode self_approval path is a documented future seam. Docs: docs/features/account-registration.md; policies.md updated. Tests: tests/Unit/Auth/ (Invite, InviteRepository) plus Policy scope updates. composer test (104), cs, and PHPStan level 6 all pass. Refs #16 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
155 lines
7.0 KiB
PHP
155 lines
7.0 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Unsupervised\Schedular;
|
|
|
|
class Schema {
|
|
|
|
/**
|
|
* Returns CREATE TABLE statements for dbDelta.
|
|
*
|
|
* @return list<string>
|
|
*/
|
|
public static function tables( string $prefix, string $charset ): array {
|
|
return [
|
|
"CREATE TABLE {$prefix}us_availability (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
instructor_id BIGINT UNSIGNED NOT NULL,
|
|
offering_id BIGINT UNSIGNED DEFAULT NULL,
|
|
start_dt DATETIME NOT NULL,
|
|
end_dt DATETIME NOT NULL,
|
|
duration_minutes SMALLINT UNSIGNED NOT NULL DEFAULT 60,
|
|
is_booked TINYINT(1) NOT NULL DEFAULT 0,
|
|
recurrence_group BIGINT UNSIGNED DEFAULT NULL,
|
|
created_at DATETIME NOT NULL,
|
|
PRIMARY KEY (id),
|
|
KEY instructor_id (instructor_id),
|
|
KEY offering_id (offering_id),
|
|
KEY start_dt (start_dt),
|
|
KEY recurrence_group (recurrence_group)
|
|
) {$charset};",
|
|
|
|
"CREATE TABLE {$prefix}us_lessons (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
slot_id BIGINT UNSIGNED NOT NULL,
|
|
student_id BIGINT UNSIGNED NOT NULL,
|
|
instructor_id BIGINT UNSIGNED NOT NULL,
|
|
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
|
notes TEXT,
|
|
created_at DATETIME NOT NULL,
|
|
PRIMARY KEY (id),
|
|
KEY slot_id (slot_id),
|
|
KEY student_id (student_id),
|
|
KEY instructor_id (instructor_id)
|
|
) {$charset};",
|
|
|
|
"CREATE TABLE {$prefix}us_offerings (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
instructor_id BIGINT UNSIGNED NOT NULL,
|
|
kind VARCHAR(20) NOT NULL,
|
|
title VARCHAR(191) NOT NULL,
|
|
description TEXT,
|
|
duration_minutes SMALLINT UNSIGNED DEFAULT NULL,
|
|
price DECIMAL(10,2) NOT NULL DEFAULT 0,
|
|
currency VARCHAR(3) NOT NULL DEFAULT 'CAD',
|
|
billing_mode VARCHAR(20) NOT NULL DEFAULT 'one_time',
|
|
allow_weekly TINYINT(1) NOT NULL DEFAULT 0,
|
|
capacity SMALLINT UNSIGNED DEFAULT NULL,
|
|
term_start DATE DEFAULT NULL,
|
|
term_end DATE DEFAULT NULL,
|
|
schedule_note VARCHAR(191) DEFAULT NULL,
|
|
is_active TINYINT(1) NOT NULL DEFAULT 1,
|
|
created_at DATETIME NOT NULL,
|
|
PRIMARY KEY (id),
|
|
KEY instructor_id (instructor_id),
|
|
KEY kind (kind),
|
|
KEY is_active (is_active)
|
|
) {$charset};",
|
|
|
|
"CREATE TABLE {$prefix}us_questions (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
offering_id BIGINT UNSIGNED NOT NULL,
|
|
label VARCHAR(255) NOT NULL,
|
|
field_type VARCHAR(20) NOT NULL DEFAULT 'text',
|
|
options TEXT,
|
|
is_required TINYINT(1) NOT NULL DEFAULT 0,
|
|
sort_order INT NOT NULL DEFAULT 0,
|
|
is_active TINYINT(1) NOT NULL DEFAULT 1,
|
|
created_at DATETIME NOT NULL,
|
|
PRIMARY KEY (id),
|
|
KEY offering_id (offering_id),
|
|
KEY is_active (is_active)
|
|
) {$charset};",
|
|
|
|
"CREATE TABLE {$prefix}us_question_answers (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
question_id BIGINT UNSIGNED NOT NULL,
|
|
registration_type VARCHAR(20) NOT NULL,
|
|
registration_id BIGINT UNSIGNED NOT NULL,
|
|
student_id BIGINT UNSIGNED NOT NULL,
|
|
answer_value TEXT,
|
|
created_at DATETIME NOT NULL,
|
|
PRIMARY KEY (id),
|
|
KEY question_id (question_id),
|
|
KEY registration (registration_type, registration_id),
|
|
KEY student_id (student_id)
|
|
) {$charset};",
|
|
|
|
"CREATE TABLE {$prefix}us_policies (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
title VARCHAR(191) NOT NULL,
|
|
slug VARCHAR(191) NOT NULL,
|
|
current_version_id BIGINT UNSIGNED DEFAULT NULL,
|
|
acceptance_scope VARCHAR(20) NOT NULL DEFAULT 'booking',
|
|
created_at DATETIME NOT NULL,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY slug (slug),
|
|
KEY acceptance_scope (acceptance_scope)
|
|
) {$charset};",
|
|
|
|
"CREATE TABLE {$prefix}us_policy_versions (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
policy_id BIGINT UNSIGNED NOT NULL,
|
|
version_number INT NOT NULL DEFAULT 1,
|
|
body LONGTEXT,
|
|
status VARCHAR(20) NOT NULL DEFAULT 'draft',
|
|
published_at DATETIME DEFAULT NULL,
|
|
created_at DATETIME NOT NULL,
|
|
PRIMARY KEY (id),
|
|
KEY policy_id (policy_id),
|
|
KEY status (status)
|
|
) {$charset};",
|
|
|
|
"CREATE TABLE {$prefix}us_policy_acceptances (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
policy_version_id BIGINT UNSIGNED NOT NULL,
|
|
student_id BIGINT UNSIGNED NOT NULL,
|
|
registration_type VARCHAR(20) NOT NULL,
|
|
registration_id BIGINT UNSIGNED NOT NULL,
|
|
accepted_at DATETIME NOT NULL,
|
|
ip_address VARCHAR(45) DEFAULT NULL,
|
|
PRIMARY KEY (id),
|
|
KEY policy_version_id (policy_version_id),
|
|
KEY student_id (student_id),
|
|
KEY registration (registration_type, registration_id)
|
|
) {$charset};",
|
|
|
|
"CREATE TABLE {$prefix}us_invites (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
email VARCHAR(191) NOT NULL,
|
|
token VARCHAR(64) NOT NULL,
|
|
role VARCHAR(32) NOT NULL DEFAULT 'us_student',
|
|
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
|
invited_by BIGINT UNSIGNED DEFAULT NULL,
|
|
accepted_user_id BIGINT UNSIGNED DEFAULT NULL,
|
|
created_at DATETIME NOT NULL,
|
|
accepted_at DATETIME DEFAULT NULL,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY token (token),
|
|
KEY email (email),
|
|
KEY status (status)
|
|
) {$charset};",
|
|
];
|
|
}
|
|
}
|