Skip to content

Commit 8a64c83

Browse files
Merge pull request #25 from diffo-dev/24-refactor-rsp-using-baseparty
refactor RSP as a BaseParty fragment with EPID as Party id
2 parents 3d3863f + d551ff9 commit 8a64c83

12 files changed

Lines changed: 61 additions & 83 deletions

File tree

documentation/domains/diffo_example_nbn.livemd

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ SPDX-License-Identifier: MIT
99
```elixir
1010
Mix.install(
1111
[
12-
{:diffo_example, "~> 0.2.0"},
12+
# {:diffo_example, "~> 0.3.0"},
13+
{:diffo_example, github: "diffo-dev/diffo_example", branch: "dev"},
14+
{:diffo, github: "diffo-dev/diffo", branch: "dev", override: true},
1315
{:kino, "~> 0.14"},
1416
{:req, "~> 0.5"}
1517
],
@@ -117,7 +119,9 @@ Speeds.speeds(:home_fast, :FixedWireless)
117119

118120
## Multi-tenancy
119121

120-
Each RSP operates in isolation — they can only see and manage the resources they own. This multi-tenancy is enforced at the Ash policy layer: every NBN resource is stamped with the owning RSP's id at creation, and subsequent reads, updates, and destroys are scoped to the record owner.
122+
Each RSP operates in isolation — they can only see and manage the resources they own. This multi-tenancy is enforced at the Ash policy layer: every NBN resource is stamped with the owning RSP's EPID at creation, and subsequent reads, updates, and destroys are scoped to the record owner.
123+
124+
RSP is modelled as a Party (using the `Diffo.Provider.BaseParty` fragment), with its EPID as the Party id. This means the `rsp_id` stamped on owned resources is a human-readable four-digit identifier rather than a UUID.
121125

122126
Select the RSP you want to operate as for the rest of this livebook. All resources you build will be owned by that RSP and isolated from resources owned by others.
123127

@@ -127,7 +131,7 @@ alias DiffoExample.Nbn.Rsp
127131
import Jason, only: [encode: 2]
128132
DiffoExample.Nbn.Initializer.init()
129133
rsps = Nbn.list_rsps!()
130-
Kino.DataTable.new(rsps, keys: [:epid, :name, :short_name, :state])
134+
Kino.DataTable.new(rsps, keys: [:id, :name, :short_name, :state])
131135
```
132136

133137
```elixir

lib/nbn/initializer.ex

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ defmodule DiffoExample.Nbn.Initializer do
1515
alias DiffoExample.Nbn
1616

1717
@rsps [
18-
%{name: "Wedge-tail Telecom", short_name: :wedgetail, epid: "0001"},
19-
%{name: "Quokka Connect", short_name: :quokka, epid: "0002"},
20-
%{name: "Ibis Telecom", short_name: :ibis, epid: "0003"},
21-
%{name: "Taipan Group", short_name: :taipan, epid: "0004"},
22-
%{name: "Echidna Networks", short_name: :echidna, epid: "0005"},
23-
%{name: "Dugong Digital", short_name: :dugong, epid: "0006"},
24-
%{name: "Lyrebird", short_name: :lyrebird, epid: "0007"}
18+
%{name: "Wedge-tail Telecom", short_name: :wedgetail, id: "0001"},
19+
%{name: "Quokka Connect", short_name: :quokka, id: "0002"},
20+
%{name: "Ibis Telecom", short_name: :ibis, id: "0003"},
21+
%{name: "Taipan Group", short_name: :taipan, id: "0004"},
22+
%{name: "Echidna Networks", short_name: :echidna, id: "0005"},
23+
%{name: "Dugong Digital", short_name: :dugong, id: "0006"},
24+
%{name: "Lyrebird", short_name: :lyrebird, id: "0007"}
2525
]
2626

2727
def init do
@@ -41,13 +41,13 @@ defmodule DiffoExample.Nbn.Initializer do
4141
defp seed_rsps do
4242
Enum.each(@rsps, fn attrs ->
4343
try do
44-
case Nbn.get_rsp_by_epid(attrs.epid) do
44+
case Nbn.get_rsp_by_epid(attrs.id) do
4545
{:ok, nil} -> seed_rsp(attrs)
4646
{:ok, _} -> :ok
4747
{:error, _} -> seed_rsp(attrs)
4848
end
4949
rescue
50-
e -> require Logger; Logger.error("Exception seeding RSP #{attrs.epid}: #{inspect(e)}")
50+
e -> require Logger; Logger.error("Exception seeding RSP #{attrs.id}: #{inspect(e)}")
5151
end
5252
end)
5353
end

lib/nbn/nbn.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,10 @@ defmodule DiffoExample.Nbn do
163163
end
164164

165165
resource Rsp do
166-
define :list_rsps, action: :list
167-
define :get_rsp_by_epid, action: :read, get_by: :epid
166+
define :list_rsps, action: :inventory
167+
define :get_rsp_by_epid, action: :read, get_by: :id
168168
define :get_rsp_by_short_name, action: :read, get_by: :short_name
169-
define :create_rsp, action: :create
169+
define :create_rsp, action: :build
170170
define :activate_rsp, action: :activate
171171
define :suspend_rsp, action: :suspend
172172
define :deactivate_rsp, action: :deactivate

lib/nbn/resources/avc.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ defmodule DiffoExample.Nbn.Avc do
4848
end
4949

5050
attributes do
51-
attribute :rsp_id, :uuid do
51+
attribute :rsp_id, :string do
5252
description "the owning RSP's id — nil for Perentie-managed infrastructure"
5353
allow_nil? true
5454
public? true

lib/nbn/resources/cvc.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ defmodule DiffoExample.Nbn.Cvc do
5252
end
5353

5454
attributes do
55-
attribute :rsp_id, :uuid do
55+
attribute :rsp_id, :string do
5656
description "the owning RSP's id — nil for Perentie-managed infrastructure"
5757
allow_nil? true
5858
public? true

lib/nbn/resources/nbn_ethernet.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ defmodule DiffoExample.Nbn.NbnEthernet do
5252
end
5353

5454
attributes do
55-
attribute :rsp_id, :uuid do
55+
attribute :rsp_id, :string do
5656
description "the owning RSP's id — nil for Perentie-managed infrastructure"
5757
allow_nil? true
5858
public? true

lib/nbn/resources/nni.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ defmodule DiffoExample.Nbn.Nni do
4848
end
4949

5050
attributes do
51-
attribute :rsp_id, :uuid do
51+
attribute :rsp_id, :string do
5252
description "the owning RSP's id — nil for Perentie-managed infrastructure"
5353
allow_nil? true
5454
public? true

lib/nbn/resources/nni_group.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ defmodule DiffoExample.Nbn.NniGroup do
5151
end
5252

5353
attributes do
54-
attribute :rsp_id, :uuid do
54+
attribute :rsp_id, :string do
5555
description "the owning RSP's id — nil for Perentie-managed infrastructure"
5656
allow_nil? true
5757
public? true

lib/nbn/resources/rsp.ex

Lines changed: 22 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,31 @@ defmodule DiffoExample.Nbn.Rsp do
1111
An RSP is a licensed provider operating within the Perentie ecosystem.
1212
Each RSP is assigned an EPID (four-digit regulator-assigned identifier)
1313
and a short_name atom used as their actor identity for authorisation.
14+
15+
RSP is a Party of kind :organization. The EPID is used as the Party id (Neo4j key).
1416
"""
1517

1618
alias DiffoExample.Nbn
1719

1820
use Ash.Resource,
1921
domain: Nbn,
20-
data_layer: AshNeo4j.DataLayer,
2122
authorizers: [Ash.Policy.Authorizer],
22-
extensions: [AshStateMachine, AshJason.Resource, AshJsonApi.Resource]
23-
24-
neo4j do
25-
label :Rsp
26-
end
23+
extensions: [AshStateMachine, AshJsonApi.Resource],
24+
fragments: [Diffo.Provider.BaseParty]
25+
26+
# BaseParty provides:
27+
# data_layer: AshNeo4j.DataLayer
28+
# extensions: AshJason.Resource, AshOutstanding.Resource, Diffo.Provider.Party.Extension
29+
# Neo4j label :Party (RSP nodes are Party nodes)
30+
# attributes: id (string/key), name, kind, created_at, updated_at
31+
# relationships: party_refs
32+
# actions: :read (primary), :destroy, :create (accept [:id,:name,:kind]),
33+
# :update (name), :list (unsorted), :find_by_name
2734

2835
json_api do
2936
type "rsp"
3037
end
3138

32-
jason do
33-
pick [:id, :name, :short_name, :epid, :state]
34-
compact true
35-
end
36-
3739
state_machine do
3840
initial_states [:inactive]
3941
default_initial_state :inactive
@@ -47,59 +49,32 @@ defmodule DiffoExample.Nbn.Rsp do
4749
end
4850

4951
attributes do
50-
attribute :id, :uuid do
51-
primary_key? true
52-
allow_nil? false
53-
public? true
54-
default &Ash.UUID.generate/0
55-
source :uuid
56-
end
57-
58-
attribute :name, :string do
59-
description "the RSP's registered trading name"
60-
allow_nil? false
61-
public? true
62-
end
63-
6452
attribute :short_name, :atom do
6553
description "atom identifier used as the actor for authorisation"
6654
allow_nil? false
6755
public? true
6856
end
6957

70-
attribute :epid, :string do
71-
description "four-digit regulator-assigned provider identifier, in historical sequence"
72-
allow_nil? false
73-
public? true
74-
constraints [match: ~r/^\d{4}$/]
75-
end
76-
7758
attribute :state, :atom do
7859
allow_nil? false
7960
default :inactive
8061
public? true
8162
constraints [one_of: [:active, :suspended, :inactive]]
8263
end
83-
84-
create_timestamp :created_at
85-
update_timestamp :updated_at
8664
end
8765

8866
actions do
89-
defaults [:destroy]
90-
91-
read :read do
92-
primary? true
93-
end
94-
95-
read :list do
96-
prepare build(sort: [epid: :asc])
67+
create :build do
68+
accept [:name, :short_name, :id]
69+
upsert? true
70+
change set_attribute(:kind, :organization)
71+
validate match(:id, ~r/^\d{4}$/) do
72+
message "must be a four-digit EPID"
73+
end
9774
end
9875

99-
create :create do
100-
accept [:name, :short_name, :epid]
101-
upsert? true
102-
upsert_identity :unique_epid
76+
read :inventory do
77+
prepare build(sort: [id: :asc])
10378
end
10479

10580
update :activate do
@@ -119,7 +94,6 @@ defmodule DiffoExample.Nbn.Rsp do
11994
end
12095

12196
identities do
122-
identity :unique_epid, [:epid]
12397
identity :unique_name, [:name]
12498
identity :unique_short_name, [:short_name]
12599
end

mix.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ defmodule DiffoExample.MixProject do
4545
nil -> default_version
4646
"local" -> [path: "../diffo"]
4747
"main" -> [git: "https://github.com/diffo-dev/diffo.git"]
48-
"0.2.0" -> [git: "https://github.com/diffo-dev/diffo.git", tag: "v0.2.0"]
48+
"dev" -> [git: "https://github.com/diffo-dev/diffo.git", branch: "dev"]
4949
version -> "~> #{version}"
5050
end
5151
end
@@ -86,7 +86,7 @@ defmodule DiffoExample.MixProject do
8686
# Run "mix help deps" to learn about dependencies.
8787
defp deps do
8888
[
89-
{:diffo, diffo_version("~> 0.2.0")},
89+
{:diffo, diffo_version([git: "https://github.com/diffo-dev/diffo.git", branch: "dev"])},
9090
{:ash_json_api, "~> 1.6"},
9191
{:plug_cowboy, "~> 2.7"},
9292
{:req, "~> 0.5", only: [:dev, :test]},

0 commit comments

Comments
 (0)