Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit f57dd92

Browse files
authored
feat(works): add teammate (#439)
* feat(works): add teamates on create/update * feat(works): is_maker flag for teammate * chore(works): is_maker in default user meta
1 parent 8a8c7e1 commit f57dd92

File tree

9 files changed

+103
-11
lines changed

9 files changed

+103
-11
lines changed

lib/groupher_server/accounts/models/embeds/user_meta.ex

+3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ defmodule GroupherServer.Accounts.Model.Embeds.UserMeta do
2929
@article_threads get_config(:article, :threads)
3030

3131
@general_options %{
32+
is_maker: false,
3233
reported_count: 0,
3334
reported_user_ids: [],
3435
follower_user_ids: [],
@@ -48,6 +49,8 @@ defmodule GroupherServer.Accounts.Model.Embeds.UserMeta do
4849
end
4950

5051
embedded_schema do
52+
field(:is_maker, :boolean, default: false)
53+
5154
field(:reported_count, :integer, default: 0)
5255
field(:reported_user_ids, {:array, :integer}, default: [])
5356

lib/groupher_server/cms/delegates/works_curd.ex

+34-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ defmodule GroupherServer.CMS.Delegate.WorksCURD do
1212
alias CMS.Model.{Community, Techstack, City, Works}
1313
alias Accounts.Model.User
1414

15+
@default_user_meta Accounts.Model.Embeds.UserMeta.default_meta()
16+
1517
alias Helper.ORM
1618
alias Ecto.Multi
1719

@@ -48,21 +50,24 @@ defmodule GroupherServer.CMS.Delegate.WorksCURD do
4850

4951
# update works spec fields
5052
defp update_works_fields(%Works{} = works, attrs) do
51-
works = Repo.preload(works, [:techstacks, :cities])
53+
works = Repo.preload(works, [:techstacks, :cities, :teammates])
5254

5355
cover = Map.get(attrs, :cover, works.cover)
5456
desc = Map.get(attrs, :desc, works.desc)
5557
home_link = Map.get(attrs, :home_link, works.home_link)
5658
techstacks = Map.get(attrs, :techstacks, works.techstacks)
59+
teammates = Map.get(attrs, :teammates, works.teammates)
5760
cities = Map.get(attrs, :cities, works.cities)
5861
social_info = Map.get(attrs, :social_info, works.social_info)
5962
app_store = Map.get(attrs, :app_store, works.app_store)
6063

6164
with {:ok, techstacks} <- get_or_create_techstacks(techstacks),
62-
{:ok, cities} <- get_or_create_cities(cities) do
65+
{:ok, cities} <- get_or_create_cities(cities),
66+
{:ok, teammates} <- get_teammates(teammates) do
6367
works
6468
|> Ecto.Changeset.change(%{cover: cover, desc: desc, home_link: home_link})
6569
|> Ecto.Changeset.put_assoc(:techstacks, uniq_by_raw(techstacks))
70+
|> Ecto.Changeset.put_assoc(:teammates, uniq_by_login(teammates))
6671
|> Ecto.Changeset.put_assoc(:cities, uniq_by_raw(cities))
6772
|> Ecto.Changeset.put_embed(:social_info, social_info)
6873
|> Ecto.Changeset.put_embed(:app_store, app_store)
@@ -109,6 +114,29 @@ defmodule GroupherServer.CMS.Delegate.WorksCURD do
109114
ORM.create(City, attrs)
110115
end
111116

117+
defp get_teammates([]), do: {:ok, []}
118+
119+
defp get_teammates(teammates) do
120+
teammates
121+
|> Enum.reduce([], fn login, acc ->
122+
with {:ok, teammate} <- ORM.find_by(User, login: login),
123+
{:ok, _} <- set_teammate_flag(teammate) do
124+
acc ++ [teammate]
125+
end
126+
end)
127+
|> done
128+
end
129+
130+
defp set_teammate_flag(%User{meta: nil} = teammate) do
131+
meta = Map.merge(@default_user_meta, %{is_maker: true})
132+
ORM.update_meta(teammate, meta)
133+
end
134+
135+
defp set_teammate_flag(%User{} = teammate) do
136+
meta = Map.merge(teammate.meta, %{is_maker: true})
137+
ORM.update_meta(teammate, meta)
138+
end
139+
112140
defp get_or_create_techstacks([]), do: {:ok, []}
113141

114142
defp get_or_create_techstacks(techstacks) do
@@ -148,9 +176,10 @@ defmodule GroupherServer.CMS.Delegate.WorksCURD do
148176
ORM.create(Techstack, attrs)
149177
end
150178

151-
defp uniq_by_raw(list) do
152-
Enum.uniq_by(list, & &1.raw)
153-
end
179+
defp uniq_by_raw([]), do: []
180+
defp uniq_by_raw(list), do: Enum.uniq_by(list, & &1.raw)
181+
defp uniq_by_login([]), do: []
182+
defp uniq_by_login(list), do: Enum.uniq_by(list, & &1.login)
154183

155184
# defp result({:ok, %{create_works: result}}), do: {:ok, result}
156185
defp result({:ok, %{update_works_fields: result}}), do: {:ok, result}

lib/groupher_server/cms/models/works.ex

+9-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ defmodule GroupherServer.CMS.Model.Works do
88
import Ecto.Changeset
99
import GroupherServer.CMS.Helper.Macros
1010

11-
alias GroupherServer.CMS
11+
alias GroupherServer.{CMS, Accounts}
1212
alias CMS.Model.{Embeds, Techstack, City}
13+
alias Accounts.Model.User
1314

1415
@timestamps_opts [type: :utc_datetime_usec]
1516

@@ -42,6 +43,13 @@ defmodule GroupherServer.CMS.Model.Works do
4243
on_replace: :delete
4344
)
4445

46+
many_to_many(
47+
:teammates,
48+
User,
49+
join_through: "works_join_teammates",
50+
on_replace: :delete
51+
)
52+
4553
many_to_many(
4654
:cities,
4755
City,

lib/groupher_server_web/schema/account/account_types.ex

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ defmodule GroupherServerWeb.Schema.Account.Types do
1919

2020
object :user_meta do
2121
field(:reported_count, :integer)
22+
field(:is_maker, :boolean)
2223
field(:published_posts_count, :integer)
2324
field(:published_jobs_count, :integer)
2425
field(:published_radars_count, :integer)

lib/groupher_server_web/schema/cms/cms_types.ex

+1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ defmodule GroupherServerWeb.Schema.CMS.Types do
102102
field(:profit_mode, :string)
103103
field(:working_mode, :string)
104104
field(:cities, list_of(:city), resolve: dataloader(CMS, :cities))
105+
field(:teammates, list_of(:common_user), resolve: dataloader(CMS, :teammates))
105106
field(:techstacks, list_of(:techstack), resolve: dataloader(CMS, :techstacks))
106107
field(:social_info, list_of(:social))
107108
field(:app_store, list_of(:app_store))

lib/groupher_server_web/schema/cms/mutations/works.ex

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ defmodule GroupherServerWeb.Schema.CMS.Mutations.Works do
1919
arg(:article_tags, list_of(:id))
2020

2121
arg(:techstacks, list_of(:string))
22+
arg(:teammates, list_of(:string))
2223
arg(:cities, list_of(:string))
2324

2425
arg(:profit_mode, :profit_mode)
@@ -45,6 +46,7 @@ defmodule GroupherServerWeb.Schema.CMS.Mutations.Works do
4546
arg(:article_tags, list_of(:id))
4647

4748
arg(:techstacks, list_of(:string))
49+
arg(:teammates, list_of(:string))
4850
arg(:cities, list_of(:string))
4951

5052
arg(:profit_mode, :profit_mode)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
defmodule GroupherServer.Repo.Migrations.WorksJoinTeammates do
2+
use Ecto.Migration
3+
4+
def change do
5+
create table(:works_join_teammates) do
6+
add(:works_id, references(:cms_works, on_delete: :delete_all), null: false)
7+
add(:user_id, references(:users, on_delete: :delete_all), null: false)
8+
end
9+
10+
create(unique_index(:works_join_teammates, [:works_id, :user_id]))
11+
end
12+
end

test/groupher_server/cms/articles/works_test.exs

+17-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ defmodule GroupherServer.Test.Articles.Works do
4545
working_mode: "FULLTIME",
4646
techstacks: ["elixir", "React"],
4747
cities: ["chengdu", "xiamen"],
48+
teammates: [user.login],
4849
social_info: social_info,
4950
app_store: app_store
5051
})
@@ -56,6 +57,8 @@ defmodule GroupherServer.Test.Articles.Works do
5657
assert works.profit_mode == "FREE"
5758
assert works.working_mode == "FULLTIME"
5859

60+
assert works.teammates |> List.first() |> Map.get(:login) === user.login
61+
5962
assert not is_nil(works.social_info)
6063
assert not is_nil(works.app_store)
6164
assert not is_nil(works.cities)
@@ -93,8 +96,10 @@ defmodule GroupherServer.Test.Articles.Works do
9396
assert techstack.raw == "elixir"
9497
end
9598

96-
test "update works with full attrs", ~m(user works_attrs)a do
99+
test "update works with full attrs", ~m(user user2 works_attrs)a do
100+
works_attrs = works_attrs |> Map.merge(%{teammates: [user.login]})
97101
{:ok, works} = CMS.create_works(works_attrs, user)
102+
assert works.teammates |> length == 1
98103

99104
social_info = [
100105
%{platform: "github", link: "https://github.com/xxx"},
@@ -107,7 +112,17 @@ defmodule GroupherServer.Test.Articles.Works do
107112
%{platform: "others", link: "https://others.com/xxx"}
108113
]
109114

110-
{:ok, works} = CMS.update_works(works, %{social_info: social_info, app_store: app_store})
115+
teammates = [user.login, user2.login]
116+
117+
{:ok, works} =
118+
CMS.update_works(works, %{
119+
social_info: social_info,
120+
app_store: app_store,
121+
teammates: teammates
122+
})
123+
124+
assert works.teammates |> length == 2
125+
111126
assert not is_nil(works.social_info)
112127
assert not is_nil(works.app_store)
113128
end

test/groupher_server_web/mutation/cms/articles/works_test.exs

+24-3
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ defmodule GroupherServer.Test.Mutation.Articles.Works do
33

44
import Helper.Utils, only: [keys_to_atoms: 1, camelize_map_key: 1]
55
alias Helper.ORM
6-
alias GroupherServer.{CMS, Repo}
6+
alias GroupherServer.{Accounts, CMS, Repo}
77

88
alias CMS.Model.Works
9+
alias Accounts.Model.User
910

1011
setup do
1112
{:ok, user} = db_insert(:user)
13+
{:ok, user2} = db_insert(:user)
1214
{:ok, community} = db_insert(:community, %{raw: "home"})
1315

1416
works_attrs = mock_attrs(:works, %{community_id: community.id})
@@ -18,7 +20,7 @@ defmodule GroupherServer.Test.Mutation.Articles.Works do
1820
user_conn = simu_conn(:user)
1921
owner_conn = simu_conn(:owner, works)
2022

21-
{:ok, ~m(user_conn guest_conn owner_conn community user works)a}
23+
{:ok, ~m(user_conn user user2 guest_conn owner_conn community user works)a}
2224
end
2325

2426
describe "[mutation works curd]" do
@@ -34,6 +36,7 @@ defmodule GroupherServer.Test.Mutation.Articles.Works do
3436
$workingMode: WorkingMode,
3537
$cities: [String],
3638
$techstacks: [String],
39+
$teammates: [String],
3740
$socialInfo: [SocialInfo],
3841
$appStore: [AppStoreInfo],
3942
$articleTags: [Id]
@@ -49,6 +52,7 @@ defmodule GroupherServer.Test.Mutation.Articles.Works do
4952
workingMode: $workingMode,
5053
cities: $cities,
5154
techstacks: $techstacks,
55+
teammates: $teammates,
5256
socialInfo: $socialInfo,
5357
appStore: $appStore,
5458
articleTags: $articleTags
@@ -70,6 +74,11 @@ defmodule GroupherServer.Test.Mutation.Articles.Works do
7074
desc
7175
logo
7276
}
77+
teammates {
78+
login
79+
nickname
80+
avatar
81+
}
7382
socialInfo {
7483
platform
7584
link
@@ -91,7 +100,8 @@ defmodule GroupherServer.Test.Mutation.Articles.Works do
91100
}
92101
}
93102
"""
94-
test "create works with valid attrs and make sure author exsit", ~m(community)a do
103+
@tag :wip
104+
test "create works with valid attrs and make sure author exsit", ~m(community user2)a do
95105
{:ok, user} = db_insert(:user)
96106
user_conn = simu_conn(:user, user)
97107

@@ -104,6 +114,7 @@ defmodule GroupherServer.Test.Mutation.Articles.Works do
104114
workingMode: "FULLTIME",
105115
cities: ["chengdu", "xiamen"],
106116
techstacks: ["elixir", "React"],
117+
teammates: [user.login, user2.login],
107118
socialInfo: [
108119
%{
109120
platform: "TWITTER",
@@ -137,6 +148,10 @@ defmodule GroupherServer.Test.Mutation.Articles.Works do
137148
assert created["cover"] == "cool cover"
138149
assert created["homeLink"] == "homeLink"
139150

151+
assert created["teammates"] |> length == 2
152+
assert user_exist_in?(user, created["teammates"])
153+
assert user_exist_in?(user2, created["teammates"])
154+
140155
assert created["profitMode"] == "FREE"
141156
assert created["workingMode"] == "FULLTIME"
142157
assert created["originalCommunity"]["id"] == to_string(community.id)
@@ -146,6 +161,12 @@ defmodule GroupherServer.Test.Mutation.Articles.Works do
146161
assert not is_nil(created["appStore"])
147162

148163
assert created["id"] == to_string(found.id)
164+
165+
{:ok, user} = ORM.find(User, user.id)
166+
{:ok, user2} = ORM.find(User, user2.id)
167+
168+
assert user.meta.is_maker
169+
assert user2.meta.is_maker
149170
end
150171

151172
test "create works with valid tags id list", ~m(user_conn user community)a do

0 commit comments

Comments
 (0)