// Levels and access
brm_get_user_levels( $user_id )
brm_get_post_required_levels( $post_id )
brm_can_user_access_content_now( $user_id, $post_id )
brm_add_user_level( $user_id, $level_id )
brm_set_post_levels( $post_id, [ 1, 2 ] )
// Progress
brm_mark_content_completed( $user_id, $post_id )
brm_is_content_completed( $user_id, $post_id )
brm_get_completion_date( $user_id, $post_id )
\BaselMedia\BricksMembers\Modules\Progress\ProgressCompletionReadService::get_instance()->get_completed_post_ids_for_user( $user_id )
\BaselMedia\BricksMembers\Modules\Progress\CompletedItemTargetReadService::get_instance()->get_last_completed_post_id( $user_id, $post_id, 'toplevel' )
\BaselMedia\BricksMembers\Modules\Progress\CompletedItemTargetReadService::get_instance()->get_last_completed_post_id_by_structure_id( $user_id, 'course_tree' )
// Navigation
brm_get_next_structure_item( $post_id, $boundary )
brm_get_previous_structure_item( $post_id, $boundary )
brm_get_structure_current_position( $post_id, $target_level )
// Content Bank
brm_is_bank_item( $post_id )
brm_is_bank_proxy( $post_id )
brm_bank_get_source_id( $post_id )
brm_bank_get_usage_count( $post_id )
Developer rule: in 0.9.82+, treat normalized tables as the canonical source for user levels, post requirements, and direct completions. Do not reintroduce legacy brm_user_data assumptions in extensions. For Content Bank-aware code, prefer the public helpers above instead of reading _brm_bank_* meta directly unless you are explicitly working inside the module internals.