Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
OutboundNotification
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
3
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 suggestedEndpoint
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace LambdaTwelve\OneRecord\Server\Spi;
6
7use DateTimeImmutable;
8use LambdaTwelve\OneRecord\Api\Notification;
9use LambdaTwelve\OneRecord\Rdf\Iri;
10
11/**
12 * A notification the server wants delivered to a partner. The host sends it
13 * (POST {partner}/notifications with its own client and egress controls),
14 * retries it, and keeps it until the partner confirms, as the spec's
15 * guaranteed-delivery rule asks.
16 */
17final readonly class OutboundNotification
18{
19    /**
20     * @param string $id unique per notification; a host retrying across restarts dedupes on it, and
21     *                   may pass it to the partner (an Idempotency-Key header, say)
22     */
23    public function __construct(
24        public Iri $recipient,
25        public Notification $notification,
26        public DateTimeImmutable $createdAt,
27        public string $id,
28    ) {}
29
30    /**
31     * The partner's notifications endpoint derived from its Organization URI
32     * ({base}/logistics-objects/{id} → {base}/notifications), which is what the
33     * spec means by "the callback URL can be derived from the subscriber". A
34     * host may know better and ignore this.
35     */
36    public function suggestedEndpoint(): ?string
37    {
38        $position = strpos($this->recipient->value, '/logistics-objects/');
39
40        return $position === false ? null : substr($this->recipient->value, 0, $position) . '/notifications';
41    }
42}