Migration from Tutor LMS

What exists today in the WordPress and Tutor LMS site and in MALYOMAR's own files, how clean it is, how it maps to the new records and the order in which it moves. Findings are computed from the same course data the prototype uses.

Source files received

70 files, February 2026
SourceWhat it holdsSizeUse in migration
Course export
Course-Export-2026-Feb-16.csv / .xlsx
One row per Tutor LMS course: title, content, excerpt, duration, benefits, level, materials, requirements, audience, price, sale price, language, categories, tags, image, status, author, slug.58 rows
44 columns
Primary source for Course
Topics export
Topics-Export-2026-Feb-16.csv
Curriculum sections. Parent course is held in the post parent field.365 rows
84 columns
Primary for curriculum topics
Lesson export
Lesson-Export-2026-Feb-16.csv
Lessons with content, video settings, attachments, preview flag and the course they belong to.570 rows
101 columns
Primary for lessons
Quiz export
Quiz-Export-2026-Feb-16.csv
Quiz shells and their options. Questions and answers are not in the file.42 rows
60 columns
Partial questions need a separate pull
Combined catalog
Tutor_LMS_Complete_Course_Catalog.csv
Course, topic, content item, order and type flattened into one sheet.921 rowsCross-check of the three exports
Field list
Tutor-LMS courses fields list.xlsx
The Tutor LMS course fields as MALYOMAR listed them.1 fileReference for mapping
MEDB 1.0 Access database
MEDB 1.0.accdb and two backups
MALYOMAR's own course database with queries for catalog, topics, lessons and quizzes.3 filesTo inspect may be more current than the site
Query outputs
Courses_Q, Topics_Q, Lessons_Q, Quiz_Q, qry_CATA*, qry_CTLQ*
Spreadsheet and XML results of the Access queries, including single-course samples.14 filesCross-check
Per-course workbooks
ML501.xlsx … ML530.xlsx, PD184.xlsx … PD838.xlsx
One workbook per course code: 23 MALYOMAR programs and 21 ASME programs.44 filesPrimary where richer than the export
Curriculum data entry template
Curriculum Data Entry Template.xlsx
The sheet layout MALYOMAR uses to prepare a curriculum.1 fileReference becomes the import template
Row and column counts were measured on the files in the shared drive folder DB.

What is not in the files

  • Learners and enrolments. No student, enrolment or progress export was provided. Needs a database pull from Tutor LMS.
  • Orders and payments. Held by the shop plugin; not exported.
  • Issued certificates. No list of past certificates or their codes.
  • Quiz questions. Only quiz shells are present.
  • Media. Lesson videos and attachments are referenced by link, not included.
  • Batches and attendance. Never held in the site; if records exist they are in spreadsheets or email.

Opening data for the new modules

Separate collection task

The modules added in revision 5 Oct 2026 have no source in the Tutor LMS export. Their opening data has to be collected from MALYOMAR's own files and from the accountant. Everything the prototype shows for them is sample data.

  • Employees and employment documents for People and HR. What is held, and where payroll is calculated, depends on .
  • Suppliers, open purchase orders and unpaid supplier bills for Purchasing and payables.
  • Opening balances, open receivables, bank and wallet balances for Finance. Which system holds the books, and so where balances are loaded, depends on .
  • Partner agreements, tender history and the annual plan for Partners, CRM and Planning and targets. Signed terms and approved targets are entered by management; none are assumed.
  • Website pages, menus and SEO metadata. Whether WordPress content is migrated, kept in place or handed over through an integration depends on .

No cut-over date or load order is set for these. They follow the decisions listed on open decisions.

Three versions of the truth. The live site, the Access database and the per-course workbooks may disagree. Step 2 of the plan decides which one wins for each field.
Today's platform. WordPress with Tutor LMS, a shop plugin for checkout and a page builder theme. Courses are WordPress posts; instructors are WordPress users.

Findings in the course data

Computed live from the catalog data
FindingCoursesWhichWhat to do

Every course, with its gaps

CourseStatusHoursPriceTopicsLessonsIssues

Status in Tutor LMS

Only “publish” is visible on the live site.

Provider and academy

Provider and academy were assigned for the prototype from codes and categories; to be confirmed course by course.

Findings in the export itself

Measured on the files
  • Authorship is a login name. Of 58 exported courses, 29 are authored by a user called “MALYOMAR”, 18 by the owner's personal login, 9 by a user called “ASME”, and 2 by other accounts. This is the source of the “course author” entries in the instructor directory.
  • Language is mostly empty. 39 of 58 courses have no language set.
  • No currency field. Price is a bare number.
  • Duplicate markers. Topics, lessons and quizzes carry dozens of “course duplicate” columns left by copying courses; they show which items were cloned and may be stale.
  • Encoding damage. Some descriptions contain broken characters where non-breaking spaces were.
  • Four exported courses are not in the prototype catalog. 58 rows in the export, in the catalog data; the four left out are a trashed test course, an empty “New Course” draft, a duplicate “(Copy 1)” of the Fitness-for-Service course and a private physics handbook. Confirm they should stay out.
Approach. Do not copy the WordPress structure. Map each source field to the new record, clean it on the way in, and let a person confirm every course on the import screen before it is published. The old site stays read-only until cut-over.
Tutor LMS / WordPress fieldNew record and fieldRule on the way inCheck
IDCourse.legacyIdKept for redirects and for linking topics and lessonsAutomatic
TitleCourse.courseCode + courseTitleSplit the code (PD643, ML513) from the title; items without a code get a temporary one and are heldReview
Slug, PermalinkCourse.slug, redirect tableOld address redirects to the new course pageAutomatic
ContentCourse.fullDescriptionStrip page-builder markup, fix encoding, keep paragraphsReview
ExcerptCourse.shortDescriptionTrim to card length; draft with AI where empty, marked as draftReview
_tutor_course_benefitsCourse.learningObjectives[]One line becomes one outcomeAutomatic
_tutor_course_target_audienceCourse.targetAudience[]Split lines; normalise to the persona listReview
_tutor_course_requirementsCourse.prerequisites[]Split lines; link to courses where a code is mentionedReview
_tutor_course_material_includesCourse.materialsIncluded[]Split linesAutomatic
_tutor_course_levelCourse.levelbeginner, intermediate, expert become Foundation, Practitioner, AdvancedAutomatic
_course_duration_in_secondsCourse.durationHoursConvert; empty stays empty and blocks publishingFix at source
tutor_course_price, tutor_course_sale_priceCourse.price, currencyCurrency set by decision; outliers held for confirmationFix at source
Course LanguageCourse.languageEmpty in most rows; set per courseFix at source
Course CategoriesCourse.school (Academy), categoryTen WordPress categories fold into five academiesReview
Course TagsCourse.standards[], software[]Tags naming a code or a tool move to the right listReview
Author UsernameCourse.providerType“ASME” becomes provider ASME; “MALYOMAR” and personal logins become provider MALYOMAR unless the code is an ASME code. Never becomes an instructorReview
(Tutor instructor assignment)Course.instructorIds[]Only real people; “Course Author” accounts are droppedReview
StatusCourse.statuspublish becomes Published after checks; pending becomes In review; draft stays Draft; private becomes InternalAutomatic
Image URLCourse.heroImageDownload and store; replace where the image carries textReview
Topics export: Title, Parent, OrderCourse.curriculum[] topicLinked by legacy course ID, orderedAutomatic
Lesson export: Title, Content, _video, _tutor_attachments, _is_previewLesson under its topicVideo and files re-hosted; preview flag keptReview
Quiz export: Title, tutor_quiz_optionQuiz (settings only)Questions pulled separately or re-enteredFix at source
WordPress users with the student roleContact, LearnerDe-duplicate by email; ask for consent again where missingReview
Tutor enrolments and completionEnrolment (historic)Imported as history without a batch; flagged “legacy”Review
Shop ordersOrder, Payment (historic)Read-only archive; not re-invoicedAutomatic
Target fields are defined on the data model.

Migration steps

Courses first, people second, history last
  1. InventoryAgree the list of sources and get the missing pulls
  2. Decide the masterPer field: site, Access or workbook
  3. Clean at sourceHours, prices, language, codes
  4. Trial importAll courses into a test hub
  5. ReviewEach course confirmed by its owner
  6. People and historyLearners, enrolments, certificates
  7. Cut-overRedirects on, old site read-only
  8. RetireArchive Tutor LMS after a quiet period

What each step delivers

StepWhoDone when
1. InventoryOwner, developerLearner, enrolment, order and certificate exports are in hand; Access database opened and described
2. Decide the masterOwnerA one-page table: for each Course field, the winning source
3. Clean at sourceOperations, instructorsNo published course lacks hours, price, currency, language or provider
4. Trial importDeveloperImport runs end to end and reports every row it changed or held
5. ReviewCourse ownersEvery course on the import screen is confirmed or parked
6. People and historyDeveloper, supportLearners can sign in and see past courses and certificates
7. Cut-overDeveloper, ownerOld addresses redirect; new enrolments go only to the hub
8. RetireOwnerBackup stored; plugins and hosting cancelled

Risks

RiskLikelihoodResponse
Sources disagree and nobody knows which is rightHighStep 2 before any import; one named owner per academy
Wrong prices or currency publishedMediumOutliers held; price approval by the owner before publish
ASME content altered during clean-upMediumASME program text locked on import; only layout changes
Learner history incomplete or cannot be exportedMediumDatabase-level pull early in phase 0; accept “legacy” records
Past certificates cannot be verified after cut-overMediumImport issued certificates with codes, or publish a legacy lookup
Search ranking lost when addresses changeMediumRedirect table from every old slug; keep titles stable at launch
Learners must reset passwordsCertainAnnounce ahead; one-click activation email
Opening data for HR, purchasing and accounting collected late or loaded twiceMediumTreat as its own task with a named owner per module; load only after the accounting and payroll boundaries are decided (DEC-01, DEC-08)
Orders in flight during cut-overLowFreeze the old checkout for a short window; handle by hand
Where AI helps in migration. Drafting missing short descriptions, proposing the academy and level for uncategorised courses, and spotting near-duplicate topics. Each proposal is shown beside the original on the import screen and needs a person to accept it. See AI layer.