SIMULATION No cameras, door controllers or dispatch links are connected to this host. Device telemetry, video and alarms are synthetic. Platform services, permissions, audit chain, package install and sandbox are real.

DX-261005-003 · Raptor Visitor Management — events

v0.1.3 · target PES · built 2026-10-05 12:09:27 EDT by it-admin-01
P1 2 P2 2 Unacked 4 Video 17/19 15:25:15 EDT OPSOC Operator 01
BuiltSandboxApprovedPromoted
bundle sha256 3baddc9595720d45… 12 files mode read_only

Next gate

Gates are operated by District IT. Current role can review the package but not advance it.

src/Transport.php

sha256 03f7d48cdaf60a7169b8…
1<?php
2declare(strict_types=1);
3
4namespace Msad17\Connectors\RaptorVisitor\B2610051209273;
5
6interface Transport
7{
8    /** @return array{status:int, body?:mixed, events?:list<mixed>} */
9    public function request(string $method, string $path, ?array $body = null): array;
10}
11
12/**
13 * Production transport. TLS verification is ON and cannot be disabled by config;
14 * supply a CA bundle path for self-signed device certificates instead.
15 * Secrets are resolved from the platform secret store at runtime — never from this package.
16 */
17final class HttpTransport implements Transport
18{
19    /** @param array<string,string> $headers already-resolved auth headers */
20    public function __construct(
21        private readonly string $baseUrl,
22        private readonly array $headers = [],
23        private readonly int $timeoutSeconds = 8,
24        private readonly ?string $caFile = null,
25    ) {
26    }
27
28    public function request(string $method, string $path, ?array $body = null): array
29    {
30        $allowed = array_map(fn(array $e) => $e[0] . ' ' . $e[1], Connector::ENDPOINTS);
31        if (!in_array($method . ' ' . $path, $allowed, true)) {
32            throw new \RuntimeException("Endpoint not declared in manifest: {$method} {$path}");
33        }
34        $ch = curl_init(rtrim($this->baseUrl, '/') . $path);
35        $hdr = [];
36        foreach ($this->headers as $k => $v) {
37            $hdr[] = $k . ': ' . $v;
38        }
39        $opts = [
40            CURLOPT_CUSTOMREQUEST => $method,
41            CURLOPT_RETURNTRANSFER => true,
42            CURLOPT_TIMEOUT => $this->timeoutSeconds,
43            CURLOPT_SSL_VERIFYPEER => true,
44            CURLOPT_SSL_VERIFYHOST => 2,
45            CURLOPT_HTTPHEADER => $hdr,
46        ];
47        if ($this->caFile) {
48            $opts[CURLOPT_CAINFO] = $this->caFile;
49        }
50        if ($body !== null) {
51            $opts[CURLOPT_POSTFIELDS] = json_encode($body);
52        }
53        curl_setopt_array($ch, $opts);
54        $raw = curl_exec($ch);
55        $status = (int)curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
56        curl_close($ch);
57        $decoded = is_string($raw) ? json_decode($raw, true) : null;
58        return ['status' => $status, 'body' => $decoded ?? $raw, 'events' => is_array($decoded) ? ($decoded['events'] ?? []) : []];
59    }
60}
61
62/** Sandbox transport: no network. Serves fixtures and records every call for policy checks. */
63final class FixtureTransport implements Transport
64{
65    /** @var list<string> */
66    public array $calls = [];
67
68    /** @param list<array<string,mixed>> $events */
69    public function __construct(private readonly array $events)
70    {
71    }
72
73    public function request(string $method, string $path, ?array $body = null): array
74    {
75        $this->calls[] = $method . ' ' . $path;
76        return ['status' => 200, 'body' => ['fixture' => true], 'events' => $this->events];
77    }
78}