flutter 0.1.0.pre.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.overcommit.yml +8 -0
- data/.rubocop.yml +10 -0
- data/CHANGELOG.md +6 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +35 -0
- data/Guardfile +9 -0
- data/LICENSE.txt +21 -0
- data/README.md +134 -0
- data/Rakefile +24 -0
- data/TODO.md +30 -0
- data/integration_tests/minitest/grape_app/.gitignore +67 -0
- data/integration_tests/minitest/grape_app/.ruby-version +1 -0
- data/integration_tests/minitest/grape_app/Gemfile +17 -0
- data/integration_tests/minitest/grape_app/Gemfile.lock +89 -0
- data/integration_tests/minitest/grape_app/README.md +2 -0
- data/integration_tests/minitest/grape_app/Rakefile +9 -0
- data/integration_tests/minitest/grape_app/api/api.rb +34 -0
- data/integration_tests/minitest/grape_app/api/routes/api_helpers.rb +12 -0
- data/integration_tests/minitest/grape_app/api/routes/change_request/api.rb +69 -0
- data/integration_tests/minitest/grape_app/api/routes/change_request/response_entity.rb +18 -0
- data/integration_tests/minitest/grape_app/api/routes/event/api.rb +121 -0
- data/integration_tests/minitest/grape_app/api/routes/event/response_entity.rb +41 -0
- data/integration_tests/minitest/grape_app/api/routes/project/api.rb +59 -0
- data/integration_tests/minitest/grape_app/api/routes/project/response_entity.rb +13 -0
- data/integration_tests/minitest/grape_app/api/routes/property/api.rb +78 -0
- data/integration_tests/minitest/grape_app/api/routes/property/response_entity.rb +31 -0
- data/integration_tests/minitest/grape_app/api/routes/trackable_object/api.rb +64 -0
- data/integration_tests/minitest/grape_app/api/routes/trackable_object/response_entity.rb +24 -0
- data/integration_tests/minitest/grape_app/api/routes/tracking_spec/api.rb +88 -0
- data/integration_tests/minitest/grape_app/api/routes/tracking_spec/response_entity.rb +17 -0
- data/integration_tests/minitest/grape_app/api/routes/tracking_spec/spec_response.rb +19 -0
- data/integration_tests/minitest/grape_app/api/routes/user/api.rb +22 -0
- data/integration_tests/minitest/grape_app/api/routes/user/response_entity.rb +12 -0
- data/integration_tests/minitest/grape_app/app/app.rb +30 -0
- data/integration_tests/minitest/grape_app/app/change_request/endpoint.rb +24 -0
- data/integration_tests/minitest/grape_app/app/change_request/generate_system_changes.rb +25 -0
- data/integration_tests/minitest/grape_app/app/change_request/service.rb +79 -0
- data/integration_tests/minitest/grape_app/app/event/endpoint.rb +78 -0
- data/integration_tests/minitest/grape_app/app/event/service.rb +68 -0
- data/integration_tests/minitest/grape_app/app/event/validator.rb +108 -0
- data/integration_tests/minitest/grape_app/app/project/endpoint.rb +24 -0
- data/integration_tests/minitest/grape_app/app/project/service.rb +42 -0
- data/integration_tests/minitest/grape_app/app/property/endpoint.rb +39 -0
- data/integration_tests/minitest/grape_app/app/property/service.rb +56 -0
- data/integration_tests/minitest/grape_app/app/trackable_object/endpoint.rb +38 -0
- data/integration_tests/minitest/grape_app/app/trackable_object/service.rb +49 -0
- data/integration_tests/minitest/grape_app/app/trackable_object/validator.rb +40 -0
- data/integration_tests/minitest/grape_app/app/tracking_spec/endpoint.rb +58 -0
- data/integration_tests/minitest/grape_app/app/tracking_spec/expand_tracking_spec_events.rb +91 -0
- data/integration_tests/minitest/grape_app/app/tracking_spec/service.rb +51 -0
- data/integration_tests/minitest/grape_app/app/tracking_spec/validator.rb +61 -0
- data/integration_tests/minitest/grape_app/app/utils/errors/api_exceptions.rb +10 -0
- data/integration_tests/minitest/grape_app/app/utils/errors/service_exceptions.rb +12 -0
- data/integration_tests/minitest/grape_app/app/versioned_entity/entity.rb +110 -0
- data/integration_tests/minitest/grape_app/app/versioned_entity/service.rb +47 -0
- data/integration_tests/minitest/grape_app/app/versioned_entity/validator.rb +61 -0
- data/integration_tests/minitest/grape_app/app/versioned_entity_snapshot/entity.rb +32 -0
- data/integration_tests/minitest/grape_app/config/boot.rb +9 -0
- data/integration_tests/minitest/grape_app/config.ru +3 -0
- data/integration_tests/minitest/grape_app/db/proto/change_request.rb +10 -0
- data/integration_tests/minitest/grape_app/db/proto/common/doc.rb +86 -0
- data/integration_tests/minitest/grape_app/db/proto/event.rb +10 -0
- data/integration_tests/minitest/grape_app/db/proto/event_snapshot.rb +10 -0
- data/integration_tests/minitest/grape_app/db/proto/project.rb +21 -0
- data/integration_tests/minitest/grape_app/db/proto/property.rb +10 -0
- data/integration_tests/minitest/grape_app/db/proto/property_snapshot.rb +10 -0
- data/integration_tests/minitest/grape_app/db/proto/trackable_object.rb +10 -0
- data/integration_tests/minitest/grape_app/db/proto/trackable_object_snapshot.rb +10 -0
- data/integration_tests/minitest/grape_app/db/proto/tracking_spec.rb +10 -0
- data/integration_tests/minitest/grape_app/test/api/functional/event_test.rb +186 -0
- data/integration_tests/minitest/grape_app/test/api/functional/property_test.rb +197 -0
- data/integration_tests/minitest/grape_app/test/api/functional/trackable_object_test.rb +134 -0
- data/integration_tests/minitest/grape_app/test/api/functional/tracking_spec_test.rb +56 -0
- data/integration_tests/minitest/grape_app/test/api/functional/user_test.rb +24 -0
- data/integration_tests/minitest/grape_app/test/api/functional/versioned_entity_helper.rb +157 -0
- data/integration_tests/minitest/grape_app/test/fixtures/change_requests.rb +83 -0
- data/integration_tests/minitest/grape_app/test/fixtures/event_snapshots.rb +105 -0
- data/integration_tests/minitest/grape_app/test/fixtures/events.rb +58 -0
- data/integration_tests/minitest/grape_app/test/fixtures/properties.rb +66 -0
- data/integration_tests/minitest/grape_app/test/fixtures/property_snapshots.rb +124 -0
- data/integration_tests/minitest/grape_app/test/fixtures/sample_tracking_spec.json +125 -0
- data/integration_tests/minitest/grape_app/test/fixtures/trackable_objects.rb +58 -0
- data/integration_tests/minitest/grape_app/test/fixtures/trackable_objects_snapshots.rb +61 -0
- data/integration_tests/minitest/grape_app/test/fixtures/tracking_specs.rb +22 -0
- data/integration_tests/minitest/grape_app/test/test_helper.rb +15 -0
- data/lib/flutter/config.rb +24 -0
- data/lib/flutter/minitest.rb +83 -0
- data/lib/flutter/parser.rb +82 -0
- data/lib/flutter/persistence.rb +152 -0
- data/lib/flutter/rspec.rb +66 -0
- data/lib/flutter/tracker.rb +133 -0
- data/lib/flutter/version.rb +5 -0
- data/lib/flutter.rb +12 -0
- data/lib/minitest/flutter_plugin.rb +16 -0
- data/sig/flutter.rbs +4 -0
- metadata +187 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative '../../app/versioned_entity/service'
|
2
|
+
require_relative 'validator'
|
3
|
+
module Skee
|
4
|
+
module App
|
5
|
+
module TrackableObject
|
6
|
+
class Service < Skee::App::VersionedEntityService
|
7
|
+
def self.entity
|
8
|
+
:trackable_object
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.create_fields_keys
|
12
|
+
%i(
|
13
|
+
change_request_id
|
14
|
+
previous_snapshot_id
|
15
|
+
is_removed
|
16
|
+
name
|
17
|
+
property_ids
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.update_fields_keys
|
22
|
+
%i(
|
23
|
+
change_request_id
|
24
|
+
is_removed
|
25
|
+
id
|
26
|
+
name
|
27
|
+
property_ids
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.add_property(params)
|
32
|
+
Skee::App::TrackableObject::Validator.new(params).
|
33
|
+
validate_add_property
|
34
|
+
trackable_object = get(id: params[:id])
|
35
|
+
trackable_object_property_ids = trackable_object.versioned_entity_snapshot.property_ids
|
36
|
+
property_id = params[:property_id]
|
37
|
+
|
38
|
+
return if trackable_object_property_ids.include?(property_id)
|
39
|
+
update_property_ids = trackable_object_property_ids + [property_id]
|
40
|
+
update(
|
41
|
+
id: params[:id],
|
42
|
+
property_ids: update_property_ids,
|
43
|
+
change_request_id: params[:change_request_id]
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative '../../app/change_request/service'
|
2
|
+
require_relative '../../app/tracking_spec/service'
|
3
|
+
module Skee
|
4
|
+
module App
|
5
|
+
module TrackableObject
|
6
|
+
class Validator
|
7
|
+
def initialize(params)
|
8
|
+
@params = params
|
9
|
+
end
|
10
|
+
|
11
|
+
ERRORS = Utils::Errors
|
12
|
+
|
13
|
+
def validate_add_property
|
14
|
+
validate_property_exists(@params[:property_id])
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate_remove_property
|
18
|
+
validate_property_exists(@params[:property_id])
|
19
|
+
validate_property_belongs_to_trackable_object(@params[:property_id], @params[:id])
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def validate_property_exists(property_id)
|
25
|
+
property_instance = Skee::App::DB_MAPPING_ENTITY[:property].find(property_id)
|
26
|
+
raise ERRORS::RecordNotFoundException.new('Resource not found') unless property_instance
|
27
|
+
end
|
28
|
+
|
29
|
+
def validate_property_belongs_to_trackable_object(property_id, trackable_object_id)
|
30
|
+
return if trackable_object(trackable_object_id).versioned_entity_snapshot.property_ids.include?(property_id)
|
31
|
+
raise ERRORS::NotAllowedToUpdate.new('Trackable object does not contain property.')
|
32
|
+
end
|
33
|
+
|
34
|
+
def trackable_object(trackable_object_id)
|
35
|
+
@trackable_object ||= Skee::App::TrackableObject::Service.get(id: trackable_object_id)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require_relative './service'
|
2
|
+
require_relative './validator'
|
3
|
+
require_relative './expand_tracking_spec_events'
|
4
|
+
|
5
|
+
module Skee::App::TrackingSpec
|
6
|
+
class Endpoint
|
7
|
+
ERRORS = Skee::App::Utils::Errors
|
8
|
+
|
9
|
+
def self.list
|
10
|
+
Service.list
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.get(params)
|
14
|
+
Service.get(params)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.full_spec(params)
|
18
|
+
Service.full_spec(params)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.create(params)
|
22
|
+
Service.create(params)
|
23
|
+
rescue ERRORS::RecordNotFoundException,
|
24
|
+
ERRORS::NotAllowedToUpdate => e
|
25
|
+
raise ERRORS::ValidationError.new(e.message)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.update(params)
|
29
|
+
Service.update(params)
|
30
|
+
rescue ERRORS::RecordNotFoundException,
|
31
|
+
ERRORS::NotAllowedToUpdate => e
|
32
|
+
raise ERRORS::ValidationError.new(e.message)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.delete(params)
|
36
|
+
Service.delete(params)
|
37
|
+
rescue ERRORS::RecordNotFoundException,
|
38
|
+
ERRORS::NotAllowedToUpdate => e
|
39
|
+
raise ERRORS::ValidationError.new(e.message)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.expand(params)
|
43
|
+
Skee::App::TrackingSpec::Validator.new(params).validate_expand_params
|
44
|
+
tracking_spec = Service.get(params)
|
45
|
+
expanded_events = ExpandTrackingSpecEvents.new(tracking_spec, params[:change_request_id]).perform
|
46
|
+
OpenStruct.new(
|
47
|
+
id: tracking_spec.id,
|
48
|
+
identifier: tracking_spec.identifier,
|
49
|
+
version: tracking_spec.version,
|
50
|
+
project_id: tracking_spec.project_id,
|
51
|
+
status: tracking_spec.status,
|
52
|
+
events: expanded_events
|
53
|
+
)
|
54
|
+
rescue ERRORS::RecordNotFoundException => e
|
55
|
+
raise ERRORS::ValidationError.new(e.message)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require_relative '../../app/event/service'
|
2
|
+
require_relative '../../app/property/service'
|
3
|
+
|
4
|
+
module Skee::App::TrackingSpec
|
5
|
+
class ExpandTrackingSpecEvents
|
6
|
+
def initialize(tracking_spec, change_request_id)
|
7
|
+
@tracking_spec = tracking_spec
|
8
|
+
@change_request_id = change_request_id
|
9
|
+
end
|
10
|
+
|
11
|
+
def perform
|
12
|
+
expand_events
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def event_snapshots
|
18
|
+
@tracking_spec.events.map do |event_id|
|
19
|
+
Skee::App::Event::Service.get(
|
20
|
+
id: event_id,
|
21
|
+
change_request_id: @change_request_id
|
22
|
+
).versioned_entity_snapshot
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def expand_events
|
27
|
+
event_snapshots.map do |snapshot|
|
28
|
+
event_payload = snapshot.payload
|
29
|
+
expanded_payload = event_payload.map do |key, value|
|
30
|
+
expanded_value = if value[:reference_entity_type] == :trackable_object
|
31
|
+
trackable_object_id = value[:reference_entity_id]
|
32
|
+
trackable_object_snapshot = get_trackable_object_snapshot(trackable_object_id)
|
33
|
+
property_ids = value[:selected_property_ids] & trackable_object_snapshot.property_ids
|
34
|
+
expand_trackable_object_properties(property_ids)
|
35
|
+
else
|
36
|
+
property_id = value[:reference_entity_id]
|
37
|
+
property_snapshot = get_property_snapshot(property_id)
|
38
|
+
expand_property(property_snapshot)
|
39
|
+
end
|
40
|
+
expanded_value = [expanqded_value] if value[:is_array]
|
41
|
+
[key, expanded_value]
|
42
|
+
end.to_h
|
43
|
+
{name: snapshot.name, description: snapshot.description, payload: expanded_payload}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def expand_trackable_object_properties(property_ids)
|
48
|
+
property_ids.map do |property_id|
|
49
|
+
property_snapshot = get_property_snapshot(property_id)
|
50
|
+
property_fields = expand_property(property_snapshot)
|
51
|
+
|
52
|
+
[property_snapshot.name, property_fields]
|
53
|
+
end.to_h
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
def expand_property(property_snapshot)
|
58
|
+
trackable_object_id = property_snapshot.trackable_object_id
|
59
|
+
if trackable_object_id
|
60
|
+
trackable_object_snapshot = get_trackable_object_snapshot(trackable_object_id)
|
61
|
+
property_ids = trackable_object_snapshot.property_ids
|
62
|
+
expanded_values = expand_trackable_object_properties(property_ids)
|
63
|
+
property_snapshot.is_array ? [expanded_values] : expanded_values
|
64
|
+
else
|
65
|
+
{
|
66
|
+
data_type: property_snapshot.data_type,
|
67
|
+
description: property_snapshot.description,
|
68
|
+
is_nullable: property_snapshot.is_nullable,
|
69
|
+
additional_instructions: property_snapshot.additional_instructions,
|
70
|
+
data_format_id: property_snapshot.data_format_id,
|
71
|
+
regex_validation: property_snapshot.regex_validation,
|
72
|
+
is_removed: property_snapshot.is_removed,
|
73
|
+
}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def get_trackable_object_snapshot(trackable_object_id)
|
78
|
+
Skee::App::TrackableObject::Service.get(
|
79
|
+
id: trackable_object_id,
|
80
|
+
change_request_id: @change_request_id
|
81
|
+
).versioned_entity_snapshot
|
82
|
+
end
|
83
|
+
|
84
|
+
def get_property_snapshot(property_id)
|
85
|
+
Skee::App::Property::Service.get(
|
86
|
+
id: property_id,
|
87
|
+
change_request_id: @change_request_id
|
88
|
+
).versioned_entity_snapshot
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require_relative '../../db/proto/tracking_spec'
|
2
|
+
module Skee
|
3
|
+
module App
|
4
|
+
module TrackingSpec
|
5
|
+
class Service
|
6
|
+
DB = Skee::DB::Proto
|
7
|
+
|
8
|
+
def self.list
|
9
|
+
DB::TrackingSpec.all
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.get(params)
|
13
|
+
DB::TrackingSpec.find(params[:id])
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.find_by(params)
|
17
|
+
DB::TrackingSpec.where(params)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.create(params)
|
21
|
+
# add any validation or filtering logic here to
|
22
|
+
# derive fields from params
|
23
|
+
fields = {
|
24
|
+
version_identifier: params[:version_identifier],
|
25
|
+
change_request_id: params[:change_request_id],
|
26
|
+
project_id: params[:project_id],
|
27
|
+
event_ids: params[:event_ids]
|
28
|
+
}
|
29
|
+
DB::TrackingSpec.create(fields)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.update(params)
|
33
|
+
# send valid fields excluding id
|
34
|
+
fields = {
|
35
|
+
version_identifier: params[:version_identifier],
|
36
|
+
change_request_id: params[:change_request_id],
|
37
|
+
project_id: params[:project_id],
|
38
|
+
event_ids: params[:event_ids]
|
39
|
+
}
|
40
|
+
tracking_spec = DB::TrackingSpec.find(params[:id])
|
41
|
+
tracking_spec.update(fields)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.delete(params)
|
45
|
+
tracking_spec = DB::TrackingSpec.find(params[:id])
|
46
|
+
tracking_spec.delete
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require_relative '../../app/change_request/service'
|
2
|
+
module Skee
|
3
|
+
module App
|
4
|
+
module TrackingSpec
|
5
|
+
class Validator
|
6
|
+
def initialize(params)
|
7
|
+
@params = params
|
8
|
+
end
|
9
|
+
|
10
|
+
ERRORS = Utils::Errors
|
11
|
+
|
12
|
+
def validate_create_params
|
13
|
+
validate_unique_version_identifier
|
14
|
+
validate_event_ids_exist
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate_update_params
|
18
|
+
validate_unique_version_identifier
|
19
|
+
validate_tracking_spec_exists
|
20
|
+
validate_event_ids_exist
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate_expand_params
|
24
|
+
validate_change_request
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def validate_unique_version_identifier
|
30
|
+
return unless @params[:version_identifier]
|
31
|
+
tracking_spec = Skee::App::TrackingSpec::Service.find_by(
|
32
|
+
version_identifier: @params[:version_identifier]
|
33
|
+
)
|
34
|
+
return unless tracking_spec
|
35
|
+
raise ERRORS::NotAllowedToUpdate.new('Invalid parameter: Version Identifier should be unique.')
|
36
|
+
end
|
37
|
+
|
38
|
+
def validate_tracking_spec_exists
|
39
|
+
tracking_spec = Skee::App::TrackingSpec::Service.get(id: @params[:id])
|
40
|
+
return if tracking_spec
|
41
|
+
raise ERRORS::RecordNotFoundException.new('Invalid parameter: Tracking spec does not exist')
|
42
|
+
end
|
43
|
+
|
44
|
+
def validate_event_ids_exist
|
45
|
+
return if @params[:event_ids].empty?
|
46
|
+
events = Skee::App::Event::Service.list(ids: @params[:event_ids])
|
47
|
+
return if (@params[:event_ids] - events.map(&:id)).empty?
|
48
|
+
raise ERRORS::NotAllowedToUpdate.new('Invalid parameter: Event IDs do not exist')
|
49
|
+
end
|
50
|
+
|
51
|
+
def validate_change_request
|
52
|
+
raise ERRORS::RecordNotFoundException.new('Invalid change request') unless change_request
|
53
|
+
end
|
54
|
+
|
55
|
+
def change_request
|
56
|
+
@change_request ||= Skee::App::ChangeRequest::Service.get(id: @params[:change_request_id])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Skee
|
2
|
+
module App
|
3
|
+
module Utils
|
4
|
+
module Errors
|
5
|
+
class UniquenessViolationException < StandardError; end
|
6
|
+
class RecordNotFoundException < StandardError; end
|
7
|
+
class NotAllowedToUpdate < StandardError; end
|
8
|
+
class NotAllowedToCancelChanges < StandardError; end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require_relative '../../app/change_request/service'
|
2
|
+
module Skee
|
3
|
+
module App
|
4
|
+
module VersionedEntity
|
5
|
+
class Entity
|
6
|
+
def initialize(entity)
|
7
|
+
@entity = entity
|
8
|
+
@db = Skee::App::DB_MAPPING_ENTITY[@entity]
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_accessor :versioned_entity, :versioned_entity_snapshot
|
12
|
+
|
13
|
+
def list(ids:, change_request_id:)
|
14
|
+
ids = @db.all.map(&:id) if ids.empty?
|
15
|
+
return_entities = ids.map{ |id| get({
|
16
|
+
id: id,
|
17
|
+
change_request_id: change_request_id
|
18
|
+
})
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def get(params)
|
23
|
+
versioned_entity_id = params[:id]
|
24
|
+
versioned_entity = @db.find(versioned_entity_id)
|
25
|
+
if change_request = Skee::App::ChangeRequest::Service.get(id: params[:change_request_id])
|
26
|
+
if change_request.change_set[@entity][versioned_entity_id]
|
27
|
+
entity_snapshot_id = change_request.change_set[@entity][versioned_entity_id].values.first
|
28
|
+
else
|
29
|
+
entity_snapshot_id = versioned_entity.latest_snapshot_id
|
30
|
+
end
|
31
|
+
else
|
32
|
+
entity_snapshot_id = versioned_entity.latest_snapshot_id
|
33
|
+
end
|
34
|
+
entity_snapshot = Skee::App::VersionedEntitySnapshot::Entity.new(@entity).get(id: entity_snapshot_id)
|
35
|
+
self.versioned_entity = versioned_entity
|
36
|
+
self.versioned_entity_snapshot = entity_snapshot
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def create(params)
|
41
|
+
versioned_entity_params = {
|
42
|
+
# may need to add more fields
|
43
|
+
# snapshot_mapping: {params[:change_request_id] => entity_snapshot.id
|
44
|
+
}
|
45
|
+
versioned_entity = @db.create(versioned_entity_params)
|
46
|
+
entity_snapshot_params = params.merge(parent_entity_id: versioned_entity.id)
|
47
|
+
entity_snapshot = Skee::App::VersionedEntitySnapshot::Entity.new(@entity).create(entity_snapshot_params)
|
48
|
+
update_change_request(params[:change_request_id], versioned_entity.id, nil, entity_snapshot.id)
|
49
|
+
self.versioned_entity = versioned_entity
|
50
|
+
self.versioned_entity_snapshot = entity_snapshot
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def update(update_params)
|
55
|
+
versioned_entity_id = update_params[:id]
|
56
|
+
change_request = Skee::App::ChangeRequest::Service.get(id: update_params[:change_request_id])
|
57
|
+
change_request.change_set[@entity] ||= {}
|
58
|
+
entity_snapshot = if change_request.change_set[@entity][versioned_entity_id]
|
59
|
+
update_existing_snapshot(change_request, update_params)
|
60
|
+
else
|
61
|
+
create_new_snapshot(update_params)
|
62
|
+
end
|
63
|
+
versioned_entity = @db.find(versioned_entity_id)
|
64
|
+
self.versioned_entity = versioned_entity
|
65
|
+
self.versioned_entity_snapshot = entity_snapshot
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def update_existing_snapshot(change_request, update_params)
|
72
|
+
versioned_entity_id = update_params[:id]
|
73
|
+
entity_snapshot_id = change_request.change_set[@entity][versioned_entity_id].values.first
|
74
|
+
existing_entity_snapshot = Skee::App::VersionedEntitySnapshot::Entity.new(@entity).get(id: entity_snapshot_id)
|
75
|
+
update_params = update_params.select {|key, _| key != :id && key != "id"}
|
76
|
+
existing_entity_snapshot.update(update_params)
|
77
|
+
end
|
78
|
+
|
79
|
+
def create_new_snapshot(update_params)
|
80
|
+
versioned_entity_id = update_params[:id]
|
81
|
+
existing_entity = @db.find(versioned_entity_id)
|
82
|
+
entity_snapshot_id = existing_entity.latest_snapshot_id
|
83
|
+
current_entity_snapshot = Skee::App::VersionedEntitySnapshot::Entity.new(@entity).get(id: entity_snapshot_id)
|
84
|
+
current_entity_snapshot_params = current_entity_snapshot.to_h.select {|key, _| key != :id && key != "id"}
|
85
|
+
new_entity_snapshot_params = current_entity_snapshot_params.each do |key, _|
|
86
|
+
current_entity_snapshot_params[key] = update_params[key] if update_params.key?(key)
|
87
|
+
end
|
88
|
+
new_entity_snapshot_params[:previous_snapshot_id] = entity_snapshot_id
|
89
|
+
new_entity_snapshot_params[:is_removed] = true if update_params[:is_removed]
|
90
|
+
new_entity_snapshot = Skee::App::VersionedEntitySnapshot::Entity.new(@entity).create(new_entity_snapshot_params)
|
91
|
+
update_change_request(update_params[:change_request_id], versioned_entity_id, entity_snapshot_id, new_entity_snapshot.id)
|
92
|
+
new_entity_snapshot
|
93
|
+
end
|
94
|
+
|
95
|
+
def update_change_request(change_request_id, versioned_entity_id, current_entity_snapshot_id, new_entity_snapshot_id)
|
96
|
+
Skee::App::ChangeRequest::Service.update_change_set(
|
97
|
+
id: change_request_id,
|
98
|
+
changes: {
|
99
|
+
@entity => {
|
100
|
+
versioned_entity_id => {
|
101
|
+
current_entity_snapshot_id => new_entity_snapshot_id
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative 'validator'
|
2
|
+
require_relative 'entity'
|
3
|
+
require_relative '../versioned_entity_snapshot/entity'
|
4
|
+
module Skee
|
5
|
+
module App
|
6
|
+
class VersionedEntityService
|
7
|
+
def self.list(ids: [], change_request_id: nil)
|
8
|
+
Skee::App::VersionedEntity::Entity.new(entity).list(ids: ids, change_request_id: change_request_id)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.get(params)
|
12
|
+
Skee::App::VersionedEntity::Entity.new(entity).get(params)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.create(params)
|
16
|
+
Skee::App::VersionedEntity::Validator.new(
|
17
|
+
params, entity
|
18
|
+
).validate_create_params
|
19
|
+
create_fields = create_fields_keys.map do |key|
|
20
|
+
value = key == :prev_entity_id ? nil : params[key]
|
21
|
+
[key, value]
|
22
|
+
end.to_h
|
23
|
+
Skee::App::VersionedEntity::Entity.new(entity).create(create_fields)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.update(params)
|
27
|
+
Skee::App::VersionedEntity::Validator.new(
|
28
|
+
params, entity
|
29
|
+
).validate_update_params
|
30
|
+
update_fields = params.slice(*update_fields_keys).compact
|
31
|
+
Skee::App::VersionedEntity::Entity.new(entity).update(update_fields)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.remove(params)
|
35
|
+
Skee::App::VersionedEntity::Validator.new(
|
36
|
+
params, entity
|
37
|
+
).validate_remove_params
|
38
|
+
remove_fields = {
|
39
|
+
change_request_id: params[:change_request_id],
|
40
|
+
id: params[:id],
|
41
|
+
is_removed: true
|
42
|
+
}
|
43
|
+
Skee::App::VersionedEntity::Entity.new(entity).update(remove_fields)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require_relative '../../app/change_request/service'
|
2
|
+
module Skee
|
3
|
+
module App
|
4
|
+
module VersionedEntity
|
5
|
+
class Validator
|
6
|
+
def initialize(params, entity_type)
|
7
|
+
@params = params
|
8
|
+
@entity_type = entity_type
|
9
|
+
end
|
10
|
+
|
11
|
+
ERRORS = Utils::Errors
|
12
|
+
|
13
|
+
def validate_create_params
|
14
|
+
validate_change_request_status
|
15
|
+
validate_uniqueness_by_name
|
16
|
+
end
|
17
|
+
|
18
|
+
def validate_update_params
|
19
|
+
validate_versioned_entity_present
|
20
|
+
validate_change_request_status
|
21
|
+
validate_uniqueness_by_name
|
22
|
+
end
|
23
|
+
|
24
|
+
def validate_remove_params
|
25
|
+
validate_versioned_entity_present
|
26
|
+
validate_change_request_status
|
27
|
+
validate_uniqueness_by_name
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def validate_versioned_entity_present
|
33
|
+
entity_instance = Skee::App::DB_MAPPING_ENTITY[@entity_type].find(@params[:id])
|
34
|
+
raise ERRORS::RecordNotFoundException.new('Resource not found') unless entity_instance
|
35
|
+
end
|
36
|
+
|
37
|
+
def validate_change_request_status
|
38
|
+
raise ERRORS::RecordNotFoundException.new('Invalid change request') unless change_request
|
39
|
+
raise ERRORS::NotAllowedToUpdate.new('Invalid change request') if change_request.status != 'open'
|
40
|
+
end
|
41
|
+
|
42
|
+
def validate_uniqueness_by_name
|
43
|
+
# todo: fix this when we know structure of tracking spec
|
44
|
+
# tracking_spec = Skee::App::TrackingSpec::Service.get(id: change_request.source_tracking_spec_id)
|
45
|
+
# existing_entity_ids = tracking_spec.entity_set[@entity_type]
|
46
|
+
# new_entity_change_set = change_request.change_set[@entity_type]
|
47
|
+
# return unless new_entity_change_set
|
48
|
+
# new_entity_ids = new_entity_change_set.values.flatten
|
49
|
+
# non_unique_name = Skee::App::DB_MAPPING_ENTITY[@entity_type].find_all(ids: (new_entity_ids + existing_entity_ids)).any? do |entity|
|
50
|
+
# entity.name == @params[:name]
|
51
|
+
# end
|
52
|
+
# raise ERRORS::UniquenessViolationException.new('Invalid name') if non_unique_name
|
53
|
+
end
|
54
|
+
|
55
|
+
def change_request
|
56
|
+
@change_request ||= Skee::App::ChangeRequest::Service.get(id: @params[:change_request_id])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative '../../app/change_request/service'
|
2
|
+
module Skee
|
3
|
+
module App
|
4
|
+
module VersionedEntitySnapshot
|
5
|
+
class Entity
|
6
|
+
def initialize(entity)
|
7
|
+
@entity = entity
|
8
|
+
@db = Skee::App::DB_MAPPING_ENTITY_SNAPSHOT[@entity]
|
9
|
+
end
|
10
|
+
|
11
|
+
def list(ids:)
|
12
|
+
return @db.all if ids.empty?
|
13
|
+
@db.find_all(ids: ids)
|
14
|
+
end
|
15
|
+
|
16
|
+
def get(params)
|
17
|
+
# add validator, to reject if nil, or does not exist.
|
18
|
+
@db.find(params[:id])
|
19
|
+
end
|
20
|
+
|
21
|
+
def create(params)
|
22
|
+
@db.create(params)
|
23
|
+
end
|
24
|
+
|
25
|
+
def update(update_params)
|
26
|
+
snapshot = @db.find(update_params[:id])
|
27
|
+
snapshot.update(update_params)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|