Code Review for Data handler using ProfileStore

This module is supposed to handle the data and ban data of players using ProfileStore (updated version of ProfileService), I am not satisfied with the difficulty of reading the code. I have already moved repeating code to helper functions but the code is still rather hard to read, would anyone be willing to provide help of making it more readable and/or optimized?

local dataHandler = {}

-- services
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local SSS = game:GetService("ServerScriptService")

-- modules
local Modules = SSS.Modules
local ProfileStore = require(Modules.ProfileStore)

-- constants
local DATA_TEMPLATE = {
	money = 0,
	isBanned = false,
}
local BAN_TEMPLATE = {
	timesBanned = 0,
	history = {},
	currentBan = {},
}

-- initialize data
local PlayerData = ProfileStore.New("PlayerData", DATA_TEMPLATE)
local PlayerBanData = ProfileStore.New("BanData", BAN_TEMPLATE)

-- use mock in studio, not live data
if RunService:IsStudio() then
	PlayerData = PlayerData.Mock
end

-- active profiles
local Profiles = {}
local BanProfiles = {} -- cache for ban data profiles

-- helper functions
local function cleanupSessions(plr)
	local profile = Profiles[plr]
	local banCache = BanProfiles[plr]
	
	if banCache then
		banCache:EndSession()
		banCache[plr] = nil
	end
	if profile then
		profile:EndSession()
		Profiles[plr] = nil
	end
end

local function safelySaveProfile(profile)
	if profile then
		local success, err = pcall(function()
			profile:Save()
		end)
		
		if not success then
			warn("failed to save:", err)
		end
	end
end

local function isValidPlayer(plr)
	return plr and plr.Parent == Players
end


-- module functions

-- loads player data and ban data
function dataHandler:loadData(plr)
	if not isValidPlayer(plr) then return end

	-- loads main profile
	local profile = PlayerData:StartSessionAsync(tostring(plr.UserId), {
		Cancel = function()
			return not isValidPlayer(plr)
		end,
	})
	
	if profile then
		profile:AddUserId(plr.UserId)
		profile:Reconcile()

		profile.OnSessionEnd:Connect(function()
			Profiles[plr] = nil
			plr:Kick("profile session ended, please rejoin.")
		end)

		if isValidPlayer(plr) then
			Profiles[plr] = profile
			print("loaded player profile: "..plr.Name)
		else
			profile:EndSession()
		end
	else
		plr:Kick("data couldnt be loaded, rejoin")
	end
end

-- saves data
function dataHandler:saveData(plr)
	local profile = Profiles[plr]
	if profile then
		safelySaveProfile(profile)
		print("Data saved for " .. plr.Name)
	end
end

-- saves data and cleans up sessions
function dataHandler:saveDataOnLeave(plr)
	self:saveData(plr)
	cleanupSessions(plr)

	print(plr.Name .. " left, data saved")
end

-- saves all profiles
function dataHandler:saveAllProfiles()
	for plr in pairs(Profiles) do
		self:saveData(plr)
	end
end

-- gets profile of player
function dataHandler:getProfile(plr)
	return Profiles[plr]
end

-- gets bandata
function dataHandler:getBanData(plr)
	-- loads ban profile
	if BanProfiles[plr] then
		return BanProfiles[plr].Data
	end
	
	local banProfile = PlayerBanData:StartSessionAsync(tostring(plr.UserId), {
		Cancel = function()
			return not isValidPlayer(plr)
			end,
	})

	if banProfile then
		banProfile:Reconcile()
		banProfile:AddUserId(plr.UserId)
		BanProfiles[plr] = banProfile
		print("Ban data loaded for "..plr.Name)
		return banProfile
	else
		warn("couldnt get ban data for "..plr.Name)
	end
end

return dataHandler