# ADR: Domain folder placement + PSR-4 namespaces for theme types ## Status Accepted (2026-07-17); **updated 2026-07-17** for Composer PSR-4. ## Context Domain folders were frozen after the root→domain move. Theme types then migrated from global `AKSRT_*` + manual `require_once` to real PHP namespaces under `src/AKSRT/` with Composer PSR-4. ## Decision ### Domain ownership (unchanged) | Concern | Domain | Why | |---------|--------|-----| | Theme shell (setup, scripts, templates, SEO, meta boxes, DB migrator, front-submit, docs presenter, home modules, stats, redirects, update checker, comment actions) | `Core` | Shared CMS plumbing | | SPA shell + controllers + schema + native ops | `Admin` | Dual-surface IA | | Settings facade + runtime delegates | `Settings` | Single public settings API | | Auth, OAuth, captcha, moderation, email rollback | `Auth` | Identity & access | | User center/home/badges/level/metrics/notifications/follow | `User` | Account surface | | Credits, balance wallet, signin, invite, points-free | `Credits` | Points + cash wallet | | Download tokens/state, content pay, VIP, visibility | `Content` | Post-centric paid content | | Topic pay, plate follow pay | `Forum` | Forum SKUs (not generic content pay) | | Orders, gateways, coupon, charge-card, revenue, creator-revenue, withdrawal, rebate, discount, after-sale, shipping, wechat-notify | `Payment` | Commerce + settlement | | Shop services/meta/reviews | `Shop` | Product catalog / cart | | SMS stack | `Sms` | Messaging channel | | AI runtime (admin AI controller stays in `Admin`) | `Ai` | Generation helpers | | Message, private message, site notice, report center | `Messages` | In-site messaging | | MeiliSearch, search-push, ip-geo, content-audit, api-audit | `Extensions` | Optional integrations | | Widgets + registry | `Widgets` | WP widgets | | Inline style / custom code / loading overlay | `Frontend` | Asset render helpers | ### PSR-4 layout - Composer: `"AKSRT\\": "src/AKSRT/"` - Namespace `AKSRT\{Domain}\…` ↔ path `src/AKSRT/{Domain}/…` - One type per file; StudlyCaps filename = short class/trait/interface name - Nested segments: `Admin\Schema`, `Admin\Native`, `Payment\Gateways`, `Admin\Schema\PostList` - OAuth stays under `Auth` (`AKSRT\Auth\OAuth`) — no separate `oauth/` tree - Do not move `TopicPay` / `PlateFollowPay` into `Content` without updating this ADR - `CreatorRevenue` and `WeChatNotify` stay under `Payment` ### Loader 1. `functions.php` loads `vendor/autoload.php` (Composer: third-party + theme PSR-4) 2. `inc/bootstrap.php` loads helpers + procedural modules (`inc/modules/*`) + core-hooks only 3. Singleton `init()` remains in `functions.php` using FQCNs ### Procedural (not PSR-4) - `inc/helpers/*` function libraries - `inc/modules/*` (captcha, user-hub/parts, user-notifications, widgets-register, …) - `inc/core-hooks.php` (+ parts) ### Map tooling - `php tools/build-psr4-map.php --write` — read-only inventory / map under `tools/psr4-map/` - One-shot mass-rewrite migrators are **not** kept in-tree (completed migration; AV false positives on file-tree rewriters) ## Out of scope - Dual-read `class_alias` shims for old `AKSRT_*` global names (rewrite references instead) - Converting all helpers to classes