hydramata-works 0.0.1.prerelease

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 (188) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.hound.yml +818 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +20 -0
  6. data/CONTRIBUTING.md +220 -0
  7. data/Gemfile +36 -0
  8. data/Guardfile +36 -0
  9. data/LICENSE +15 -0
  10. data/README.md +36 -0
  11. data/Rakefile +47 -0
  12. data/TODO.md +74 -0
  13. data/VISION.md +19 -0
  14. data/app/forms/hydramata/works/entity_form.rb +92 -0
  15. data/app/forms/hydramata/works/validation_service.rb +78 -0
  16. data/app/models/hydramata/works/data_definition.rb +57 -0
  17. data/app/models/hydramata/works/entities.rb +11 -0
  18. data/app/models/hydramata/works/entity.rb +75 -0
  19. data/app/models/hydramata/works/predicate.rb +35 -0
  20. data/app/models/hydramata/works/predicate_presentation_sequences/storage.rb +29 -0
  21. data/app/models/hydramata/works/predicate_set.rb +44 -0
  22. data/app/models/hydramata/works/predicate_sets/storage.rb +45 -0
  23. data/app/models/hydramata/works/predicates.rb +14 -0
  24. data/app/models/hydramata/works/predicates/storage.rb +33 -0
  25. data/app/models/hydramata/works/presentation_structure.rb +29 -0
  26. data/app/models/hydramata/works/property.rb +72 -0
  27. data/app/models/hydramata/works/property_set.rb +89 -0
  28. data/app/models/hydramata/works/validations.rb +6 -0
  29. data/app/models/hydramata/works/value.rb +34 -0
  30. data/app/models/hydramata/works/work_type.rb +49 -0
  31. data/app/models/hydramata/works/work_types.rb +14 -0
  32. data/app/models/hydramata/works/work_types/storage.rb +42 -0
  33. data/app/parsers/hydramata/works/datastream_parser.rb +36 -0
  34. data/app/parsers/hydramata/works/datastream_parsers/rdf_ntriples_parser.rb +60 -0
  35. data/app/parsers/hydramata/works/datastream_parsers/simple_xml_parser.rb +27 -0
  36. data/app/parsers/hydramata/works/predicate_parser.rb +31 -0
  37. data/app/parsers/hydramata/works/predicate_parsers/simple_parser.rb +13 -0
  38. data/app/parsers/hydramata/works/validations_parser.rb +22 -0
  39. data/app/parsers/hydramata/works/value_parser.rb +26 -0
  40. data/app/parsers/hydramata/works/value_parsers.rb +27 -0
  41. data/app/parsers/hydramata/works/value_parsers/date_parser.rb +13 -0
  42. data/app/parsers/hydramata/works/value_parsers/interrogation_parser.rb +18 -0
  43. data/app/parsers/hydramata/works/value_parsers/simple_parser.rb +14 -0
  44. data/app/presenters/hydramata/works/base_presenter.rb +146 -0
  45. data/app/presenters/hydramata/works/dom_attributes_builder.rb +24 -0
  46. data/app/presenters/hydramata/works/entity_presenter.rb +67 -0
  47. data/app/presenters/hydramata/works/fieldset_presenter.rb +54 -0
  48. data/app/presenters/hydramata/works/property_presenter.rb +51 -0
  49. data/app/presenters/hydramata/works/value_presenter.rb +60 -0
  50. data/app/renderers/hydramata/works/entity_renderer.rb +45 -0
  51. data/app/views/hydramata/works/fieldsets/_edit.html.erb +4 -0
  52. data/app/views/hydramata/works/fieldsets/_show.html.erb +8 -0
  53. data/app/views/hydramata/works/fieldsets/_show.json.jbuilder +8 -0
  54. data/app/views/hydramata/works/properties/_edit.html.erb +12 -0
  55. data/app/views/hydramata/works/properties/_show.html.erb +3 -0
  56. data/app/views/hydramata/works/properties/_show.json.jbuilder +1 -0
  57. data/app/views/hydramata/works/works/_edit.html.erb +8 -0
  58. data/app/views/hydramata/works/works/_new.html.erb +8 -0
  59. data/app/views/hydramata/works/works/_show.html.erb +3 -0
  60. data/app/views/hydramata/works/works/_show.json.jbuilder +13 -0
  61. data/app/wranglers/hydramata/works/fedora_wrangler.rb +66 -0
  62. data/bin/rails +12 -0
  63. data/db/migrate/20140606132349_create_hydramata_work_predicates.rb +13 -0
  64. data/db/migrate/20140606132350_create_hydramata_work_types.rb +9 -0
  65. data/db/migrate/20140606132351_create_hydramata_work_predicate_sets.rb +13 -0
  66. data/db/migrate/20140606132352_create_hydramata_work_predicate_presentation_sequences.rb +12 -0
  67. data/db/migrate/20140623200635_add_validations_to_predicates.rb +5 -0
  68. data/db/migrate/20140627134133_adding_item_type_schema_dot_org_to_work_type.rb +5 -0
  69. data/db/migrate/20140627140840_adding_item_prop_schema_dot_org_to_predicate.rb +5 -0
  70. data/db/seeds.rb +36 -0
  71. data/documents/administrative-set-strawperson.md +45 -0
  72. data/documents/diagrams/hydramata-refactor-tasks.dot +88 -0
  73. data/documents/diagrams/hydramata-sip-dip-aip.dot +88 -0
  74. data/documents/diagrams/hydramata-work-architecture.dot +129 -0
  75. data/documents/diagrams/hydramata-work-subcomponents.dot +36 -0
  76. data/documents/diagrams/map-from-database-to-work-object.dot +44 -0
  77. data/documents/diagrams/map-from-fedora-to-work-object.dot +51 -0
  78. data/documents/diagrams/map-from-input-to-work-object.dot +37 -0
  79. data/documents/diagrams/map-from-work-object-to-database.dot +31 -0
  80. data/documents/diagrams/work-rendering.dot +53 -0
  81. data/documents/diagrams/work-structure.dot +32 -0
  82. data/documents/handling-work.md +224 -0
  83. data/documents/high-level-stories.md +105 -0
  84. data/documents/hydramata-components.md +82 -0
  85. data/documents/interface-between-work-and-permissions.md +131 -0
  86. data/documents/interface-between-work-and-workflow.md +6 -0
  87. data/documents/timeline.md +75 -0
  88. data/fs +3 -0
  89. data/gemfiles/rails4.1.gemfile +12 -0
  90. data/gemfiles/rails4.gemfile +13 -0
  91. data/hydramata-works.gemspec +43 -0
  92. data/lib/hydramata-works.rb +23 -0
  93. data/lib/hydramata/works/conversions.rb +21 -0
  94. data/lib/hydramata/works/conversions/exceptions.rb +18 -0
  95. data/lib/hydramata/works/conversions/predicate.rb +22 -0
  96. data/lib/hydramata/works/conversions/predicate_set.rb +28 -0
  97. data/lib/hydramata/works/conversions/presented_fieldsets.rb +28 -0
  98. data/lib/hydramata/works/conversions/presenter.rb +13 -0
  99. data/lib/hydramata/works/conversions/property.rb +31 -0
  100. data/lib/hydramata/works/conversions/property_set.rb +23 -0
  101. data/lib/hydramata/works/conversions/translation_key_fragment.rb +20 -0
  102. data/lib/hydramata/works/conversions/value.rb +20 -0
  103. data/lib/hydramata/works/conversions/work_type.rb +26 -0
  104. data/lib/hydramata/works/engine.rb +31 -0
  105. data/lib/hydramata/works/linters.rb +99 -0
  106. data/lib/hydramata/works/linters/implement_data_definition_interface_matcher.rb +17 -0
  107. data/lib/hydramata/works/linters/implement_entity_interface_matcher.rb +16 -0
  108. data/lib/hydramata/works/linters/implement_predicate_interface_matcher.rb +17 -0
  109. data/lib/hydramata/works/linters/implement_predicate_set_interface_matcher.rb +8 -0
  110. data/lib/hydramata/works/linters/implement_property_set_interface_matcher.rb +8 -0
  111. data/lib/hydramata/works/linters/implement_value_interface_matcher.rb +8 -0
  112. data/lib/hydramata/works/linters/implement_work_type_interface_matcher.rb +13 -0
  113. data/lib/hydramata/works/linters/interface_matcher_builder.rb +36 -0
  114. data/lib/hydramata/works/translator.rb +67 -0
  115. data/lib/hydramata/works/version.rb +5 -0
  116. data/lib/hydramata_works.rb +2 -0
  117. data/lib/tasks/hydramata_work_tasks.rake +4 -0
  118. data/run_each_spec_in_isolation +16 -0
  119. data/run_each_spec_in_isolation.txt +110 -0
  120. data/script/analyzer.rb +124 -0
  121. data/script/fast_specs +22 -0
  122. data/spec/features/fedora_to_in_memory_spec.rb +60 -0
  123. data/spec/features/format_and_view_path_overrides_spec.rb +72 -0
  124. data/spec/features/in_memory_to_output_buffer_spec.rb +109 -0
  125. data/spec/features/instantiate_entity_from_persisted_work_type_spec.rb +26 -0
  126. data/spec/features/new_user_input_to_in_memory_spec.rb +75 -0
  127. data/spec/features/translation_services_spec.rb +107 -0
  128. data/spec/features/validate_entity_based_on_work_type_structure_spec.rb +19 -0
  129. data/spec/fixtures/cassettes/fedora-object.yml +299 -0
  130. data/spec/fixtures/translations.yml +20 -0
  131. data/spec/forms/hydramata/works/entity_form_spec.rb +83 -0
  132. data/spec/forms/hydramata/works/validation_service_spec.rb +32 -0
  133. data/spec/lib/hydramata-work_spec.rb +14 -0
  134. data/spec/lib/hydramata/works/conversions/predicate_set_spec.rb +50 -0
  135. data/spec/lib/hydramata/works/conversions/predicate_spec.rb +43 -0
  136. data/spec/lib/hydramata/works/conversions/presented_fieldsets_spec.rb +52 -0
  137. data/spec/lib/hydramata/works/conversions/presenter_spec.rb +22 -0
  138. data/spec/lib/hydramata/works/conversions/property_set_spec.rb +42 -0
  139. data/spec/lib/hydramata/works/conversions/property_spec.rb +68 -0
  140. data/spec/lib/hydramata/works/conversions/translation_key_fragment_spec.rb +45 -0
  141. data/spec/lib/hydramata/works/conversions/value_spec.rb +36 -0
  142. data/spec/lib/hydramata/works/conversions/work_type_spec.rb +55 -0
  143. data/spec/lib/hydramata/works/translator_spec.rb +81 -0
  144. data/spec/models/hydramata/works/data_definition_spec.rb +53 -0
  145. data/spec/models/hydramata/works/entity_spec.rb +50 -0
  146. data/spec/models/hydramata/works/predicate_presentation_sequences/storage_spec.rb +15 -0
  147. data/spec/models/hydramata/works/predicate_set_spec.rb +63 -0
  148. data/spec/models/hydramata/works/predicate_sets/storage_spec.rb +37 -0
  149. data/spec/models/hydramata/works/predicate_spec.rb +16 -0
  150. data/spec/models/hydramata/works/predicates/storage_spec.rb +78 -0
  151. data/spec/models/hydramata/works/predicates_spec.rb +18 -0
  152. data/spec/models/hydramata/works/presentation_structure_spec.rb +27 -0
  153. data/spec/models/hydramata/works/property_set_spec.rb +135 -0
  154. data/spec/models/hydramata/works/property_spec.rb +74 -0
  155. data/spec/models/hydramata/works/value_spec.rb +61 -0
  156. data/spec/models/hydramata/works/work_type_spec.rb +45 -0
  157. data/spec/models/hydramata/works/work_types/storage_spec.rb +74 -0
  158. data/spec/models/hydramata/works/work_types_spec.rb +16 -0
  159. data/spec/parsers/hydramata/works/datastream_parser_spec.rb +29 -0
  160. data/spec/parsers/hydramata/works/datastream_parsers/rdf_ntriples_parser_spec.rb +65 -0
  161. data/spec/parsers/hydramata/works/datastream_parsers/simple_xml_parser_spec.rb +37 -0
  162. data/spec/parsers/hydramata/works/predicate_parser_spec.rb +30 -0
  163. data/spec/parsers/hydramata/works/predicate_parsers/simple_parser_spec.rb +20 -0
  164. data/spec/parsers/hydramata/works/validations_parser_spec.rb +31 -0
  165. data/spec/parsers/hydramata/works/value_parser_spec.rb +22 -0
  166. data/spec/parsers/hydramata/works/value_parsers/simple_parser_spec.rb +20 -0
  167. data/spec/parsers/hydramata/works/value_parsers_spec.rb +36 -0
  168. data/spec/presenters/hydramata/works/base_presenter_spec.rb +111 -0
  169. data/spec/presenters/hydramata/works/dom_attributes_builder_spec.rb +26 -0
  170. data/spec/presenters/hydramata/works/entity_presenter_spec.rb +51 -0
  171. data/spec/presenters/hydramata/works/fieldset_presenter_spec.rb +58 -0
  172. data/spec/presenters/hydramata/works/property_presenter_spec.rb +42 -0
  173. data/spec/presenters/hydramata/works/value_presenter_spec.rb +49 -0
  174. data/spec/renderers/hydramata/works/entity_renderer_spec.rb +25 -0
  175. data/spec/spec_active_record_helper.rb +30 -0
  176. data/spec/spec_fast_helper.rb +12 -0
  177. data/spec/spec_slow_helper.rb +56 -0
  178. data/spec/spec_view_helper.rb +14 -0
  179. data/spec/test_app_templates/lib/generators/test_app_generator.rb +21 -0
  180. data/spec/views/hydramata/works/fieldsets/_edit.html.erb_spec.rb +29 -0
  181. data/spec/views/hydramata/works/fieldsets/_show.html.erb_spec.rb +25 -0
  182. data/spec/views/hydramata/works/properties/_edit.html.erb_spec.rb +22 -0
  183. data/spec/views/hydramata/works/properties/_show.html.erb_spec.rb +22 -0
  184. data/spec/views/hydramata/works/works/_edit.html.erb_spec.rb +23 -0
  185. data/spec/views/hydramata/works/works/_new.html.erb_spec.rb +23 -0
  186. data/spec/views/hydramata/works/works/_show.html.erb_spec.rb +24 -0
  187. data/spec/wranglers/hydramata/works/fedora_wrangler_spec.rb +26 -0
  188. metadata +466 -0
@@ -0,0 +1,51 @@
1
+ digraph "G" {
2
+ label="Map from Fedora to Work Object"
3
+ compound=true;
4
+ node[color="grey15" shape=record penwidth=2 margin="0.15, 0.125"];
5
+
6
+ subgraph 1 {
7
+ label="Records"
8
+ node[color="grey" style=filled fillcolor=olivedrab3];
9
+ fedora[label="Fedora"]
10
+ work[label="{ <f0> Work (in memory) | <f1> #pid | <f2> #work_type | <f3> #property_set }"]
11
+ }
12
+
13
+ subgraph cluster_0 {
14
+ label="Sequence for Transforming\nFedora object to a Work"
15
+ color="orange"
16
+ style="filled"
17
+ node[style=filled fillcolor=white]
18
+ fedora_request_pid[label="Request PID"]
19
+ fedora_retrieve_object[label="Retrieve Object"]
20
+ fedora_instantiate_work[label="Instantiate Work"]
21
+ fedora_assign_work_type[label="Assign Work Type"]
22
+ fedora_retrieve_datastreams[label="Retrieve Datastreams"]
23
+ fedora_for_each_datastream[label="For each Datastream"]
24
+ fedora_parse_datastream[label="Parse Datastream"]
25
+ fedora_for_each_property[label="For each Property"]
26
+ fedora_loop_for_each_property[label="More Properties" shape="diamond"]
27
+ fedora_loop_for_each_datastream[label="More Datastreams" shape="diamond"]
28
+ fedora_push_property_to_work_property_set[label="Push Property to Work Property Set"]
29
+ return_work[label="Return Work object"]
30
+
31
+ fedora_request_pid -> fedora_retrieve_object
32
+ fedora_retrieve_object -> fedora_instantiate_work ->
33
+ fedora_instantiate_work -> fedora_assign_work_type
34
+ fedora_assign_work_type -> fedora_retrieve_datastreams
35
+ fedora_retrieve_datastreams -> fedora_for_each_datastream
36
+ fedora_for_each_datastream-> fedora_parse_datastream
37
+ fedora_parse_datastream -> fedora_for_each_property
38
+ fedora_for_each_property -> fedora_push_property_to_work_property_set
39
+ fedora_push_property_to_work_property_set -> fedora_loop_for_each_property
40
+ fedora_loop_for_each_property -> fedora_for_each_property [label="NEXT"]
41
+ fedora_loop_for_each_property -> fedora_loop_for_each_datastream [label="NO"]
42
+ fedora_loop_for_each_datastream -> fedora_for_each_datastream [label="NEXT"]
43
+ fedora_loop_for_each_datastream -> return_work [label="NO"]
44
+ }
45
+
46
+ fedora_instantiate_work -> work[dir=both]
47
+ fedora_assign_work_type -> work:f2
48
+ fedora_retrieve_object -> fedora[dir=both]
49
+ fedora_push_property_to_work_property_set -> work:f3
50
+ work -> return_work
51
+ }
@@ -0,0 +1,37 @@
1
+ digraph "G" {
2
+ label="Map from User Input to Work Object"
3
+ compound=true;
4
+ node[color="grey15" shape=record penwidth=2 margin="0.15, 0.125"];
5
+
6
+ subgraph 1 {
7
+ label="Records"
8
+ node[color="grey" style=filled fillcolor=olivedrab3];
9
+ input[label="Input"]
10
+ work[label="{ <f0> Work (in memory) | <f1> #pid | <f2> #work_type | <f3> #property_set }"]
11
+ }
12
+
13
+ subgraph cluster_0 {
14
+ label="Sequence for Transforming\nUser Input to a Work"
15
+ color="orange"
16
+ style="filled"
17
+ node[style=filled fillcolor=white]
18
+ post_user_input[label="Post User Input"]
19
+ for_each_input_key[label="For each Input Key/Value pair"]
20
+ determine_predicate_for_key[label="Determine Predicate by Key"]
21
+ coerce_value[label="Use Predicate to coerce Value into a Property"]
22
+ push_value_to_onto_work[label="Push Property onto Work"]
23
+ loop_input_key[label="More input keys?" shape="diamond"]
24
+ return_work[label="Return Work object"]
25
+
26
+ post_user_input -> for_each_input_key
27
+ for_each_input_key -> determine_predicate_for_key
28
+ determine_predicate_for_key -> coerce_value
29
+ coerce_value -> push_value_to_onto_work
30
+ push_value_to_onto_work -> loop_input_key
31
+ loop_input_key -> for_each_input_key[label="NEXT"]
32
+ loop_input_key -> return_work[label="NO"]
33
+ }
34
+ coerce_value -> work
35
+ work -> return_work
36
+ input -> for_each_input_key
37
+ }
@@ -0,0 +1,31 @@
1
+ digraph "G" {
2
+ label="Map from Work Object to Database"
3
+ compound=true;
4
+ node[color="grey15" shape=record penwidth=2 margin="0.15, 0.125"];
5
+
6
+ subgraph 1 {
7
+ label="Records"
8
+ node[color="grey" style=filled fillcolor=olivedrab3];
9
+ database[label="database"]
10
+ work[label="{ <f0> Work (in memory) | <f1> #pid | <f2> #work_type | <f3> #property_set }"]
11
+ }
12
+
13
+ subgraph cluster_0 {
14
+ label="Sequence for Transforming\nan in Memory Work to the Database"
15
+ color="orange"
16
+ style="filled"
17
+ node[style=filled fillcolor=white]
18
+ save_work[label="Request to save Work"]
19
+ validate[label="Validate Work"]
20
+ request_pid[label="Request PID (if applicable)"]
21
+ serialize_property_set[label="Serialize PropertySet to JSON"]
22
+
23
+ save_work -> validate
24
+ validate -> work[dir=both]
25
+ work -> serialize_property_set
26
+ validate -> request_pid
27
+ request_pid -> serialize_property_set
28
+ serialize_property_set -> database
29
+ }
30
+
31
+ }
@@ -0,0 +1,53 @@
1
+ digraph "G" {
2
+ label="Render a Work"
3
+ compound=true;
4
+ node[color="grey15" shape=record penwidth=2 margin="0.15, 0.125"];
5
+
6
+ subgraph 1 {
7
+ label="Records"
8
+ node[color="grey" style=filled fillcolor=olivedrab3];
9
+ work[label="{ <f0> Work (in memory) | <f1> #pid | <f2> #work_type | <f3> #property_set }"]
10
+ output_buffer[label=" { Rendered output }"]
11
+ }
12
+
13
+ subgraph cluster_0 {
14
+ label="Sequence for Transforming\nWork to Rendered Output"
15
+ color="orange"
16
+ style="filled"
17
+ node[style=filled fillcolor=white]
18
+ request_for_content_type[label="Request Work for Content Type (i.e. XML)"]
19
+ determine_presentation_structure[label="With Presentation Structure"]
20
+ for_each_fieldset[label="For each Fieldset"]
21
+ render_fieldset_container[label="Render Fieldset container"]
22
+ for_each_predicate[label="For each Predicate"]
23
+ render_predicate_container[label="Render Predicate container"]
24
+ fetch_work_property_by_predicate[label="Fetch Property from Work by Predicate"]
25
+ render_work_property[label="Render Work's Property#values"]
26
+ loop_for_each_predicate[shape="diamond" label="More Predicates?"]
27
+ loop_for_each_fieldset[shape="diamond" label="More Fieldsets?"]
28
+ render_remaining_work_properties_in_junk_drawer_fieldset[label="Render remaining Work Properties (if applicable)"]
29
+ return_output_buffer[label="Return rendered output to requester"]
30
+
31
+ request_for_content_type -> determine_presentation_structure
32
+ determine_presentation_structure -> for_each_fieldset
33
+ for_each_fieldset -> render_fieldset_container
34
+ render_fieldset_container -> for_each_predicate
35
+ for_each_predicate -> render_predicate_container
36
+ render_predicate_container -> fetch_work_property_by_predicate
37
+ fetch_work_property_by_predicate -> render_work_property
38
+ render_work_property -> loop_for_each_predicate
39
+ loop_for_each_predicate -> for_each_predicate [label="NEXT"]
40
+ loop_for_each_predicate -> loop_for_each_fieldset [label="NO"]
41
+ loop_for_each_fieldset -> for_each_fieldset [label="NEXT"]
42
+ loop_for_each_fieldset -> render_remaining_work_properties_in_junk_drawer_fieldset [label="NO"]
43
+ render_remaining_work_properties_in_junk_drawer_fieldset -> return_output_buffer
44
+ }
45
+
46
+ fetch_work_property_by_predicate -> work:f3[arrowhead=none]
47
+ determine_presentation_structure -> work:f2[arrowhead=none]
48
+ render_fieldset_container -> output_buffer
49
+ render_predicate_container -> output_buffer
50
+ render_work_property -> output_buffer
51
+ render_remaining_work_properties_in_junk_drawer_fieldset -> output_buffer
52
+ output_buffer -> return_output_buffer
53
+ }
@@ -0,0 +1,32 @@
1
+ digraph "G" {
2
+ label="Work Structure"
3
+ compound=true;
4
+ node[color="grey15" shape=record penwidth=2 margin="0.15, 0.125"];
5
+ edge[arrowhead="crowfeet"]
6
+
7
+ work[label="{ <f0> Work (in memory) | <f1> #pid | <f2> #work_type | <f3> #property_set }"]
8
+ work_type [label="{ WorkType | #name | #presentation_structure }"]
9
+ property [label="{ Property (in memory) | #predicate | #values }"]
10
+ workflow [label="{ Workflow | #first_task | #task_graph }"]
11
+ fieldset [label="{ Fieldset | #name | #predicates | #presentation_sequence_number }"]
12
+ fieldset_predicates [label="{ FieldsetPredicate | #fieldset | #predicate | #presentation_sequence_number }"]
13
+ predicate [label="{ <f0> Predicate | <f1> #name | <f2> #uri | <f3> #datastream_name | <f4> #predicate_coercer_class_name | <f5> #predicate_parser_class_name | <f6> #indexing_strategy | <f7> #key }"]
14
+ work_type_datastream_parser [label="{ WorkTypeDatastreamParser | #work_type | #datastream_name | #parser_class_name }"]
15
+ presentation_structure [label="{ Presentation Structure | #name }"]
16
+ presentation_context [label="{ PresentationContext | #work_type | #content_type (ie 'solr', 'xml', 'html') | #context (ie 'show', 'edit') | #renderer_class_name }"]
17
+ work_type_processing_context [label="{ ProcessingContext | #work_type | #context (ie 'create', 'update', 'destroy') }"]
18
+ property_set [label="{ PropertySet (in memory) | #work | #push(a_property) }"]
19
+
20
+ work_type -> work
21
+ work -> property_set [arrowhead=lcrow]
22
+ property_set -> property
23
+ predicate -> property
24
+ presentation_structure -> fieldset
25
+ fieldset -> fieldset_predicates
26
+ predicate -> fieldset_predicates
27
+ work_type -> presentation_structure
28
+ work_type -> presentation_context
29
+ work_type -> work_type_processing_context -> workflow
30
+
31
+ work_type -> work_type_datastream_parser
32
+ }
@@ -0,0 +1,224 @@
1
+ The audience for (most of) the specs that verify the feature is a developer.
2
+
3
+ RSpec with a statement of target audience for each spec (i.e. product_owner: true).
4
+
5
+ # To Render a New Work's SIP Form
6
+
7
+ For the requested work_type
8
+ Instantiate a work with a presentation structure
9
+ For each fieldset in the instatiated work's presentation structure
10
+ For each property key (predicate) in the fieldset
11
+ Render property key with Work's property
12
+
13
+ ## Done Looks Like
14
+
15
+ ```gherkin
16
+ Given work_type 'Article' has the following presentation structure:
17
+ | fieldset | property_key
18
+ | :required | [['DC:TITLE', multi_value: true]]
19
+ | :optional | [['DC:ABSTRACT', multi_value: false]]
20
+ When I request an HTML form for a new 'Article'
21
+ Then I should see a well-structured output with CSS selectors:
22
+ | css_selector
23
+ | .required .dc-title.multi_value input.value
24
+ | .optional .dc-abstract input.value
25
+ And in the response document the .required container preceeds the .optional container.
26
+ ```
27
+
28
+ # To Submit a Work's SIP Form
29
+
30
+ This is a PO-level feature.
31
+
32
+ ## Done Looks Like
33
+
34
+ ```gherkin
35
+ Given I have a valid form for a work_type
36
+ When I submit the form
37
+ Then a SIP is created with a unique PID
38
+ And the SIP is submitted for processing
39
+ And a :created response is issued
40
+ ```
41
+
42
+ # To Render a Work's SIP
43
+
44
+ For the requested PID
45
+ Find the work in the database and assign the work's properties
46
+ For each fieldset in the work's presentation structure
47
+ For each property key (predicate) in the fieldset
48
+ Render property key with Work's property
49
+
50
+ ## Done Looks Like
51
+
52
+ ```gherkin
53
+ Given a PID that exists in the database
54
+ And it has the following serialized structure properties:
55
+ {'DC:TITLE' => ['My Book', 'A Lengthy Treatise'], 'DC:ABSTRACT' => 'Lots of Words'}
56
+ And its work_type of Article has a presentation structure of:
57
+ | fieldset | property_key
58
+ | :required | [['DC:TITLE', multi_value: true]
59
+ | :optional | ['DC:ABSTRACT']
60
+ When I request an HTML version of that PID
61
+ Then I should see a well-structured output with CSS selectors:
62
+ | css_selector | text_value
63
+ | .required .dc-title.multi_value .value | "My Book"
64
+ | .required .dc-title.multi_value .value | "Lengthy Treatise"
65
+ | .optional .dc-abstract .value | "Lots of Words"
66
+ And in the response document the .required container preceeds the .optional container.
67
+ ```
68
+
69
+ # To Render a Work's AIP
70
+
71
+ For the requested PID
72
+ Find the work in Fedora and assign the work's properties
73
+ For each fieldset in the work's presentation structure
74
+ For each property key (predicate) in the fieldset
75
+ Render property key with Work's property
76
+
77
+ ## Done Looks Like
78
+
79
+ ```gherkin
80
+ Given a PID that exists in Fedora
81
+ And it has the following RDF properties:
82
+ | predicate | object
83
+ | DC:TITLE | My Book
84
+ | DC:TITLE | A Lengthy Treatise
85
+ | DC:ABSTRACT | Lots of Words
86
+ And its work_type of Article has a presentation structure of:
87
+ | fieldset | property_key
88
+ | :required | ['DC:TITLE']
89
+ | :optional | ['DC:ABSTRACT']
90
+ When I request an HTML version of that PID
91
+ Then I should see a well-structured output with CSS selectors:
92
+ | css_selector | text_value
93
+ | .required .dc-title .value | "My Book"
94
+ | .required .dc-title .value | "Lengthy Treatise"
95
+ | .optional .dc-abstract .value | "Lots of Words"
96
+ And in the response document the .required container preceeds the .optional container.
97
+ ```
98
+
99
+ # A workflow processing a SIP
100
+
101
+ For queued up SIP Workflow (eg State Machine).
102
+ A task is a discreet function that can be run in isolation (i.e. characterize all files associated with this SIP).
103
+ A workflow is composed of a sequence of tasks.
104
+
105
+ **Workflow properties**
106
+
107
+ A workflow has a unique name
108
+ A workflow is comprised of tasks definitions
109
+ A task definition is comprised of a unique name
110
+
111
+ **Outstanding questions**
112
+
113
+ How is the workflow defined?
114
+ How each task is defined (i.e. what is the object interface)?
115
+ How is a workflow processed (i.e. how do we run one task, then respond accordingly and start another task)?
116
+ How are errors reported/monitored/recovered from?
117
+
118
+ *Look to [Heracles](https://github.com/ndlib/heracles) for guidance.*
119
+
120
+ ## Done Looks Like
121
+
122
+ ```gherkin
123
+ Given a workflow with tasks:
124
+ | task_name | responder
125
+ | :a | { ok: :b }
126
+ | :b | { ok: :done }
127
+ And `first_task :a`
128
+ When the workflow is started
129
+ Then task :a is invoked
130
+ ```
131
+
132
+ ```gherkin
133
+ Given a workflow with tasks:
134
+ | task_name | responder
135
+ | :a | { ok: :b }
136
+ | :b | { ok: :done }
137
+ And `first_task :a`
138
+ When task :a is completed with response :ok
139
+ Then task :b is invoked
140
+ ```
141
+
142
+ ```gherkin
143
+ Given a workflow with tasks:
144
+ | task_name | responder
145
+ | :a | { ok: :b }
146
+ | :b | { ok: :done }
147
+ And `first_task :a`
148
+ When task :a throws an exception
149
+ Then task :b is not invoked
150
+ And an error is submitted to the monitoring system
151
+ ```
152
+
153
+ ```gherkin
154
+ Given a task of :generate_derivatives
155
+ When the task :generate_derivatives is invoked with a SIP
156
+ Then derivatives are generated for each of the SIP's associated primary files (i.e. don't generate derivatives for the derivatives)
157
+ And append the derivatives to the SIP's payload
158
+ ```
159
+
160
+ ```gherkin
161
+ Given a task of :run_antivirus
162
+ When the task :run_antivirus is invoked with a SIP
163
+ And one of the attached files is a virus
164
+ Then return a :virus_found
165
+ ```
166
+
167
+ ```gherkin
168
+ Given a task of :run_antivirus
169
+ When the task :run_antivirus is invoked with a SIP
170
+ And none of the attached files contain a virus
171
+ Then return :virus_not_found
172
+ ```
173
+
174
+ See the [Raw Object Format repository](https://github.com/ndlib/rof).
175
+
176
+ ```gherkin
177
+ Given a task :validate_rof
178
+ And a SIP that is will-formed and ready for ingest
179
+ When the task :validate_rof is invoked with a SIP
180
+ Then return :rof_is_valid
181
+ ```
182
+
183
+ # To Index a Work's AIP
184
+
185
+ SOLR strategy for a given property appears to be the same across work types.
186
+ Each Property has a SOLR strategy
187
+
188
+ # To Represent a Work's Files
189
+
190
+ If we ask an object for its datastreams, how do we know which ones are files?
191
+ Files are attached on children of a Work.
192
+ There are manifestations of the Work's files in the datastreams.
193
+ Predicate :realization for the File "Work"
194
+
195
+ # Glossary?
196
+
197
+ ## Work
198
+
199
+ Responsible for being a container of the data that is persisted in a data store.
200
+
201
+ * Each work has many properties
202
+ * Each property has a key (predicate) and one or more values
203
+
204
+ ## Presentation Structure
205
+
206
+ Responsible for saying where in the rendering something occurs (eg Title occurs before Author).
207
+ Provides logical groupings via Fieldsets (eg the "Required fields" occur before the "Optional fields")
208
+
209
+ * Each work type has one presentation structure
210
+ * Each presentation structure has many fieldsets
211
+ * Each fieldset has many property keys
212
+
213
+ ## Fieldset
214
+
215
+ Responsible for providing logical groupings of properties.
216
+ Arbitrarily named; use internationalization (I18n) for name and legend.
217
+
218
+ ## Property Key
219
+
220
+ ## Work's Property
221
+
222
+ ## Renderers
223
+
224
+ ShowRenderer, EditRenderer, NewRenderer
@@ -0,0 +1,105 @@
1
+ # High-level Stories
2
+
3
+ Below are stories that are supported in the `./documents` directory.
4
+
5
+ ## Done
6
+
7
+ ### (1) Transform in memory Work object to Show JSON Document
8
+
9
+ ### (2) Transform Fedora object to in memory Work object
10
+
11
+ * Done Looks Like: All of the persisted datastreams are in the database are reified in the Work object's #properties.
12
+
13
+ ### (1) Create an interface for rendering a fieldset
14
+
15
+ ### (1) Transform in memory Work object to Show HTML Document
16
+
17
+ **Done looks like**
18
+
19
+ ```gherkin
20
+ Given a work object with the following propety_set:
21
+ | fieldset | predicate | value |
22
+ | :required | :title | 'Hello' |
23
+ | :required | :title | 'World' |
24
+ | :required | :title | 'Bang!' |
25
+ | :optional | :abstract | 'Long Text' |
26
+ | :optional | :abstract | 'Longer Text' |
27
+ | :optional | :keyword | 'Programming' |
28
+ When I request an HTML version of the work
29
+ Then I should have the following css-selectors and text:
30
+ | css_selector | text |
31
+ | .required .title .label | Title |
32
+ | .required .title .value | Hello |
33
+ | .required .title .value | World |
34
+ | .required .title .value | Bang! |
35
+ | .optional .abstract .label | Abstract |
36
+ | .optional .abstract .value | Long Text |
37
+ | .optional .abstract .value | Longer Text |
38
+ | .optional .keyword .label | Keyword |
39
+ | .optional .keyword .value | Programming |
40
+ ```
41
+
42
+ ## Must Have
43
+
44
+ ### (4) Transform in memory Work object to New HTML Document
45
+
46
+ **Done looks like**
47
+
48
+ ```gherkin
49
+ Given a work object with the following propety_set:
50
+ | fieldset | predicate | value |
51
+ | :required | :title | 'Hello' |
52
+ | :required | :title | '' |
53
+ | :optional | :abstract | '' |
54
+ | :optional | :keyword | '' |
55
+ When I request an HTML version of the work
56
+ Then I should have the following css-selectors and text:
57
+ | css_selector | text |
58
+ | fieldset.required.caption | 'Required' |
59
+ | .required .title label.label | 'Title' |
60
+ | .required .title input.value[name=work[title]] | 'Hello' |
61
+ | .required .title input.value[name=work[title]] | '' |
62
+ | fieldset.optional.caption | 'Optional' |
63
+ | .optional .abstract input.value[name=work[abstract]] | '' |
64
+ | .optional .keyword input.value[name=work[keyword]] | '' |
65
+ ```
66
+
67
+ ### (3) Create an interface for rendering a property
68
+
69
+ * in Edit HTML
70
+ * in New HTML
71
+ * in Show HTML
72
+ * in Solr Document
73
+
74
+ ### (1) Transform Database object to in memory Work object
75
+
76
+ * Done Looks Like: All of the persisted properties in the database are reified in the Work object's #properties.
77
+
78
+ ### (2) Transform Solr object to in memory Work object
79
+
80
+ ### (2) Transform in memory Work object to SOLR Document
81
+ ### (3) Transform in memory Work object to Raw Datastreams
82
+ ### (1) Transform in memory Work object to Edit HTML Document
83
+ ### (1) Transform in memory Work object to Database
84
+ ### (3) Transform in memory Work to Fedora object
85
+ ### (1) Transform user input from Edit Form to in memory Work object
86
+ ### (1) Transform user input from New Form to in memory Work object
87
+
88
+ #### Components
89
+
90
+ * Define a Work type's suggested predicates
91
+ * Define a Work type's presentation structure
92
+ * Define an abstract Predicate
93
+ * Create a presented fieldset
94
+ * Should render itself for its context
95
+ * Create a presented property
96
+ * Should render itself for its context
97
+
98
+ ## Nice to Have
99
+
100
+ * Transform in memory Work object to New JSON Document
101
+
102
+ ## There are Small Work Items
103
+
104
+ * Predicate parsers and coercers
105
+ * Datastream parsers and coercers