Skip to content

Instantly share code, notes, and snippets.

@rybex rybex/add_new_team.rb Secret
Created Sep 18, 2015

Embed
What would you like to do?
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
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
Rails.application.configure do
#other stuff
config.event_store = EventStore::SetupEventStore.new.()
end
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
module EventStore
module Injector
def event_store
@event_store ||= Rails.application.config.event_store
end
end
end
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
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
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
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
You can’t perform that action at this time.