Skip to content
Merged

dev #110

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
bb4c60f
base party and related DSL and livebook
matt-beanland Apr 26, 2026
5197a37
Merge pull request #82 from diffo-dev/81-baseparty-fragment-and-dsl
matt-beanland Apr 26, 2026
141dcb6
Instance DSL parties — multiplicity, validation, and enforcement
matt-beanland Apr 27, 2026
4a0d34c
Merge pull request #89 from diffo-dev/84-instance-dsl-parties-multipl…
matt-beanland Apr 27, 2026
7386b03
verifiers for instance extension
matt-beanland Apr 27, 2026
620624c
fix domain boundary in build_after — eliminate reload workaround
matt-beanland Apr 27, 2026
dc26701
Instance Extension transformers — bake DSL data at compile time
matt-beanland Apr 28, 2026
def1915
Instance Extension — structure/behaviour DSL, persisters, transformer…
matt-beanland Apr 28, 2026
4ec4b31
documents
matt-beanland Apr 28, 2026
31a58e9
Instance Extension — party_type BaseParty verification, instance?/1, …
matt-beanland Apr 28, 2026
5c4226e
Merge pull request #92 from diffo-dev/86-transformers-persisters-veri…
matt-beanland Apr 28, 2026
dac6587
minimal base place and place extension
matt-beanland Apr 28, 2026
30f3d09
place extension
matt-beanland Apr 28, 2026
115fbfd
places do in instance and party extensions
matt-beanland Apr 28, 2026
2308991
Place DSL — BasePlace fragment, Place/Party/Instance Extension sectio…
matt-beanland Apr 29, 2026
4004f8d
Merge pull request #93 from diffo-dev/91-place-dsl
matt-beanland Apr 29, 2026
bc36520
fixed provider instance specification doesn't set description
matt-beanland Apr 29, 2026
6dcda5d
description now present
matt-beanland Apr 29, 2026
c1e8cad
Merge pull request #95 from diffo-dev/79-provider-instance-specificat…
matt-beanland Apr 29, 2026
361f207
added provider instance specification field minor_version, patch_vers…
matt-beanland Apr 29, 2026
7e039dd
provider instance specification DSL — minor, patch and tmf versions
matt-beanland Apr 29, 2026
77f5c66
Merge pull request #97 from diffo-dev/94-provider-instance-specificat…
matt-beanland Apr 29, 2026
7b2f6eb
document instance versioning lifecycle
matt-beanland Apr 29, 2026
2cb7374
Merge pull request #98 from diffo-dev/96-document-instance-versioning
matt-beanland Apr 29, 2026
efeb20d
accept raw dynamic
matt-beanland Apr 29, 2026
3ff1a65
Merge pull request #100 from diffo-dev/99-value-cast-should-accept-ba…
matt-beanland Apr 29, 2026
73d5da3
tests use sandbox
matt-beanland May 6, 2026
556c747
removed duplicate tests
matt-beanland May 6, 2026
4416d9a
Merge pull request #108 from diffo-dev/106-resolve-test-resource-spar…
matt-beanland May 6, 2026
199b8dc
ash_neo4j and bolty bump
matt-beanland May 6, 2026
abfc0e8
Merge pull request #109 from diffo-dev/105-latest_ash_neo4j
matt-beanland May 6, 2026
748a855
release 0.2.1
matt-beanland May 6, 2026
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
3 changes: 0 additions & 3 deletions .gitignore.license

This file was deleted.

3 changes: 0 additions & 3 deletions .tool-versions.license

This file was deleted.

34 changes: 0 additions & 34 deletions .vscode/launch.json

This file was deleted.

111 changes: 65 additions & 46 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,56 +11,26 @@ See [Conventional Commits](Https://conventionalcommits.org) for commit guideline

<!-- changelog -->

## [v0.1.0](https://github.com/diffo-dev/diffo/compare/v0.1.0...v0.1.0) (2025-08-11)

### Features:
* initial version on AshNeo4j DataLayer

## [v0.1.1](https://github.com/diffo-dev/diffo/compare/v0.1.0...v0.1.1) (2025-09-09)

### Features:
* update for AshNeo4j DSL changes
* refactor specification relationships
* characteristic value schemas
* customise instance via specification
* improve relationships to avoid circular loads

## [v0.1.2](https://github.com/diffo-dev/diffo/compare/v0.1.1...v0.1.2) (2025-10-20)

### Features

* REUSE compliant

## [v0.1.3](https://github.com/diffo-dev/diffo/compare/v0.1.2...v0.1.3) (2025-12-01)

### Features
## [v0.2.1](https://github.com/diffo-dev/diffo/compare/v0.2.0...v0.2.1) (2026-05-06)

* place_ref source party or place
* party_ref source place or party
* instance events

### Maintenance

* remove access domain

## [v0.1.4](https://github.com/diffo-dev/diffo/compare/v0.1.3...v0.1.4) (2026-03-12)
## Notable Changes
* Updated to ash_neo4j 0.4.1 and bolty 0.0.12, now supporting transactions and test sandbox
* Improvements to provider DSL and documentation

### Features
## What's Changed
* base party and related DSL and livebook by @matt-beanland in https://github.com/diffo-dev/diffo/pull/82
* Instance DSL parties — multiplicity, validation, and enforcement by @matt-beanland in https://github.com/diffo-dev/diffo/pull/89
* 86 transformers persisters verifiers by @matt-beanland in https://github.com/diffo-dev/diffo/pull/92
* 91 place dsl by @matt-beanland in https://github.com/diffo-dev/diffo/pull/93
* 79 provider instance specification doesnt set description by @matt-beanland in https://github.com/diffo-dev/diffo/pull/95
* 94 provider instance specification dsl additional fields by @matt-beanland in https://github.com/diffo-dev/diffo/pull/97
* document instance versioning lifecycle by @matt-beanland in https://github.com/diffo-dev/diffo/pull/98
* accept raw dynamic by @matt-beanland in https://github.com/diffo-dev/diffo/pull/100
* removed duplicate tests by @matt-beanland in https://github.com/diffo-dev/diffo/pull/108
* 105 latest ash neo4j by @matt-beanland in https://github.com/diffo-dev/diffo/pull/109

* assigner unassign operation

### Maintenance

* updated ash_neo4j, uses bolty rather than boltx

## [v0.1.5](https://github.com/diffo-dev/diffo/compare/v0.1.4...v0.1.5) (2026-03-19)

### Fixes

* fixed relationship enrichment inconsistent across neo4j versions

## [v0.2.0](https://github.com/diffo-dev/diffo/compare/v0.1.6...v0.2.0) (2026-04-24)

### Breaking Changes

* Updated to ash_neo4j 0.3.1 and bolty 0.0.10 — no database compatibility with prior versions due to significant changes in the data layer and Bolt protocol handling
Expand Down Expand Up @@ -94,4 +64,53 @@ See [Conventional Commits](Https://conventionalcommits.org) for commit guideline

### Maintenance

* improved error handling
* improved error handling

[v0.1.5](https://github.com/diffo-dev/diffo/compare/v0.1.4...v0.1.5) (2026-03-19)

### Fixes

* fixed relationship enrichment inconsistent across neo4j versions

## [v0.1.4](https://github.com/diffo-dev/diffo/compare/v0.1.3...v0.1.4) (2026-03-12)

### Features

* assigner unassign operation

### Maintenance

* updated ash_neo4j, uses bolty rather than boltx

## [v0.1.3](https://github.com/diffo-dev/diffo/compare/v0.1.2...v0.1.3) (2025-12-01)

### Features

* place_ref source party or place
* party_ref source place or party
* instance events

### Maintenance

* remove access domain

## [v0.1.2](https://github.com/diffo-dev/diffo/compare/v0.1.1...v0.1.2) (2025-10-20)

### Features

* REUSE compliant

## [v0.1.1](https://github.com/diffo-dev/diffo/compare/v0.1.0...v0.1.1) (2025-09-09)

### Features:
* update for AshNeo4j DSL changes
* refactor specification relationships
* characteristic value schemas
* customise instance via specification
* improve relationships to avoid circular loads

## [v0.1.0](https://github.com/diffo-dev/diffo/compare/v0.1.0...v0.1.0) (2025-08-11)

### Features:
* initial version on AshNeo4j DataLayer

12 changes: 12 additions & 0 deletions REUSE.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version = 1

[[annotations]]
path = [
".gitignore",
".tool-versions",
"mix.lock",
"logos/diffo.jpg",
"documentation/dsls/**",
]
SPDX-FileCopyrightText = "2025 diffo contributors <https://github.com/diffo-dev/diffo/graphs.contributors>"
SPDX-License-Identifier = "MIT"
58 changes: 46 additions & 12 deletions diffo.livemd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!--
<!--
SPDX-FileCopyrightText: 2025 diffo contributors <https://github.com/diffo-dev/diffo/graphs.contributors>

SPDX-License-Identifier: MIT
Expand All @@ -9,7 +9,7 @@ SPDX-License-Identifier: MIT
```elixir
Mix.install(
[
{:diffo, "~> 0.2.0"}
{:diffo, "~> 0.2.1"}
],
consolidate_protocols: false
)
Expand Down Expand Up @@ -113,10 +113,41 @@ alias Diffo.Provider.PartyRef
alias Diffo.Provider.Place
alias Diffo.Provider.PartyRef
alias Diffo.Uuid
alias Diffo.Type.Value
import Jason, only: [encode: 2]
use Outstand
```

The value types used in this livebook are defined without the Provider Extension DSL — each requires a dedicated `Ash.TypedStruct` so that `Diffo.Type.Dynamic` can round-trip values through Neo4j storage.

```elixir
defmodule Diffo.Livebook.E2eValue do
@derive Jason.Encoder
use Ash.TypedStruct
typed_struct do
field :downstream, :integer
field :upstream, :integer
field :units, :atom
end
end

defmodule Diffo.Livebook.OptionsValue do
@derive Jason.Encoder
use Ash.TypedStruct
typed_struct do
field :options, {:array, :atom}
end
end

defmodule Diffo.Livebook.TechnologyValue do
@derive Jason.Encoder
use Ash.TypedStruct
typed_struct do
field :access, :atom
end
end
```

We can either create specification instances with Ash directly, or use the Diffo.Provider code interface.

```elixir
Expand Down Expand Up @@ -173,13 +204,13 @@ individual =
Diffo.Provider.create_party!(%{
id: "IND000000897354",
name: :individualId,
referredType: :Individual
referred_type: :Individual
})
org =
Diffo.Provider.create_party!(%{
id: "ORG000000123456",
name: :organizationId,
referredType: :Organization
referred_type: :Organization
})
parties = [individual, org]
Jason.encode!(parties, pretty: true) |> IO.puts
Expand All @@ -197,7 +228,7 @@ Jason.encode!(parties, pretty: true) |> IO.puts
We'll also add a CustomerSite place where the service is to be delivered to the customer. Historically this is the Z-end.

```elixir
z_end = Provider.create_place!(%{id: "1657363", name: :addressId, href: "place/telco/1657363", referredType: :GeographicAddress})
z_end = Provider.create_place!(%{id: "1657363", name: :addressId, href: "place/telco/1657363", referred_type: :GeographicAddress})
Jason.encode!(z_end, pretty: true) |> IO.puts
```

Expand Down Expand Up @@ -230,7 +261,7 @@ First we'll create a backup feature to indicate that we want mobile backup, and
We'll create an e2e 'instance' characteristic to detail our bandwidth and latency requirements:

```elixir
e2e = Provider.create_characteristic!(%{type: :instance, name: :e2e, value: %{bandwidth: %{downstream: 250, upstream: 25, units: :Mbps}}})
e2e = Provider.create_characteristic!(%{type: :instance, name: :e2e, value: Value.dynamic(%Diffo.Livebook.E2eValue{downstream: 250, upstream: 25, units: :Mbps})})
broadband_0001 = broadband_0001
|> Provider.relate_instance_characteristics!(%{characteristics: [e2e.id]})
broadband_0001 |> Jason.encode!(pretty: true) |> IO.puts
Expand All @@ -240,7 +271,7 @@ We'll create mobile backup and device management features. The device management

```elixir
backup = Provider.create_feature!(%{name: :backup, isEnabled: true})
options = Provider.create_characteristic!(%{type: :feature, name: :options, value: [:updates, :monitoring]})
options = Provider.create_characteristic!(%{type: :feature, name: :options, value: Value.dynamic(%Diffo.Livebook.OptionsValue{options: [:updates, :monitoring]})})
device_management = Provider.create_feature!(%{name: :deviceManagement, isEnabled: true, characteristics: [options.id]})
broadband_0001 = broadband_0001
|> Provider.relate_instance_features!(%{features: [backup.id, device_management.id]})
Expand Down Expand Up @@ -305,13 +336,13 @@ We'll have a few things outstanding which we would normally find out during serv
We recommend using outstanding to drive next task logic, so that the orchestration is directed by the difference engine. This could look like an address lookup (where we learn the provider) followed by a provider service qualification (where we learn the technology) and the related network places.

```elixir
nbn = Provider.create_party!(%{id: :nbn, name: "NBNCo", referredType: :Organization})
nbn = Provider.create_party!(%{id: "nbn", name: "NBNCo", referred_type: :Organization})
nbn_party_ref = Provider.create_party_ref!(%{instance_id: broadband_0001.id, party_id: nbn.id, role: :Provider})
provider_z_end = Provider.create_place!(%{id: "LOC000000899353", name: "locationId", href: "place/nbnco/LOC000000899353",referredType: :GeographicAddress})
provider_z_end = Provider.create_place!(%{id: "LOC000000899353", name: "locationId", href: "place/nbnco/LOC000000899353", referred_type: :GeographicAddress})
provider_z_end_place_ref = Provider.create_place_ref!(%{instance_id: broadband_0001.id, role: :CustomerSite, place_id: provider_z_end.id})
csa = Provider.create_place!(%{id: "CSA200000000685", name: "csaId", href: "place/nbnco/CSA200000000685", referredType: :GeographicLocation})
csa = Provider.create_place!(%{id: "CSA200000000685", name: "csaId", href: "place/nbnco/CSA200000000685", referred_type: :GeographicLocation})
csa_place_ref = Provider.create_place_ref!(%{instance_id: broadband_0001.id, role: :ServingArea, place_id: csa.id})
poi = Provider.create_place!(%{id: "2CAR", name: "poiId", href: "place/nbnco/2CAR",referredType: :GeographicSite})
poi = Provider.create_place!(%{id: "2CAR", name: "poiId", href: "place/nbnco/2CAR", referred_type: :GeographicSite})
poi_place_ref = Provider.create_place_ref!(%{instance_id: broadband_0001.id, role: :AccessNNI, place_id: poi.id})

places = Diffo.Provider.list_place_refs!()
Expand All @@ -331,7 +362,7 @@ outstanding = expected_instance --- broadband_0001
We create and add the technology characteristic to the actual service. This should resolve the characteristic expectation.

```elixir
technology = Provider.create_characteristic!(%{type: :instance, name: :technology, value: %{access: :nbnEthernet}})
technology = Provider.create_characteristic!(%{type: :instance, name: :technology, value: Value.dynamic(%Diffo.Livebook.TechnologyValue{access: :nbnEthernet})})
broadband_0001 |> Provider.relate_instance_characteristics!(%{characteristics: [technology.id]})


Expand All @@ -358,6 +389,7 @@ Given that our feasibilityCheck above was complete we want to set the :feasibili

```elixir
broadband_0001 = broadband_0001 |> Provider.feasibilityCheck_service!(%{service_operating_status: :feasible})
broadband_0001 = Provider.get_instance_by_id!(broadband_0001.id)
broadband_0001 |> Jason.encode!(pretty: true) |> IO.puts
```

Expand Down Expand Up @@ -450,4 +482,6 @@ broadband_0001 |> Jason.encode!(pretty: true) |> IO.puts
In this tutorial you've used Diffo to create, relate and update some TMF Service and Resources, simulating activities over the service and resource lifecycle, and you've learned how this functionality is underpinned by open source Neo4j, Ash Framework and Elixir.
Diffo contains an example Access domain showing how to specialise the structure and behaviour of TMF Services and Resources.

But there is a lot of friction here and we still only have structure and not much behaviour. In practice, you'd use the Provider Extension DSLs to do the heavy lifting. But what you've learned here is foundational to help you move on to the other livebooks.

If you find Diffo useful please visit and star on [github](https://github.com/diffo-dev/diffo/). Feel free to join discussions and raise issues to discuss PR's.
Loading
Loading