MD Services Training Management Platform — developer reference
The API layer is organized into three modules accessible from @/api: entity CRUD wrappers (api/entities.js), backend function wrappers (api/functions.js), and React Query hooks (api/hooks.js). All data operations go through the pre-initialized Base44 SDK client.
import { courseApi, feedbackApi, useCourses, useAllFeedback, functionsApi, authApi } from "@/api";Each entity exposes the following operations:
listlist(sort?, limit?)List all records
getget(id)Get a single record by ID
filterfilter(query, sort?, limit?)Filter records by query
createcreate(data)Create a new record
updateupdate(id, data)Update a record
deletedelete(id)Delete a record
bulkCreatebulkCreate(data[])Create multiple records
bulkUpdatebulkUpdate(data[])Update multiple records by ID
updateManyupdateMany(query, $set|$unset|$inc…)Update all matching records
deleteManydeleteMany(query)Delete all matching records
Training course catalog entries
titlecategorydescriptionformatduration_valueduration_unitmax_capacitypriceimage_urllocation_idlocation_namescheduled_datesdate_tbcis_publishedcertificationcertification_periodkey_training_aspectstarget_audiencetraining_content_areascandidate_requirementscourse_examinationnotesavailability_statusList courses (sorted)
import { courseApi } from "@/api";
const courses = await courseApi.list("-created_date", 50);Filter sessions
import { sessionApi } from "@/api";
const upcoming = await sessionApi.filter(
{ status: "scheduled" },
"start_date",
100
);Create a trainer
import { trainerApi } from "@/api";
const trainer = await trainerApi.create({
full_name: "Jane Smith",
email: "jane@example.com",
specialisations: "First Aid, WHS",
});Invoked via functionsApi.<name>(payload) — returns response.data directly.
getPublicCourses→ { courses, sessions, locations }
—Returns all published courses, upcoming sessions, and active locations for the public portal.
getUsers→ { users: User[] }
—Lists all registered site users. Admin-only.
getAccessRequests→ { accessRequests: AccessRequest[] }
—Lists all access requests. Admin-only.
submitAccessRequest→ { accessRequest }
{ full_name, email, phone?, company?, reason? }Creates or updates a public access request. Enriches name/email from auth token if available.
processAccessRequest→ { success, status }
{ requestId, action: 'approve' | 'deny' }Approves (invites user) or denies a pending access request. Admin-only.
inviteCourseBooker→ { success }
{ full_name, email, organisation, phone? }Invites a new course booker, sets their role and organisation, and sends a branded welcome email. Admin-only.
createAndRegisterUsers→ { results: { invited, registered, emailsSent, errors } }
{ newUsers?: [{full_name, email}], existingUserIds?: string[], sessionId }Creates/invites new trainees and/or registers existing users into a session, sending confirmation emails.
generateCertificates→ { count, certificates }
{ sessionId }Generates PDF certificates for completed registrations in a session and uploads them. Admin-only.
notifyWaitlist{ session_id }Notifies the next waitlisted trainee when a spot opens on a session.
notifySessionFullentity automation (session data)Sends an alert to admins when a session reaches maximum capacity.
sendSessionReminders—Sends 3-day reminder emails to registered trainees for upcoming sessions. Runs on a schedule.
updateUserActivity→ { success }
—Updates the current user's last_activity timestamp for presence tracking.
Invoke a backend function
import { functionsApi } from "@/api";
const data = await functionsApi.getPublicCourses();
// → { courses, sessions, locations }
const result = await functionsApi.createAndRegisterUsers({
newUsers: [{ full_name: "John Doe", email: "john@example.com" }],
sessionId: "session_123",
});Pre-built hooks with centralized query keys and automatic cache invalidation. Import from @/api.
useCourses(){ data: Course[] }["courses"]useSessions(sort, limit){ data: TrainingSession[] }["sessions"]useScheduledSessions(){ data: TrainingSession[] }["sessions-bulk"]useTrainers(){ data: Trainer[] }["trainers"]useLocations(){ data: Location[] }["locations"]useActiveLocations(){ data: Location[] }["locations"]useRegistrations(){ data: Registration[] }["registrations"]useRegisteredRegistrations(){ data: Registration[] }["registrations-bulk"]useUsers(){ data: User[] }["users"]useAccessRequests(){ data: AccessRequest[] }["access-requests"]usePublicCourses(){ data: {courses, sessions, locations} }["public-courses"]useCourseMutations(){ create, update, delete }—useSessionMutations(){ create, update, delete }—useTrainerMutations(){ create, update, delete }—useLocationMutations(){ create, update, delete }—useAccessRequestMutations(){ approve, deny, submit }—useGenerateCertificates()mutation—useAllFeedback(){ data: Feedback[] }["feedback"]useMyFeedback(userId){ data: Feedback[] }["feedback", userId]useFeedbackMutations(){ create }—Using hooks in a component
import { useCourses, useSessionMutations } from "@/api";
function MyComponent() {
const { data: courses = [], isLoading } = useCourses();
const { create, update, delete: del } = useSessionMutations();
const handleCreate = (data) =>
create.mutate(data, {
onSuccess: () => toast.success("Session created"),
});
}Auth operations via authApi. The platform owns the auth backend (tokens, sessions, email verification).
meGet the current authenticated user
updateMeUpdate current user profile data
isAuthenticatedCheck if a session is active (returns Promise<boolean>)
logoutLog out and optionally redirect
redirectToLoginRedirect to the login page
Every entity record includes these fields automatically — never declared in schemas:
idUnique record identifiercreated_dateAuto-set creation timestampupdated_dateAuto-updated on modificationcreated_by_idID of the user who created the record