Restructure src/ and tests/ from package-by-type to package-by-domain
All checks were successful
CI / Coding Standards (push) Successful in 43s
CI / PHPStan (push) Successful in 52s
CI / Tests (PHP 8.1) (push) Successful in 47s
CI / Tests (PHP 8.2) (push) Successful in 49s
CI / Tests (PHP 8.3) (push) Successful in 37s
CI / No Debug Code (push) Successful in 2s

All classes are now organised by domain (Availability, Booking, Auth).
Each domain package contains its value object, repository, admin controller,
REST endpoint, and any shortcode pages under a matching sub-namespace.
Cross-cutting wiring (Plugin, AdminMenu, RestRegistrar, ShortcodeRegistrar,
Schema) lives at src/ root. Tests mirror the domain structure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-30 16:37:30 -03:00
parent ed49924f95
commit 2fb2ca392d
26 changed files with 108 additions and 83 deletions

View File

@@ -13,7 +13,7 @@ composer cs # PHPCS coding standards check
composer cs:fix # Auto-fix coding standards
# Run a single test file
./vendor/bin/phpunit tests/Unit/Data/AvailabilityRepositoryTest.php
./vendor/bin/phpunit tests/Unit/Availability/AvailabilityRepositoryTest.php
# Run a single test by name
./vendor/bin/phpunit --filter testInsertCallsWpdbInsertAndReturnsId
@@ -28,19 +28,33 @@ composer cs:fix # Auto-fix coding standards
### Directory Structure
```
src/ — All plugin PHP (PSR-4 namespace: Unsupervised\Schedular\)
templates/ — PHP view files included by controllers/shortcodes
assets/ — CSS and JS (vanilla JS, no build step)
tests/Unit/ — PHPUnit unit tests (PSR-4: Unsupervised\Schedular\Tests\)
docs/features/— One markdown file per feature describing data model, API, and test locations
src/ — All plugin PHP (PSR-4 namespace: Unsupervised\Schedular\)
Availability/ — Availability slots: value object, repository, controller, REST endpoint
Booking/ — Lessons/bookings: value object, repository, controller, REST endpoint, shortcode page
Auth/ — Roles, capabilities, login page
Plugin.php — Wires all components together on plugins_loaded
Installer.php — Creates DB tables and roles on activation
Schema.php — CREATE TABLE SQL for dbDelta
AdminMenu.php — Registers wp-admin menu pages
RestRegistrar.php — Registers all REST routes under us-scheduler/v1
ShortcodeRegistrar.php — Registers [us_booking] and [us_student_login] shortcodes
templates/ — PHP view files included by controllers/shortcodes
assets/ — CSS and JS (vanilla JS, no build step)
tests/Unit/ — PHPUnit unit tests (PSR-4: Unsupervised\Schedular\Tests\)
Availability/ — Tests for src/Availability/
Booking/ — Tests for src/Booking/
Auth/ — Tests for src/Auth/
docs/features/ — One markdown file per feature describing data model, API, and test locations
```
**Code is organised package-by-domain** (Availability, Booking, Auth). Each domain package contains everything related to that domain: value objects, repositories, controllers, REST endpoints, and shortcode pages. Cross-cutting wiring classes (Plugin, AdminMenu, RestRegistrar, ShortcodeRegistrar, Schema) live directly under `src/`.
### Data Storage
Two custom database tables (created via `dbDelta` on activation):
- `{prefix}us_availability` — instructor availability windows
- `{prefix}us_lessons` — booked lessons
All database access goes through repository classes in `src/Data/`. No direct `$wpdb` calls outside repositories.
All database access goes through repository classes within their domain package. No direct `$wpdb` calls outside repositories.
### Key Classes
@@ -48,20 +62,21 @@ All database access goes through repository classes in `src/Data/`. No direct `$
|---|---|
| `Plugin` | Wires all components together on `plugins_loaded` |
| `Installer` | Creates DB tables and roles on activation |
| `Roles\RoleManager` | Registers `us_instructor` and `us_student` roles with custom caps |
| `Data\AvailabilityRepository` | CRUD for availability slots |
| `Data\BookingRepository` | CRUD for lesson bookings |
| `Model\AvailabilitySlot` | Immutable value object for a slot row |
| `Model\Lesson` | Immutable value object for a lesson row |
| `Admin\AdminMenu` | Registers wp-admin menu pages |
| `Admin\AvailabilityController` | Instructor availability management page |
| `Admin\LessonController` | Admin and instructor lesson list pages |
| `Api\RestRegistrar` | Registers all REST routes under `us-scheduler/v1` |
| `Api\AvailabilityEndpoint` | REST handlers for availability CRUD |
| `Api\BookingEndpoint` | REST handlers for booking and status updates |
| `Frontend\ShortcodeRegistrar` | Registers `[us_booking]` and `[us_student_login]` shortcodes |
| `Frontend\BookingPage` | Renders student booking UI shell (JS takes over) |
| `Frontend\LoginPage` | Renders front-end student login form |
| `Schema` | CREATE TABLE SQL strings for dbDelta |
| `AdminMenu` | Registers wp-admin menu pages |
| `RestRegistrar` | Registers all REST routes under `us-scheduler/v1` |
| `ShortcodeRegistrar` | Registers `[us_booking]` and `[us_student_login]` shortcodes |
| `Auth\RoleManager` | Registers `us_instructor` and `us_student` roles with custom caps |
| `Auth\LoginPage` | Renders front-end student login form |
| `Availability\AvailabilitySlot` | Immutable value object for a slot row |
| `Availability\AvailabilityRepository` | CRUD for availability slots |
| `Availability\AvailabilityController` | Instructor availability management page |
| `Availability\AvailabilityEndpoint` | REST handlers for availability CRUD |
| `Booking\Lesson` | Immutable value object for a lesson row |
| `Booking\BookingRepository` | CRUD for lesson bookings |
| `Booking\BookingEndpoint` | REST handlers for booking and status updates |
| `Booking\BookingPage` | Renders student booking UI shell (JS takes over) |
| `Booking\LessonController` | Admin and instructor lesson list pages |
### REST API Namespace
All endpoints live under `/wp-json/us-scheduler/v1/`. Permissions are enforced via `permission_callback` using capability checks (`manage_availability`, `book_lesson`), never role name checks.
@@ -81,9 +96,9 @@ All test classes extend `tests/Unit/TestCase.php`, which handles `Monkey\setUp()
### Adding a Feature
1. Write the feature doc in `docs/features/<feature-name>.md` (data model, API, classes, test paths).
2. Implement the classes under `src/`.
2. Create a domain package under `src/<Domain>/` containing all classes for that feature.
3. Add template(s) under `templates/` if needed.
4. Write unit tests under `tests/Unit/` mirroring the `src/` directory structure.
4. Write unit tests under `tests/Unit/<Domain>/` mirroring the `src/<Domain>/` structure.
5. Run `composer test` — all tests must pass before the feature is complete.
### CI