dataemergencia / emergency-bff
Backend-for-frontend for the DataEmergencia emergency module.
Requires
- php: ^8.4
- ext-curl: *
- ext-json: *
- ext-mbstring: *
- guzzlehttp/guzzle: ^7.9
- psr/http-client: ^1.0
- psr/http-factory: ^1.1
- psr/http-message: ^2.0
- psr/log: ^3.0
Requires (Dev)
- phpunit/phpunit: ^11.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Backend-for-frontend for the DataEmergencia emergency flow. It runs the server-side work behind an SOS activation: validating the identity code, coordinating the emergency contacts and keeping the upstream emergency state in sync. Your application owns the front controller, the web server and the session backend.
Recommended library
Use @dataemergencia/emergency
for the browser panel. It consumes this backend and provides the user-facing SOS
experience; this package supplies the API it needs.
Requirements
- PHP 8.4 or newer with
json,curlandmbstring. - Composer 2.x.
- A PSR-18 HTTP client, PSR-17 request/stream factories and a PSR-3 logger (Guzzle and its factories are installed by default).
Install
composer require dataemergencia/emergency-bff
Configuration
Configuration is read from the environment. The same values can be passed
explicitly to Config::fromArray().
| Variable | Purpose |
|---|---|
EMERGENCY_BFF_API_KEY |
Per-customer API credential. Server-side only. |
EMERGENCY_BFF_APPLICATION_IDENTIFIER |
Per-customer application identifier. |
Both values are issued per deployment. Keep them in the server environment and
never commit them or expose them to the browser. If either is missing,
Bootstrap::create() throws a ConfigurationException before serving a
request.
See the configuration reference for the optional tuning variables.
Usage
The package is a library, not an application. A minimal front controller:
use DataEmergencia\EmergencyBff\Http\Request; use DataEmergencia\EmergencyBff\Support\Bootstrap; Bootstrap::create() ->handle(Request::fromGlobals()) ->send();
public/index.php in this package is the reference front controller.
HTTP API
All responses are JSON. Routes are relative to the configured prefix, which is
/de-bff/emergency by default. Read the CSRF token from GET /config and send
it as X-CSRF-Token on unsafe requests; POST /session rotates it.
GET /health
{ "status": "ok", "service": "dataemergencia/emergency-bff" }
GET /config
Returns the route prefix, the public realtime configuration and the first CSRF token.
{
"route_prefix": "/de-bff/emergency",
"realtime": { "mode": "public", "pusher": { "key": "…", "cluster": "…" } },
"csrf_token": "…"
}
POST /session
Validates the identity code and starts a session.
{ "code": "DABC12" }
{ "code": "DABC12", "csrf_token": "…", "expires_in": 3600 }
GET /current
Returns the active emergency for the session, or "active": false when there
is none.
{
"active": true,
"emergency": {
"emergency_id": "EMG123456",
"is_active": true,
"is_simulated": false,
"responders": []
},
"realtime": { "mode": "public", "pusher": { "…": "…" } }
}
POST /activate
Activates the emergency and messages the emergency contacts.
{ "geolocation": { "latitude": 4.711, "longitude": -74.0721 } }
{
"emergency_id": "EMG123456",
"simulated": false,
"responders": [
{
"phone": "573001234567",
"name": "Grace Hopper",
"sent": true,
"delivered": false,
"read": false,
"failed": false,
"message_id": "wamid.…"
}
],
"failures": [],
"partial_failure": false,
"total_failure": false
}
POST /simulacrum
Sends the simulation messages to the emergency contacts. The response has the
same shape as activation with "simulated": true and "emergency_id": null.
It never creates an emergency.
POST /{id}/refresh
Returns the current upstream state for an emergency.
{
"emergency": { "emergency_id": "EMG123456" },
"responders": []
}
DELETE /{id}
Aborts the emergency and clears the session state.
{
"emergency_id": "EMG123456",
"simulated": false,
"responders": [],
"failures": [],
"partial_failure": false,
"total_failure": false,
"deleted": true
}
Errors use one envelope and carry the same id as the X-Request-Id response
header:
{
"error": {
"code": "inactive_code",
"message": "The code is not available for emergencies.",
"details": [],
"request_id": "…"
}
}
Host integration
Bootstrap::create() wires native sessions, Guzzle, the payload builder and the
emergency service. Hosts that own their framework can construct Kernel
directly and replace any collaborator:
- Session storage — implement
SessionStoreand pass it toSessionManager. - Upstream transport — implement
ApiClientor inject any PSR-18 client throughPsr18ApiClient. - Profiles, emergencies and WhatsApp —
ProfileRepository,EmergencyRepositoryandWhatsAppClientare replaceable. - Logging — pass a PSR-3 logger. Tokens and API keys are never logged.
Realtime
Realtime delivery updates require two environment variables:
EMERGENCY_BFF_PUSHER_KEY=public-key EMERGENCY_BFF_PUSHER_CLUSTER=us2
The package exposes only the public key and cluster; the Pusher secret is never
read. Channels are public and carry metadata only, so treat their events as
hints and reconcile through GET /current or POST /{id}/refresh.
Example
examples/vanilla-php contains a dependency-free demo and a mock upstream. See
its README for the two-server command sequence.
Tests
composer validate --strict
composer install
composer test
Documentation
Start at the documentation index.
License
MIT. See LICENSE.