What is the best way to setup leaderstats with Datastores using single script architecture & Modules?

My current system involves of one script that has a PlayerAdded event connected to a function that runs PlayerData module, which then runs my LeaderStats module. The PlayerData module also runs when the PlayerRemoving event is fired.
Server Script:

local Services = script.Parent.Services;

local Players = game:GetService("Players");
local PlayerDataService = require(Services.PlayerDataService); --module script

local function onPlayerAdded(player: Player)
	PlayerDataService.onPlayerAddedAsync(player)
end
local function onPlayerRemoving(player: Player)
	PlayerDataService.onPlayerRemoving(player)
end
Players.PlayerRemoving:Connect(onPlayerRemoving)
Players.PlayerAdded:Connect(onPlayerAdded)

game:BindToClose(function()
	for _, player in Players:GetPlayers() do
		onPlayerRemoving(player)
	end
end)

Player Data Module

--!strict
local DataStoreService = game:GetService("DataStoreService")
local mainDataStore = DataStoreService:GetDataStore("mainDataStore", "DEV");

local LeaderstatsService = require(script.Parent.LeaderstatsService)
local PlayerDefaultData = require(script.PlayerDefaultData) --module script 
--[[
local PlayerDefaultData = {}
export type playerData = {
	minutes: number,
	points: number,
}

PlayerDefaultData._defaultData = {
	minutes = 0,
	points = 0
}:: playerData
return PlayerDefaultData
]]--

local prefix = "user_";

_G._playerData = {}:: {[Player]: PlayerDefaultData.playerData};

local PlayerDataService = {}

function PlayerDataService.onPlayerAddedAsync(player: Player)
	assert(player:IsA("Player"), "Invalid player argument")
	local key = prefix..player.UserId;
	local data: PlayerDefaultData.playerData;
	
	local success, err = pcall(function()
		data = mainDataStore:GetAsync(key);
	end)
	
	if not success then
		warn(err)
		data = PlayerDefaultData._defaultData;
	elseif not data then
		data = PlayerDefaultData._defaultData;
	end
	_G._playerData[player] = data;
	LeaderstatsService.newPlayer(player, data.minutes, data.points)
end

function PlayerDataService.onPlayerRemoving(player: Player)
	assert(player:IsA("Player"), "Invalid player argument")
	local key = prefix..player.UserId;
	local data: PlayerDefaultData.playerData = _G._playerData[player];
	print(data)
	local tries = 0;
	local MAX_TRIES = 5;
	
	local success, err
	repeat
		success, err = pcall(function()
			mainDataStore:SetAsync(key, data)
		end)
		tries += 1
	until success or tries == MAX_TRIES;
	
	if success then print("SUCCESSFULLY SAVED DATA") end
	
end

return PlayerDataService

Leaderstats Module

--!strict

local LeaderstatsService = {}

function LeaderstatsService.newPlayer(player: Player, minutes: number, points: number)
	
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player;

	local _minutes = Instance.new("IntValue")
	_minutes.Name = "Minutes"
	_minutes.Parent = leaderstats
	_minutes.Value = minutes
	
	local _points = Instance.new("IntValue")
	_points.Name = "Points"
	_points.Parent = leaderstats
	_points.Value = points
	
end

return LeaderstatsService

Sorry if this is super messy and all over the place. I am new to SSA and any advice would greatly be appreciated! I was thinking of having the LeaderstatsModule create a new leaderstats object that has methods to edit the minute value and point value. With this I would edit the minute value and point value after loading the data from the datastore and setting it within the PlayerAdded event.