Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add schema migration for new tables #1485

Merged
merged 42 commits into from
May 17, 2021
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
f44cee9
Add schema migration for new tables
jschaul May 4, 2021
2f64fba
initial query cql
jschaul May 5, 2021
a7122fd
Try making use of a KnownOrign type to distinguish between local and …
jschaul May 5, 2021
86ece23
Remove KnownOrigin idea and use Tagged instead
jschaul May 5, 2021
c129bb7
some conversations don't need remote users at this point
jschaul May 5, 2021
e31c121
add function to remove members
jschaul May 5, 2021
14e9cac
WIP: remove Internal ?
jschaul May 5, 2021
fee2bbe
reshuffle types: introduce internal RemoteMember
jschaul May 5, 2021
a091691
WIP
jschaul May 6, 2021
7a9171b
define RemoteMember and add a list of remote members to the internal …
jschaul May 10, 2021
e6a9f99
WIP: add remote member to conversation
jschaul May 10, 2021
c28ed83
lookup remote members, too
jschaul May 10, 2021
4737da5
Remote users don't have a conversation role. At least for now
jschaul May 10, 2021
e958865
Merge branch 'develop' into add-remote-users-to-conversation-schema
jschaul May 10, 2021
dedcc5b
WIP: add schema-p schema for InviteQualified and its subtypes.
jschaul May 10, 2021
42e9db1
Merge branch 'develop' into add-remote-users-to-conversation-schema
akshaymankar May 11, 2021
1863c15
Add ToSchema instances to get galley to compile
akshaymankar May 11, 2021
36e891b
galley: Add test to add remote member in a conv
akshaymankar May 11, 2021
089fc8f
Merge branch 'develop' into add-remote-users-to-conversation-schema
jschaul May 11, 2021
2c49568
undo accidental change in cargohold
jschaul May 11, 2021
a98e597
add member to conv tests: check event type
jschaul May 11, 2021
5e75452
Add servant scaffolding for galley internal endpoints
jschaul May 11, 2021
c9ffc15
WIP: internal endpoints to test the cassandra stuff without all of th…
jschaul May 11, 2021
3c459f1
Remove redundant import
akshaymankar May 12, 2021
a8e0a33
Data.Qualified: Better type signature for pattern Remote
akshaymankar May 12, 2021
beea506
Remove unnecessary type signature in <-
akshaymankar May 12, 2021
e0bebf4
Ormolu
akshaymankar May 12, 2021
4204fbf
Don't introduce new internal endpoints for add-remote-member; instead…
jschaul May 12, 2021
1a83140
Qualify OtherMember and add to the output of Conversation
jschaul May 12, 2021
8002e33
Also store RoleName
jschaul May 12, 2021
d6b6af8
Golden tests: change haskell definitions
jschaul May 12, 2021
a658e4e
golden tests: delete and have json files regenerated
jschaul May 12, 2021
3b87a92
Update comments, slight refactor, write down next steps
jschaul May 12, 2021
dcbfb05
fix compilation brig;api-bot
jschaul May 12, 2021
ccf0277
Merge remote-tracking branch 'origin/develop' into add-remote-users-t…
pcapriotti May 14, 2021
c8fec4b
Fix build
pcapriotti May 14, 2021
bc5d68a
Remove manual JSON instances for OtherMember
pcapriotti May 14, 2021
81df0ee
Merge branch 'develop' into add-remote-users-to-conversation-schema
akshaymankar May 17, 2021
e251ee4
PR feedback comments
jschaul May 17, 2021
adcc72a
PR feedback: rename
jschaul May 17, 2021
7c41a8e
remove contentious omId function
jschaul May 17, 2021
aacb294
Update reference docs on cassandra schema
jschaul May 17, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion libs/api-bot/src/Network/Wire/Bot/Assert.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
module Network.Wire.Bot.Assert where

import Data.Id (ConvId, UserId)
import Data.Qualified (qUnqualified)
import qualified Data.Set as Set
import Imports
import Network.Wire.Bot.Monad
Expand All @@ -46,7 +47,7 @@ assertConvCreated c b bs = do
EConvCreate e ->
let cnv = convEvtData e
mems = cnvMembers cnv
omems = Set.fromList (map omId (cmOthers mems))
omems = Set.fromList (map (qUnqualified . omQualifiedId) (cmOthers mems))
jschaul marked this conversation as resolved.
Show resolved Hide resolved
in cnvId cnv == c
&& convEvtFrom e == botId b
&& cnvType cnv == RegularConv
Expand Down
3 changes: 2 additions & 1 deletion libs/galley-types/src/Galley/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module Galley.Types
-- * re-exports
Conversation (..),
LocalMember,
RemoteMember,
InternalMember (..),
ConvMembers (..),
OtherMember (..),
Expand Down Expand Up @@ -76,7 +77,7 @@ import Data.Id (ClientId, ConvId, TeamId, UserId)
import Data.Json.Util ((#))
import qualified Data.Map.Strict as Map
import Data.Misc (Milliseconds)
import Galley.Types.Conversations.Members (InternalMember (..), LocalMember)
import Galley.Types.Conversations.Members (InternalMember (..), LocalMember, RemoteMember)
import Imports
import Wire.API.Conversation hiding (Member (..))
import Wire.API.Conversation.Code
Expand Down
12 changes: 10 additions & 2 deletions libs/galley-types/src/Galley/Types/Conversations/Members.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,28 @@

module Galley.Types.Conversations.Members
( LocalMember,
RemoteMember (..),
InternalMember (..),
)
where

import Data.Id as Id
import Data.Qualified (Remote)
import Imports
import Wire.API.Conversation.Member (MutedStatus)
import Wire.API.Conversation.Role (RoleName)
import Wire.API.Provider.Service (ServiceRef)

type LocalMember = InternalMember Id.UserId

-- | Internal representation of a conversation member.
data InternalMember id = Member
data RemoteMember = RemoteMember
{ rmId :: Remote UserId,
rmConvRoleName :: RoleName
}
deriving stock (Show)

-- | Internal (cassandra) representation of a conversation member.
data InternalMember id = InternalMember
{ memId :: id,
memService :: Maybe ServiceRef,
-- | DEPRECATED, remove it once enough clients use `memOtrMutedStatus`
Expand Down
2 changes: 0 additions & 2 deletions libs/types-common/src/Data/Id.hs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ data T

data STo

data Remote a

type AssetId = Id A

type InvitationId = Id I
Expand Down
20 changes: 19 additions & 1 deletion libs/types-common/src/Data/Qualified.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ module Data.Qualified

-- * Qualified
Qualified (..),
Remote,
toRemote,
renderQualifiedId,
partitionRemoteOrLocalIds,
partitionRemoteOrLocalIds',
partitionQualified,
deprecatedSchema,
)
Expand All @@ -39,6 +42,7 @@ import Control.Applicative (optional)
import Control.Lens ((?~))
import Data.Aeson (FromJSON (..), ToJSON (..))
import qualified Data.Attoparsec.ByteString.Char8 as Atto
import Data.Bifunctor (first)
import Data.ByteString.Conversion (FromByteString (parser))
import Data.Domain (Domain, domainText)
import Data.Handle (Handle (..))
Expand All @@ -47,12 +51,13 @@ import qualified Data.Map as Map
import Data.Schema
import Data.String.Conversions (cs)
import qualified Data.Swagger as S
import Data.Tagged
import qualified Data.UUID as UUID
import Imports hiding (local)
import Test.QuickCheck (Arbitrary (arbitrary))

----------------------------------------------------------------------
-- OPTIONALLY QUALIFIED
-- OPTIONALLY QUALIFIED -- FUTUREWORK: remove optionally qualified, not used

data OptionallyQualified a = OptionallyQualified
{ oqUnqualified :: a,
Expand Down Expand Up @@ -96,6 +101,16 @@ data Qualified a = Qualified
}
deriving stock (Eq, Ord, Show, Generic, Functor)

-- | A type to differentiate between generally Qualified values, and values
-- where it is known if they are coming from a Remote backend or not.
-- Use 'toRemote' or 'partitionRemoteOrLocalIds\'' to get Remote values and use
-- 'unTagged' to convert from a Remote value back to a plain Qualified one.
type Remote a = Tagged "remote" (Qualified a)
jschaul marked this conversation as resolved.
Show resolved Hide resolved

-- | Convert a Qualified something to a Remote something.
toRemote :: Qualified a -> Remote a
toRemote = Tagged

-- | FUTUREWORK: Maybe delete this, it is only used in printing federation not
-- implemented errors
renderQualified :: (a -> Text) -> Qualified a -> Text
Expand All @@ -108,6 +123,9 @@ partitionRemoteOrLocalIds localDomain = foldMap $ \qualifiedId ->
then (mempty, [qUnqualified qualifiedId])
else ([qualifiedId], mempty)

partitionRemoteOrLocalIds' :: Foldable f => Domain -> f (Qualified a) -> ([Remote a], [a])
partitionRemoteOrLocalIds' localDomain xs = first (fmap toRemote) $ partitionRemoteOrLocalIds localDomain xs

jschaul marked this conversation as resolved.
Show resolved Hide resolved
-- | Index a list of qualified values by domain
partitionQualified :: [Qualified a] -> Map Domain [a]
partitionQualified = foldr add mempty
Expand Down
21 changes: 20 additions & 1 deletion libs/wire-api/src/Wire/API/Conversation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ module Wire.API.Conversation

-- * invite
Invite (..),
InviteQualified (..),
newInvite,

-- * update
Expand Down Expand Up @@ -74,9 +75,11 @@ import qualified Data.Aeson as A
import qualified Data.Aeson.Types as A
import Data.Id
import Data.Json.Util
import Data.List.NonEmpty (NonEmpty)
import Data.List1
import Data.Misc
import Data.Proxy (Proxy (Proxy))
import Data.Qualified (Qualified)
import Data.Schema
import Data.String.Conversions (cs)
import qualified Data.Swagger as S
Expand Down Expand Up @@ -541,14 +544,30 @@ instance FromJSON ConvTeamInfo where
--------------------------------------------------------------------------------
-- invite

data Invite = Invite
data Invite = Invite -- Deprecated, use InviteQualified (and maybe rename?)
{ invUsers :: List1 UserId,
-- | This role name is to be applied to all users
invRoleName :: RoleName
}
deriving stock (Eq, Show, Generic)
deriving (Arbitrary) via (GenericUniform Invite)

data InviteQualified = InviteQualified
{ invQUsers :: NonEmpty (Qualified UserId),
-- | This role name is to be applied to all users
invQRoleName :: RoleName
}
deriving stock (Eq, Show, Generic)
deriving (Arbitrary) via (GenericUniform InviteQualified)
deriving (ToJSON, FromJSON, S.ToSchema) via (Schema InviteQualified)

instance ToSchema InviteQualified where
schema =
object "InviteQualified" $
InviteQualified
<$> invQUsers .= field "qualified_users" (nonEmptyArray schema)
<*> invQRoleName .= (field "conversation_role" schema <|> pure roleNameWireAdmin)

newInvite :: List1 UserId -> Invite
newInvite us = Invite us roleNameWireAdmin

Expand Down
28 changes: 9 additions & 19 deletions libs/wire-api/src/Wire/API/Conversation/Member.hs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import Data.Aeson (FromJSON (..), ToJSON (..))
import qualified Data.Aeson as A
import Data.Id
import Data.Json.Util
import Data.Qualified
import Data.Schema
import qualified Data.Swagger as S
import qualified Data.Swagger.Build.Api as Doc
Expand Down Expand Up @@ -169,26 +170,31 @@ newtype MutedStatus = MutedStatus {fromMutedStatus :: Int32}
deriving (FromJSON, ToJSON, S.ToSchema) via Schema MutedStatus

data OtherMember = OtherMember
{ omId :: UserId,
{ omQualifiedId :: Qualified UserId,
omService :: Maybe ServiceRef,
omConvRoleName :: RoleName
}
deriving stock (Eq, Show, Generic)
deriving (Arbitrary) via (GenericUniform OtherMember)
deriving (FromJSON, ToJSON, S.ToSchema) via Schema OtherMember

omId :: OtherMember -> UserId
omId = qUnqualified . omQualifiedId
jschaul marked this conversation as resolved.
Show resolved Hide resolved

instance ToSchema OtherMember where
schema =
object "OtherMember" $
OtherMember
<$> omId .= field "id" schema
<$> omQualifiedId .= field "qualified_id" schema
<* omId .= optional (field "id" schema)
<*> omService .= opt (fieldWithDocModifier "service" (description ?~ desc) schema)
<*> omConvRoleName .= (field "conversation_role" schema <|> pure roleNameWireAdmin)
<* const (0 :: Int) .= optional (fieldWithDocModifier "status" (description ?~ "deprecated") schema) -- TODO: remove
where
desc = "The reference to the owning service, if the member is a 'bot'."

instance Ord OtherMember where
compare a b = compare (omId a) (omId b)
compare a b = compare (omQualifiedId a) (omQualifiedId b)

modelOtherMember :: Doc.Model
modelOtherMember = Doc.defineModel "OtherMember" $ do
Expand All @@ -198,22 +204,6 @@ modelOtherMember = Doc.defineModel "OtherMember" $ do
Doc.description "The reference to the owning service, if the member is a 'bot'."
Doc.optional

instance ToJSON OtherMember where
toJSON m =
A.object $
"id" A..= omId m
# "status" A..= (0 :: Int) -- TODO: Remove
# "service" A..= omService m
# "conversation_role" A..= omConvRoleName m
# []

instance FromJSON OtherMember where
parseJSON = A.withObject "other-member" $ \o ->
OtherMember
<$> o A..: "id"
<*> o A..:? "service"
<*> o A..:? "conversation_role" A..!= roleNameWireAdmin

--------------------------------------------------------------------------------
-- Member Updates

Expand Down
5 changes: 5 additions & 0 deletions libs/wire-api/src/Wire/API/Event/Conversation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import Data.Aeson.Types (Parser)
import qualified Data.HashMap.Strict as HashMap
import Data.Id
import Data.Json.Util (ToJSONObject (toJSONObject), UTCTimeMillis (fromUTCTimeMillis), toUTCTimeMillis, (#))
import qualified Data.Swagger as S
import qualified Data.Swagger.Build.Api as Doc
import Data.Time
import Imports
Expand All @@ -92,6 +93,10 @@ data Event = Event
}
deriving stock (Eq, Show, Generic)

-- TODO: Merge work from https://github.com/wireapp/wire-server/pull/1482
jschaul marked this conversation as resolved.
Show resolved Hide resolved
instance S.ToSchema Event where
declareNamedSchema _ = pure $ S.NamedSchema Nothing mempty

modelEvent :: Doc.Model
modelEvent = Doc.defineModel "Event" $ do
Doc.description "Event data"
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"members":[{"status":0,"service":{"id":"00000001-0000-0000-0000-000100000000","provider":"00000000-0000-0000-0000-000000000001"},"conversation_role":"t4vroye869mch4","id":"00000001-0000-0000-0000-000000000000"},{"status":0,"conversation_role":"bi8z5mc78lg3bqqk29yd36x2_haz6b05t6ybil8p7zbkj","id":"00000000-0000-0000-0000-000000000001"},{"status":0,"service":{"id":"00000000-0000-0000-0000-000000000001","provider":"00000001-0000-0000-0000-000100000000"},"conversation_role":"ncz23zan6fw786izkcx","id":"00000000-0000-0000-0000-000100000001"},{"status":0,"service":{"id":"00000001-0000-0001-0000-000100000000","provider":"00000001-0000-0000-0000-000100000001"},"conversation_role":"_brjrjrldhybr251gl72y3_nqqwhdh8k2c0oznqgiwrhzf0szdd15laruwrrm640pa_z8eg5d2mvm_nppm51rszf20dwpshy7ushykyavtq5dq2mwdqqcpv_nb7lkl","id":"00000000-0000-0000-0000-000100000000"},{"status":0,"service":{"id":"00000001-0000-0000-0000-000100000000","provider":"00000000-0000-0000-0000-000000000001"},"conversation_role":"jpy159h7vqij1p08dgsehcpyxg6_ovkcpjruqg6xp8b4lpegp7qrfr_qsyoo3qnngi7btjxrt6bbjcfmit2p6g_j5abxj4o5xliz","id":"00000001-0000-0001-0000-000100000001"}],"id":"00000006-0000-0012-0000-001900000009"}
{"members":[{"status":0,"service":{"id":"00000001-0000-0000-0000-000100000000","provider":"00000000-0000-0000-0000-000000000001"},"conversation_role":"t4vroye869mch4","qualified_id":{"domain":"golden.example.com","id":"00000001-0000-0000-0000-000000000000"},"id":"00000001-0000-0000-0000-000000000000"},{"status":0,"conversation_role":"bi8z5mc78lg3bqqk29yd36x2_haz6b05t6ybil8p7zbkj","qualified_id":{"domain":"golden.example.com","id":"00000000-0000-0000-0000-000000000001"},"id":"00000000-0000-0000-0000-000000000001"},{"status":0,"service":{"id":"00000000-0000-0000-0000-000000000001","provider":"00000001-0000-0000-0000-000100000000"},"conversation_role":"ncz23zan6fw786izkcx","qualified_id":{"domain":"golden.example.com","id":"00000000-0000-0000-0000-000100000001"},"id":"00000000-0000-0000-0000-000100000001"},{"status":0,"service":{"id":"00000001-0000-0001-0000-000100000000","provider":"00000001-0000-0000-0000-000100000001"},"conversation_role":"_brjrjrldhybr251gl72y3_nqqwhdh8k2c0oznqgiwrhzf0szdd15laruwrrm640pa_z8eg5d2mvm_nppm51rszf20dwpshy7ushykyavtq5dq2mwdqqcpv_nb7lkl","qualified_id":{"domain":"golden.example.com","id":"00000000-0000-0000-0000-000100000000"},"id":"00000000-0000-0000-0000-000100000000"},{"status":0,"service":{"id":"00000001-0000-0000-0000-000100000000","provider":"00000000-0000-0000-0000-000000000001"},"conversation_role":"jpy159h7vqij1p08dgsehcpyxg6_ovkcpjruqg6xp8b4lpegp7qrfr_qsyoo3qnngi7btjxrt6bbjcfmit2p6g_j5abxj4o5xliz","qualified_id":{"domain":"golden.example.com","id":"00000001-0000-0001-0000-000100000001"},"id":"00000001-0000-0001-0000-000100000001"}],"id":"00000006-0000-0012-0000-001900000009"}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"members":[{"status":0,"conversation_role":"mofz","id":"00000002-0000-0000-0000-000000000001"}],"name":"􃙓#𫸜𨖜","id":"00000001-0000-000b-0000-001300000020"}
{"members":[{"status":0,"conversation_role":"mofz","qualified_id":{"domain":"golden.example.com","id":"00000002-0000-0000-0000-000000000001"},"id":"00000002-0000-0000-0000-000000000001"}],"name":"􃙓#𫸜𨖜","id":"00000001-0000-000b-0000-001300000020"}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"members":[{"status":0,"service":{"id":"00000000-0000-0001-0000-000000000000","provider":"00000001-0000-0001-0000-000100000000"},"conversation_role":"7argokhlu22zw7um1_4anu2_q13ldqtz2mgeszjizp9qrr8m1wn1yy0lv1bta1cjhxjp_du_5vaatnt94upydlr0v2xqx12ivlbva5eza4c","id":"00000001-0000-0000-0000-000100000001"},{"status":0,"service":{"id":"00000001-0000-0000-0000-000000000001","provider":"00000001-0000-0001-0000-000000000000"},"conversation_role":"_tzj3fgev1_6jgm5uuhbqnskv04r7k0bkk6si04ylakfznc1qttv6pv98l07_afzg_r_hw2xszllzu49u7x9eeu2hamh4ew2g","id":"00000000-0000-0000-0000-000000000001"},{"status":0,"conversation_role":"x8k0vqtenaqv3tj5elrnuwxuhgjl0iugwd3v0uk_8sejey5lgyq4fr746msrtk4eqxl7r3rvaljdyrmjtqvfisx0ml512oneq3bbh7mwr_k3f36od70t3ttj_dc","id":"00000001-0000-0000-0000-000100000001"},{"status":0,"service":{"id":"00000001-0000-0000-0000-000000000000","provider":"00000001-0000-0001-0000-000100000001"},"conversation_role":"89hefsk","id":"00000001-0000-0001-0000-000000000000"},{"status":0,"service":{"id":"00000000-0000-0000-0000-000000000001","provider":"00000001-0000-0000-0000-000100000000"},"conversation_role":"65gk5l2gvypqgykq35etz1df_7","id":"00000000-0000-0001-0000-000100000000"}],"name":"O$:","id":"0000000c-0000-0014-0000-001a00000017"}
{"members":[{"status":0,"service":{"id":"00000000-0000-0001-0000-000000000000","provider":"00000001-0000-0001-0000-000100000000"},"conversation_role":"7argokhlu22zw7um1_4anu2_q13ldqtz2mgeszjizp9qrr8m1wn1yy0lv1bta1cjhxjp_du_5vaatnt94upydlr0v2xqx12ivlbva5eza4c","qualified_id":{"domain":"golden.example.com","id":"00000001-0000-0000-0000-000100000001"},"id":"00000001-0000-0000-0000-000100000001"},{"status":0,"service":{"id":"00000001-0000-0000-0000-000000000001","provider":"00000001-0000-0001-0000-000000000000"},"conversation_role":"_tzj3fgev1_6jgm5uuhbqnskv04r7k0bkk6si04ylakfznc1qttv6pv98l07_afzg_r_hw2xszllzu49u7x9eeu2hamh4ew2g","qualified_id":{"domain":"golden.example.com","id":"00000000-0000-0000-0000-000000000001"},"id":"00000000-0000-0000-0000-000000000001"},{"status":0,"conversation_role":"x8k0vqtenaqv3tj5elrnuwxuhgjl0iugwd3v0uk_8sejey5lgyq4fr746msrtk4eqxl7r3rvaljdyrmjtqvfisx0ml512oneq3bbh7mwr_k3f36od70t3ttj_dc","qualified_id":{"domain":"golden.example.com","id":"00000001-0000-0000-0000-000100000001"},"id":"00000001-0000-0000-0000-000100000001"},{"status":0,"service":{"id":"00000001-0000-0000-0000-000000000000","provider":"00000001-0000-0001-0000-000100000001"},"conversation_role":"89hefsk","qualified_id":{"domain":"golden.example.com","id":"00000001-0000-0001-0000-000000000000"},"id":"00000001-0000-0001-0000-000000000000"},{"status":0,"service":{"id":"00000000-0000-0000-0000-000000000001","provider":"00000001-0000-0000-0000-000100000000"},"conversation_role":"65gk5l2gvypqgykq35etz1df_7","qualified_id":{"domain":"golden.example.com","id":"00000000-0000-0001-0000-000100000000"},"id":"00000000-0000-0001-0000-000100000000"}],"name":"O$:","id":"0000000c-0000-0014-0000-001a00000017"}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"members":[{"status":0,"service":{"id":"00000000-0000-0001-0000-000000000001","provider":"00000001-0000-0001-0000-000100000000"},"conversation_role":"0oabkv381mgh54t8zcgvwg19ru1qbjub_0i8gidad9j7","id":"00000000-0000-0001-0000-000000000000"},{"status":0,"service":{"id":"00000000-0000-0000-0000-000100000001","provider":"00000000-0000-0001-0000-000100000001"},"conversation_role":"ns3h9jzrfx8_o","id":"00000001-0000-0000-0000-000000000000"},{"status":0,"service":{"id":"00000000-0000-0000-0000-000100000001","provider":"00000001-0000-0000-0000-000000000000"},"conversation_role":"_5kwpvh_ud02gj31kh4wz0ev55qmfoiknvib6auu8nkufhe1t63871_0k52ptbydxbwiw8z0fsht6oigc1geezhsw7uosy88xhvxf4iorzc9_ji2v5760f434aem0ti","id":"00000001-0000-0000-0000-000100000001"}],"name":"T","id":"0000001f-0000-0012-0000-000100000010"}
{"members":[{"status":0,"service":{"id":"00000000-0000-0001-0000-000000000001","provider":"00000001-0000-0001-0000-000100000000"},"conversation_role":"0oabkv381mgh54t8zcgvwg19ru1qbjub_0i8gidad9j7","qualified_id":{"domain":"golden.example.com","id":"00000000-0000-0001-0000-000000000000"},"id":"00000000-0000-0001-0000-000000000000"},{"status":0,"service":{"id":"00000000-0000-0000-0000-000100000001","provider":"00000000-0000-0001-0000-000100000001"},"conversation_role":"ns3h9jzrfx8_o","qualified_id":{"domain":"golden.example.com","id":"00000001-0000-0000-0000-000000000000"},"id":"00000001-0000-0000-0000-000000000000"},{"status":0,"service":{"id":"00000000-0000-0000-0000-000100000001","provider":"00000001-0000-0000-0000-000000000000"},"conversation_role":"_5kwpvh_ud02gj31kh4wz0ev55qmfoiknvib6auu8nkufhe1t63871_0k52ptbydxbwiw8z0fsht6oigc1geezhsw7uosy88xhvxf4iorzc9_ji2v5760f434aem0ti","qualified_id":{"domain":"golden.example.com","id":"00000001-0000-0000-0000-000100000001"},"id":"00000001-0000-0000-0000-000100000001"}],"name":"T","id":"0000001f-0000-0012-0000-000100000010"}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"members":[{"status":0,"service":{"id":"00000000-0000-0001-0000-000000000000","provider":"00000000-0000-0001-0000-000000000000"},"conversation_role":"614zvjitytbb_zu","id":"00000000-0000-0000-0000-000100000000"}],"name":"","id":"00000009-0000-000a-0000-00010000000b"}
{"members":[{"status":0,"service":{"id":"00000000-0000-0001-0000-000000000000","provider":"00000000-0000-0001-0000-000000000000"},"conversation_role":"614zvjitytbb_zu","qualified_id":{"domain":"golden.example.com","id":"00000000-0000-0000-0000-000100000000"},"id":"00000000-0000-0000-0000-000100000000"}],"name":"","id":"00000009-0000-000a-0000-00010000000b"}
Loading