So my main issue is that both of Members and Roles have a field called team.
I was thinking maybe have team and role be associated with each other and then member will be linked to roles. But that also just seems messy and unorthodox.
I've seen people say you could make use of aggregations but that would still result in a circular dependency (as far as I know)
I should also mention that each team have custom roles which they can create and edit as opposed to predefined set of roles (example: [ADMIN, STAFF, USER, CUSTOMER] in some config file)

First sketch
This could be a typical example of an association class:
Memberand theTeam;Roleof theMemberin theTeam. This means that every link between a member object and a team object would correspond to a different instance of the role:Important remark: Note that in UML you should not underline the identifier. This is current practice in ERD, but in UML, it would mean that id is static, i.e. every instance of the class share the same static property.
The role according to your narrative
The challenge in your case is that the roles are defined per team but seem independent of the person that fulfils this role. There are several possible solution to address this, for example:
Solution 1: develop on the idea of association class (which gives the role of a member in the team), calling it
Membership, and associate this association class withRolewith is itself associated withTeam. Are the same role can be used in several teams:Solution 2: use a ternary association between
Member,RoleandTeam. Role could still be associated with the Team. Beware that ternary associations are more difficult to deal with.Solution 3: if the
Roleis fully dependent of theTeam(i.e. a role only exist in the context of a team and cannot be used across the teams, e.g. admin of team 1 coud have different authorisations than admin of team 2), you could simplify and associate theMemberwith theRole, theRolewith theTeamand deduce (prefix/before the name of the association) the association of the member with the team from the role.In the first two cases, you'd need to add some constraints to ensure consistency between team membership and role (to avoid that a team member uses a role which doesn't exist in the team). You can do this in plaintext
{ role of the membership must be a role of the membership's team }In the last case, you could consider a composite aggregation between
TeamandRole(black diamond on team side, to say that the lifecycle of the role depends of the team). But a simple association with a multiplicity of1is sufficient.Can you avoid the circular dependency?
If your classes are tightly associated and if moreover you need bidirectional navigation from one class to the other, you will have a circular dependency. A frequent implementation is to have each class referring to each other. If this is a problem for you, you may as well have use third class representing the association: This third class would the have a dependency to the two others. However, if one object wants to navigate to the other on its own, it would then need to know about the third class, and you would end-up again with (another) circular dependency. The problem is simply shifted to another class. This is simply related to the interdependency of the two modelled concepts.
In no case should you consider shared aggregation (white diamond): while it is still very popular, UML does not define any special semantic for it, making it no different from a simple association, and simplicity should always prevail). See more details here.