Feature flippers¶
Feature flippers allow enabling and disabling specific platform features dynamically. They can be controlled per platform, user group, or individual user - and even limited to specific contexts (such as courses).
Tip
For development, this also enables continuous deployment by deploying “unfinished” features, hidden behind such a flipper.
See below for explanations on managing feature flippers (creating a flipper and using it in the code).
Annotations
- Experimental and temporary features intended for migration purposes or prototypical use.
- Feature is programmatically enabled / disabled, typically part of a broader feature set, and is tied to a specific user.
- Deprecated feature, which is planned to be removed.
List of features¶
account.login-
Enable (native) platform login: This will enable password reset and shows the login form (with user / password input).
Scope:
Group.all_users,Context.root account.registration-
Enable (native) platform registration: This will show the registration form and the respective button for the login form.
Scope:
Group.all_users,Context.root announcements-
Enable accessing “global” announcements (admin- and user-facing pages) on the platform (including the start page) as well as publishing them via email.
Scope:
Group.all_users,Context.rootNote
This is not referring to “targeted announcements”. See the
admin_announcementsfeature below. admin_announcements-
Enable the new admin-only announcement overview (accessible via platform admin menu).
Scope:
Group.administrators,Context.root alternative_sections.create-
Enables the ability to create alternative sections. This doesn’t affect existing alternative sections, these can be visited and edited without this flipper.
Scope:
Group.all_users,Context.root certificate_requirements-
Display the certificate requirements on the course page.
Scope:
Group.all_users,Context.root course.access-group-
Allow courses that are only accessible for certain user groups, usually coupled with SSO.
Scope:
Group.all_users,Context.root course.reactivated-
This user has purchased a course reactivation for a specific course; items are fetched for this user (thus: overriding caching), in order to apply enforced submission deadlines.
Scope:
User,CourseInfo
The feature is set programmatically. Set the
course_reactivationflipper to allow course reactivations for the platform. course.required_items-
Enable the admin interface for adding required items to a learning unit.
Scope:
Group.administrators,Context.root course_dashboard.show_cops_details-
Display detailed CoPs statistics (at the course end and since the course end) on the course dashboard. Hidden by default until results are deemed reliable.
Scope:
Group.all_users,Context.root course_details.learning_goals-
Display the learning goals on the course details page.
Scope:
Group.all_users,Context.root course_list-
Enable the global course list.
Scope:
Group.all_users,Context.rootWarning
Should be disabled on “headless” platforms that sit behind a custom portal.
course_rating-
Enable the course rating widget on the course details pages.
Scope:
Group.all_users,Context.root course_reactivation-
Enable course reactivation for the platform. Course reactivation can then be enabled individually per course via UI.
Scope:
Group.all_users,Context.root chatbot.prototype-2-
Enable the chatbot prototype in the helpdesk widget.
Scope:
Group.all_users,Context.rootInfo
This requires the chatbot backend to be set up properly. Further configuration is required.
dashboard.course_recommendations-
Enable the course recommendation widget on the user’s dashboard, showing courses for promotion (e.g., current or upcoming courses).
Scope:
Group.all_users,Context.root gamification-
Enable gamification for the platform (e.g., XP in navigation and user badges in the discussion forum).
Scope:
Group.all_users,Context.root geo_ip_block-
Block users from Russia and Belarus on the registration pages.
Scope:
Group.all_users,Context.root ical_feed-
Enable the iCal feed for the user’s next (course) dates (button on the dashboard).
Scope:
Group.all_users,Context.root integration.external_booking-
Enable integration with external booking tools for courses. This adds a JWT token to external registration URLs.
Scope:
Group.all_users,Context.root new_pinboard.phase-1.2-
Enable the new pinboard prototype, i.e. a specific variant of the discussion forum.
Scope:
User,Course (A/B tests) open_mode-
Enable the preview of video items for anonymous or non-enrolled users for items that are flagged for ‘open mode’ via the item settings.
Scope:
Group.all_users,Context.rootWarning
Do not enable this feature for staging / testing systems.
password_change.remove_sessions-
Log out users on other browsers when they change their password in the profile.
Scope:
Group.all_users,Context.root preview_graded_quiz_points-
Display achieved score (not the results) for graded quizzes immediately after submission.
Scope:
Group.all_users,Context.root primary_email_suspended-
Disable email notifications and show a warning for users where emails to the primary email bounced.
Scope:
User,Context.rootInfo
The feature is set programmatically.
proctoring-
Enable proctoring for the platform. Proctoring can be enabled individually per course, there is a course-specific
proctoredsetting.Scope:
Group.all_users,Context.rootInfo
This feature requires further configuration. The following keys must be set in the
config/secrets.ymlfile:smowl_entity: my_entity smowl_password: my_password profile-
Enable the user profile page.
Scope:
Group.all_users,Context.rootWarning
Should be disabled on “headless” platforms that sit behind a custom portal.
quiz_recap-
Enable the quiz recap feature in the course area.
Scope:
Group.all_users,Context.root records.exclude_birthdate-
Hide notes / hints about the preference to display a user’s birthdate on records.
Scope:
Group.all_users,Context.root social_sharing.certificate-
Enable social sharing for open badges on the certificates page.
Scope:
Group.all_users,Context.root time_effort-
Enable time effort estimation shown in the item navigation and on the item page.
Scope:
Group.all_users,Context.rootInfo
This requires the time effort service to be set up for the platform.
time_effort.video_only-
Enable time effort estimation shown in the item navigation and on the item page.
Scope:
Group.all_users,Context.rootInfo
This feature must be used in conjunction with the
time_effortfeature. users.search_by_auth_uid-
Allow admins to search users via authorization UID.
Scope:
Group.administrators,Context.root video_slide_thumbnails-
Enable slide thumbnails in the video player.
Scope:
Group.all_users,Context.root
Manage feature flippers¶
This section explains how to manage feature flippers for a platform.
Enable features¶
For enabling a specific feature - either locally or for a production system - a corresponding Feature record needs to be created via Rails console (account service):
AccountService::Feature.create!(
name: 'feature_name',
value: true,
owner: User.find(user_id),
context: Context.root # or a specific (course) context
)
AccountService::Feature.create!(
name: 'feature_name',
value: true,
owner: Group.all_users, # or a any other group
context: Context.root
)
This will enable the feature_name feature for the respective users in the given context.
The following global special groups can be used:
Group.active_users- all confirmed, non-archived usersGroup.administrators- all members of the groupxikolo.administratorsGroup.affiliated_users- all active users with the affiliated flagGroup.all_users- all users (including anonymous, non-confirmed, archived)Group.confirmed_users- all confirmed users (including archived)Group.unconfirmed_users- all unconfirmed users (including anonymous)Group.archived_users- all archived users
Feature owners
User.find('00000000-0000-0000-0000-000000000000') # Query user by ID
User.query('jane.doe@example.com').first # Query user by email
Group.find('00000000-0000-0000-0000-000000000000') # Query group by ID
Group.active_users # Use a special group
Check features for the current user¶
When developing a feature, enabled features for a user can be checked as follows.
if current_user.feature?('feature_name')
# Execute logic...
end
When running code in other services, such as in a cron job or background job and not for of spcific user, it may be necessary to check whether a feature is enabled for the platform. In this case, the anonymous session can be used to check for the status of the feature for all users:
Xikolo.api(:account).value!
.rel(:session).get(id: 'anonymous', embed: 'features').value!
=> {"id"=>nil,
"self_url"=>"http://localhost:3100/sessions/anonymous",
"user_id"=>"02e4fdd9-23f3-45f5-ba45-95cbc41c42f0",
"user_url"=>"http://localhost:3100/users/02e4fdd9-23f3-45f5-ba45-95cbc41c42f0",
"user_agent"=>nil,
"masqueraded"=>false,
"interrupt"=>false,
"interrupts"=>[],
"features"=>{"for_everyone"=>"t"}}
Disable features¶
If you want to disable a specific feature that has been previously enabled, the corresponding Feature record needs to be destroyed.
AccountService::Feature.find_by!(name: 'feature_name', owner: User.find(user_id)).destroy!
Best practices¶
- Regularly review enabled features.
- Test new features before enabling them for all users.
- Maintain documentation of changes.