refactor: flatten src/AKSRT → src (drop theme-identifier dir)

Move all domain folders from src/AKSRT/{Domain} to src/{Domain}; remap
Composer PSR-4 "AKSRT\\": "src/"; update audit script + README + ADR
paths; remove dead tools/build-psr4-map.php (scanned deleted inc/classes).
This commit is contained in:
2026-08-02 22:06:06 +08:00
parent 56f1a8175f
commit 8c5b1555c9
285 changed files with 26 additions and 3600 deletions
+106
View File
@@ -0,0 +1,106 @@
<?php
/**
* Identity verification state transitions.
*
* @package AKSRT
*/
namespace AKSRT\Identity;
defined('ABSPATH') || exit;
final class TransitionService {
private const ALLOWED = [
'created' => ['provider_pending', 'provider_failed', 'provider_unsupported', 'provider_expired', 'manual_pending', 'cancelled'],
'provider_pending' => ['provider_processing', 'provider_failed', 'provider_unsupported', 'provider_expired', 'verified', 'manual_pending', 'cancelled'],
'provider_processing' => ['provider_failed', 'provider_unsupported', 'provider_expired', 'verified', 'manual_pending'],
'provider_failed' => ['provider_pending', 'manual_pending', 'rejected', 'cancelled'],
'provider_unsupported' => ['manual_pending', 'rejected', 'cancelled'],
'provider_expired' => ['provider_pending', 'manual_pending', 'rejected', 'cancelled'],
'manual_pending' => ['verified', 'rejected', 'cancelled'],
'verified' => ['cancelled'],
];
public function __construct(
private ?ApplicationRepository $applications = null,
private ?EventRepository $events = null
) {
$this->applications ??= new ApplicationRepository();
$this->events ??= new EventRepository();
}
/** @param array<string,mixed> $fields @param array<string,mixed> $event */
public function transition(array $application, string $next, array $fields = [], array $event = []) {
$current = sanitize_key((string) ($application['status'] ?? ''));
$next = sanitize_key($next);
if (!in_array($next, self::ALLOWED[$current] ?? [], true)) {
return new \WP_Error('aksrt_identity_transition', __('该认证记录当前不可执行此操作', 'aksrt'));
}
if (in_array($next, ['verified', 'rejected', 'cancelled'], true)) {
$fields['completed_at'] = current_time('mysql', true);
$fields['sensitive_blob'] = null;
}
if (!$this->applications->transition((int) $application['id'], $current, $next, $fields)) {
return new \WP_Error('aksrt_identity_conflict', __('认证状态已变化,请刷新后重试', 'aksrt'));
}
$dedupe = (string) ($event['dedupe_key'] ?? hash('sha256', implode('|', [
(string) $application['application_uuid'], $current, $next, wp_generate_uuid4(),
])));
$this->events->record([
'application_id' => (int) $application['id'],
'source' => (string) ($event['source'] ?? 'system'),
'event_type' => (string) ($event['event_type'] ?? 'status_changed'),
'external_event_id' => (string) ($event['external_event_id'] ?? ''),
'dedupe_key' => $dedupe,
'from_status' => $current,
'to_status' => $next,
'result_code' => (string) ($event['result_code'] ?? ''),
'summary' => is_array($event['summary'] ?? null) ? $event['summary'] : [],
'actor_user_id' => (int) ($event['actor_user_id'] ?? 0),
]);
if ($next === 'verified') {
$this->send_notification((int) $application['user_id'], 'verified', '');
} elseif ($next === 'rejected' || $next === 'cancelled') {
$this->send_notification((int) $application['user_id'], $next, (string) ($fields['review_note'] ?? ''));
}
do_action('aksrt_user_auth_reviewed', (int) $application['user_id'], self::public_status($next), (string) ($fields['review_note'] ?? ''), (int) ($fields['reviewer_id'] ?? 0));
return $this->applications->find_by_id((int) $application['id']);
}
public static function public_status(string $status): string {
if ($status === 'verified') {
return 'verified';
}
if ($status === 'cancelled') {
return 'cancelled';
}
if ($status === 'rejected') {
return 'rejected';
}
return in_array($status, ApplicationRepository::ACTIVE_STATUSES, true) ? 'pending' : 'rejected';
}
private function send_notification(int $user_id, string $status, string $note): void {
if (!class_exists('\\AKSRT\\Messages\\Message')) {
return;
}
if ($status === 'verified') {
$title = __('官方认证结果', 'aksrt');
$message = __('您的官方认证已通过', 'aksrt');
} elseif ($status === 'cancelled') {
$title = __('官方认证已取消', 'aksrt');
$message = sprintf(__('您的官方认证已被取消:%s', 'aksrt'), $note);
} else {
$title = __('官方认证结果', 'aksrt');
$message = sprintf(__('您的官方认证申请未通过:%s', 'aksrt'), $note);
}
\AKSRT\Messages\Message::get_instance()->send($user_id, 'auth_apply_reply', $message, [
'title' => $title,
'target_url' => aksrt_get_user_center_tab_url('auth'),
]);
}
}