hdo-storting-importer 0.0.8 → 0.0.9

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.
Files changed (50) hide show
  1. data/Gemfile +1 -1
  2. data/Rakefile +0 -1
  3. data/features/convert.feature +97 -79
  4. data/hdo-storting-importer.gemspec +5 -0
  5. data/lib/hdo/storting_importer/category.rb +16 -56
  6. data/lib/hdo/storting_importer/cli.rb +6 -34
  7. data/lib/hdo/storting_importer/committee.rb +13 -24
  8. data/lib/hdo/storting_importer/converter.rb +4 -9
  9. data/lib/hdo/storting_importer/district.rb +12 -24
  10. data/lib/hdo/storting_importer/fusion_table.rb +52 -0
  11. data/lib/hdo/storting_importer/has_json_schema.rb +85 -0
  12. data/lib/hdo/storting_importer/issue.rb +29 -60
  13. data/lib/hdo/storting_importer/party.rb +13 -24
  14. data/lib/hdo/storting_importer/promise.rb +60 -55
  15. data/lib/hdo/storting_importer/proposition.rb +61 -0
  16. data/lib/hdo/storting_importer/representative.rb +37 -70
  17. data/lib/hdo/storting_importer/schema/category.json +28 -0
  18. data/lib/hdo/storting_importer/schema/committee.json +21 -0
  19. data/lib/hdo/storting_importer/schema/district.json +21 -0
  20. data/lib/hdo/storting_importer/schema/issue.json +62 -0
  21. data/lib/hdo/storting_importer/schema/party.json +21 -0
  22. data/lib/hdo/storting_importer/schema/promise.json +42 -0
  23. data/lib/hdo/storting_importer/schema/proposition.json +34 -0
  24. data/lib/hdo/storting_importer/schema/representative.json +61 -0
  25. data/lib/hdo/storting_importer/schema/vote.json +64 -0
  26. data/lib/hdo/storting_importer/schema.json +5 -0
  27. data/lib/hdo/storting_importer/util.rb +13 -11
  28. data/lib/hdo/storting_importer/version.rb +1 -1
  29. data/lib/hdo/storting_importer/vote.rb +46 -143
  30. data/lib/hdo/storting_importer.rb +12 -3
  31. data/spec/fixtures/output/categories.json +1 -0
  32. data/spec/fixtures/output/committees.json +1 -0
  33. data/spec/fixtures/output/districts.json +1 -0
  34. data/spec/fixtures/output/issues.json +1 -0
  35. data/spec/fixtures/output/parties.json +1 -0
  36. data/spec/fixtures/output/representatives.json +1 -0
  37. data/spec/fixtures/output/votes.json +1 -0
  38. data/spec/hdo/storting_importer/category_spec.rb +29 -33
  39. data/spec/hdo/storting_importer/committee_spec.rb +29 -16
  40. data/spec/hdo/storting_importer/converter_spec.rb +3 -3
  41. data/spec/hdo/storting_importer/district_spec.rb +27 -18
  42. data/spec/hdo/storting_importer/issue_spec.rb +44 -27
  43. data/spec/hdo/storting_importer/party_spec.rb +25 -16
  44. data/spec/hdo/storting_importer/promise_spec.rb +54 -40
  45. data/spec/hdo/storting_importer/proposition_spec.rb +44 -0
  46. data/spec/hdo/storting_importer/representative_spec.rb +73 -26
  47. data/spec/hdo/storting_importer/vote_spec.rb +73 -75
  48. data/spec/spec_helper.rb +21 -1
  49. metadata +95 -3
  50. data/.gitmodules +0 -3
@@ -3,19 +3,14 @@
3
3
  module Hdo
4
4
  module StortingImporter
5
5
  class Issue
6
+ include HasJsonSchema
6
7
  include IvarEquality
7
8
  include Inspectable
8
9
 
9
10
  attr_reader :external_id, :summary, :description, :type, :status, :last_update,
10
11
  :reference, :document_group, :committee, :categories
11
12
 
12
- def self.type_name
13
- 'issue'
14
- end
15
-
16
- def self.description
17
- 'a parliament issue'
18
- end
13
+ schema_path StortingImporter.lib.join("hdo/storting_importer/schema/issue.json").to_s
19
14
 
20
15
  def self.example
21
16
  new(
@@ -32,23 +27,8 @@ module Hdo
32
27
  )
33
28
  end
34
29
 
35
- def self.xml_example(builder = Util.builder)
36
- example.to_hdo_xml(builder)
37
- end
38
-
39
- def self.fields
40
- [
41
- EXTERNAL_ID_FIELD,
42
- Field.new(:summary, true, :string, 'A (preferably one-line) summary of the issue.'),
43
- Field.new(:description, true, :string, 'A longer description of the issue.'),
44
- Field.new(:type, true, :string, 'The type of issue.'),
45
- Field.new(:status, true, :string, 'The status of the issue.'),
46
- Field.new(:lastUpdate, true, :string, 'The time the issue was last updated in the parliament.'),
47
- Field.new(:reference, true, :string, 'A reference.'),
48
- Field.new(:documentGroup, true, :string, 'What document group this issue belongs to.'),
49
- Field.new(:committee, false, :string, "What committee this issue belongs to. Should match the 'name' field in the committee type."),
50
- Field.new(:categories, false, 'list', "List of categories (matching the 'name' field of the category type).")
51
- ]
30
+ def self.json_example
31
+ Util.json_pretty example
52
32
  end
53
33
 
54
34
  def self.from_storting_doc(doc)
@@ -83,23 +63,17 @@ module Hdo
83
63
  raise
84
64
  end
85
65
 
86
- def self.from_hdo_doc(doc)
87
- doc.css("issues > issue").map { |e| from_hdo_node(e) }
88
- end
89
-
90
- def self.from_hdo_node(node)
91
- external_id = node.css("externalId").first.text
92
- summary = node.css("summary").first.text
93
- description = node.css("description").first.text
94
- type = node.css("type").first.text
95
- status = node.css("status").first.text
96
- last_update = node.css("lastUpdate").first.text
97
- reference = node.css("reference").first.text
98
- document_group = node.css("documentGroup").first.text
99
- committee = node.css("committee").first.text
100
- categories = node.css("categories category").map { |e| e.text }
101
-
102
- new external_id, summary, description, type, status, last_update, reference, document_group, committee, categories
66
+ def self.from_hash(hash)
67
+ new hash.fetch('externalId'),
68
+ hash.fetch('summary'),
69
+ hash.fetch('description'),
70
+ hash.fetch('type'),
71
+ hash.fetch('status'),
72
+ hash.fetch('lastUpdate'),
73
+ hash.fetch('reference'),
74
+ hash.fetch('documentGroup'),
75
+ hash.fetch('committee'),
76
+ hash.fetch('categories')
103
77
  end
104
78
 
105
79
  def initialize(external_id, summary, description, type, status, last_update,
@@ -120,25 +94,20 @@ module Hdo
120
94
  short_inspect_string :include => [:external_id, :summary]
121
95
  end
122
96
 
123
- def to_hdo_xml(builder = Util.builder)
124
- builder.issue do |i|
125
- i.externalId external_id
126
- i.summary summary
127
- i.description description
128
- i.type type
129
- i.status status
130
- i.lastUpdate last_update
131
- i.reference reference
132
- i.documentGroup document_group
133
- i.committee(committee) if committee
134
-
135
- if categories.any?
136
- i.categories do |cats|
137
- categories.each { |e| cats.category e }
138
- end
139
- end
140
- end
141
-
97
+ def to_hash
98
+ {
99
+ :kind => self.class.kind,
100
+ :externalId => @external_id,
101
+ :summary => @summary,
102
+ :description => @description,
103
+ :type => @type,
104
+ :status => @status,
105
+ :lastUpdate => @last_update,
106
+ :reference => @reference,
107
+ :documentGroup => @document_group,
108
+ :committee => @committee,
109
+ :categories => @categories
110
+ }
142
111
  end
143
112
 
144
113
  end
@@ -1,29 +1,20 @@
1
1
  module Hdo
2
2
  module StortingImporter
3
3
  class Party
4
+ include HasJsonSchema
4
5
  include IvarEquality
5
6
 
6
7
  attr_reader :external_id, :name
7
8
  alias_method :short_inspect, :inspect
8
9
 
9
- def self.type_name
10
- 'party'
11
- end
12
-
13
- def self.description
14
- 'a political party'
15
- end
10
+ schema_path StortingImporter.lib.join("hdo/storting_importer/schema/party.json").to_s
16
11
 
17
12
  def self.example
18
13
  new("DEM", "Democratic Party")
19
14
  end
20
15
 
21
- def self.xml_example(builder = Util.builder)
22
- example.to_hdo_xml(builder)
23
- end
24
-
25
- def self.fields
26
- [EXTERNAL_ID_FIELD, Field.new(:name, true, :string, 'The name of the party.')]
16
+ def self.json_example
17
+ Util.json_pretty example
27
18
  end
28
19
 
29
20
  def self.from_storting_doc(doc)
@@ -32,12 +23,8 @@ module Hdo
32
23
  end
33
24
  end
34
25
 
35
- def self.from_hdo_doc(doc)
36
- doc.css("parties > party").map { |e| from_hdo_node(e) }
37
- end
38
-
39
- def self.from_hdo_node(node)
40
- new node.css("externalId").first.text, node.css("name").first.text
26
+ def self.from_hash(hash)
27
+ new hash.fetch('externalId'), hash.fetch('name')
41
28
  end
42
29
 
43
30
  def initialize(external_id, name)
@@ -49,12 +36,14 @@ module Hdo
49
36
  Util.unescape_param @external_id
50
37
  end
51
38
 
52
- def to_hdo_xml(builder = Util.builder)
53
- builder.party do |party|
54
- party.externalId external_id
55
- party.name name
56
- end
39
+ def to_hash
40
+ {
41
+ :kind => self.class.kind,
42
+ :externalId => @external_id,
43
+ :name => @name
44
+ }
57
45
  end
46
+
58
47
  end
59
48
  end
60
49
  end
@@ -5,49 +5,25 @@ require 'csv'
5
5
  module Hdo
6
6
  module StortingImporter
7
7
  class Promise
8
+ include HasJsonSchema
9
+ include IvarEquality
10
+
8
11
  attr_reader :party, :body, :general, :categories, :source, :page
12
+ attr_accessor :external_id
9
13
  alias_method :general?, :general
10
14
  alias_method :short_inspect, :inspect
11
15
 
12
- def self.type_name
13
- 'promise'
14
- end
15
-
16
- def self.description
17
- 'a party promise'
18
- end
19
-
20
- def self.fields
21
- [
22
- Field.new(:party, true, :string, 'The external id of the party.'),
23
- Field.new(:general, true, :boolean, "Whether this is considered a general promise (i.e. can be ambigious whether it has been fulfilled)."),
24
- Field.new(:categories, true, :list, "List of category names (matching names imported in <a href='#input-format-category'>&lt;category&gt;</a>)"),
25
- Field.new(:source, true, :string, "The source of the promise. (TODO: this should always be a URL)"),
26
- Field.new(:body, true, :string, "The body text of the promise."),
27
- ]
28
- end
16
+ schema_path StortingImporter.lib.join("hdo/storting_importer/schema/promise.json").to_s
29
17
 
30
18
  def self.example
31
- new("H", "Stille strengere krav til orden og oppførsel for å hindre at uro ødelegger undervisningen.", true, ["GRUNNSKOLE"], "PP", 8)
32
- end
19
+ pr = new("H", "Stille strengere krav til orden og oppførsel for å hindre at uro ødelegger undervisningen.", true, ["GRUNNSKOLE"], "PP", 8)
20
+ pr.external_id = "1"
33
21
 
34
- def self.xml_example(builder = Util.builder)
35
- example.to_hdo_xml(builder)
22
+ pr
36
23
  end
37
24
 
38
- def self.from_hdo_doc(doc)
39
- doc.css("promises > promise").map { |e| from_hdo_node(e) }
40
- end
41
-
42
- def self.from_hdo_node(node)
43
- source, page = node.css("source").first.text.split(":")
44
-
45
- new node.css("party").first.text,
46
- node.css("body").first.text,
47
- node.css("general").first.text == "true",
48
- node.css("categories > category").map { |e| e.text },
49
- source,
50
- page
25
+ def self.json_example
26
+ Util.json_pretty example
51
27
  end
52
28
 
53
29
  def self.from_csv(str)
@@ -79,34 +55,63 @@ module Hdo
79
55
  end.compact
80
56
  end
81
57
 
58
+ # doesn't really belong here - data source?
82
59
  def self.from_fusion_table(table_id, api_key)
83
- url = "https://www.googleapis.com/fusiontables/v1/query"
60
+ table = FusionTable.new(api_key)
61
+
62
+ column_names = table.columns_for(table_id).map { |e| e['name'] }.map { |e| e.inspect }.join(",")
63
+ row_count = Integer(table.query("select count(rowid) from #{table_id}", :rows => true).flatten.first)
84
64
 
85
- resp = RestClient.get(url, :params => {:sql => "select * from #{table_id}", :key => api_key})
86
- MultiJson.decode(resp).fetch('rows').map { |data| new(*data) }
87
- rescue RestClient::RequestFailed => ex
88
- raise "#{ex.message}: #{ex.http_body}"
65
+ # do this in batches of 100
66
+ limit = 100
67
+ result = []
68
+
69
+ (0..row_count).step(limit) do |offset|
70
+ sql = "SELECT #{column_names},\"rowid\" FROM #{table_id} OFFSET #{offset} LIMIT #{limit}"
71
+ result.concat table.query(sql, :rows => true).map { |data| new(*data) }
72
+ end
73
+
74
+ result
75
+ end
76
+
77
+ def self.from_hash(hash)
78
+ pr = new hash.fetch('party'),
79
+ hash.fetch('body'),
80
+ hash.fetch('general'),
81
+ hash.fetch('categories'),
82
+ hash.fetch('source'),
83
+ hash.fetch('page')
84
+
85
+ pr.external_id = hash['externalId']
86
+
87
+ pr
89
88
  end
90
89
 
91
90
  def initialize(party, body, general, categories, source, page)
92
- @party = party
93
- @body = body
94
- @general = general
95
- @categories = clean_categories(categories)
96
- @source = source
97
- @page = page
91
+ @party = party.strip
92
+ @body = body.strip
93
+ @general = general
94
+ @categories = clean_categories(categories)
95
+ @source = source.strip
96
+ @page = page
97
+
98
+ @external_id = nil
98
99
  end
99
100
 
100
- def to_hdo_xml(builder = Util.builder)
101
- builder.promise do |promise|
102
- promise.party party
103
- promise.general general?
104
- promise.categories do |cats|
105
- categories.each { |e| cats.category e }
106
- end
107
- promise.source [source, page].join(":")
108
- promise.body body
109
- end
101
+ def to_hash
102
+ h = {
103
+ :kind => self.class.kind,
104
+ :party => @party,
105
+ :general => @general,
106
+ :categories => @categories,
107
+ :source => @source,
108
+ :page => @page,
109
+ :body => @body
110
+ }
111
+
112
+ h[:externalId] = @external_id if @external_id
113
+
114
+ h
110
115
  end
111
116
 
112
117
  private
@@ -0,0 +1,61 @@
1
+ module Hdo
2
+ module StortingImporter
3
+ class Proposition
4
+ include HasJsonSchema
5
+ include IvarEquality
6
+ include Inspectable
7
+
8
+ attr_reader :external_id, :description, :on_behalf_of, :body, :delivered_by
9
+
10
+ schema_path StortingImporter.lib.join("hdo/storting_importer/schema/proposition.json").to_s
11
+
12
+ def self.example
13
+ new('1234', 'description', 'on behalf of', 'body', Representative.example)
14
+ end
15
+
16
+ def self.json_example
17
+ Util.json_pretty example
18
+ end
19
+
20
+ def self.from_hash(hash)
21
+ arr = [
22
+ hash.fetch('externalId'),
23
+ hash.fetch('description'),
24
+ hash.fetch('onBehalfOf'),
25
+ hash.fetch('body')
26
+ ]
27
+
28
+ delivered_by = hash['deliveredBy']
29
+ arr << Representative.from_hash(delivered_by) if delivered_by
30
+
31
+ new(*arr)
32
+ end
33
+
34
+ def initialize(external_id, description, on_behalf_of, body, delivered_by)
35
+ @external_id = external_id
36
+ @description = description
37
+ @on_behalf_of = on_behalf_of
38
+ @body = body
39
+ @delivered_by = delivered_by
40
+ end
41
+
42
+ def short_inspect
43
+ short_inspect_string :include => [:external_id, :description, :on_behalf_of]
44
+ end
45
+
46
+ def to_hash
47
+ h = {
48
+ :kind => self.class.kind,
49
+ :externalId => @external_id,
50
+ :description => @description,
51
+ :onBehalfOf => @on_behalf_of,
52
+ :body => @body
53
+ }
54
+
55
+ h[:deliveredBy] = @delivered_by.to_hash if @delivered_by
56
+
57
+ h
58
+ end
59
+ end # Proposition
60
+ end
61
+ end
@@ -3,6 +3,7 @@
3
3
  module Hdo
4
4
  module StortingImporter
5
5
  class Representative
6
+ include HasJsonSchema
6
7
  include IvarEquality
7
8
  include Inspectable
8
9
 
@@ -11,13 +12,7 @@ module Hdo
11
12
 
12
13
  attr_accessor :vote_result
13
14
 
14
- def self.type_name
15
- 'representative'
16
- end
17
-
18
- def self.description
19
- 'a member of parliament'
20
- end
15
+ schema_path StortingImporter.lib.join("hdo/storting_importer/schema/representative.json").to_s
21
16
 
22
17
  def self.example
23
18
  new(
@@ -34,22 +29,8 @@ module Hdo
34
29
  )
35
30
  end
36
31
 
37
- def self.xml_example(builder = Util.builder)
38
- example.to_hdo_xml(builder)
39
- end
40
-
41
- def self.fields
42
- [
43
- EXTERNAL_ID_FIELD,
44
- Field.new(:firstName, true, :string, 'The first name of the representative.'),
45
- Field.new(:lastName, true, :string, 'The last name of the representative.'),
46
- Field.new(:period, true, :string, "An identifier for the period the representative is elected for."),
47
- Field.new(:district, true, :string, "The electoral district the representative belongs to. Must match the 'name' field of the district type."),
48
- Field.new(:party, true, :string, "The name of the representative's party."),
49
- Field.new(:committee, true, :list, "A (possibly empty) list of committees the representative is a member of. This should match the 'name' field of the committee type."),
50
- Field.new(:dateOfBirth, true, :string, "The representative's birth date."),
51
- Field.new(:dateOfDeath, false, :string, "The representative's death date."),
52
- ]
32
+ def self.json_example
33
+ Util.json_pretty example
53
34
  end
54
35
 
55
36
  def self.from_storting_doc(doc)
@@ -83,32 +64,21 @@ module Hdo
83
64
  )
84
65
  end
85
66
 
86
- def self.from_hdo_doc(doc)
87
- doc.css("representatives > representative").map { |e| from_hdo_node e }
88
- end
89
-
90
- def self.from_hdo_node(node)
91
- district_node = node.css("district").first
92
- district = district_node ? district_node.text : ''
93
-
94
- party_node = node.css("party").first
95
- party = party_node ? party_node.text : ''
96
-
97
- rep = new node.css("externalId").first.text,
98
- node.css("firstName").first.text,
99
- node.css("lastName").first.text,
100
- node.css("gender").first.text,
101
- node.css("dateOfBirth").first.text,
102
- node.css("dateOfDeath").first.text,
103
- district,
104
- party,
105
- node.css("committees committee").map { |e| e.text.strip },
106
- node.css("period").first.text
107
-
108
- result_node = node.css("voteResult").first
109
- rep.vote_result = result_node.text if result_node
110
-
111
- rep
67
+ def self.from_hash(hash)
68
+ v = new hash.fetch('externalId'),
69
+ hash.fetch('firstName'),
70
+ hash.fetch('lastName'),
71
+ hash.fetch('gender'),
72
+ hash.fetch('dateOfBirth'),
73
+ hash.fetch('dateOfDeath'),
74
+ hash.fetch('district'),
75
+ hash.fetch('party'),
76
+ hash.fetch('committees'),
77
+ hash.fetch('period')
78
+
79
+ v.vote_result = hash['voteResult']
80
+
81
+ v
112
82
  end
113
83
 
114
84
  def initialize(external_id, first_name, last_name, gender, date_of_birth, date_of_death, district, party, committees, period)
@@ -134,27 +104,24 @@ module Hdo
134
104
  Util.unescape_param @external_id
135
105
  end
136
106
 
137
- def to_hdo_xml(builder = Util.builder)
138
- builder.representative do |rep|
139
- rep.externalId external_id
140
- rep.firstName first_name
141
- rep.lastName last_name
142
- rep.gender gender
143
- rep.dateOfBirth date_of_birth
144
- rep.dateOfDeath date_of_death
145
- rep.district district
146
- rep.party party
147
-
148
- rep.committees do |coms|
149
- committees.each { |e| coms.committee e }
150
- end
151
-
152
- rep.period period
153
-
154
- if vote_result
155
- rep.voteResult vote_result
156
- end
157
- end
107
+ def to_hash
108
+ h = {
109
+ :kind => self.class.kind,
110
+ :externalId => @external_id,
111
+ :firstName => @first_name,
112
+ :lastName => @last_name,
113
+ :gender => @gender,
114
+ :dateOfBirth => @date_of_birth,
115
+ :dateOfDeath => @date_of_death,
116
+ :district => @district,
117
+ :party => @party,
118
+ :committees => @committees,
119
+ :period => @period
120
+ }
121
+
122
+ h[:voteResult] = @vote_result if @vote_result
123
+
124
+ h
158
125
  end
159
126
 
160
127
  end
@@ -0,0 +1,28 @@
1
+ {
2
+ "id": "hdo#category",
3
+ "description": "a parliamentary category, used to categorize issues and promises",
4
+ "type":"object",
5
+ "properties": {
6
+ "kind": {
7
+ "type": "string",
8
+ "description": "This is always 'hdo#category'",
9
+ "default": "hdo#category",
10
+ "required": true
11
+ },
12
+ "externalId": {
13
+ "type": "string"
14
+ },
15
+ "name": {
16
+ "description": "The name of the category",
17
+ "type": "string",
18
+ "required": true
19
+ },
20
+ "subCategories": {
21
+ "description": "A list of subcategories.",
22
+ "type":"array",
23
+ "items":{
24
+ "$ref": "hdo#category"
25
+ }
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "id": "hdo#committee",
3
+ "description": "a parliamentary committe",
4
+ "type":"object",
5
+ "properties": {
6
+ "kind": {
7
+ "type": "string",
8
+ "description": "This is always 'hdo#committee'",
9
+ "default": "hdo#committee",
10
+ "required": true
11
+ },
12
+ "externalId": {
13
+ "type": "string"
14
+ },
15
+ "name": {
16
+ "description": "The name of the committee",
17
+ "type": "string",
18
+ "required": true
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "id": "hdo#district",
3
+ "description": "an electoral district",
4
+ "type":"object",
5
+ "properties": {
6
+ "kind": {
7
+ "type": "string",
8
+ "description": "This is always 'hdo#district'",
9
+ "default": "hdo#district",
10
+ "required": true
11
+ },
12
+ "externalId": {
13
+ "type": "string"
14
+ },
15
+ "name": {
16
+ "description": "The name of the district",
17
+ "type": "string",
18
+ "required": true
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,62 @@
1
+ {
2
+ "id": "hdo#issue",
3
+ "description": "a parliament issue",
4
+ "type":"object",
5
+ "properties": {
6
+ "kind": {
7
+ "type": "string",
8
+ "description": "This is always 'hdo#issue'",
9
+ "default": "hdo#issue",
10
+ "required": true
11
+ },
12
+ "externalId": {
13
+ "type": "string",
14
+ "description": "",
15
+ "required": false
16
+ },
17
+ "summary": {
18
+ "type": "string",
19
+ "description": "A (preferably one-line) summary of the issue.",
20
+ "required": true
21
+ },
22
+ "description": {
23
+ "type": "string",
24
+ "description": "A longer description of the issue.",
25
+ "required": true
26
+ },
27
+ "type": {
28
+ "type": "string",
29
+ "description": "The type of issue.",
30
+ "required": true
31
+ },
32
+ "status": {
33
+ "type": "string",
34
+ "description": "The status of the issue.",
35
+ "required": true
36
+ },
37
+ "lastUpdate": {
38
+ "type": "string",
39
+ "description": "The date the issue was last updated in the parliament.",
40
+ "required": true
41
+ },
42
+ "reference": {
43
+ "type": "string",
44
+ "description": "A reference",
45
+ "required": true
46
+ },
47
+ "documentGroup": {
48
+ "type": "string",
49
+ "description": "What document group this issue belongs to.",
50
+ "required": true
51
+ },
52
+ "committee": {
53
+ "type": "string",
54
+ "description": "What committee this issue belongs to. Should match the 'name' field in the committee type."
55
+ },
56
+ "categories": {
57
+ "type": "array",
58
+ "description": "List of categories (matching the 'name' field of the category type).",
59
+ "items": { "type": "string" }
60
+ }
61
+ }
62
+ }