Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,37 @@ See [Conventional Commits](Https://conventionalcommits.org) for commit guideline

<!-- changelog -->

## [v0.2.3](https://github.com/diffo-dev/diffo/compare/v0.2.2..v0.2.3) (2026-05-22)

### Maintenance:
* updated to diffo 0.4.1 (issue #48)
* refreshed agent guidance via `mix usage_rules.sync`

### Refactors:
* adopted upstream `Diffo.Provider.Changes.{Define,Relate,Assign}` across 11 instance resources; deleted the local `DiffoExample.Changes.*` trio now that the same modules ship in diffo proper ([diffo#170](https://github.com/diffo-dev/diffo/pull/170))
* slimmed 16 `BaseCharacteristic`-derived resources by relying on the auto-generated `:create`/`:update` actions ([diffo#171](https://github.com/diffo-dev/diffo/pull/171)) — ~360 lines removed; custom `:update` retained on `cable`, `path`, `circuit`, `constraints` where unit/bandwidth-profile composition is needed
* `Cable.relate` inline `after_action` (which referenced an unaliased `Relationship` module) folded into `change Diffo.Provider.Changes.Relate`

### Resolved workarounds:
* `DslAccess.qualify_result` now transitions to `:feasibilityChecked` — restores correct TMF form following [diffo#168](https://github.com/diffo-dev/diffo/pull/168) broadening the Assigner lifecycle gate to include `:feasibilityChecked`
* `Util.summarise_characteristics/2` no longer called from tests — typed characteristic + pool records now surface in TMF JSON by default ([diffo#169](https://github.com/diffo-dev/diffo/pull/169)). The projection function is retained in [lib/diffo_example/util.ex](lib/diffo_example/util.ex) for future projection demonstrations. Expected JSON strings updated across `cable`, `card`, `cable`, `path`, `shelf`, `dsl_access`, `nbn_ethernet` tests to reflect the real typed/pool surfacing

### Features:
* NBN — AVC, CVC, NniGroup characteristic inheritance and metrics (issue #49):
* AVC inherits the upstream CVC's `cvc` characteristic via the `:cvlan` assignment (single-hop), and the NniGroup's `nni_group` characteristic transitively via `[:cvlan, :svlan]` (two-hop). Both singular.
* CVC inherits the upstream NniGroup's `nni_group` characteristic via the `:svlan` assignment (singular).
* NniGroup brings up the typed value of every comprised NNI as `nnis[]` via the `:contains` relationship.
* New `cvc_metrics` characteristic on CVC carries `avcs_count` and `avcs_total_bandwidth` aggregated live over assigned AVCs.
* New `nni_group_metrics` characteristic on NniGroup carries `cvcs_count`/`cvcs_total_bandwidth` (demand), `nnis_count`/`nnis_total_bandwidth` (capacity), and `utilization = cvcs_total_bandwidth / nnis_total_bandwidth`.
* NBN — NTD brings up assigned UNIs as `unis[]` via the `:port` assignment (issue #49 part 2).
* NBN — NbnEthernet (PRI) brings up four characteristics surfacing the full delivery chain (issue #49 part 3): `avc` single-hop via the `:circuit` owns relationship, `uni` single-hop via the `:port` owns relationship, `cvc` two-hop via `:circuit` then `:cvc`, and `ntd` two-hop via `:port` then `:ntd`. All singular.
* NBN and Access — consumer-side aliases on assignments and relationships now name the **upstream related resource** the consumer is part of (its domain role), not the slot/thing being received. NBN: AVC sets `:cvc` on its cvlan assignment, CVC sets `:nni_group` on its svlan assignment, UNI sets `:ntd` on its port assignment; PRI's two `:owns` relationships are aliased `:circuit` (AVC) and `:port` (UNI). Access: Card sets `:shelf` on its slot assignment, Path sets `:card` on its port assignment, and `Shelf.cards` filters on `alias: :shelf`. Inheritance walks use these consumer-aliases. Pool/metric aggregations are unaffected — they still filter by `thing`.
* `BandwidthProfile.downstream/1` — atom-to-Mbps mapping used by the metrics aggregation. CVCs are treated as symmetric capacity in this model (satellite asymmetry ignored).

### Refactors (continued):
* `DiffoExample.Calculations.InheritedCharacteristic` renamed to `InheritedCharacteristicViaAssignment`; new sibling `InheritedCharacteristicViaRelationship` traverses `Provider.Relationship` edges (forward source → target). Both calcs accept `singular?:` to unwrap to a single value where graph identity guarantees ≤1 result. `InheritedCharacteristicViaRelationship` also accepts a `then_via:` list of assignment aliases to continue the walk via `AssignmentRelationship` after the relationship hop — covers mixed paths like PRI's `cvc` (relationship + assignment).
* `ReverseInheritedCharacteristic` extended with a `thing:` filter option, complementing the existing `alias:` filter. Source-side aggregations should prefer `thing:` since it's always set from the pool DSL — see the assignment-direction-asymmetry rationale.

## [v0.2.2](https://github.com/diffo-dev/diffo/compare/v0.2.1..v0.2.2) (2026-05-21)

### Maintenance:
Expand Down
1 change: 0 additions & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ config :spark,
:characteristics,
:neo4j,
:jason,
:json_api,
:outstanding,
:actions,
:state_machine,
Expand Down
60 changes: 60 additions & 0 deletions documentation/domains/_access_api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!--
SPDX-FileCopyrightText: 2025 diffo_example contributors <https://github.com/diffo-dev/diffo_example/graphs.contributors>

SPDX-License-Identifier: MIT

Auto-generated by `mix gen.api_docs`. Do not edit by hand.
Regenerate after changing any domain's `code_interface` defines.
-->

# Access Domain API

The Elixir function-call surface for each resource in the `DiffoExample.Access` domain. Generated from the `define` declarations in the domain's `resources do` block.

## Cable

| Function | Action | Arguments | Purpose |
|---|---|---|---|
| `assign_pair` | `:assign_pair` | `assignment` (struct) | relates the cable with an instance by assigning a pair |
| `build_cable` | `:build` | `id`, `name`, `type`, `which`, `relationships` (list of struct), `places` (list of struct), `parties` (list of struct) | creates a new Cable resource instance for build |
| `define_cable` | `:define` | `characteristic_value_updates` (list of term) | defines the cable |
| `get_cable_by_id` | `:read` | `id` | read a service or resource instance |
| `relate_cable` | `:relate` | `relationships` (list of struct) | relates the cable with other instances |

## Card

| Function | Action | Arguments | Purpose |
|---|---|---|---|
| `assign_port` | `:assign_port` | `assignment` (struct) | relates the card with an instance by assigning a port |
| `build_card` | `:build` | `id`, `name`, `type`, `which`, `relationships` (list of struct), `places` (list of struct), `parties` (list of struct) | creates a new Card resource instance for build |
| `define_card` | `:define` | `characteristic_value_updates` (list of term) | defines the card |
| `get_card_by_id` | `:read` | `id` | read a service or resource instance |
| `relate_card` | `:relate` | `relationships` (list of struct) | relates the card with other instances |

## DslAccess

| Function | Action | Arguments | Purpose |
|---|---|---|---|
| `design_dsl_result` | `:design_result` | `characteristic_value_updates` (list of term) | updates the DSL Access service with the design |
| `get_dsl_by_id` | `:read` | `id` | read a service or resource instance |
| `qualify_dsl` | `:qualify` | `id`, `name`, `type`, `which`, `places` (list of struct), `parties` (list of struct) | creates a new DSL Access service instance for qualification |
| `qualify_dsl_result` | `:qualify_result` | `service_operating_status`, `places` (list of struct) | updates the DSL Access service with qualification result |

## Path

| Function | Action | Arguments | Purpose |
|---|---|---|---|
| `build_path` | `:build` | `id`, `name`, `type`, `which`, `relationships` (list of struct), `places` (list of struct), `parties` (list of struct) | creates a new Path resource instance for build |
| `define_path` | `:define` | `characteristic_value_updates` (list of term) | defines the path |
| `get_path_by_id` | `:read` | `id` | read a service or resource instance |
| `relate_path` | `:relate` | `relationships` (list of struct) | relates the path with other instances |

## Shelf

| Function | Action | Arguments | Purpose |
|---|---|---|---|
| `assign_slot` | `:assign_slot` | `assignment` (struct) | relates the shelf with an instance by assigning a slot |
| `build_shelf` | `:build` | `id`, `name`, `type`, `which`, `relationships` (list of struct), `places` (list of struct), `parties` (list of struct) | creates a new Shelf resource instance for build |
| `define_shelf` | `:define` | `characteristic_value_updates` (list of term) | defines the shelf |
| `get_shelf_by_id` | `:read` | `id` | read a service or resource instance |
| `relate_shelf` | `:relate` | `relationships` (list of struct) | relates the shelf with cards |
90 changes: 90 additions & 0 deletions documentation/domains/_nbn_api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<!--
SPDX-FileCopyrightText: 2025 diffo_example contributors <https://github.com/diffo-dev/diffo_example/graphs.contributors>

SPDX-License-Identifier: MIT

Auto-generated by `mix gen.api_docs`. Do not edit by hand.
Regenerate after changing any domain's `code_interface` defines.
-->

# NBN Domain API

The Elixir function-call surface for each resource in the `DiffoExample.Nbn` domain. Generated from the `define` declarations in the domain's `resources do` block.

## Avc

| Function | Action | Arguments | Purpose |
|---|---|---|---|
| `build_avc` | `:build` | `id`, `which`, `relationships` (list of struct), `places` (list of struct), `parties` (list of struct) | creates a new AVC resource instance |
| `define_avc` | `:define` | `characteristic_value_updates` (list of term) | defines the AVC |
| `get_avc_by_id` | `:read` | `id` | read a service or resource instance |
| `relate_avc` | `:relate` | `relationships` (list of struct) | relates the AVC with other instances |

## Cvc

| Function | Action | Arguments | Purpose |
|---|---|---|---|
| `assign_cvlan` | `:assign_cvlan` | `assignment` (struct) | assigns a C-VLAN ID from the CVC pool to an AVC |
| `build_cvc` | `:build` | `id`, `which`, `relationships` (list of struct), `places` (list of struct), `parties` (list of struct) | creates a new CVC resource instance |
| `define_cvc` | `:define` | `characteristic_value_updates` (list of term) | defines the CVC |
| `get_cvc_by_id` | `:read` | `id` | read a service or resource instance |
| `relate_cvc` | `:relate` | `relationships` (list of struct) | relates the CVC with other instances (e.g. AVC aggregation, NNI Group termination) |

## NbnEthernet

| Function | Action | Arguments | Purpose |
|---|---|---|---|
| `build_nbn_ethernet` | `:build` | `id`, `which`, `relationships` (list of struct), `places` (list of struct), `parties` (list of struct) | creates a new NBN Ethernet access resource instance |
| `define_nbn_ethernet` | `:define` | `characteristic_value_updates` (list of term) | defines the NBN Ethernet access |
| `get_nbn_ethernet_by_id` | `:read` | `id` | read a service or resource instance |
| `relate_nbn_ethernet` | `:relate` | `relationships` (list of struct) | relates the NBN Ethernet access with other instances (e.g. UNI) |

## Nni

| Function | Action | Arguments | Purpose |
|---|---|---|---|
| `build_nni` | `:build` | `id`, `which`, `relationships` (list of struct), `places` (list of struct), `parties` (list of struct) | creates a new NNI resource instance |
| `define_nni` | `:define` | `characteristic_value_updates` (list of term) | defines the NNI |
| `get_nni_by_id` | `:read` | `id` | read a service or resource instance |
| `relate_nni` | `:relate` | `relationships` (list of struct) | relates the NNI with other instances (e.g. its parent NNI Group) |

## NniGroup

| Function | Action | Arguments | Purpose |
|---|---|---|---|
| `assign_svlan` | `:assign_svlan` | `assignment` (struct) | assigns an S-VLAN ID from the NNI Group pool to a CVC |
| `build_nni_group` | `:build` | `id`, `name`, `which`, `relationships` (list of struct), `places` (list of struct), `parties` (list of struct) | creates a new NNI Group resource instance |
| `define_nni_group` | `:define` | `characteristic_value_updates` (list of term) | defines the NNI Group |
| `get_nni_group_by_id` | `:read` | `id` | read a service or resource instance |
| `relate_nni_group` | `:relate` | `relationships` (list of struct) | relates the NNI Group with other instances (e.g. NNI resources it comprises) |

## Ntd

| Function | Action | Arguments | Purpose |
|---|---|---|---|
| `assign_port` | `:assign_port` | `assignment` (struct) | assigns a port from the NTD pool to a UNI |
| `build_ntd` | `:build` | `id`, `which`, `relationships` (list of struct), `places` (list of struct), `parties` (list of struct) | creates a new NTD resource instance |
| `define_ntd` | `:define` | `characteristic_value_updates` (list of term) | defines the NTD |
| `get_ntd_by_id` | `:read` | `id` | read a service or resource instance |
| `relate_ntd` | `:relate` | `relationships` (list of struct) | relates the NTD with other instances (e.g. UNI) |

## Rsp

| Function | Action | Arguments | Purpose |
|---|---|---|---|
| `activate_rsp` | `:activate` | — | — |
| `create_rsp` | `:build` | `name`, `short_name`, `id` | — |
| `deactivate_rsp` | `:deactivate` | — | — |
| `get_rsp_by_epid` | `:read` | `id` | — |
| `get_rsp_by_short_name` | `:read` | `short_name` | — |
| `list_rsps` | `:inventory` | — | — |
| `suspend_rsp` | `:suspend` | — | — |

## Uni

| Function | Action | Arguments | Purpose |
|---|---|---|---|
| `build_uni` | `:build` | `id`, `which`, `relationships` (list of struct), `places` (list of struct), `parties` (list of struct) | creates a new UNI resource instance |
| `define_uni` | `:define` | `characteristic_value_updates` (list of term) | defines the UNI |
| `get_uni_by_id` | `:read` | `id` | read a service or resource instance |
| `relate_uni` | `:relate` | `relationships` (list of struct) | relates the UNI with other instances (e.g. NTD, NBN Ethernet access) |
Loading
Loading