-
-
Save rybex/3d150e2e850fb5b8ea46 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module AppServices | |
class AddNewTeam | |
include EventStore::Injector | |
def initialize(team_repository = ::OrganizationBc::Adapters::TeamRepository.new) | |
@team_repository = team_repository | |
end | |
def call(team_data) | |
team = create_new_team(team_data) | |
publish_team_created(team_data, team.id, parent.department) | |
team | |
end | |
private | |
attr_reader :team_repository | |
def create_new_team(team_data) | |
add_new_team = OrganizationBc::Teams::Services::AddNewTeam.new(team_repository) | |
add_new_team.(team_data) | |
end | |
def publish_team_created(team, team_id, department) | |
stream_name = "team/#{team_id}" | |
event = ::Event::TeamCreated.new({ | |
data: { | |
team: { | |
id: team_id, | |
organization_id: team[:organization_id], | |
name: team[:name], | |
parent_id: team[:parent_id], | |
department: team[:department], | |
type: 'team' | |
} | |
} | |
}) | |
event_store.publish_event(event, stream_name) | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module OrganizationBc | |
module Teams | |
module Services | |
class AddNewTeam | |
def initialize(repository) | |
@repository = repository | |
end | |
def call(team) | |
team = Team.new({ | |
id: team[:id], | |
name: team[:name], | |
organization_id: team[:organization_id] | |
}) | |
repository.create(team) | |
end | |
private | |
attr_reader :repository | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Rails.application.configure do | |
#other stuff | |
config.event_store = EventStore::SetupEventStore.new.() | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class TeamsController < ApplicationController | |
before_action :authenticate_user_from_token! | |
def in_organization | |
teams = AppServices::TeamsInOrganization.new.(params[:organization_id]) | |
render json: { teams: teams } | |
end | |
def show | |
AppServices::GetTeam.new.(params[:id]) | |
end | |
def create | |
AppServices::AddNewTeam.new.(params[:team]) | |
end | |
def update | |
AppServices::EditTeamData.new.(params[:team]) | |
end | |
def destroy | |
AppServices::RemoveTeam.new.(params[:id]) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module EventStore | |
module Injector | |
def event_store | |
@event_store ||= Rails.application.config.event_store | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module AppQueries | |
class LoadOrganizationStructure | |
def initialize(repository = OrganizationBc::Adapters::StructureReadModelRepository.new) | |
@repository = repository | |
end | |
def call(organization_id) | |
repository.find_by_organization_id!(organization_id) | |
end | |
private | |
attr_reader :repository | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module EventStore | |
class SetupEventStore | |
def call | |
event_store = RailsEventStore::Client.new | |
structure_read_model = OrganizationBc::ReadModels::Structure.new | |
event_store = config_structure_handler(structure_read_model, event_store) | |
event_store | |
end | |
private | |
def config_structure_handler(structure_read_model, event_store) | |
events = ['Event::OrganizationCreated', | |
'Event::MemberAdded', | |
'Event::MemberUpdated', | |
'Event::MemberDeleted', | |
'Event::MemberUnassigned', | |
'Event::TeamCreated', | |
'Event::TeamUpdated', | |
'Event::TeamRemoved'] | |
event_store.subscribe(structure_read_model, events) | |
event_store | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module OrganizationBc | |
module ReadModels | |
class Structure | |
def initialize(repository = ::OrganizationBc::Adapters::StructureReadModelRepository.new) | |
@repository = repository | |
end | |
def handle_event(event) | |
case event.event_type | |
when 'Event::OrganizationCreated' | |
create_structure_for_organization(event.data[:organization]) | |
when 'Event::MemberAdded' | |
update_structure(event.data[:member]) { |structure, member| add_member_to_model(structure, member) } | |
when 'Event::MemberUpdated' | |
update_structure(event.data[:member]) { |structure, member| update_member_in_model(structure, member) } | |
when 'Event::MemberDeleted' | |
update_structure(event.data[:member]) { |structure, member| remove_member_from_model(structure, member) } | |
when 'Event::MemberUnassigned' | |
update_structure(event.data[:member]) { |structure, member| remove_member_from_model(structure, member) } | |
when 'Event::TeamCreated' | |
update_structure(event.data[:team]) { |structure, team| add_team_to_model(structure, team) } | |
when 'Event::TeamUpdated' | |
handle_team_updated(event) | |
when 'Event::TeamRemoved' | |
update_structure(event.data[:team]) { |structure, team| remove_team_from_model(structure, team) } | |
end | |
end | |
private | |
attr_reader :repository | |
def create_structure_for_organization(organization) | |
save_structure(organization[:id]) | |
end | |
def update_structure(element) | |
org_structure = get_organization_structure(element[:organization_id]) | |
yield(org_structure[:structure], element.merge!(children: [])) | |
save_structure(element[:organization_id], org_structure) | |
end | |
def add_member_to_model(people, member) | |
if member[:parent_id] == '' | |
people.push member | |
else | |
people.each do |person| | |
if person['id'] == member[:parent_id] | |
person['children'] << member | |
else | |
add_member_to_model(person['children'], member) | |
end | |
end | |
end | |
end | |
def update_member_in_model(people, member) | |
people.each_with_index do |person, index| | |
if person['id'] == member[:id] | |
people[index] = member | |
else | |
update_member_in_model(person['children'], member) | |
end | |
end | |
end | |
def remove_member_from_model(people, member) | |
people.each_with_index do |person, index| | |
if person['id'] == member[:id] | |
people.delete_at(index) | |
else | |
remove_member_from_model(person['children'], member) | |
end | |
end | |
end | |
def add_team_to_model(people, team) | |
people.each do |person| | |
if person['id'] == team[:parent_id] | |
person['children'] << team | |
else | |
add_team_to_model(person['children'], team) | |
end | |
end | |
end | |
def handle_team_updated(event) | |
#code | |
end | |
def update_team_in_nodes(nodes, team) | |
nodes.map do |node| | |
if node['id'] == team[:id] | |
team[:children] = node['children'] | |
team | |
else | |
node['children'] = update_team_in_nodes(node['children'], team) | |
node | |
end | |
end | |
end | |
def remove_team_from_model(people, team) | |
people.each_with_index do |person, index| | |
if person['id'] == team[:id] | |
people.delete_at(index) | |
else | |
remove_team_from_model(person['children'], team) | |
end | |
end | |
end | |
def get_organization_structure(organization_id) | |
record = repository.find_by_organization_id!(organization_id) | |
{structure: record.model['structure'], departments: record.model['departments'], version: record.version} | |
end | |
def save_structure(organization_id, model = {structure: [], departments: [], version: 0}) | |
repository.create(organization_id, model) | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module OrganizationBc | |
module Adapters | |
class StructureReadModelRepository | |
class StructureReadModel < ActiveRecord::Base | |
self.table_name = 'structures_read_models' | |
end | |
ReadModelNotFound = Class.new(StandardError) | |
def create(organization_id, model) | |
version = model[:version] + 1 | |
model[:version] = version | |
record = StructureReadModel.new({ organization_id: organization_id, version: version, model: model}) | |
record.save! | |
end | |
def find_by_organization_id!(organization_id) | |
record = find_by_organization_id(organization_id) | |
raise ReadModelNotFound.new if record.nil? | |
record | |
end | |
private | |
def find_by_organization_id(organization_id) | |
StructureReadModel.where(organization_id: organization_id).order(:version).last | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment