labimotion 2.3.0 → 2.4.0.rc11

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -1
  3. data/lib/labimotion/apis/generic_dataset_api.rb +93 -3
  4. data/lib/labimotion/apis/generic_element_api.rb +198 -8
  5. data/lib/labimotion/apis/generic_klass_api.rb +74 -8
  6. data/lib/labimotion/apis/klass_share_api.rb +648 -0
  7. data/lib/labimotion/apis/labimotion_ai_api.rb +252 -0
  8. data/lib/labimotion/apis/labimotion_api.rb +4 -0
  9. data/lib/labimotion/apis/labimotion_doi_api.rb +24 -10
  10. data/lib/labimotion/apis/labimotion_template_browse_api.rb +13 -1
  11. data/lib/labimotion/apis/ontology_root_api.rb +74 -0
  12. data/lib/labimotion/apis/segment_api.rb +77 -10
  13. data/lib/labimotion/apis/user_klass_settings_api.rb +93 -0
  14. data/lib/labimotion/conf.rb +5 -0
  15. data/lib/labimotion/constants.rb +64 -0
  16. data/lib/labimotion/entities/application_entity.rb +8 -0
  17. data/lib/labimotion/entities/eln_element_entity.rb +6 -0
  18. data/lib/labimotion/entities/generic_klass_entity.rb +126 -0
  19. data/lib/labimotion/entities/klass_share_entity.rb +48 -0
  20. data/lib/labimotion/entities/properties_entity.rb +78 -2
  21. data/lib/labimotion/entities/segment_entity.rb +8 -0
  22. data/lib/labimotion/entities/user_klass_setting_entity.rb +10 -0
  23. data/lib/labimotion/helpers/cover_image_helpers.rb +181 -0
  24. data/lib/labimotion/helpers/dataset_helpers.rb +187 -1
  25. data/lib/labimotion/helpers/element_helpers.rb +282 -6
  26. data/lib/labimotion/helpers/exporter_helpers.rb +17 -2
  27. data/lib/labimotion/helpers/generic_helpers.rb +293 -4
  28. data/lib/labimotion/helpers/param_helpers.rb +105 -0
  29. data/lib/labimotion/helpers/sample_association_helpers.rb +7 -0
  30. data/lib/labimotion/helpers/segment_helpers.rb +102 -4
  31. data/lib/labimotion/libs/ai_egress_guard.rb +99 -0
  32. data/lib/labimotion/libs/ai_klass_queue.rb +88 -0
  33. data/lib/labimotion/libs/ai_klass_validator.rb +74 -0
  34. data/lib/labimotion/libs/ai_models.rb +201 -0
  35. data/lib/labimotion/libs/ai_template.rb +2285 -0
  36. data/lib/labimotion/libs/converter.rb +5 -43
  37. data/lib/labimotion/libs/data/datacite/labimotion_template.html.erb +67 -0
  38. data/lib/labimotion/libs/export_element.rb +128 -13
  39. data/lib/labimotion/libs/file_extractor.rb +210 -0
  40. data/lib/labimotion/libs/linked_element.rb +313 -0
  41. data/lib/labimotion/libs/ontology_store.rb +226 -0
  42. data/lib/labimotion/libs/ontology_terms.rb +227 -0
  43. data/lib/labimotion/libs/owner_resolver.rb +50 -0
  44. data/lib/labimotion/libs/ownership_audit.rb +73 -0
  45. data/lib/labimotion/libs/sample_association.rb +52 -1
  46. data/lib/labimotion/libs/share_notifier.rb +114 -0
  47. data/lib/labimotion/libs/share_resolver.rb +373 -0
  48. data/lib/labimotion/libs/user_ai_settings.rb +129 -0
  49. data/lib/labimotion/models/cellline.rb +47 -0
  50. data/lib/labimotion/models/concerns/datasetable.rb +3 -0
  51. data/lib/labimotion/models/concerns/matrice_labimotion.rb +124 -0
  52. data/lib/labimotion/models/concerns/segmentable.rb +2 -0
  53. data/lib/labimotion/models/concerns/template_doi.rb +133 -0
  54. data/lib/labimotion/models/dataset_klass.rb +1 -1
  55. data/lib/labimotion/models/element_klass.rb +1 -1
  56. data/lib/labimotion/models/klass_share.rb +129 -0
  57. data/lib/labimotion/models/segment_klass.rb +1 -1
  58. data/lib/labimotion/models/user_klass_setting.rb +58 -0
  59. data/lib/labimotion/models/user_setting.rb +60 -0
  60. data/lib/labimotion/usecases/build_template_doi_xml.rb +69 -23
  61. data/lib/labimotion/usecases/release_template_doi.rb +42 -17
  62. data/lib/labimotion/usecases/template_doi_helpers.rb +28 -6
  63. data/lib/labimotion/usecases/update_template_publication_metadata.rb +71 -2
  64. data/lib/labimotion/utils/export_utils.rb +1 -0
  65. data/lib/labimotion/utils/import_utils.rb +20 -3
  66. data/lib/labimotion/utils/serializer.rb +27 -0
  67. data/lib/labimotion/utils/units.rb +32 -67
  68. data/lib/labimotion/version.rb +1 -1
  69. data/lib/labimotion.rb +27 -0
  70. metadata +45 -3
@@ -14,18 +14,21 @@ module Labimotion
14
14
  desc 'export klass'
15
15
  params do
16
16
  requires :id, type: Integer, desc: 'element id'
17
- requires :klass, type: String, desc: 'Klass', values: %w[ElementKlass SegmentKlass DatasetKlass]
17
+ requires :klass, type: String, desc: 'Klass', values: Labimotion::Constants::Klass::ALL
18
18
  end
19
19
  get do
20
- entity = "Labimotion::#{params[:klass]}".constantize.find_by(id: params[:id])
21
- entity.update_columns(identifier: SecureRandom.uuid) if entity&.identifier.nil?
20
+ # This export previously accepted any logged-in account (no admin gate at all) and,
21
+ # worse, wrote through update_columns inside a GET — minting the identifier that Hub
22
+ # sync keys on, for whoever happened to press download first. Gated :read now, and a
23
+ # template with no identifier simply exports without one; minting stays with the
24
+ # write paths.
25
+ entity = fetch_klass(params[:klass], params[:id])
26
+ authorize_klass!(entity, :read)
22
27
  env['api.format'] = :binary
23
28
  content_type('application/json')
24
29
  filename = CGI.escape("LabIMotion_#{params[:klass]}_#{entity.label}-#{Time.new.strftime("%Y%m%d%H%M%S")}.json")
25
- # header['Content-Disposition'] = "attachment; filename=abc.docx"
26
30
  header('Content-Disposition', "attachment; filename=\"#{filename}\"")
27
31
  "Labimotion::#{params[:klass]}Entity".constantize.represent(entity)
28
- # klass.as_json
29
32
  rescue StandardError => e
30
33
  Labimotion.log_exception(e, current_user)
31
34
  {}
@@ -35,12 +38,12 @@ module Labimotion
35
38
  namespace :de_activate do
36
39
  desc 'activate or deactivate Generic Klass'
37
40
  params do
38
- requires :klass, type: String, desc: 'Klass', values: %w[ElementKlass SegmentKlass DatasetKlass]
41
+ requires :klass, type: String, desc: 'Klass', values: Labimotion::Constants::Klass::ALL
39
42
  requires :id, type: Integer, desc: 'Klass ID'
40
43
  requires :is_active, type: Boolean, desc: 'Active or Inactive Klass'
41
44
  end
42
45
  after_validation do
43
- authenticate_admin!(params[:klass].gsub(/(Klass)/, 's').downcase)
46
+ # authorize_klass!(:deactivate) runs inside the helper, on the loaded record.
44
47
  fetch_klass(params[:klass], params[:id])
45
48
  end
46
49
  post do
@@ -54,11 +57,74 @@ module Labimotion
54
57
  end
55
58
  end
56
59
 
60
+ namespace :update_settings do
61
+ desc 'update Generic Klass settings'
62
+ params do
63
+ requires :klass, type: String, desc: 'Klass', values: Labimotion::Constants::Klass::ALL
64
+ requires :id, type: Integer, desc: 'Klass ID'
65
+ requires :settings, type: Hash, desc: 'Klass settings'
66
+ end
67
+ after_validation do
68
+ # authorize_klass!(:write) runs inside the helper, on the loaded record.
69
+ fetch_klass(params[:klass], params[:id])
70
+ end
71
+ post do
72
+ updated_klass = update_klass_settings(params)
73
+ entity_class = "Labimotion::#{params[:klass]}Entity".constantize
74
+ serialized_data = entity_class.represent(updated_klass)
75
+ { mc: 'ss00', data: serialized_data }
76
+ rescue StandardError => e
77
+ Labimotion.log_exception(e, current_user)
78
+ { mc: 'se00', msg: e.message, data: {} }
79
+ end
80
+ end
81
+
82
+ namespace :deleted_klasses do
83
+ desc 'list the soft-deleted Generic Klasses of one type'
84
+ params do
85
+ requires :klass, type: String, desc: 'Klass', values: Labimotion::Constants::Klass::ALL
86
+ end
87
+ after_validation do
88
+ authenticate_admin!(Labimotion::Constants::Family::FAMILY_OF[params[:klass]])
89
+ end
90
+ get do
91
+ list = deleted_klasses(params)
92
+ entity_class = "Labimotion::#{params[:klass]}Entity".constantize
93
+ # `deleted_at` is not on the klass entities (a sibling PR owns those files), and a
94
+ # restore list that cannot say when a template was deleted is not much of a list.
95
+ serialized = list.map do |klz|
96
+ entity_class.represent(klz).as_json.merge(deleted_at: klz.deleted_at&.iso8601)
97
+ end
98
+ { klass: serialized }
99
+ rescue StandardError => e
100
+ Labimotion.log_exception(e, current_user)
101
+ { mc: 'se00', msg: e.message, klass: [] }
102
+ end
103
+ end
104
+
105
+ namespace :restore_klass do
106
+ desc 'restore a soft-deleted Generic Klass'
107
+ params do
108
+ requires :klass, type: String, desc: 'Klass', values: Labimotion::Constants::Klass::ALL
109
+ requires :id, type: Integer, desc: 'Klass ID'
110
+ end
111
+ # authorize_klass!(:destroy) runs inside the helper, on the loaded deleted record —
112
+ # shares survive deletion, so the owner row is still there to gate the restore.
113
+ post do
114
+ restored_klass = restore_klass(params)
115
+ entity_class = "Labimotion::#{params[:klass]}Entity".constantize
116
+ { mc: 'ss00', data: entity_class.represent(restored_klass) }
117
+ rescue StandardError => e
118
+ Labimotion.log_exception(e, current_user)
119
+ { mc: 'se00', msg: e.message, data: {} }
120
+ end
121
+ end
122
+
57
123
  namespace :fetch do
58
124
  desc 'fetch Generic Klass by id'
59
125
  params do
60
126
  requires :id, type: Integer, desc: 'Klass ID'
61
- requires :klass, type: String, desc: 'Klass', values: %w[ElementKlass SegmentKlass DatasetKlass]
127
+ requires :klass, type: String, desc: 'Klass', values: Labimotion::Constants::Klass::ALL
62
128
  end
63
129
  get do
64
130
  klass_obj = fetch_klass(params[:klass], params[:id])