Locations & maps¶
Locations (Lokacja) and maps (Mapa) are entities too, but they carry a geography the
plain entity routes ignore: a containment tree (@lokacja), authored passages (@drzwi),
exterior/interior links (@outerior), and the Margonem map catalogue. This page covers the
location tree, the connectivity graph, the map-traversal edges inferred from sessions and
logs, the claim-ledger lint, and creating or editing locations and maps. Names are
URL-encoded in the path; the reads use the fixture geography around Thuzal — its child
Gildia Teologów, plus Ithan, Nithal, Karka-han.
Reads need entity.read, writes need entity.write (a reindex needs location.override).
Every example runs against a live daemon — see how the reference is tested.
Routes¶
| Method | Path | Cmdlet | Cap | Write |
|---|---|---|---|---|
| GET | /locations |
Find-NerthusLocation |
entity.read |
— |
| GET | /locations/graph |
Get-NerthusLocationGraph |
entity.read |
— |
| GET | /claims/lint |
Test-NerthusClaims |
entity.read |
— |
| POST | /locations/reindex |
Invoke-NerthusReindex |
location.override |
✓ |
| POST | /locations |
New-NerthusLocationEntity |
entity.write |
✓ |
| PATCH | /locations/{name} |
Set-NerthusLocationEntity |
entity.write |
✓ |
| GET | /locations/{name} |
Get-NerthusLocation |
entity.read |
— |
| GET | /maps/traversal |
Get-NerthusMapTraversalGraph |
entity.read |
— |
| POST | /maps/traversal |
Set-NerthusTraversalEntities |
entity.write |
✓ |
| POST | /maps |
New-NerthusMapEntity |
entity.write |
✓ |
| PATCH | /maps/{name} |
Set-NerthusMapEntity |
entity.write |
✓ |
Cap is the required capability (— = public, no token); Write (✓) marks routes that pass the write gate; a — in Cmdlet is reached directly, no wrapper. Paths are relative to /v1/api; the cross-cutting contract — middleware, envelopes, status codes — is on the API reference index.
List locations¶
GET /v1/api/locations returns the { count, items } envelope of every Lokacja
projection. Filter with ?parent= (@lokacja) or ?outerior=. Here, the seven fixtures.
Response 200 (trimmed):
{ "count": 7, "items": [
{ "Name": "Thuzal", "Type": "Lokacja", "Status": "Aktywny" },
{ "Name": "Gildia Teologów", "Type": "Lokacja", "Location": "Thuzal" }
] }
Fetch one location¶
GET /v1/api/locations/{name} resolves the name as a Lokacja and enriches the projection
with its child locations. An unknown name is 404.
Response 200 (trimmed):
The location graph¶
GET /v1/api/locations/graph returns the containment (@lokacja) plus door (@drzwi)
edges across every Lokacja, with the node and edge counts. The seven fixtures give seven
nodes.
Response 200 (trimmed):
{ "NodeCount": 7, "EdgeCount": 2, "Edges": [
{ "Source": "Thuzal", "Target": "Gildia Teologów", "Type": "Containment" }
] }
Lint the claim ledger¶
GET /v1/api/claims/lint checks the @forma_sesyjna routing ledger against the live
session model — duplicate claims, claims on soft-deleted blocks, duplicate headings, and
operator claims matching no observed session form. It returns { file, findingCount,
findings, stats }; stats carries the ledger tallies (claims, blocks, operator, …).
Response 200 (trimmed):
{ "findingCount": 0, "findings": [], "stats": { "claims": 0, "blocks": 26, "operator": 0, "auto": 0 } }
Map traversal edges¶
GET /v1/api/maps/traversal merges movement edges from session @Lokacje route sequences
and cached log transcripts. Each edge carries a Weight and an Origins set; a move
between two non-adjacent locations is typed Teleport — the cue for an undocumented
passage.
Response 200 (trimmed):
{ "EdgeCount": 1, "Edges": [
{ "Source": "Thuzal", "Target": "Rezydencja Tussal", "Type": "Containment", "Weight": 1, "Origins": ["session"] }
] }
Preview a reindex¶
POST /v1/api/locations/reindex re-runs the full import so edited @forma_sesyjna claims
re-route. With ?dryRun=true it writes nothing and returns { wouldReindex, findingCount,
findings, stats } — the claim lint, so a conflict never takes effect silently.
Response 200:
Preview a location create¶
POST /v1/api/locations forces type = Lokacja, so the body needs only a name.
?dryRun=true returns 200 { wouldCreate, type } and touches no disk — proven by the
follow-up 404. The scratch location is a tavern in Thuzal, drawn from the session's world.
Response 200:
Create a location¶
POST /v1/api/locations for real writes the Lokacja block and returns 201 { created,
type }. The tavern in Thuzal is scene-derived.
Response 201:
Update a location tag¶
PATCH /v1/api/locations/{name} sets one tag from the closed schema. Here the tavern gets
its @lokacja parent — placing it under Thuzal in the containment tree. An unknown tag is
422.
Response 200:
Preview a map create¶
POST /v1/api/maps forces type = Mapa and accepts the map metadata keys (margonemid,
url, wymiary, koordynaty, slug, …). ?dryRun=true returns 200 { wouldCreate, type
} and writes nothing — proven by the follow-up 404. The scratch map is the ground-floor
map of that Thuzal tavern, scene-derived.
Response 200:
Create a map¶
POST /v1/api/maps for real writes the Mapa block (seeded @status: Aktywny plus any
metadata keys supplied) and returns 201 { created, type }.
Response 201:
Update a map tag¶
PATCH /v1/api/maps/{name} sets one schema tag on a Mapa — here the Margonem @margonemid.
Response 200:
Promote an inferred passage¶
POST /v1/api/maps/traversal turns an inferred movement into an authored @drzwi passage
on the source location, returning { source, target, linked }. Here Thuzal gains a door to
Ithan. Both must be existing locations; ?dryRun=true returns { wouldLink } instead.
Response 200: