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

feat: add migration to AddUserMember interactor [FLOW-BE-34] #74

Merged
merged 14 commits into from
Feb 27, 2025

Conversation

akiyatomohiro
Copy link
Contributor

@akiyatomohiro akiyatomohiro commented Feb 20, 2025

ref:
https://eukarya-inc.slack.com/archives/C064TUMGNDA/p1739512520086599?thread_ts=1739394205.301159&cid=C064TUMGNDA

Summary by CodeRabbit

  • New Features

    • Enhanced role and permission management across accounts and workspaces.
    • Workspaces now ensure proper role assignment during user addition, streamlining access control.
    • Introduced robust tools for managing roles and permissions with improved concurrent and database operations.
    • New interfaces for Permittable and Role to standardize permission and role management.
  • Tests

    • Expanded test suite to validate role assignments and permission workflows during workspace updates.

Copy link

coderabbitai bot commented Feb 20, 2025

Warning

Rate limit exceeded

@akiyatomohiro has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 24 minutes and 32 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 2063494 and 5950671.

📒 Files selected for processing (1)
  • account/accountusecase/accountrepo/container.go (1 hunks)

Walkthrough

This pull request adds new domain types, builders, and interfaces to support role and permission management. It introduces new ID types, helper functions, and list/set constructs for roles and permittables. Additionally, it provides in-memory and MongoDB-backed implementations for managing these entities. The workspace business logic has been enhanced with functions to ensure that users receive the appropriate maintainer role during member addition. Temporary comments indicate that many of these changes are slated for removal once the permission check migration is complete.

Changes

File(s) Change Summary
account/accountdomain/id.go Added new domain types for Role and Permittable, including ID aliases, constructors, and helper variables. Temporary for permission migration.
account/accountdomain/permittable/{builder.go, id.go, list.go, permittable.go} Introduced builders, ID wrappers, list types, and methods for the Permittable type. Marked for future deletion.
account/accountdomain/role/{builder.go, id.go, list.go, role.go} Added builders, ID wrappers, list types, and CRUD methods for Role entities. Temporary for migration.
account/accountinfrastructure/accountmemory/{container.go, permittable.go, role.go} Updated container to include Role and Permittable fields; introduced in-memory stores for permission and role management with concurrency controls.
account/accountinfrastructure/accountmongo/mongodoc/{permittable.go, role.go} Added MongoDB document wrappers for Permittable and Role including consumer functions and model converters.
account/accountinfrastructure/accountmongo/{permittable.go, role.go} Provided MongoDB implementations for handling Permittable and Role entities with index initialization and CRUD operations.
account/accountusecase/accountinteractor/{workspace.go, workspace_test.go} Enhanced workspace logic with functions to retrieve and assign the maintainer role, along with tests for permission migration.
account/accountusecase/accountrepo/{container.go, permittable.go, role.go} Updated repository container and added interfaces for managing Permittable and Role objects.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant W as Workspace
    participant RR as RoleRepo
    participant PR as PermittableRepo

    U->>W: AddUserMember(userID)
    W->>RR: getMaintainerRole(ctx)
    RR-->>W: return maintainerRole
    W->>PR: ensureUserHasMaintainerRole(ctx, userID, maintainerRole)
    alt User already has role
      PR-->>W: Role exists
    else 
      PR-->>W: Created new Permittable with role
    end
    W-->>U: Member added with maintainer role
Loading

Poem

Hoppin’ through code with a brand new beat,
IDs and builders make my nibble complete.
Roles and permittables dancing in line,
In-memory or Mongo, everything’s just fine.
I, the coding rabbit, cheer this migration treat!
🥕🐇 Happy hops and smooth commits!


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@akiyatomohiro akiyatomohiro marked this pull request as ready for review February 20, 2025 13:40
@akiyatomohiro akiyatomohiro self-assigned this Feb 20, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (19)
account/accountusecase/accountinteractor/workspace.go (4)

148-152: Temporary TODO comment.

These lines, which retrieve the maintainer role during user addition, are flagged for removal once the permission check migration is finalized. Track these changes so they don’t remain in production code beyond the planned timeframe.


159-162: Ensure consistent naming in TODO.

This supplemental step, which ensures a user has the maintainer role, references a second method (ensureUserHasMaintainerRole). The name is clear and consistent with the preceding getMaintainerRole, but remember to remove or rename them after the migration.


415-452: Proactively handle concurrency for role creation.

The getMaintainerRole function checks existing roles before creating a new one, which is correct. However, in a high-concurrency environment, it might lead to duplicate creation if multiple transactions run in parallel. Consider adding repository-level checks or unique constraints to avoid duplicates.


489-500: Use a more descriptive name for hasRole.

hasRole” is a clear name, but to align with typical naming in domain-driven design, you might prefer something like permitsRole or grantsRole. This is a minor suggestion, but it can help unify naming across the domain.

account/accountdomain/permittable/permittable.go (1)

38-43: Add validation to EditRoleIDs method.

Consider adding validation to ensure roleIDs are valid before assignment:

  • Check for nil roleIDs
  • Validate individual role IDs
  • Consider returning an error instead of silently accepting invalid input
-func (p *Permittable) EditRoleIDs(roleIDs accountdomain.RoleIDList) {
+func (p *Permittable) EditRoleIDs(roleIDs accountdomain.RoleIDList) error {
 	if p == nil {
-		return
+		return errors.New("permittable is nil")
 	}
+	if roleIDs == nil {
+		return errors.New("roleIDs cannot be nil")
+	}
+	for _, rid := range roleIDs {
+		if rid.IsNil() {
+			return errors.New("invalid role ID in list")
+		}
+	}
 	p.roleIDs = roleIDs
+	return nil
 }
account/accountinfrastructure/accountmongo/mongodoc/role.go (1)

22-28: Add validation to NewRole function.

Consider validating the input Role before creating a document:

 func NewRole(g role.Role) (*RoleDocument, string) {
+	if g.ID().IsNil() {
+		return nil, ""
+	}
+	if g.Name() == "" {
+		return nil, ""
+	}
 	id := g.ID().String()
 	return &RoleDocument{
 		ID:   id,
 		Name: g.Name(),
 	}, id
 }
account/accountdomain/permittable/builder.go (3)

1-1: Consider adding more context to the TODO comment.

The TODO comment should include more context about why this file needs to be deleted and what will replace it after the migration.

-// TODO: Delete this file once the permission check migration is complete.
+// TODO: Delete this file once the permission check migration is complete.
+// This is a temporary implementation that will be replaced by the new permission system.
+// Related issue: <add issue link>

18-26: Consider improving error handling in Build().

The current implementation returns the same ErrInvalidID for both id and userID validation failures. This makes it harder to debug which field caused the validation to fail.

 func (b *Builder) Build() (*Permittable, error) {
 	if b.p.id.IsNil() {
-		return nil, ErrInvalidID
+		return nil, fmt.Errorf("invalid permittable id: %w", ErrInvalidID)
 	}
 	if b.p.userID.IsNil() {
-		return nil, ErrInvalidID
+		return nil, fmt.Errorf("invalid user id: %w", ErrInvalidID)
 	}
 	return b.p, nil
 }

28-34: Consider improving panic message in MustBuild().

The current implementation panics with the raw error, which might not provide enough context about where the panic occurred.

 func (b *Builder) MustBuild() *Permittable {
 	u, err := b.Build()
 	if err != nil {
-		panic(err)
+		panic(fmt.Sprintf("failed to build permittable: %v", err))
 	}
 	return u
 }
account/accountinfrastructure/accountmongo/mongodoc/permittable.go (2)

27-30: Consider pre-allocating roleIds slice with exact capacity.

The current implementation creates a new slice and appends to it. For better performance, consider allocating the slice with the exact size needed.

-	roleIds := make([]string, 0, len(p.RoleIDs()))
-	for _, r := range p.RoleIDs() {
-		roleIds = append(roleIds, r.String())
+	roleIds := make([]string, len(p.RoleIDs()))
+	for i, r := range p.RoleIDs() {
+		roleIds[i] = r.String()

39-64: Consider consolidating error handling in Model().

The current implementation has repetitive error handling patterns. Consider using a helper function to reduce duplication.

+func handleIDConversion[T any](convert func(string) (T, error), id string) (T, error) {
+	result, err := convert(id)
+	if err != nil {
+		return result, fmt.Errorf("failed to convert ID %s: %w", id, err)
+	}
+	return result, nil
+}

 func (d *PermittableDocument) Model() (*permittable.Permittable, error) {
 	if d == nil {
 		return nil, nil
 	}

-	uid, err := accountdomain.PermittableIDFrom(d.ID)
+	uid, err := handleIDConversion(accountdomain.PermittableIDFrom, d.ID)
 	if err != nil {
 		return nil, err
 	}

-	userId, err := user.IDFrom(d.UserID)
+	userId, err := handleIDConversion(user.IDFrom, d.UserID)
 	if err != nil {
 		return nil, err
 	}
account/accountinfrastructure/accountmemory/role.go (1)

34-43: Consider optimizing slice allocations in Find methods.

Both FindAll and FindByIDs could benefit from more efficient slice handling.

 func (r *Role) FindAll(ctx context.Context) (role.List, error) {
 	r.lock.Lock()
 	defer r.lock.Unlock()

-	res := make(role.List, 0, len(r.data))
+	res := make(role.List, len(r.data))
+	i := 0
 	for _, v := range r.data {
-		res = append(res, v)
+		res[i] = v
+		i++
 	}
 	return res, nil
 }

Also applies to: 56-67

account/accountdomain/id.go (1)

39-39: Enhance the TODO comment with migration details.

The TODO comment should provide more context about the migration plan and what will replace these types.

-// TODO: Delete the below once the permission check migration is complete.
+// TODO: Delete the below once the permission check migration is complete.
+// These types are temporary and will be replaced by the new permission system.
+// Migration tracking issue: <add issue link>
+// Target completion date: <add date>
account/accountinfrastructure/accountmemory/permittable.go (2)

16-19: Consider adding indices for better lookup performance.

The current implementation uses a single map indexed by PermittableID, requiring O(n) scans for user ID lookups. Consider adding a secondary index map for UserID to improve lookup performance.

 type Permittable struct {
 	lock sync.Mutex
 	data map[accountdomain.PermittableID]*permittable.Permittable
+	// Secondary index for faster user ID lookups
+	userIndex map[user.ID]*permittable.Permittable
 }

48-67: Optimize FindByUserIDs implementation.

The current implementation has nested loops which could be inefficient for large datasets. Consider using a map to track found items and break early when all requested IDs are found.

 func (p *Permittable) FindByUserIDs(ctx context.Context, userIDs user.IDList) (permittable.List, error) {
 	p.lock.Lock()
 	defer p.lock.Unlock()
 
+	// Use map for tracking found IDs
+	found := make(map[user.ID]bool)
 	results := make(permittable.List, 0, len(userIDs))
-	for _, userID := range userIDs {
-		for _, perm := range p.data {
-			if perm.UserID() == userID {
-				results = append(results, perm)
-				break
-			}
+	
+	for _, perm := range p.data {
+		if userIDs.Has(perm.UserID()) {
+			results = append(results, perm)
+			found[perm.UserID()] = true
+			// Break early if all IDs are found
+			if len(found) == len(userIDs) {
+				break
+			}
 		}
 	}
account/accountinfrastructure/accountmongo/role.go (2)

16-19: Consider adding TTL index for temporary migration data.

Since this is temporary migration code (as indicated by the TODO), consider adding a TTL index to automatically clean up old data.

 var (
 	roleIndexes       = []string{}
-	roleUniqueIndexes = []string{"id", "name"}
+	roleUniqueIndexes = []string{"id", "name"}
+	roleTTLIndexes    = []string{"created_at"}
 )

31-33: Add TTL index creation to Init method.

Update the Init method to create TTL indexes for automatic cleanup of temporary migration data.

 func (r *Role) Init(ctx context.Context) error {
-	return createIndexes(ctx, r.client, roleIndexes, roleUniqueIndexes)
+	if err := createIndexes(ctx, r.client, roleIndexes, roleUniqueIndexes); err != nil {
+		return err
+	}
+	return r.client.CreateIndex(ctx, mongox.Index{
+		Key: bson.D{{Key: "created_at", Value: 1}},
+		Options: options.Index().SetExpireAfterSeconds(7 * 24 * 60 * 60), // 7 days
+	})
 }
account/accountinfrastructure/accountmongo/permittable.go (2)

18-21: Add index for roleids field to optimize FindByRoleID queries.

The FindByRoleID method performs queries on the roleids field, but there's no index for it.

 var (
-	newPermittableIndexes       = []string{}
+	newPermittableIndexes       = []string{"roleids"}
 	newPermittableUniqueIndexes = []string{"id", "userid"}
 )

49-53: Optimize FindByRoleID query for better performance.

The current query might not use the index effectively. Consider using $elemMatch for better performance with array fields.

 func (r *Permittable) FindByRoleID(ctx context.Context, roleId accountdomain.RoleID) (permittable.List, error) {
 	return r.find(ctx, bson.M{
-		"roleids": bson.M{"$in": []string{roleId.String()}},
+		"roleids": bson.M{"$elemMatch": bson.M{"$eq": roleId.String()}},
 	})
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7860571 and 0ad6d16.

📒 Files selected for processing (21)
  • account/accountdomain/id.go (1 hunks)
  • account/accountdomain/permittable/builder.go (1 hunks)
  • account/accountdomain/permittable/id.go (1 hunks)
  • account/accountdomain/permittable/list.go (1 hunks)
  • account/accountdomain/permittable/permittable.go (1 hunks)
  • account/accountdomain/role/builder.go (1 hunks)
  • account/accountdomain/role/id.go (1 hunks)
  • account/accountdomain/role/list.go (1 hunks)
  • account/accountdomain/role/role.go (1 hunks)
  • account/accountinfrastructure/accountmemory/container.go (1 hunks)
  • account/accountinfrastructure/accountmemory/permittable.go (1 hunks)
  • account/accountinfrastructure/accountmemory/role.go (1 hunks)
  • account/accountinfrastructure/accountmongo/mongodoc/permittable.go (1 hunks)
  • account/accountinfrastructure/accountmongo/mongodoc/role.go (1 hunks)
  • account/accountinfrastructure/accountmongo/permittable.go (1 hunks)
  • account/accountinfrastructure/accountmongo/role.go (1 hunks)
  • account/accountusecase/accountinteractor/workspace.go (3 hunks)
  • account/accountusecase/accountinteractor/workspace_test.go (10 hunks)
  • account/accountusecase/accountrepo/container.go (1 hunks)
  • account/accountusecase/accountrepo/permittable.go (1 hunks)
  • account/accountusecase/accountrepo/role.go (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • account/accountdomain/role/list.go
  • account/accountdomain/permittable/list.go
🔇 Additional comments (19)
account/accountusecase/accountinteractor/workspace.go (2)

5-5: Use caution with new imports.

The newly introduced imports (fmt, permittable, role, log) make sense for the role-handling logic and logging. Ensure that this expanded dependency set does not introduce conflicts or overshadow existing naming.

Also applies to: 8-10, 16-16


454-487: Ensure robust error propagation in ensureUserHasMaintainerRole.

  1. If the FindByUserID call returns a transient error, you currently exit with that error. Ensure caller code can handle or retry.
  2. If partial creation fails (e.g., Permittable.Save fails), the function stops but leaves the code in an intermediate state. Consider rolling back or verifying that partial states are acceptable.
account/accountusecase/accountinteractor/workspace_test.go (3)

9-10: Imports for new role and permittable logic.

The test now includes permittable and role references, along with accountrepo. This is consistent with your domain changes. Just confirm that these tests won’t conflict with more advanced mocking frameworks or stubs if introduced.

Also applies to: 16-17


957-960: Minor expansions in existing tests.

The expansions in these lines appear to extend coverage for workspace membership, ensuring correct handling of additional roles. Keep test scenarios minimal and focus on the essential logic to avoid test bloat.

Also applies to: 967-967, 974-974, 1007-1007, 1060-1061, 1069-1071, 1127-1128


1323-1554: Comprehensive test coverage for migration logic.

  1. TestWorkspace_AddMember_Migration covers scenario-based user role assignment, including edge cases like existing roles, multiple roles, or duplicate creations. This thorough approach is helpful for verifying domain correctness.
  2. assertPermittablesAndRoles is well-written, verifying both the presence of a “maintainer” role and the integrity of associated user IDs.
  3. Consider including concurrency or cross-transaction tests if the domain expects parallel usage.

Overall, these tests robustly confirm the migration logic.

account/accountdomain/role/id.go (1)

1-19: Temporary file note & type alias usage.

  1. The comment indicates this file is temporary for the permission check migration. Revisit and remove or merge it once the migration is complete to minimize fragmentation.
  2. The type alias and exposed variables (e.g., ErrInvalidID, NewID, etc.) mirror the underlying domain definitions, which is a neat approach.
  3. Keep an eye on future changes to accountdomain.RoleID to ensure these aliases stay in sync.

No issues found; changes look straightforward.

account/accountdomain/permittable/id.go (2)

1-2: Ensure migration completion criteria is documented.

The TODO comment indicates this file is temporary, but the criteria for completing the permission check migration and safely removing this file should be documented.

Consider:

  1. What conditions must be met to consider the migration complete?
  2. Are there any dependencies that need to be updated before removal?
  3. What tests should pass to verify safe removal?

7-17: LGTM! Clean type alias and variable declarations.

The code provides a well-structured wrapper around accountdomain types and functions, making them easily accessible within the permittable package context.

account/accountinfrastructure/accountmemory/container.go (1)

12-13: LGTM! Clean container initialization with new fields.

The Role and Permittable fields are properly initialized using their respective factory functions. The TODO comments clearly indicate these are temporary additions for the migration.

account/accountdomain/role/role.go (1)

7-14: LGTM! Clean error handling and struct definition.

The code properly defines the error for empty names and encapsulates the role properties.

account/accountusecase/accountrepo/role.go (1)

12-18: LGTM! Well-defined repository interface.

The Role interface provides a comprehensive set of methods for role management with proper context handling and error returns.

account/accountusecase/accountrepo/permittable.go (2)

13-18: Well-designed interface for permission management.

The interface follows Go best practices with:

  • Context support for cancellation
  • Clear method signatures
  • Appropriate error handling
  • Consistent return types

1-1:

❓ Verification inconclusive

Verify the migration timeline.

Please ensure there's a tracking issue or project milestone for the permission check migration to avoid this temporary code becoming permanent.


🏁 Script executed:

#!/bin/bash
# Search for related migration issues or TODOs
rg -i "permission.*check.*migration|TODO.*permission" 

Length of output: 3604


Action: Confirm and Track Permission Check Migration
The // TODO: Delete this file once the permission check migration is complete. comment in account/accountusecase/accountrepo/permittable.go is consistent with similar annotations throughout the repository. Please ensure that a dedicated tracking issue or project milestone is established for the permission check migration. This will help guarantee that the temporary code is removed once the migration is complete and prevent it from inadvertently becoming permanent.

account/accountdomain/role/builder.go (1)

13-21: Good validation in Build method.

The validation logic properly checks for:

  • Non-nil ID
  • Non-empty name
  • Returns appropriate errors
account/accountdomain/permittable/permittable.go (1)

17-36: Well-implemented defensive programming with nil checks.

The methods consistently handle nil receivers and return appropriate zero values, preventing nil pointer dereferences.

account/accountinfrastructure/accountmongo/mongodoc/role.go (1)

30-44: Well-implemented Model conversion with proper error handling.

The Model method:

  • Handles nil receiver
  • Validates ID conversion
  • Uses builder pattern effectively
  • Returns appropriate errors
account/accountdomain/permittable/builder.go (1)

51-54: Consider validating roleIDs input.

The RoleIDs method accepts a slice without any validation. Consider adding checks for nil or empty roleIDs.

 func (b *Builder) RoleIDs(roleIDs []accountdomain.RoleID) *Builder {
+	if roleIDs == nil {
+		roleIDs = make([]accountdomain.RoleID, 0)
+	}
 	b.p.roleIDs = roleIDs
 	return b
 }
account/accountinfrastructure/accountmemory/role.go (1)

69-75: Consider adding validation in Save method.

The Save method doesn't validate the role before saving. Consider adding checks for nil or invalid role ID.

 func (r *Role) Save(ctx context.Context, rl role.Role) error {
 	r.lock.Lock()
 	defer r.lock.Unlock()

+	if rl.ID().IsNil() {
+		return fmt.Errorf("cannot save role with nil ID")
+	}
+
 	r.data[rl.ID()] = &rl
 	return nil
 }
account/accountdomain/id.go (1)

41-46: LGTM! Well-structured type definitions.

The type definitions and their Type() methods follow the established pattern in the file, maintaining consistency with existing types.

@akiyatomohiro akiyatomohiro requested a review from pyshx February 20, 2025 16:25
@akiyatomohiro akiyatomohiro changed the title feat: add migration to AddUserMember interactor feat: add migration to AddUserMember interactor [FLOW-BE-34] Feb 27, 2025
@pyshx pyshx merged commit 6f054a7 into main Feb 27, 2025
2 checks passed
@pyshx pyshx deleted the feat/authorization-and-roles-management-service-3 branch February 27, 2025 10:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants