File size: 4,652 Bytes
f51c224
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<?php
defined( 'ABSPATH' ) || exit;

class SA_Orch_Rest {

    const REST_NS = 'sa-orch/v1';

    public static function register_routes() {
        register_rest_route( self::REST_NS, '/arbitration', [
            'methods'             => 'POST',
            'callback'            => [ __CLASS__, 'post_arbitration' ],
            'permission_callback' => [ __CLASS__, 'check_admin' ],
        ] );

        register_rest_route( self::REST_NS, '/acceptance', [
            'methods'             => 'POST',
            'callback'            => [ __CLASS__, 'post_acceptance' ],
            'permission_callback' => [ __CLASS__, 'check_admin' ],
        ] );

        register_rest_route( self::REST_NS, '/demand/(?P<surface>[a-z\-]+)/(?P<ref>[^/]+)/trace', [
            'methods'             => 'GET',
            'callback'            => [ __CLASS__, 'get_demand_trace' ],
            'permission_callback' => [ __CLASS__, 'check_admin' ],
        ] );
    }

    public static function check_admin() {
        return current_user_can( 'manage_options' );
    }

    public static function post_arbitration( WP_REST_Request $request ) {
        $params = $request->get_json_params();
        if ( ! is_array( $params ) || empty( $params ) ) {
            $params = $request->get_params();
        }
        $result = SA_Orch_Arbitration::write( $params );
        if ( is_wp_error( $result ) ) {
            return new WP_REST_Response( [
                'ok'      => false,
                'error'   => $result->get_error_code(),
                'message' => $result->get_error_message(),
                'data'    => $result->get_error_data(),
            ], 400 );
        }
        return new WP_REST_Response( [ 'ok' => true, 'data' => $result ], 201 );
    }

    public static function post_acceptance( WP_REST_Request $request ) {
        $params = $request->get_json_params();
        if ( ! is_array( $params ) || empty( $params ) ) {
            $params = $request->get_params();
        }
        $result = SA_Orch_Acceptance::write( $params );
        if ( is_wp_error( $result ) ) {
            return new WP_REST_Response( [
                'ok'      => false,
                'error'   => $result->get_error_code(),
                'message' => $result->get_error_message(),
                'data'    => $result->get_error_data(),
            ], 400 );
        }
        return new WP_REST_Response( [ 'ok' => true, 'data' => $result ], 201 );
    }

    public static function get_demand_trace( WP_REST_Request $request ) {
        global $wpdb;
        $surface = $request['surface'];
        $ref     = $request['ref'];
        $p       = $wpdb->prefix . SA_ORCH_DB_PREFIX;

        $arbs = $wpdb->get_results( $wpdb->prepare(
            "SELECT * FROM {$p}arbitration WHERE demand_surface = %s AND demand_ref = %s ORDER BY created_at, id",
            $surface, $ref
        ) );

        $links = [];
        if ( ! empty( $arbs ) ) {
            $arb_ids      = array_map( function ( $a ) { return (int) $a->id; }, $arbs );
            $placeholders = implode( ',', array_fill( 0, count( $arb_ids ), '%d' ) );
            $links = $wpdb->get_results( $wpdb->prepare(
                "SELECT * FROM {$p}arbitration_plan_link WHERE arbitration_id IN ($placeholders) ORDER BY created_at, id",
                ...$arb_ids
            ) );
        }

        $events = $wpdb->get_results( $wpdb->prepare(
            "SELECT * FROM {$p}acceptance_event WHERE demand_surface = %s AND demand_ref = %s ORDER BY observed_at, id",
            $surface, $ref
        ) );

        $closure_state_basic      = SA_Orch_Acceptance::basic_closure_state( $surface, $ref );
        $closure_state_role_aware = SA_Orch_Acceptance::role_aware_closure_state( $surface, $ref );
        $closure_authority_valid  = SA_Orch_Acceptance::closure_authority_valid( $surface, $ref );

        return new WP_REST_Response( [
            'ok'                       => true,
            'demand'                   => [ 'surface' => $surface, 'ref' => $ref ],
            'arbitrations'             => $arbs,
            'plan_links'               => $links,
            'acceptance'               => $events,
            // Existing field (v0.1) — retained as alias of closure_state_basic for backward compatibility
            'closure_state'            => $closure_state_basic,
            // Added in v0.2 — explicit naming
            'closure_state_basic'      => $closure_state_basic,
            'closure_state_role_aware' => $closure_state_role_aware,
            'closure_authority_valid'  => $closure_authority_valid,
        ], 200 );
    }
}