diff --git a/internal/adapter/gql/resolver_mutation_team.go b/internal/adapter/gql/resolver_mutation_team.go index 4595933a..0e4037a1 100644 --- a/internal/adapter/gql/resolver_mutation_team.go +++ b/internal/adapter/gql/resolver_mutation_team.go @@ -8,7 +8,7 @@ import ( ) func (r *mutationResolver) CreateTeam(ctx context.Context, input gqlmodel.CreateTeamInput) (*gqlmodel.CreateTeamPayload, error) { - res, err := usecases(ctx).Team.Create(ctx, input.Name, getUser(ctx).ID()) + res, err := usecases(ctx).Team.Create(ctx, input.Name, getUser(ctx).ID(), getOperator(ctx)) if err != nil { return nil, err } diff --git a/internal/infrastructure/fs/plugin.go b/internal/infrastructure/fs/plugin.go index 8b993ac4..e1950108 100644 --- a/internal/infrastructure/fs/plugin.go +++ b/internal/infrastructure/fs/plugin.go @@ -28,7 +28,7 @@ func NewPlugin(fs afero.Fs) repo.Plugin { func (r *pluginRepo) Filtered(f repo.SceneFilter) repo.Plugin { return &pluginRepo{ fs: r.fs, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/fs/property_schema.go b/internal/infrastructure/fs/property_schema.go index 47353ad3..ffb0b961 100644 --- a/internal/infrastructure/fs/property_schema.go +++ b/internal/infrastructure/fs/property_schema.go @@ -25,7 +25,7 @@ func NewPropertySchema(fs afero.Fs) repo.PropertySchema { func (r *propertySchema) Filtered(f repo.SceneFilter) repo.PropertySchema { return &propertySchema{ fs: r.fs, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/memory/asset.go b/internal/infrastructure/memory/asset.go index 557023f9..08df3ed2 100644 --- a/internal/infrastructure/memory/asset.go +++ b/internal/infrastructure/memory/asset.go @@ -29,7 +29,7 @@ func (r *Asset) Filtered(f repo.TeamFilter) repo.Asset { return &Asset{ // note data is shared between the source repo and mutex cannot work well data: r.data, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/memory/dataset.go b/internal/infrastructure/memory/dataset.go index cea85ccd..3c4d3f7a 100644 --- a/internal/infrastructure/memory/dataset.go +++ b/internal/infrastructure/memory/dataset.go @@ -27,7 +27,7 @@ func (r *Dataset) Filtered(f repo.SceneFilter) repo.Dataset { return &Dataset{ // note data is shared between the source repo and mutex cannot work well data: r.data, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/memory/dataset_schema.go b/internal/infrastructure/memory/dataset_schema.go index dfad074c..75081eb6 100644 --- a/internal/infrastructure/memory/dataset_schema.go +++ b/internal/infrastructure/memory/dataset_schema.go @@ -27,7 +27,7 @@ func (r *DatasetSchema) Filtered(f repo.SceneFilter) repo.DatasetSchema { return &DatasetSchema{ // note data is shared between the source repo and mutex cannot work well data: r.data, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/memory/layer.go b/internal/infrastructure/memory/layer.go index afdddde3..eefab91a 100644 --- a/internal/infrastructure/memory/layer.go +++ b/internal/infrastructure/memory/layer.go @@ -26,7 +26,7 @@ func (r *Layer) Filtered(f repo.SceneFilter) repo.Layer { return &Layer{ // note data is shared between the source repo and mutex cannot work well data: r.data, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/memory/plugin.go b/internal/infrastructure/memory/plugin.go index d9361716..68b8a8ad 100644 --- a/internal/infrastructure/memory/plugin.go +++ b/internal/infrastructure/memory/plugin.go @@ -28,7 +28,7 @@ func (r *Plugin) Filtered(f repo.SceneFilter) repo.Plugin { return &Plugin{ // note data is shared between the source repo and mutex cannot work well data: r.data, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/memory/project.go b/internal/infrastructure/memory/project.go index e6c28ca3..48c6127c 100644 --- a/internal/infrastructure/memory/project.go +++ b/internal/infrastructure/memory/project.go @@ -28,7 +28,7 @@ func (r *Project) Filtered(f repo.TeamFilter) repo.Project { return &Project{ // note data is shared between the source repo and mutex cannot work well data: r.data, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/memory/property.go b/internal/infrastructure/memory/property.go index c4dd0350..715481dd 100644 --- a/internal/infrastructure/memory/property.go +++ b/internal/infrastructure/memory/property.go @@ -28,7 +28,7 @@ func (r *Property) Filtered(f repo.SceneFilter) repo.Property { return &Property{ // note data is shared between the source repo and mutex cannot work well data: r.data, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/memory/property_schema.go b/internal/infrastructure/memory/property_schema.go index 5df9558d..e67b3963 100644 --- a/internal/infrastructure/memory/property_schema.go +++ b/internal/infrastructure/memory/property_schema.go @@ -32,7 +32,7 @@ func (r *PropertySchema) Filtered(f repo.SceneFilter) repo.PropertySchema { return &PropertySchema{ // note data is shared between the source repo and mutex cannot work well data: r.data, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/memory/scene.go b/internal/infrastructure/memory/scene.go index b067222f..7032a92b 100644 --- a/internal/infrastructure/memory/scene.go +++ b/internal/infrastructure/memory/scene.go @@ -28,7 +28,7 @@ func (r *Scene) Filtered(f repo.TeamFilter) repo.Scene { return &Scene{ // note data is shared between the source repo and mutex cannot work well data: r.data, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/memory/tag.go b/internal/infrastructure/memory/tag.go index a92e7639..ec206bfd 100644 --- a/internal/infrastructure/memory/tag.go +++ b/internal/infrastructure/memory/tag.go @@ -27,7 +27,7 @@ func (r *Tag) Filtered(f repo.SceneFilter) repo.Tag { return &Tag{ // note data is shared between the source repo and mutex cannot work well data: r.data, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/mongo/asset.go b/internal/infrastructure/mongo/asset.go index 827069c0..c06206be 100644 --- a/internal/infrastructure/mongo/asset.go +++ b/internal/infrastructure/mongo/asset.go @@ -30,7 +30,7 @@ func NewAsset(client *mongodoc.Client) repo.Asset { func (r *assetRepo) Filtered(f repo.TeamFilter) repo.Asset { return &assetRepo{ client: r.client, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/mongo/dataset.go b/internal/infrastructure/mongo/dataset.go index 66f62dbb..be2db28c 100644 --- a/internal/infrastructure/mongo/dataset.go +++ b/internal/infrastructure/mongo/dataset.go @@ -30,7 +30,7 @@ func NewDataset(client *mongodoc.Client) repo.Dataset { func (r *datasetRepo) Filtered(f repo.SceneFilter) repo.Dataset { return &datasetRepo{ client: r.client, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/mongo/dataset_schema.go b/internal/infrastructure/mongo/dataset_schema.go index 928a5d4e..2ad8d995 100644 --- a/internal/infrastructure/mongo/dataset_schema.go +++ b/internal/infrastructure/mongo/dataset_schema.go @@ -35,7 +35,7 @@ func (r *datasetSchemaRepo) init() { func (r *datasetSchemaRepo) Filtered(f repo.SceneFilter) repo.DatasetSchema { return &datasetSchemaRepo{ client: r.client, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/mongo/layer.go b/internal/infrastructure/mongo/layer.go index e5e1b387..e12834c6 100644 --- a/internal/infrastructure/mongo/layer.go +++ b/internal/infrastructure/mongo/layer.go @@ -34,7 +34,7 @@ func (r *layerRepo) init() { func (r *layerRepo) Filtered(f repo.SceneFilter) repo.Layer { return &layerRepo{ client: r.client, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/mongo/plugin.go b/internal/infrastructure/mongo/plugin.go index 9bd95e56..ebadde8e 100644 --- a/internal/infrastructure/mongo/plugin.go +++ b/internal/infrastructure/mongo/plugin.go @@ -36,7 +36,7 @@ func (r *pluginRepo) init() { func (r *pluginRepo) Filtered(f repo.SceneFilter) repo.Plugin { return &pluginRepo{ client: r.client, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/mongo/project.go b/internal/infrastructure/mongo/project.go index 7377b330..257b088f 100644 --- a/internal/infrastructure/mongo/project.go +++ b/internal/infrastructure/mongo/project.go @@ -35,7 +35,7 @@ func (r *projectRepo) init() { func (r *projectRepo) Filtered(f repo.TeamFilter) repo.Project { return &projectRepo{ client: r.client, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/mongo/property.go b/internal/infrastructure/mongo/property.go index a0f3de5a..f6311259 100644 --- a/internal/infrastructure/mongo/property.go +++ b/internal/infrastructure/mongo/property.go @@ -33,7 +33,7 @@ func (r *propertyRepo) init() { func (r *propertyRepo) Filtered(f repo.SceneFilter) repo.Property { return &propertyRepo{ client: r.client, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/mongo/property_schema.go b/internal/infrastructure/mongo/property_schema.go index f06933f5..87a28b07 100644 --- a/internal/infrastructure/mongo/property_schema.go +++ b/internal/infrastructure/mongo/property_schema.go @@ -34,7 +34,7 @@ func (r *propertySchemaRepo) init() { func (r *propertySchemaRepo) Filtered(f repo.SceneFilter) repo.PropertySchema { return &propertySchemaRepo{ client: r.client, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/mongo/scene.go b/internal/infrastructure/mongo/scene.go index 140ed42e..4c001ffe 100644 --- a/internal/infrastructure/mongo/scene.go +++ b/internal/infrastructure/mongo/scene.go @@ -34,7 +34,7 @@ func (r *sceneRepo) init() { func (r *sceneRepo) Filtered(f repo.TeamFilter) repo.Scene { return &sceneRepo{ client: r.client, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/infrastructure/mongo/tag.go b/internal/infrastructure/mongo/tag.go index 9fb6914b..7daae79f 100644 --- a/internal/infrastructure/mongo/tag.go +++ b/internal/infrastructure/mongo/tag.go @@ -34,7 +34,7 @@ func (r *tagRepo) init() { func (r *tagRepo) Filtered(f repo.SceneFilter) repo.Tag { return &tagRepo{ client: r.client, - f: f.Clone(), + f: r.f.Merge(f), } } diff --git a/internal/usecase/interactor/scene.go b/internal/usecase/interactor/scene.go index fe8dc936..f45c5eed 100644 --- a/internal/usecase/interactor/scene.go +++ b/internal/usecase/interactor/scene.go @@ -74,7 +74,8 @@ func (i *Scene) Create(ctx context.Context, pid id.ProjectID, operator *usecase. if err != nil { return nil, err } - if err := i.CanWriteTeam(prj.Team(), operator); err != nil { + team := prj.Team() + if err := i.CanWriteTeam(team, operator); err != nil { return nil, err } @@ -100,7 +101,7 @@ func (i *Scene) Create(ctx context.Context, pid id.ProjectID, operator *usecase. g := p.GetOrCreateGroupList(schema, property.PointItemBySchema(tiles)) g.Add(property.NewGroup().NewID().SchemaGroup(tiles).MustBuild(), -1) - scene, err := scene.New(). + res, err := scene.New(). ID(sceneID). Project(pid). Team(prj.Team()). @@ -114,24 +115,25 @@ func (i *Scene) Create(ctx context.Context, pid id.ProjectID, operator *usecase. } if p != nil { - err = i.propertyRepo.Save(ctx, p) + err = i.propertyRepo.Filtered(repo.SceneFilter{Writable: scene.IDList{sceneID}}).Save(ctx, p) if err != nil { return nil, err } } - err = i.layerRepo.Save(ctx, rootLayer) + err = i.layerRepo.Filtered(repo.SceneFilter{Writable: scene.IDList{sceneID}}).Save(ctx, rootLayer) if err != nil { return nil, err } - err = i.sceneRepo.Save(ctx, scene) + err = i.sceneRepo.Save(ctx, res) if err != nil { return nil, err } + operator.AddNewScene(team, sceneID) tx.Commit() - return scene, err + return res, err } func (s *Scene) FetchLock(ctx context.Context, ids []id.SceneID, operator *usecase.Operator) ([]scene.LockMode, error) { diff --git a/internal/usecase/interactor/team.go b/internal/usecase/interactor/team.go index 6201f82b..0f012b3d 100644 --- a/internal/usecase/interactor/team.go +++ b/internal/usecase/interactor/team.go @@ -45,7 +45,7 @@ func (i *Team) FindByUser(ctx context.Context, id id.UserID, operator *usecase.O return res2, err } -func (i *Team) Create(ctx context.Context, name string, firstUser id.UserID) (_ *user.Team, err error) { +func (i *Team) Create(ctx context.Context, name string, firstUser id.UserID, operator *usecase.Operator) (_ *user.Team, err error) { tx, err := i.transaction.Begin() if err != nil { return @@ -64,16 +64,15 @@ func (i *Team) Create(ctx context.Context, name string, firstUser id.UserID) (_ return nil, err } - err = team.Members().Join(firstUser, user.RoleOwner) - if err != nil { + if err := team.Members().Join(firstUser, user.RoleOwner); err != nil { return nil, err } - err = i.teamRepo.Save(ctx, team) - if err != nil { + if err := i.teamRepo.Save(ctx, team); err != nil { return nil, err } + operator.AddNewTeam(team.ID()) tx.Commit() return team, nil } diff --git a/internal/usecase/interactor/team_test.go b/internal/usecase/interactor/team_test.go index d160009c..a334e340 100644 --- a/internal/usecase/interactor/team_test.go +++ b/internal/usecase/interactor/team_test.go @@ -16,11 +16,10 @@ func TestCreateTeam(t *testing.T) { db := memory.InitRepos(nil) - user := user.New().NewID().Team(id.NewTeamID()).MustBuild() - + u := user.New().NewID().Team(id.NewTeamID()).MustBuild() teamUC := NewTeam(db) - - team, err := teamUC.Create(ctx, "team name", user.ID()) + op := &usecase.Operator{User: u.ID()} + team, err := teamUC.Create(ctx, "team name", u.ID(), op) assert.Nil(t, err) assert.NotNil(t, team) @@ -33,4 +32,5 @@ func TestCreateTeam(t *testing.T) { assert.NotEmpty(t, resultTeams) assert.Equal(t, resultTeams[0].ID(), team.ID()) assert.Equal(t, resultTeams[0].Name(), "team name") + assert.Equal(t, user.TeamIDList{resultTeams[0].ID()}, op.OwningTeams) } diff --git a/internal/usecase/interfaces/team.go b/internal/usecase/interfaces/team.go index a4ba619f..503b07bb 100644 --- a/internal/usecase/interfaces/team.go +++ b/internal/usecase/interfaces/team.go @@ -18,7 +18,7 @@ var ( type Team interface { Fetch(context.Context, []id.TeamID, *usecase.Operator) ([]*user.Team, error) FindByUser(context.Context, id.UserID, *usecase.Operator) ([]*user.Team, error) - Create(context.Context, string, id.UserID) (*user.Team, error) + Create(context.Context, string, id.UserID, *usecase.Operator) (*user.Team, error) Update(context.Context, id.TeamID, string, *usecase.Operator) (*user.Team, error) AddMember(context.Context, id.TeamID, id.UserID, user.Role, *usecase.Operator) (*user.Team, error) RemoveMember(context.Context, id.TeamID, id.UserID, *usecase.Operator) (*user.Team, error) diff --git a/internal/usecase/operator.go b/internal/usecase/operator.go index 753edd74..28eddf88 100644 --- a/internal/usecase/operator.go +++ b/internal/usecase/operator.go @@ -79,3 +79,15 @@ func (o *Operator) IsWritableScene(scene ...id.SceneID) bool { func (o *Operator) IsOwningScene(scene ...id.SceneID) bool { return o.AllOwningScenes().Includes(scene...) } + +func (o *Operator) AddNewTeam(team id.TeamID) { + o.OwningTeams = append(o.OwningTeams, team) +} + +func (o *Operator) AddNewScene(team id.TeamID, scene id.SceneID) { + if o.IsOwningTeam(team) { + o.OwningScenes = append(o.OwningScenes, scene) + } else if o.IsWritableTeam(team) { + o.WritableScenes = append(o.WritableScenes, scene) + } +} diff --git a/internal/usecase/repo/container.go b/internal/usecase/repo/container.go index 6e5bee8e..7099ed5d 100644 --- a/internal/usecase/repo/container.go +++ b/internal/usecase/repo/container.go @@ -73,6 +73,13 @@ func (f TeamFilter) Clone() TeamFilter { } } +func (f TeamFilter) Merge(g TeamFilter) TeamFilter { + return TeamFilter{ + Readable: append(f.Readable, g.Readable...), + Writable: append(f.Writable, g.Writable...), + } +} + func (f TeamFilter) CanRead(id user.TeamID) bool { return f.Readable == nil || f.Readable.Includes(id) } @@ -93,6 +100,13 @@ func SceneFilterFromOperator(o *usecase.Operator) SceneFilter { } } +func (f SceneFilter) Merge(g SceneFilter) SceneFilter { + return SceneFilter{ + Readable: append(f.Readable, g.Readable...), + Writable: append(f.Writable, g.Writable...), + } +} + func (f SceneFilter) Clone() SceneFilter { return SceneFilter{ Readable: f.Readable.Clone(),