edoxen 0.8.1 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/edoxen/agenda_item.rb +6 -0
- data/lib/edoxen/body.rb +26 -0
- data/lib/edoxen/body_register.rb +17 -0
- data/lib/edoxen/cli.rb +4 -4
- data/lib/edoxen/contact.rb +3 -1
- data/lib/edoxen/{contact_collection.rb → contact_register.rb} +2 -2
- data/lib/edoxen/entity_resolver.rb +70 -0
- data/lib/edoxen/meeting.rb +5 -3
- data/lib/edoxen/urn_for.rb +68 -0
- data/lib/edoxen/venue.rb +3 -1
- data/lib/edoxen/{venue_collection.rb → venue_register.rb} +2 -2
- data/lib/edoxen/version.rb +1 -1
- data/lib/edoxen.rb +6 -2
- data/schema/edoxen.yaml +60 -9
- data/schema/meeting.yaml +73 -5
- metadata +8 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9be35dc39f7766b3bebb55769f484b13e4e0f43d5d29e4cdaba916dc64594a82
|
|
4
|
+
data.tar.gz: 1466534420ad8b83df31b1a84c1fe0c3e27e28a6f4529c190b4658c2622c4700
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4912179fadc07811533420e68c07edd374468369fd4f3ffa0135d2556e310ee1ed7f7c595a9241d6ac8378c6a62ea36e7673a0f9fa8ac0fe98d39668606475d9
|
|
7
|
+
data.tar.gz: 8cba6a15881824a1b6bef2e29e113fab969302b485ae1404e8100121cefddae44c435a529a999ed24ebae15eddb0bc757c3e9270ad19cde4e3d5530c6cd239c4
|
data/lib/edoxen/agenda_item.rb
CHANGED
|
@@ -6,10 +6,16 @@ module Edoxen
|
|
|
6
6
|
# closing/aob; `outcome` records what happened; `decision_ref`
|
|
7
7
|
# optionally links to the URN of the decision this item produced.
|
|
8
8
|
#
|
|
9
|
+
# `urn` is the first-class URN of this item, derived from the parent
|
|
10
|
+
# meeting URN and the label (e.g. "urn:oiml:ciml:meeting:ciml-60:agenda:6.2").
|
|
11
|
+
# It is optional in source data — when absent it can be computed on
|
|
12
|
+
# the fly via {Edoxen::UrnFor.agenda_item}.
|
|
13
|
+
#
|
|
9
14
|
# Topics (0..*) are the subject(s) of discussion at this agenda item.
|
|
10
15
|
# AOB (Any Other Business) items have 0 topics until raised during
|
|
11
16
|
# the meeting.
|
|
12
17
|
class AgendaItem < Lutaml::Model::Serializable
|
|
18
|
+
attribute :urn, :string
|
|
13
19
|
attribute :label, :string
|
|
14
20
|
attribute :kind, :string, values: Enums::AGENDA_ITEM_KIND
|
|
15
21
|
attribute :title, LocalizedString, collection: true
|
data/lib/edoxen/body.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Edoxen
|
|
4
|
+
# A committee, subcommittee, working group, or other organised body
|
|
5
|
+
# that owns meetings and decisions. Carries a short code (e.g.
|
|
6
|
+
# "ISO/TC 154", "CIML") and a localised full name.
|
|
7
|
+
#
|
|
8
|
+
# Three-tier entity resolution (same pattern as Contact and Venue):
|
|
9
|
+
# +ref+ set → resolve from global BodyRegister by URN.
|
|
10
|
+
# +local_ref+ set → resolve from document-scoped Meeting#bodies[].
|
|
11
|
+
# Both nil → inline data.
|
|
12
|
+
class Body < Lutaml::Model::Serializable
|
|
13
|
+
attribute :ref, :string
|
|
14
|
+
attribute :local_ref, :string
|
|
15
|
+
attribute :code, :string
|
|
16
|
+
attribute :name, LocalizedString, collection: true
|
|
17
|
+
attribute :kind, :string
|
|
18
|
+
attribute :parent_ref, EntityRef
|
|
19
|
+
attribute :extensions, MeetingExtension, collection: true
|
|
20
|
+
|
|
21
|
+
def reference?
|
|
22
|
+
(!ref.nil? && !ref.to_s.empty?) ||
|
|
23
|
+
(!local_ref.nil? && !local_ref.to_s.empty?)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Edoxen
|
|
4
|
+
# Authoritative register of Bodies (committees, subcommittees, working
|
|
5
|
+
# groups). Members carry `urn: urn:edoxen:body:{scope}:{local-id}`;
|
|
6
|
+
# the register's +scope+ MUST match the scope segment in member URNs.
|
|
7
|
+
class BodyRegister < Lutaml::Model::Serializable
|
|
8
|
+
attribute :scope, :string
|
|
9
|
+
attribute :title, LocalizedString, collection: true
|
|
10
|
+
attribute :bodies, Body, collection: true
|
|
11
|
+
attribute :extensions, MeetingExtension, collection: true
|
|
12
|
+
|
|
13
|
+
def find_by_urn(urn)
|
|
14
|
+
bodies&.find { |b| b.code == urn || b.ref == urn }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/edoxen/cli.rb
CHANGED
|
@@ -34,8 +34,8 @@ module Edoxen
|
|
|
34
34
|
lambda do |content|
|
|
35
35
|
data = YAML.safe_load(content, permitted_classes: [Date, Time])
|
|
36
36
|
case Batch.decision_kind(data)
|
|
37
|
-
when :contacts then
|
|
38
|
-
when :venues then
|
|
37
|
+
when :contacts then ContactRegister.from_yaml(content)
|
|
38
|
+
when :venues then VenueRegister.from_yaml(content)
|
|
39
39
|
else DecisionCollection.from_yaml(content)
|
|
40
40
|
end
|
|
41
41
|
end
|
|
@@ -78,8 +78,8 @@ module Edoxen
|
|
|
78
78
|
# Discriminate the three top-level shapes the canonical
|
|
79
79
|
# `schema/edoxen.yaml` accepts via `oneOf`:
|
|
80
80
|
#
|
|
81
|
-
# * :contacts — `{ contacts: [...] }` (
|
|
82
|
-
# * :venues — `{ venues: [...] }` (
|
|
81
|
+
# * :contacts — `{ contacts: [...] }` (ContactRegister registry).
|
|
82
|
+
# * :venues — `{ venues: [...] }` (VenueRegister registry).
|
|
83
83
|
# * :decisions — anything else (DecisionCollection, the default).
|
|
84
84
|
def decision_kind(data)
|
|
85
85
|
return :decisions unless data.is_a?(Hash)
|
data/lib/edoxen/contact.rb
CHANGED
|
@@ -17,6 +17,7 @@ module Edoxen
|
|
|
17
17
|
# accepts a Contact.
|
|
18
18
|
class Contact < Lutaml::Model::Serializable
|
|
19
19
|
attribute :ref, :string
|
|
20
|
+
attribute :local_ref, :string
|
|
20
21
|
attribute :urn, :string
|
|
21
22
|
attribute :name, LocalizedName, collection: true
|
|
22
23
|
attribute :kind, :string
|
|
@@ -29,7 +30,8 @@ module Edoxen
|
|
|
29
30
|
attribute :extensions, MeetingExtension, collection: true
|
|
30
31
|
|
|
31
32
|
def reference?
|
|
32
|
-
!ref.nil? && !ref.to_s.empty?
|
|
33
|
+
(!ref.nil? && !ref.to_s.empty?) ||
|
|
34
|
+
(!local_ref.nil? && !local_ref.to_s.empty?)
|
|
33
35
|
end
|
|
34
36
|
end
|
|
35
37
|
end
|
|
@@ -7,13 +7,13 @@ module Edoxen
|
|
|
7
7
|
#
|
|
8
8
|
# Other documents (Meeting, MeetingComponent, HostRef, etc.) reference
|
|
9
9
|
# contacts via `ref: urn:edoxen:contact:{scope}:{local-id}` and
|
|
10
|
-
# resolve against the matching
|
|
10
|
+
# resolve against the matching ContactRegister.
|
|
11
11
|
#
|
|
12
12
|
# Storage: single YAML file (typical) or YAML Stream (one Contact per
|
|
13
13
|
# document, for large registries that need partial updates). Stream
|
|
14
14
|
# loading is a service-layer concern (file-system I/O); the model
|
|
15
15
|
# owns only the (de)serialisation of one collection.
|
|
16
|
-
class
|
|
16
|
+
class ContactRegister < Lutaml::Model::Serializable
|
|
17
17
|
attribute :scope, :string
|
|
18
18
|
attribute :title, LocalizedString, collection: true
|
|
19
19
|
attribute :contacts, Contact, collection: true
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Edoxen
|
|
4
|
+
# EntityResolver — resolves Contact/Venue/Body references by walking
|
|
5
|
+
# the three-tier scope hierarchy:
|
|
6
|
+
#
|
|
7
|
+
# 1. Inline: if the entity has no +ref+ and no +local_ref+, return
|
|
8
|
+
# it as-is (it carries full data).
|
|
9
|
+
# 2. Document-scoped: if +local_ref+ is set, look up in the
|
|
10
|
+
# document-scoped collection (e.g. Meeting#contacts) by matching
|
|
11
|
+
# +urn+ against +local_ref+ (+code+ for Body, which has no +urn+).
|
|
12
|
+
# 3. Global register: if +ref+ is set, look up in the global
|
|
13
|
+
# register (e.g. ContactRegister) by matching +urn+ against +ref+.
|
|
14
|
+
#
|
|
15
|
+
# Pure service: no mutation. Returns the resolved entity or nil.
|
|
16
|
+
class EntityResolver
|
|
17
|
+
attr_reader :scoped_collections, :global_registers
|
|
18
|
+
|
|
19
|
+
def initialize(scoped: {}, registers: {})
|
|
20
|
+
@scoped_collections = scoped
|
|
21
|
+
@global_registers = registers
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def resolve(entity)
|
|
25
|
+
return entity unless entity.reference?
|
|
26
|
+
|
|
27
|
+
resolve_local(entity) || resolve_global(entity)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def resolve_all(entities)
|
|
31
|
+
entities.map { |e| resolve(e) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def resolve_local(entity)
|
|
37
|
+
return nil if entity.local_ref.nil? || entity.local_ref.to_s.empty?
|
|
38
|
+
|
|
39
|
+
collection = find_scoped_collection(entity.class)
|
|
40
|
+
return nil unless collection
|
|
41
|
+
|
|
42
|
+
collection.find { |member| member_key(member) == entity.local_ref }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def resolve_global(entity)
|
|
46
|
+
return nil if entity.ref.nil? || entity.ref.to_s.empty?
|
|
47
|
+
|
|
48
|
+
register = find_global_register(entity.class)
|
|
49
|
+
return nil unless register
|
|
50
|
+
|
|
51
|
+
register.find_by_urn(entity.ref)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def find_scoped_collection(klass)
|
|
55
|
+
@scoped_collections[klass] ||
|
|
56
|
+
@scoped_collections[klass.superclass]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def find_global_register(klass)
|
|
60
|
+
@global_registers[klass] ||
|
|
61
|
+
@global_registers[klass.superclass]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def member_key(member)
|
|
65
|
+
# Body has no +urn+ — its local key is +code+ (same lookup
|
|
66
|
+
# semantics as BodyRegister#find_by_urn).
|
|
67
|
+
member.respond_to?(:urn) ? member.urn : member.code
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
data/lib/edoxen/meeting.rb
CHANGED
|
@@ -33,8 +33,8 @@ module Edoxen
|
|
|
33
33
|
attribute :city, :string
|
|
34
34
|
attribute :country_code, :string
|
|
35
35
|
|
|
36
|
-
attribute :committee,
|
|
37
|
-
attribute :committee_group,
|
|
36
|
+
attribute :committee, Body
|
|
37
|
+
attribute :committee_group, Body
|
|
38
38
|
|
|
39
39
|
attribute :officers, Officer, collection: true
|
|
40
40
|
attribute :hosts, HostRef, collection: true
|
|
@@ -44,6 +44,8 @@ module Edoxen
|
|
|
44
44
|
attribute :registration_url, :string
|
|
45
45
|
attribute :note, LocalizedString, collection: true
|
|
46
46
|
attribute :contact, Contact
|
|
47
|
+
attribute :contacts, Contact, collection: true
|
|
48
|
+
attribute :bodies, Body, collection: true
|
|
47
49
|
|
|
48
50
|
attribute :agenda, Agenda
|
|
49
51
|
attribute :components, MeetingComponent, collection: true
|
|
@@ -54,7 +56,7 @@ module Edoxen
|
|
|
54
56
|
attribute :declarations, Declaration, collection: true
|
|
55
57
|
|
|
56
58
|
# Outcomes (canonical location on Meeting)
|
|
57
|
-
attribute :decisions,
|
|
59
|
+
attribute :decisions, StructuredIdentifier, collection: true
|
|
58
60
|
attribute :motions, Motion, collection: true
|
|
59
61
|
attribute :votings, Voting, collection: true
|
|
60
62
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Edoxen
|
|
4
|
+
# URN helpers for entities that don't carry their URN inline (e.g.
|
|
5
|
+
# AgendaItem which derives its URN from the parent Meeting). The
|
|
6
|
+
# scheme is hierarchical:
|
|
7
|
+
#
|
|
8
|
+
# urn:oiml:{body}:{kind}:{slug}(:{sub-kind}:{sub-id})*
|
|
9
|
+
#
|
|
10
|
+
# Examples:
|
|
11
|
+
# urn:oiml:ciml:meeting:ciml-60
|
|
12
|
+
# urn:oiml:ciml:meeting:ciml-60:agenda:6.2
|
|
13
|
+
# urn:oiml:doc:ciml:resolution:2025-01
|
|
14
|
+
#
|
|
15
|
+
# Use {UrnFor.agenda_item} to compute an agenda item URN from its
|
|
16
|
+
# parent meeting URN + label, and {UrnFor.parse} to decompose one.
|
|
17
|
+
module UrnFor
|
|
18
|
+
AGENDA_SEGMENT = "agenda"
|
|
19
|
+
SEGMENT_RE = /[^:]+/
|
|
20
|
+
|
|
21
|
+
# Build an AgendaItem URN from its parent Meeting URN and the
|
|
22
|
+
# agenda item label (e.g. "6.2"). Returns nil if either input is
|
|
23
|
+
# blank so callers can use this as a default-value generator
|
|
24
|
+
# without raising.
|
|
25
|
+
def self.agenda_item(meeting_urn:, label:)
|
|
26
|
+
m = meeting_urn.to_s
|
|
27
|
+
l = label.to_s
|
|
28
|
+
return nil if m.empty? || l.empty?
|
|
29
|
+
|
|
30
|
+
"#{m}:#{AGENDA_SEGMENT}:#{l}"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Parse an agenda item URN into its component parts. Returns a Hash
|
|
34
|
+
# with :meeting_urn and :label keys, or nil if the URN doesn't
|
|
35
|
+
# match the expected shape.
|
|
36
|
+
#
|
|
37
|
+
# UrnFor.parse("urn:oiml:ciml:meeting:ciml-60:agenda:6.2")
|
|
38
|
+
# # => { meeting_urn: "urn:oiml:ciml:meeting:ciml-60",
|
|
39
|
+
# # label: "6.2" }
|
|
40
|
+
def self.parse(urn)
|
|
41
|
+
return nil unless urn
|
|
42
|
+
|
|
43
|
+
s = urn.to_s
|
|
44
|
+
idx = s.rindex(":#{AGENDA_SEGMENT}:")
|
|
45
|
+
return nil unless idx
|
|
46
|
+
|
|
47
|
+
meeting_urn = s[0...idx]
|
|
48
|
+
label = s[(idx + AGENDA_SEGMENT.length + 2)..]
|
|
49
|
+
return nil if meeting_urn.empty? || label.to_s.empty?
|
|
50
|
+
|
|
51
|
+
{ meeting_urn: meeting_urn, label: label }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Walk an Agenda tree and set each item's `urn` based on the
|
|
55
|
+
# parent meeting URN. Skips items that already have a URN. Useful
|
|
56
|
+
# as a backfill step in data-fix scripts.
|
|
57
|
+
def self.assign_to_agenda!(agenda, meeting_urn)
|
|
58
|
+
return nil unless agenda && meeting_urn
|
|
59
|
+
|
|
60
|
+
(agenda.items || []).each do |item|
|
|
61
|
+
next if item.urn && !item.urn.to_s.empty?
|
|
62
|
+
|
|
63
|
+
item.urn = agenda_item(meeting_urn: meeting_urn, label: item.label)
|
|
64
|
+
end
|
|
65
|
+
agenda
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
data/lib/edoxen/venue.rb
CHANGED
|
@@ -13,6 +13,7 @@ module Edoxen
|
|
|
13
13
|
# - Added: `urn` for registry storage; `ref` for reference-by-URN.
|
|
14
14
|
class Venue < Lutaml::Model::Serializable
|
|
15
15
|
attribute :ref, :string
|
|
16
|
+
attribute :local_ref, :string
|
|
16
17
|
attribute :urn, :string
|
|
17
18
|
attribute :kind, :string, values: Enums::VENUE_KIND
|
|
18
19
|
attribute :name, LocalizedString, collection: true
|
|
@@ -47,7 +48,8 @@ module Edoxen
|
|
|
47
48
|
attribute :extensions, MeetingExtension, collection: true
|
|
48
49
|
|
|
49
50
|
def reference?
|
|
50
|
-
!ref.nil? && !ref.to_s.empty?
|
|
51
|
+
(!ref.nil? && !ref.to_s.empty?) ||
|
|
52
|
+
(!local_ref.nil? && !local_ref.to_s.empty?)
|
|
51
53
|
end
|
|
52
54
|
|
|
53
55
|
def physical?
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Edoxen
|
|
4
|
-
# Registry of Venues indexed by scoped URN. Mirrors
|
|
4
|
+
# Registry of Venues indexed by scoped URN. Mirrors ContactRegister:
|
|
5
5
|
# members carry `urn: urn:edoxen:venue:{scope}:{local-id}`; the
|
|
6
6
|
# collection's `scope` MUST match the scope segment in member URNs.
|
|
7
7
|
# Stream loading belongs to the service layer.
|
|
8
|
-
class
|
|
8
|
+
class VenueRegister < Lutaml::Model::Serializable
|
|
9
9
|
attribute :scope, :string
|
|
10
10
|
attribute :title, LocalizedString, collection: true
|
|
11
11
|
attribute :venues, Venue, collection: true
|
data/lib/edoxen/version.rb
CHANGED
data/lib/edoxen.rb
CHANGED
|
@@ -38,6 +38,7 @@ module Edoxen
|
|
|
38
38
|
autoload :Consideration, "edoxen/consideration"
|
|
39
39
|
autoload :SourceUrl, "edoxen/source_url"
|
|
40
40
|
autoload :Url, "edoxen/url"
|
|
41
|
+
autoload :UrnFor, "edoxen/urn_for"
|
|
41
42
|
autoload :DecisionRelation, "edoxen/decision_relation"
|
|
42
43
|
autoload :Decision, "edoxen/decision"
|
|
43
44
|
autoload :DecisionMetadata, "edoxen/decision_metadata"
|
|
@@ -91,11 +92,14 @@ module Edoxen
|
|
|
91
92
|
autoload :MeetingComponent, "edoxen/meeting_component"
|
|
92
93
|
autoload :Officer, "edoxen/officer"
|
|
93
94
|
autoload :VenueValidator, "edoxen/venue_validator"
|
|
94
|
-
autoload :
|
|
95
|
-
autoload :
|
|
95
|
+
autoload :ContactRegister, "edoxen/contact_register"
|
|
96
|
+
autoload :VenueRegister, "edoxen/venue_register"
|
|
97
|
+
autoload :Body, "edoxen/body"
|
|
98
|
+
autoload :BodyRegister, "edoxen/body_register"
|
|
96
99
|
|
|
97
100
|
# --- Services ---------------------------------------------------------
|
|
98
101
|
autoload :SchemaValidator, "edoxen/schema_validator"
|
|
99
102
|
autoload :LinkChecker, "edoxen/link_checker"
|
|
103
|
+
autoload :EntityResolver, "edoxen/entity_resolver"
|
|
100
104
|
autoload :Cli, "edoxen/cli"
|
|
101
105
|
end
|
data/schema/edoxen.yaml
CHANGED
|
@@ -8,8 +8,8 @@ description: |
|
|
|
8
8
|
Accepts three top-level document kinds via `oneOf`:
|
|
9
9
|
|
|
10
10
|
* `DecisionCollection` — the formal outcomes adopted by a Meeting.
|
|
11
|
-
* `
|
|
12
|
-
* `
|
|
11
|
+
* `ContactRegister` — a scoped-URN registry of Contacts.
|
|
12
|
+
* `VenueRegister` — a scoped-URN registry of Venues.
|
|
13
13
|
|
|
14
14
|
Mirrors the canonical LutaML information model in
|
|
15
15
|
https://github.com/edoxen/edoxen-model/tree/main/models .
|
|
@@ -26,8 +26,9 @@ description: |
|
|
|
26
26
|
type: object
|
|
27
27
|
oneOf:
|
|
28
28
|
- "$ref": "#/$defs/DecisionCollection"
|
|
29
|
-
- "$ref": "#/$defs/
|
|
30
|
-
- "$ref": "#/$defs/
|
|
29
|
+
- "$ref": "#/$defs/ContactRegister"
|
|
30
|
+
- "$ref": "#/$defs/VenueRegister"
|
|
31
|
+
- "$ref": "#/$defs/BodyRegister"
|
|
31
32
|
"$defs":
|
|
32
33
|
DecisionCollection:
|
|
33
34
|
type: object
|
|
@@ -569,7 +570,8 @@ oneOf:
|
|
|
569
570
|
properties:
|
|
570
571
|
ref:
|
|
571
572
|
type: string
|
|
572
|
-
|
|
573
|
+
local_ref:
|
|
574
|
+
type: string
|
|
573
575
|
urn:
|
|
574
576
|
type: string
|
|
575
577
|
pattern: "^urn:edoxen:venue:[^:]+:[^:]+$"
|
|
@@ -877,7 +879,8 @@ oneOf:
|
|
|
877
879
|
properties:
|
|
878
880
|
ref:
|
|
879
881
|
type: string
|
|
880
|
-
|
|
882
|
+
local_ref:
|
|
883
|
+
type: string
|
|
881
884
|
urn:
|
|
882
885
|
type: string
|
|
883
886
|
pattern: "^urn:edoxen:contact:[^:]+:[^:]+$"
|
|
@@ -923,6 +926,8 @@ oneOf:
|
|
|
923
926
|
properties:
|
|
924
927
|
ref:
|
|
925
928
|
type: string
|
|
929
|
+
local_ref:
|
|
930
|
+
type: string
|
|
926
931
|
urn:
|
|
927
932
|
type: string
|
|
928
933
|
pattern: "^urn:edoxen:contact:[^:]+:[^:]+$"
|
|
@@ -1123,7 +1128,7 @@ oneOf:
|
|
|
1123
1128
|
type: string
|
|
1124
1129
|
contact:
|
|
1125
1130
|
"$ref": "#/$defs/Contact"
|
|
1126
|
-
|
|
1131
|
+
ContactRegister:
|
|
1127
1132
|
type: object
|
|
1128
1133
|
description: |
|
|
1129
1134
|
Registry of Contacts indexed by scoped URN. Members carry
|
|
@@ -1145,9 +1150,9 @@ oneOf:
|
|
|
1145
1150
|
type: array
|
|
1146
1151
|
items:
|
|
1147
1152
|
"$ref": "#/$defs/MeetingExtension"
|
|
1148
|
-
|
|
1153
|
+
VenueRegister:
|
|
1149
1154
|
type: object
|
|
1150
|
-
description: 'Registry of Venues indexed by scoped URN. Mirrors
|
|
1155
|
+
description: 'Registry of Venues indexed by scoped URN. Mirrors ContactRegister.
|
|
1151
1156
|
|
|
1152
1157
|
'
|
|
1153
1158
|
additionalProperties: false
|
|
@@ -1518,3 +1523,49 @@ oneOf:
|
|
|
1518
1523
|
type: array
|
|
1519
1524
|
items:
|
|
1520
1525
|
"$ref": "#/$defs/MeetingExtension"
|
|
1526
|
+
Body:
|
|
1527
|
+
type: object
|
|
1528
|
+
description: |
|
|
1529
|
+
A committee, subcommittee, working group, or other organised body.
|
|
1530
|
+
Three-tier entity resolution (ref / local_ref / inline).
|
|
1531
|
+
additionalProperties: false
|
|
1532
|
+
properties:
|
|
1533
|
+
ref:
|
|
1534
|
+
type: string
|
|
1535
|
+
local_ref:
|
|
1536
|
+
type: string
|
|
1537
|
+
code:
|
|
1538
|
+
type: string
|
|
1539
|
+
name:
|
|
1540
|
+
type: array
|
|
1541
|
+
items:
|
|
1542
|
+
"$ref": "#/$defs/LocalizedString"
|
|
1543
|
+
kind:
|
|
1544
|
+
type: string
|
|
1545
|
+
parent_ref:
|
|
1546
|
+
"$ref": "#/$defs/EntityRef"
|
|
1547
|
+
extensions:
|
|
1548
|
+
type: array
|
|
1549
|
+
items:
|
|
1550
|
+
"$ref": "#/$defs/MeetingExtension"
|
|
1551
|
+
BodyRegister:
|
|
1552
|
+
type: object
|
|
1553
|
+
description: |
|
|
1554
|
+
Authoritative register of Bodies (committees, subcommittees,
|
|
1555
|
+
working groups).
|
|
1556
|
+
additionalProperties: false
|
|
1557
|
+
properties:
|
|
1558
|
+
scope:
|
|
1559
|
+
type: string
|
|
1560
|
+
title:
|
|
1561
|
+
type: array
|
|
1562
|
+
items:
|
|
1563
|
+
"$ref": "#/$defs/LocalizedString"
|
|
1564
|
+
bodies:
|
|
1565
|
+
type: array
|
|
1566
|
+
items:
|
|
1567
|
+
"$ref": "#/$defs/Body"
|
|
1568
|
+
extensions:
|
|
1569
|
+
type: array
|
|
1570
|
+
items:
|
|
1571
|
+
"$ref": "#/$defs/MeetingExtension"
|
data/schema/meeting.yaml
CHANGED
|
@@ -215,7 +215,8 @@ oneOf:
|
|
|
215
215
|
properties:
|
|
216
216
|
ref:
|
|
217
217
|
type: string
|
|
218
|
-
|
|
218
|
+
local_ref:
|
|
219
|
+
type: string
|
|
219
220
|
urn:
|
|
220
221
|
type: string
|
|
221
222
|
pattern: "^urn:edoxen:contact:[^:]+:[^:]+$"
|
|
@@ -261,6 +262,8 @@ oneOf:
|
|
|
261
262
|
properties:
|
|
262
263
|
ref:
|
|
263
264
|
type: string
|
|
265
|
+
local_ref:
|
|
266
|
+
type: string
|
|
264
267
|
urn:
|
|
265
268
|
type: string
|
|
266
269
|
pattern: "^urn:edoxen:contact:[^:]+:[^:]+$"
|
|
@@ -449,9 +452,19 @@ oneOf:
|
|
|
449
452
|
"$ref": "#/$defs/LocalizedString"
|
|
450
453
|
AgendaItem:
|
|
451
454
|
type: object
|
|
452
|
-
description:
|
|
455
|
+
description: |
|
|
456
|
+
One entry on an Agenda. 1.0: per-field Localized.
|
|
457
|
+
`urn` is the first-class URN of this item, derived from the
|
|
458
|
+
parent meeting URN and label (e.g.
|
|
459
|
+
`urn:oiml:ciml:meeting:ciml-60:agenda:6.2`). Optional in source
|
|
460
|
+
data; can be computed via `Edoxen::UrnFor.agenda_item`.
|
|
453
461
|
additionalProperties: false
|
|
454
462
|
properties:
|
|
463
|
+
urn:
|
|
464
|
+
type: string
|
|
465
|
+
description: |
|
|
466
|
+
First-class URN for this agenda item. Hierarchical under the
|
|
467
|
+
parent meeting URN: `urn:oiml:{body}:meeting:{slug}:agenda:{label}`.
|
|
455
468
|
label:
|
|
456
469
|
type: string
|
|
457
470
|
kind:
|
|
@@ -619,7 +632,8 @@ oneOf:
|
|
|
619
632
|
properties:
|
|
620
633
|
ref:
|
|
621
634
|
type: string
|
|
622
|
-
|
|
635
|
+
local_ref:
|
|
636
|
+
type: string
|
|
623
637
|
urn:
|
|
624
638
|
type: string
|
|
625
639
|
pattern: "^urn:edoxen:venue:[^:]+:[^:]+$"
|
|
@@ -1003,9 +1017,9 @@ oneOf:
|
|
|
1003
1017
|
type: string
|
|
1004
1018
|
pattern: "^[A-Z]{2}$"
|
|
1005
1019
|
committee:
|
|
1006
|
-
|
|
1020
|
+
"$ref": "#/$defs/Body"
|
|
1007
1021
|
committee_group:
|
|
1008
|
-
|
|
1022
|
+
"$ref": "#/$defs/Body"
|
|
1009
1023
|
officers:
|
|
1010
1024
|
type: array
|
|
1011
1025
|
items:
|
|
@@ -1028,6 +1042,14 @@ oneOf:
|
|
|
1028
1042
|
"$ref": "#/$defs/LocalizedString"
|
|
1029
1043
|
contact:
|
|
1030
1044
|
"$ref": "#/$defs/Contact"
|
|
1045
|
+
contacts:
|
|
1046
|
+
type: array
|
|
1047
|
+
items:
|
|
1048
|
+
"$ref": "#/$defs/Contact"
|
|
1049
|
+
bodies:
|
|
1050
|
+
type: array
|
|
1051
|
+
items:
|
|
1052
|
+
"$ref": "#/$defs/Body"
|
|
1031
1053
|
agenda:
|
|
1032
1054
|
"$ref": "#/$defs/Agenda"
|
|
1033
1055
|
components:
|
|
@@ -1413,3 +1435,49 @@ oneOf:
|
|
|
1413
1435
|
type: array
|
|
1414
1436
|
items:
|
|
1415
1437
|
"$ref": "#/$defs/MeetingExtension"
|
|
1438
|
+
Body:
|
|
1439
|
+
type: object
|
|
1440
|
+
description: |
|
|
1441
|
+
A committee, subcommittee, working group, or other organised body.
|
|
1442
|
+
Three-tier entity resolution (ref / local_ref / inline).
|
|
1443
|
+
additionalProperties: false
|
|
1444
|
+
properties:
|
|
1445
|
+
ref:
|
|
1446
|
+
type: string
|
|
1447
|
+
local_ref:
|
|
1448
|
+
type: string
|
|
1449
|
+
code:
|
|
1450
|
+
type: string
|
|
1451
|
+
name:
|
|
1452
|
+
type: array
|
|
1453
|
+
items:
|
|
1454
|
+
"$ref": "#/$defs/LocalizedString"
|
|
1455
|
+
kind:
|
|
1456
|
+
type: string
|
|
1457
|
+
parent_ref:
|
|
1458
|
+
"$ref": "#/$defs/EntityRef"
|
|
1459
|
+
extensions:
|
|
1460
|
+
type: array
|
|
1461
|
+
items:
|
|
1462
|
+
"$ref": "#/$defs/MeetingExtension"
|
|
1463
|
+
BodyRegister:
|
|
1464
|
+
type: object
|
|
1465
|
+
description: |
|
|
1466
|
+
Authoritative register of Bodies (committees, subcommittees,
|
|
1467
|
+
working groups).
|
|
1468
|
+
additionalProperties: false
|
|
1469
|
+
properties:
|
|
1470
|
+
scope:
|
|
1471
|
+
type: string
|
|
1472
|
+
title:
|
|
1473
|
+
type: array
|
|
1474
|
+
items:
|
|
1475
|
+
"$ref": "#/$defs/LocalizedString"
|
|
1476
|
+
bodies:
|
|
1477
|
+
type: array
|
|
1478
|
+
items:
|
|
1479
|
+
"$ref": "#/$defs/Body"
|
|
1480
|
+
extensions:
|
|
1481
|
+
type: array
|
|
1482
|
+
items:
|
|
1483
|
+
"$ref": "#/$defs/MeetingExtension"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: edoxen
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: json_schemer
|
|
@@ -121,14 +121,16 @@ files:
|
|
|
121
121
|
- lib/edoxen/agenda_item.rb
|
|
122
122
|
- lib/edoxen/approval.rb
|
|
123
123
|
- lib/edoxen/attendance.rb
|
|
124
|
+
- lib/edoxen/body.rb
|
|
125
|
+
- lib/edoxen/body_register.rb
|
|
124
126
|
- lib/edoxen/body_vocabulary_entry.rb
|
|
125
127
|
- lib/edoxen/body_vocabulary_host.rb
|
|
126
128
|
- lib/edoxen/cli.rb
|
|
127
129
|
- lib/edoxen/consideration.rb
|
|
128
130
|
- lib/edoxen/contact.rb
|
|
129
|
-
- lib/edoxen/contact_collection.rb
|
|
130
131
|
- lib/edoxen/contact_identifier.rb
|
|
131
132
|
- lib/edoxen/contact_method.rb
|
|
133
|
+
- lib/edoxen/contact_register.rb
|
|
132
134
|
- lib/edoxen/date_range.rb
|
|
133
135
|
- lib/edoxen/date_time_range.rb
|
|
134
136
|
- lib/edoxen/deadline.rb
|
|
@@ -139,6 +141,7 @@ files:
|
|
|
139
141
|
- lib/edoxen/decision_relation.rb
|
|
140
142
|
- lib/edoxen/declaration.rb
|
|
141
143
|
- lib/edoxen/entity_ref.rb
|
|
144
|
+
- lib/edoxen/entity_resolver.rb
|
|
142
145
|
- lib/edoxen/enums.rb
|
|
143
146
|
- lib/edoxen/error.rb
|
|
144
147
|
- lib/edoxen/extension_attribute.rb
|
|
@@ -174,8 +177,9 @@ files:
|
|
|
174
177
|
- lib/edoxen/topic_asset.rb
|
|
175
178
|
- lib/edoxen/topic_document.rb
|
|
176
179
|
- lib/edoxen/url.rb
|
|
180
|
+
- lib/edoxen/urn_for.rb
|
|
177
181
|
- lib/edoxen/venue.rb
|
|
178
|
-
- lib/edoxen/
|
|
182
|
+
- lib/edoxen/venue_register.rb
|
|
179
183
|
- lib/edoxen/venue_validator.rb
|
|
180
184
|
- lib/edoxen/version.rb
|
|
181
185
|
- lib/edoxen/virtual_venue.rb
|