Description
Given a customer location (lat/lng, possibly via an assigned identifier), the Access domain should answer: which Shelves can serve this customer, and on what technologies? Doing this in Access first is right — Shelf is concrete (a DSLAM at a known place with a known cable-reach by technology) and the spatial question is sharp before we layer on NBN's TSA/CSA polygons in #26.
In choreography form:
- Shelf brings up its location (place) and its reach (cable-length × technology — DSL falls off with distance from the DSLAM).
- Customer Location carries lat/lng (an assigned identifier).
- Service qualification is the spatial alignment — which shelves' reaches contain or are close-enough-to this lat/lng for each technology offered.
No central registry of shelf-to-customer mappings; the answer emerges from spatial joins against the graph. Customer asks "who can reach me" and the data layer answers from the geometry it already knows.
What we'd find useful
The dream is for the data layer to answer the spatial question the Ash way — not Cypher-from-application-code, not custom traversal logic in characteristic calcs, but expressions on Ash queries that AshNeo4j translates to Neo4j's spatial functions:
Shelf
|> Ash.Query.filter(within_reach_of(location: ^customer_location, technology: :adsl2plus))
|> Ash.read()
Or, from the customer's side:
Location
|> Ash.Query.for_read(:get, %{id: customer_id})
|> Ash.Query.load(servicable_shelves: %{technology: :adsl2plus})
|> Ash.read_one()
The diffo layer expresses the domain primitives (Shelf has a reach calc per technology, Location has a lat/lng); AshNeo4j translates spatial filter/aggregate expressions to Neo4j's point.distance / point.withinBBox / containment functions; Ash hides the translation.
Why it matters
Service qualification is the entry-point question for almost every telecom domain interaction — can we even serve this customer, and how? Today consumers reach for Cypher or external GIS to answer it, which breaks the Ash-everywhere story and pulls the domain model apart. If the data layer can answer the spatial question natively, the choreography stays intact: shelf advertises reach, customer's location asks who can serve it, the data layer aligns them.
It also unlocks the bigger story — once Access can answer it for shelves and cable reach, NBN can answer it for TSA polygons, then for inter-RSP service transfer (which RSPs have presence in this CSA), then for design optimisation (best reach + best capacity + best path).
A possible direction
Two diffo/ash_neo4j gaps may surface:
- Spatial attribute types on places —
:point (lat/lng) and :polygon (TSA/CSA boundary) as first-class attribute types, mapped to Neo4j's spatial types.
- Spatial filter/aggregate expressions —
within_distance(point, ^km), contains(polygon, ^point), expressible in Ash queries and translated by AshNeo4j.
The exemplar work would be to model Shelf's location and per-technology reach, then prototype the customer-asks-who-can-serve-me query — both as it works today (likely with custom code falling back to Cypher) and as we'd like it to read (Ash expressions). The delta becomes the yarn for diffo / ash_neo4j in #125 style.
Related: #26 (TSA/CSA places) — once spatial works for Shelf reach, the polygon-containment question for TSAs naturally follows.
Description
Given a customer location (lat/lng, possibly via an assigned identifier), the Access domain should answer: which Shelves can serve this customer, and on what technologies? Doing this in Access first is right — Shelf is concrete (a DSLAM at a known place with a known cable-reach by technology) and the spatial question is sharp before we layer on NBN's TSA/CSA polygons in #26.
In choreography form:
No central registry of shelf-to-customer mappings; the answer emerges from spatial joins against the graph. Customer asks "who can reach me" and the data layer answers from the geometry it already knows.
What we'd find useful
The dream is for the data layer to answer the spatial question the Ash way — not Cypher-from-application-code, not custom traversal logic in characteristic calcs, but expressions on Ash queries that AshNeo4j translates to Neo4j's spatial functions:
Or, from the customer's side:
The diffo layer expresses the domain primitives (Shelf has a reach calc per technology, Location has a lat/lng); AshNeo4j translates spatial filter/aggregate expressions to Neo4j's
point.distance/point.withinBBox/ containment functions; Ash hides the translation.Why it matters
Service qualification is the entry-point question for almost every telecom domain interaction — can we even serve this customer, and how? Today consumers reach for Cypher or external GIS to answer it, which breaks the Ash-everywhere story and pulls the domain model apart. If the data layer can answer the spatial question natively, the choreography stays intact: shelf advertises reach, customer's location asks who can serve it, the data layer aligns them.
It also unlocks the bigger story — once Access can answer it for shelves and cable reach, NBN can answer it for TSA polygons, then for inter-RSP service transfer (which RSPs have presence in this CSA), then for design optimisation (best reach + best capacity + best path).
A possible direction
Two diffo/ash_neo4j gaps may surface:
:point(lat/lng) and:polygon(TSA/CSA boundary) as first-class attribute types, mapped to Neo4j's spatial types.within_distance(point, ^km),contains(polygon, ^point), expressible in Ash queries and translated by AshNeo4j.The exemplar work would be to model Shelf's location and per-technology reach, then prototype the customer-asks-who-can-serve-me query — both as it works today (likely with custom code falling back to Cypher) and as we'd like it to read (Ash expressions). The delta becomes the yarn for diffo / ash_neo4j in #125 style.
Related: #26 (TSA/CSA places) — once spatial works for Shelf reach, the polygon-containment question for TSAs naturally follows.