Appearance
Team module
Introduction
A Team is a group of Members collaborating within our platform. Every Team can have 2 or more Members, but a Member can be part of only one Team at a time. Note: The minimum number of seats on a Team membership is 2 as stated in the Nova help text when creating a team. Otherwise, the Team can't be created.
Key Concepts and Definitions
- Member: An individual user of the platform.
- Team: An abstract grouping of Members.
- Company: A specific type of Team (a Team that has a Company Membership).
- Team Membership: Entity that describes the current billing/membership period: start, finish, expire dates and number of seats purchased.
- Company Membership: A type of Team Membership that belongs to a Team. Read more about Team Types in the section below.
- Team Role: A role of a Member within a Team.
- Coordinator: A Team Manager without access to courses. Non-billed seat.
- Supervisor: A Team Manager with access to courses. Billed seat.
- Learner: A regular team member with access to courses. Billed seat.
Team Types
While Team is an abstract concept, Company is a specific type of Team. Different types of Teams may have different functionalities and behaviors, implemented at the MembershipPlan level.
Currently, we support only the Company type, using company_membership_type MembershipPlan. In the future, we plan to introduce more Team types, such as Academic Institutions, Universities, Non-profits, etc., each with different Membership Plans, permissions, and features.
Roles and Permissions
Teams consist of Members assigned to one of three roles:
- Coordinator:
- 🆓 Non-billed seat
- 🟢 Team management permissions
- 🔴 No access to courses
- Supervisor:
- 💰 Billed seat
- 🟢 Team management permissions
- 🟢 Access to courses
- Learner:
- 💰 Billed seat
- 🔴 No Team management permissions
- 🟢 Access to courses
Manager refers collectively to Coordinators and Supervisors.
Key Points:
- Course access is always a paid feature, while team management is not (this is why the Coordinator role is free).
- Every Team must have at least one Manager to handle billing, manage Members, and configure settings.
- There is no hard limit on the number of Coordinators or Supervisors a Team can have.
- Typically, the number of Coordinators is proportional to the number of paid seats, but this is not enforced.
Relationships
In PHP code:
php
Team::hasMany(TeamParticipation::class);
TeamParticipation::belongsTo(Member::class);
TeamParticipation::belongsTo(Team::class);TeamParticipationis a pivot model betweenMemberandTeamwith an additionalteam_rolecolumn indicating the Member's role within the Team.- A
Membercan have zero or oneTeamParticipationrecords. The records are non-soft-deleted, reflecting the fact that they can be part of max. oneTeamat any time.- Soft deletes are used to track the history of TeamParticipations and calculate the number of free and used seats (see "Seat Rotation").
Team Memberships
Historically, Teams had different membership types. Since 2018, we only use company_membership_type as a sole Team Membership Plan.
NOTE
We used "Membership Type" term in the past, but changed conception a bit and now call it "Membership Plan". In some places you can find usages on old term, please do not be confused by the "company_membership_type" name - it's a Plan name.
Company Membership
Company Membership is the only currently available Team Membership Plan.
Companies benefit from several advanced features:
- SAML/SSO Integration: Simplify login and authentication using Single Sign-On protocols.
- Advanced Statistics and Reports: Access detailed analytics on Member progress and Team performance.
- Consolidated Billing: Single billing for all Team Members, streamlining payment processes.
- Auto-Registration: Automatically register new Team Members who use specified email domains.
Trial Team Membership (state)
When a company requests to try our platform, our staff may create a Trial Team Membership for them.
Differences between a trial team membership and a regular team membership:
- Duration and Cost: Trial memberships are free and have a shorter duration.
- Expiration Handling:
- When a Trial Membership expires, all Members are detached from the Team, and their memberships are canceled.
- For non-trial memberships, detached Members are moved to an expiring individual membership.
NOTE
Individual Members may also have trial memberships, but their technical implementation differs (for historical reasons):
- Individual trial membership is a separate Membership Plan.
- Trial Team Membership is indicated by a flag in the TeamMembership model.
Team Lifecycle States
At any time, a Team can be in one of the following states:
State Definitions:
- Active: The Team's membership is valid, and all features are accessible.
- Expired: The Team's membership has expired and requires renewal. No access to courses.
- Canceled: The Team's membership is terminated, and all associated Members are detached (see "Removing Team Members").
It's almost the same as the Individual Membership lifecycle, but there is no Reactivation option for Teams (Teams usually contact our support to reactivate their accounts or they can simply create a new membership).
Seat rotation
When a Member is removed from a Team, their seat remains occupied until the end of the current billing period. This policy prevents Teams from circumventing seat limits by frequently rotating Members. In other words, when a Team account, e.g., a Company membership, is at 100% seat occupancy and the supervisor/coordinator removes someone from the team, that seat doesn't automatically become available for someone else. Teams frequently reach out to support in order to replace members who have left their teams due to turnover within their company.
Key Points:
- Removed Members still count towards the total number of used seats until the billing period renews.
- Seats become available only at the start of a new billing period unless additional seats are purchased.
Checking Seat Availability:
php
/** @var \App\Modules\Team\Models\Team $team */
$team->getNumberOfSeats(); // Total seats purchased
$team->getNumberOfUsedSeats(); // Seats currently occupied
$team->getNumberOfFreeSeats(); // Seats available for new Members
// The following expression is always true:
$team->getNumberOfSeats() === $team->getNumberOfUsedSeats() + $team->getNumberOfFreeSeats();Team Operations
Adding Team Members
To add an existing Member to a Team:
php
$team->addMemberToTeamWithExtraRoles($member, TeamMemberRole::Learner);Removing Team Members
When a Team Member is detached from the Team, the following actions occur:
- For Trial Team Memberships:
- The Member's membership is canceled immediately with the reason Removed from trial company.
- For Regular Team Memberships:
- The Member is moved to an individual Professional membership with a short expiration date (currently 16 days).
- The grace-period of 16 days (
ixdf_membership.days_until_expiration_for_detached_company_members) is chosen to match the notification schedule ofNotifyCreditCardWillBeAutoChargedwhich is 15 days (NUMBER_OF_DAYS_UNTIL_NEXT_PAYMENT). - The Member is notified of their removal and informed about the upcoming membership renewal, with options to continue or cancel.
API Usage:
php
/** @var \App\Modules\Team\Actions\DetachFromTeamToIndividualGracePeriodAction $detachMemberAction */
$detachMemberAction->execute($teamParticipation, removeEvenIfLastManager: false);Auto-Approval of Team Members
Team supervisors can enable the auto-approval feature for their team. When this feature is enabled, new team members with email addresses from specified domains are automatically added to the team without the need for manual approval.
The auto-approval URL is in the following format: /join/company/company-slug. New team members can use this URL to join the team by providing their name and email address. Once this is done, a new instance of TeamParticipantPendingAuthorization is created with auto_approval confirmation type.
In the final step, the new team member needs to confirm their email by clicking on the link sent to their email address. The new team member then gets attached to the team, receives MemberAddedToTeam notification, and the TeamParticipantPendingAuthorization instance is soft-deleted.
Team Membership Cancelation
When a Team Membership is canceled, all Team Members are detached from the Team and moved to expiring Professional Individual Memberships (see "Removing Team Members").
Changing team size
Each Team membership has a strictly defined maximum number of seats. If a Team Supervisor decides to increase the number of available seats, they can reach out to IxDF or do it themselves on the Company Billing tab within their profile.
Consider the following scenario:
Let's assume the Company Membership price is 240.00 USD per year. Initially, a Company purchased 2 seats, amounting to 480.00 USD.
On 1st April 2023, three months (90 days) into the billing period, the team supervisor decides to increase the number of seats from 2 to 4. How much will the company be charged?
- Seat price per day: 240.00 USD / 365 days ≈ $0.6575
- Days that there is no need to pay for: 90 days
- Deduct from the price of new Memberships: $0.6575 90 days 2 seats = $118.35
Therefore, for the two extra seats, the Company will be charged:
(2 seats * $240.00) - $118.35 USD = $361.65
In other words, the company is charged a pro-rated amount based on the number of days left in its membership period.
After successful payment, a new Company membership will be created with the following parameters:
- Start date: 1st April 2023
- Expiration date: 1st January 2024
- Number of seats: 4
Limitations:
The discount calculation is applicable only to company memberships with a standard billing period inline with the recurrence (typically P1Y). Company memberships that were extended manually do not qualify for a discount when purchasing extra seats on the platform.
Events
To execute code on every Team operation, you may listen for various events dispatched by the Team module:
php
use App\Modules\Team\Events\MemberAttachedToTeam;
use App\Modules\Team\Events\MemberDetachedFromTeam;