Skip to content

installer availability — who can install in space and time given their technology relationships #39

@matt-beanland

Description

@matt-beanland

Description

Where #38 asks "which Shelves can serve a customer at lat/lng," this asks the next-step question: "which Installers can come to a customer at lat/lng, in this time window, with the technology competence to install what's been ordered?"

Installers are Parties (people, teams, contractor crews) with three dimensions:

  • Spatial — where they are / where they cover. Could be a base lat/lng with a service radius, or a coverage polygon, or a roster of TSAs they're assigned to.
  • Temporal — when they're available. A calendar of free/busy slots, with travel time between locations factored in.
  • Technology — what they can install. Relationships to technology types they're certified or competent in.

The question becomes a three-way alignment: spatial proximity × temporal availability × technology match.

In choreography form:

  • Installer (Party) brings up their coverage area, availability calendar, and technology competence.
  • Customer Location (Place) carries lat/lng and the technology being ordered.
  • Service order (Instance) carries the desired time window.
  • Installation qualification is the alignment — which installers' coverage contains/is close enough to this location, whose calendar is free in the window, who can install this technology.

No central dispatcher; each installer advertises their bring-up, the customer's order asks who's aligned. Choreography in time and space.

What we'd find useful

The data layer should answer the alignment question the Ash way:

Installer
|> Ash.Query.filter(
  available_at(location: ^customer_location, window: ^time_window) and
  competent_in(technology: :adsl2plus)
)
|> Ash.read()

Or, from the customer's side:

ServiceOrder
|> Ash.Query.for_read(:get, %{id: order_id})
|> Ash.Query.load(eligible_installers: [])
|> Ash.read_one()

Diffo expresses the domain primitives (Installer is a Party with coverage, calendar, and technology relationships); AshNeo4j translates spatial + temporal filter expressions to Neo4j (spatial functions for distance/containment, range queries on availability intervals); Ash hides the translation.

Why it matters

Installation feasibility is the deliverability question that gates whether service qualification matters. A shelf can reach a customer perfectly, but if no installer can be there in the customer's window, the order can't be fulfilled. The choreography story stays clean — each installer watches their own world (coverage, calendar, competence), the order asks who's aligned — but only if the data layer can answer the three-way alignment without consumers dropping into custom code for each dimension.

Time as a first-class query dimension also opens scheduling, re-scheduling, and conflict-resolution as native domain operations rather than bolt-ons.

A possible direction

Several diffo/ash_neo4j gaps may surface:

  1. Calendar / availability as a first-class attribute — interval lists with conflict-detection, expressible as Ash query predicates.
  2. Temporal expressionsavailable_in(^window), intersects(^window, ^window), similar to the spatial expressions hoped for in #38.
  3. Technology competence as relationship — installer → technology edges, queryable via the same FieldViaRelationship-style traversal we discussed for #10.

The exemplar work would be to model Installer as a Party with coverage + calendar + technology relationships, then prototype the three-way alignment query. The delta between how it works today (likely Cypher + custom predicates) and how we'd like it to read (Ash expressions) becomes the yarn for diffo / ash_neo4j.

Related:

  • #38 — spatial service qualification (network-side feasibility)
  • #26 — TSA/CSA places (which installers cover which TSAs is the bridge between the two)
  • #3 — persistent expectations (an order can expect an installer to be assigned before it's installable)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions