The ShelfOrigin property is designed for handling external data, but it requires explanation to be used correctly.
Your database has a Unit with ID
GUID-A.ResQueServe assigns it ID
105.How do you know that
105corresponds toGUID-Anext time you run an update?
You could save the ResQueServe ID back to your database, but that is brittle or you even can't because you don't own the database. Instead, ResQueServe solves this with the Shelf Origin Pattern.
What is a "Shelf Origin"?
Every major entity in the ResQueServe ecosystem (Unit, Poi, Keyword) implements the IShelf interface, which contains an Origin property. This property allows you to stamp your system's metadata directly onto the ResQueServe object.
The Data Structure
The ShelfOrigin is polymorphic. It accepts a Namespace (who owns the data), an ID (the external key), and an optional Version.
C#
// The Abstract Base
public abstract record ShelfOriginBase { ... }
// The Concrete Implementation
public record ShelfOrigin<T>(
string Namespace,
string Id,
ShelfVersion<T>? Version
);
Property | Purpose | Example |
Namespace | Identifies the source system. Prevents collisions if you import from both SAP and OpenStreetMap. |
|
Id | The unique key in the source system. |
|
Version | Used for Delta Updates. Supports |
|
Implementation Guide: The "Upsert" Workflow
Here is how to write a robust synchronization job that pushes data from your local CSV/DB to ResQueServe without creating duplicates.
Step 1: Define your Origin
Always use a consistent Namespace constant.
C#
const string MySource = "MyLegacyDatabase";
Step 2: Create Entities with Origins
When creating a new object, attach the origin info.
C#
var newUnit = new Unit
{
Callsign = "Rescue 1",
// ... other properties ...
// Attach external metadata
Origin = new ShelfOrigin<DateTimeOffset>(
Namespace: MySource,
Id: "LOCAL_DB_ID_99",
Version: new ShelfVersion<DateTimeOffset>(DateTimeOffset.UtcNow)
)
};
await unitClient.CreateAsync(dpcId, newUnit);
Step 3: Syncing & Updating (The "Smart Update")
When your sync job runs again, you don't want to blindly overwrite everything. You can use the Version field to detect changes.
C#
public async Task SyncFleet(long dpcId, List<MyLocalUnit> localUnits)
{
// 1. Fetch all existing units from ResQueServe
// (Using pagination to get the full list)
var remoteUnits = await FetchAllRemoteUnits(dpcId);
foreach (var localUnit in localUnits)
{
// 2. Find if this unit already exists in ResQueServe by checking the Origin
var match = remoteUnits.FirstOrDefault(u =>
u.Origin is ShelfOrigin<DateTimeOffset> origin &&
origin.Namespace == MySource &&
origin.Id == localUnit.LocalId
);
if (match == null)
{
// CREATE: It doesn't exist yet
await CreateUnitAsync(localUnit);
}
else
{
// UPDATE: Check if it needs updating
// Cast the origin to the specific generic type we used
var origin = (ShelfOrigin<DateTimeOffset>)match.Origin;
// If local data is newer than the remote data
if (localUnit.LastModified > origin.Version.Value)
{
await UpdateUnitAsync(match.Id, localUnit);
}
}
}
}
Working with Third-Party Data (e.g., OpenStreetMap)
If you are building a plugin that enriches ResQueServe with public data (like importing Fire Stations from OSM), the Shelf Origin is mandatory to respect the "Single Source of Truth."
Example JSON for an OSM Import:
JSON
{
"name": "Fire Station 1",
"category": 14,
"origin": {
"namespace": "OpenStreetMap",
"id": "way/4522910",
"version": "5"
}
}Do not store ResQueServe IDs in your external database if you can avoid it.
Do use
ShelfOriginto store your IDs inside ResQueServe.Do use the
Versiongeneric to implement efficient "Delta Updates," saving bandwidth and API calls.
