eventIdstringGlobally unique immutable identity used to deduplicate delivery and replay.
requiredroute_plan.navigation_handed_offApplication-owned route planning session fact emitted after confirm_handoff reaches handed_off.
This versioned envelope is an application architecture contract derived from the published iOS direction planning and navigation handoff transition model. Keep provider request and response bodies behind their separately sourced API contracts.
The application accepts a command, checks its expected aggregate version and invariant set, commits exactly one new version, and records this fact in the same transaction.
confirm_handoffNavigation adapterhandoff_pendinghanded_offPersist the target acknowledgement once and let its separate lifecycle own later progress.
The outer envelope is closed to unknown fields. The data object is intentionally application-owned and must be versioned deliberately for real consumers.
eventIdstringGlobally unique immutable identity used to deduplicate delivery and replay.
requiredeventTypestringNames the application-owned fact. Consumers must reject or quarantine unknown values.
requiredeventVersionintegerVersion of this event contract. Version 1 is the only published version in this catalog.
requiredaggregateTypestringApplication aggregate that owns the transition.
requiredaggregateIdstringStable application identity; do not substitute a mutable display label.
requiredaggregateVersionintegerMonotonically increasing aggregate version after the transition.
requiredtenantIdstringApplication tenant boundary used for authorization and routing.
requiredactorobjectAttributable actor type and application identity that caused or recorded the fact.
requiredoccurredAtstring · date-timeUTC time at which the underlying action occurred.
requiredrecordedAtstring · date-timeUTC time at which the application durably committed the event.
requiredidempotencyKeystringStable key supplied by the producing command and retained across retries.
requiredcorrelationIdstringIdentity shared by events and calls in one business journey.
requiredcausationIdstring | nullEvent or command that directly caused this fact; null only for a root event.
requireddataobjectApplication-owned, event-specific data. This catalog does not claim a Mappls provider payload shape.
requiredExamples contain no credential, precise real-world location, media, or personal identity. Replace the event-specific data only after defining its compatibility policy.
{
"eventId": "evt_example_ios_direction_planning_handoff_route_plan_navigation_handed_off",
"eventType": "route_plan.navigation_handed_off",
"eventVersion": 1,
"aggregateType": "route planning session",
"aggregateId": "example-ios-direction-planning-handoff-001",
"aggregateVersion": 1,
"tenantId": "tenant_example",
"actor": {
"type": "Navigation adapter",
"id": "actor_example"
},
"occurredAt": "2026-01-01T10:00:00.000Z",
"recordedAt": "2026-01-01T10:00:00.125Z",
"idempotencyKey": "cmd_example_0001",
"correlationId": "corr_example_0001",
"causationId": null,
"data": {
"resultingState": "handed_off",
"command": "confirm_handoff",
"evidenceBoundary": "application-owned-example"
}
}These compact adapters show the mandatory type, version, aggregate-version, and event-ID gates. Store the projection and deduplication record atomically.
export function consumeRoutePlanNavigationHandedOff(event, seen) {
if (event.eventType !== "route_plan.navigation_handed_off" || event.eventVersion !== 1) return;
if (seen.has(event.eventId)) return;
if (!Number.isInteger(event.aggregateVersion) || event.aggregateVersion < 1) throw new Error("Invalid aggregateVersion");
// Apply one idempotent application-side projection here.
seen.add(event.eventId);
}Commit the aggregate transition and a transactional outbox row together; publish from the outbox after commit.
Partition and serialize by aggregateId; reject stale aggregate versions at the projection boundary.
Commit the consumer side effect and eventId receipt together.
Replay the immutable event with the same eventId. A consumer must not repeat its side effect when that eventId was already committed.
After a timeout, reconcile the aggregate and outbox before retrying the same idempotencyKey; do not mint a replacement command identity.
Keep credentials, raw precise-location traces, media, and unnecessary personal data out of the envelope. Put governed references in data only when the application policy permits them.
These links ground adjacent Mappls capabilities. They do not promote this application envelope into a provider contract.