面对实际交付,我看ai-mms的重点不在星标,而在这项能力:高等教育信息技术学院的特许经营课程注册 LMS 和 TMS — 来自单个代码库的每个合作伙伴网站一个商店 (SG/MY/GH)。把它放到部署与运行环境流程中,最容易暴露的是权限、依赖和环境差异会放大维护成本,不能只看演示是否顺利。短测时我会在非生产环境复现一次安装与运行,并保留依赖锁定、权限边界、日志、回滚和资源消耗的结果,方便团队复盘。整体来看,它适合愿意维护环境并重视故障恢复的工程团队拿来做对照测试,最终决定仍应回到真实结果和维护状态。

截图
管理指南
从管理员运行 LMS 的分步、屏幕截图驱动指南 面板 — 参见 docs/admin-guide/:
关于
高等教育课程 LMS 是一个完整的生产级课程注册和学习管理平台,基于 OpenMage 1.x (Magento 1 LTS) 构建,并为高等教育信息技术学院定制。每件产品都是一个课程(讲师指导的培训、研讨会、认证)——没有实物库存或运输。店面是课程注册门户,管理面板被重新命名为教师和操作人员的培训管理系统。
该系统以特许经营模式运行:
tertiarycourses.com.sg · tertiarycourses.com.my · tertiarycourses.com.gh。Become a franchise partner
想要在您的国家/地区运营一所由 AI- 提供支持的未来技术培训学院 - 使用现成的 WSQ / IBF / SkillsFuture-aligned 目录并在您自己的服务器上设置此 LMS 吗? 申请成为特许经营合作伙伴 — 在网站上填写申请表,我们的团队将与您联系。
主要特点
| 特点 | 描述 |
|---|---|
| 课程 = 产品 | 讲师指导/在线直播/混合课程目录 - 无库存、重量或运输。 |
| 特许经营模式 | 相同的代码库部署到每个合作伙伴自己的服务器上 - 每个网站一个商店(SG、MY、GH),每个合作伙伴完全独立(自己的域、货币、语言、定价)。 |
| 资金和补贴挂钩 | SG SkillsFuture 信用 / WSQ / IBF、MY HRDC — 自动计算的资金等级(基准、MCES)。在 WSQ 课程上,资金卡是复选框驱动的:六个编辑课程复选框(WSQ/CASL、MCES/SME、SFEC、UTAP、PSEA、缺勤工资单)写入资金徽章标签,并且该卡使用从课程自己的代码生成的 SkillsFuture 链接呈现规范的每个方案副本。每个 WSQ 课程页面都会显示其 SSG 资金有效性窗口(来自 TPG 主列表,可在管理“常规”选项卡中按课程进行编辑)。资助卡的计划链接是正确的按钮(SFC / SFEC / UTAP / PSEA),学习者通过专用的 /psea-submission/ 页面提交填写的 PSEA 提款表格,该页面将所附表格直接通过电子邮件发送给招生(无DB 记录)。除了正府计划之外,课程还可以带有免费 AI 订阅特权徽章 - 一个标签可以驱动课程标题下的店面药丸和直接在 WSQ 资金卡上方呈现的促销“6 个月免费 AI 订阅”卡,因此两者永远不会分开。 SEO 指南页面引导学习者完成每个旅程 - 如何注册 WSQ 课程、如何注册 IBF 课程(均从查询巨型菜单链接)、如何索取 SkillsFuture 学分以及如何下载 SWDA SOA — 每个都有分步卡、FAQs 和 HowTo/FAQPage 结构化数据。 |
| 课程页面部分卡 | 每个课程的六个 CMS 块部分 - 学习成果、手册、技能框架、认证、关于 IBF 认证、资金 - 在每个课程页面上呈现为样式卡(块优先,从描述中使用正则表达式回退),并在“课程详细信息”选项卡中按课程进行编辑。合作伙伴认证 (ATC) 卡 — Microsoft 学习合作伙伴、CompTIA、Linux Foundation、Autodesk ATC、Pearson VUE、Kryterion、PSI — 在认证卡之后的左栏中呈现,后面是认证考试场地卡,由多选驱动使用规范的每个合作伙伴副本编辑课程复选框(atc_partners 属性)。 |
| 形式发票 | 按需自筹 SkillsFuture-claim 形式与 GST 按补贴前标价结算。 |
| 自动班级形成 | 订单通过 cron 在带外实现为班级和名册 - 店面 HTTP 路径保持不变。 |
| 班级日历 | 已确认课程的角色感知日历(月/日/年):培训师可以看到我的日历以及他们自己分配的课程,学习者可以看到他们注册的课程,管理员可以获得所有培训师的培训日历。 |
| 课堂和 AI 工具 | LMS 仪表板上的侧边栏工具启动器 — 18 个组(教育工具、项目管理、问题解决、网络安全、财务、HR、数据分析、ML、统计、DOE、SPC、可持续性、网络、区块链、量子、GenAI、Agentic AI、虚拟)——对于培训师和学习者来说是相同的。 |
| 课程反馈 → 评论 | QR-链接的每班反馈表(可通过课程评论 → 表单生成器自定义),其提交的内容会直接保存到 Magento 评论系统中,作为批准的课程评论,并带有每个问题的星级评级(学习成果/培训师质量/培训环境),可在编辑器的课程评论选项卡中浏览每门课程,并提供可扩展的完整消息。培训师在其课程页面上的 课程反馈 部分显示 QR;该表格会自动填写课程标题、代码、运行 ID、指定的培训师和扫描班级中的 start/end 日期。 |
| ⭐ 特色推荐 | 管理员从“所有评论”网格(特色列、过滤器和批量“标记为特色”)中手工挑选具有营销价值的课程评论,然后在课程评论→特色评论上管理精选集——这是一个专用页面,准确显示公众所看到的内容,包括 live/hidden KPIs 和一键删除。主页在博客条的正下方显示了 4 个随机特色评论,/testimonials 列出了所有评论 — 每张卡片都显示星级、引言以及学习者所修课程的链接。 |
| 社交分享和点攒 | 每个课程页面都有一个分享栏(LinkedIn、X、Meta 社交平台、WhatsApp、电子邮件、复制链接)和药丸式评论摘要旁边的“点攒”按钮 - 与博客相同的分享行。按钮上的数字是课程页面的查看次数(来自 Magento 的 report_event 日志,带有“N 视图”工具提示);点击仍然记录每个访客一个。 |
| 六角色管理员 | 学习者/培训师/开发人员/营销/管理员/培训提供商,具有基于会话的角色切换和每个角色页面强制 - 每个角色仅到达其自己的页面(学习者被列入允许列表;trainer/marketing/developer 受到控制器映射的限制;管理员和培训提供商可以看到所有内容)。 |
| LMS 登录 | 每个站点上针对 LMS 角色(学习者、培训师、开发人员、营销)的专用 /lmslogin 页面 — 电子邮件 + 密码或 电子邮件 OTP;多角色用户选择一个角色,单角色用户直接登陆他们的仪表板。 /learnerlogin 保留为旧别名;管理员和培训提供商在员工门户登录,该门户接受每个角色。 |
| SG → 合作伙伴同步 | 将非 WSQ(C 前缀)课程单向导出到 MY/GH — 从合作伙伴管理员批量“同步全部”或每门课程“同步一个”,或从 SG 的特许经营管理远程触发(通过每个合作伙伴的 api_sync_trigger 进行课程/类别/时间表同步)。合作伙伴拥有的课程费用、时间表和培训师信息绝不会在课程更新时被覆盖;计划同步明确将合作伙伴课程 Date/Time 选项替换为 SG。 |
| 推荐课程铁路 | 每个SG课程页面至少显示5个“推荐课程”(追加销售链接);通过 scripts/maintenance/backfill-course-upsells.php(幂等,在合作伙伴网站上无操作)按类别亲和力使用相关的 WSQ 课程来弥补不足。 |
| 特许经营管理 | 超级管理员侧边栏组有四页:特许经营报告(从 MY/GH 合作伙伴网站提取的已确认 + 已完成课程 - 课程代码、课程、日期、培训师、已标记出勤的学习者 - 带过滤器、周日上午 10 点自动拉取 + 立即拉取)和 课程/类别/时间表同步(单向 SG → 特许经营商按合作伙伴选择推送触发器;合作伙伴永远不能写回SG)。 |
| 部署安全防护人员 | apply.php 为每个迁移提供显式的 @mms_instance 身份,强制每个站点一个存储的拓扑不变(损坏的迁移会导致部署失败),并且每日凌晨 2 点维护 cron 会发布 /media/health.json。 |
| 付款 | Stripe、HitPay、PayNow 和银彳。 |
| 证书和出席 | 每个课程日的每节课 (AM/PM) 电子出勤,以及成绩证书生成 — 当出勤率超过 70% 时,在下午 6:30 自动发送,并由培训师管理的每个学习者交付名册用于手动发送。 |
| 自主通讯 | SG-only 代理传单管道:周一和周四上午 10 点设计课程传单 → 经理批准(经理,通过电子邮件或管理员)→ MailerLite 周一和周四上午 8 点通过静态 R2 托管注册 QR 进行爆炸。自主流的硬上限2 flyers/week;未经批准,任何内容都不会发送。管理队列包含每行设计简介 - 自由文本特殊说明(引导 AI 副本和配色方案:命名方案或任何十六进制重新绘制整个设计)以及根据课程真实发布的课程日期进行验证的固定入学日期;当课程添加到队列中时,简短的对话框会自动打开,因此在设计运行可以选择它之前就已经设置了指令。概要永远不会默默地被删除:如果 AI 复制步骤失败,运行将中止而不是传送先前设计的副本,并且队列行(概要的唯一副本)将恢复到队列的头部以进行重试。颜色询问独立于复制步骤而保留,因此即使文字重新生成失败,它也会重新绘制。 |
| 时事通讯订阅者同步 | 每日凌晨 4 点 cron 会向网站自己的 MailerLite 订阅者组添加新的订单电子邮件,以及一次性历史回填。以前取消订阅的学习者永远不会被重新添加。 API 密钥、组、源商店和 on/off 都是公司设置,因此每个特许经营站点都指向其自己的列表。 |
| ✍ 代理铅磁博客 | /blog,带子块 URLs、SEO 元 + BlogPosting / FAQPage / BreadcrumbList JSON-LD (FAQ 架构从每个帖子的原生 ` |
手风琴中自动提取)、Magento 标签重用、点攒、社交分享、R2 英雄图像。代理团队撰写 2 个 posts/week:研究代理(Claude 网络搜索)侦察最新的 AI 主题,作家代理制作一篇深入的帖子,其中包含品牌的、以主题为主题的自动生成的英雄(13 个关键字选择的主题,包括 Microsoft Copilot 系列,因此一系列帖子呈现为一组),经理通过电子邮件或管理时间线批准,批准的帖子于周二发布和周五上午 9 点,然后自动分享到 LinkedIn + Meta 社交平台。管理员从博客管道面板对下一个课程进行排队。 | | **课程目录APIs** | SG 目录的经过密钥验证的只读 JSON 源 -/courses/api_wsq(TGS- 课程)和 /courses/api_nonwsq(C- 课程),保留为单独的端点,因此两个资金轨道永远不会混合。添加 ?fields=full以获取详细描述、适用性、先决条件和评估。在/courses/api_courses?sku=和/courses/api_schedule上实时查询每门课程和时间表。每个端点都记录在管理 **API 摘要** 面板中。 | | **AI- 概览就绪架构** | 课程页面会发出丰富的课程 JSON-LD — SKU 为courseCode、聚合评论评分,以及 **真正即将上课的日期** 作为从课程日期选项解析的 CourseInstance` 条目 — 加上 BreadcrumbList;该博客发出 BlogPosting / FAQPage / CollectionPage。仅结构化数据,零视觉变化。 |
| Ultimo店面 | 高级响应式主题+自定义深色管理主题。 |
技术堆栈
可以通过请求更改并再次审核重新打开已安排的未发送的新闻通讯传单。
管道在从反馈重新生成之前验证 MailerLite 取消,
释放已取消的发送槽,并需要新的经理批准。已经
发送或毁坏的传单不能重新打开;现有社会职位不变。
运行孤立回归检查
docker exec ai-mms-web-1 php /var/www/html/scripts/local-dev/test-flyer-scheduled-changes.php.
凭证 → AI 提供者 选择 Claude(现有 OAuth/API 配置)或
OpenAI OAuth 在全球范围内用于电子邮件回复草稿、博客 research/writing、时事通讯
聊天、传单修订、SEO 和宣传册副本。 OpenAI 通过 gpt-5.6-sol 使用
官方 @openai/codex-sdk (0.149.0)。可选的、显式启用的后备用途
@anthropic-ai/claude-agent-sdk (0.3.268) 和经过测试的
克劳德 OAuth 与 claude-opus-5 连接。先尝试OpenAI;失败了
通过 Claude 使用相同的 prompt/images/research 模式重试一次。
回退使用记录在 var/log/ai-provider.log 中;两次失败都保留了内容。
Claude OAuth — Opus 5 备份卡测试并加密替换令牌
无需更改主要提供商。它还提供管理的克劳德
当 Claude 被选为主时的连接。导入法典
ChatGPT OAuth auth.json; 测试并保存提供程序之前验证模型访问
激活。只有 admin/training-provider 角色可以更改全局连接。
OAuth 代币在数据库中加密,永不显示,并具体化
仅在私人临时会话中(无 shell、插件或应用程序工具)。参考
图像和博客研究网络搜索被保留。将 auth.json 排除在 Git 之外,
电子邮件和聊天。更改提供商不会批准或发送待处理的内容。
设备登录参见OpenAI认证。
两个 OAuth-compatible SDKs 都通过 scripts/ai/bridge.mjs 运行,并固定,
Docker 中经过锁定文件验证的依赖项和 Node 22。 Codex SDK 使用
校验和固定的 Codex 运行时; Claude Agent SDK 使用其匹配的捆绑运行时。
这些是官方代理SDKs,而不是REST API-key客户端。 SDK 环境
被隔离,除了明确要求的研究搜索之外,工具访问被禁用,
和 credentials/prompts 不包含在错误输出中。运行 SDK 边界测试
npm ci --prefix scripts/ai 之后为 node --test scripts/ai/bridge.test.mjs。
克劳德模式传单生成路线订阅 OAuth 通过安装
克劳德客户; API 密钥使用消息 API。组织级访问拒绝保留修订
无需通过电子邮件发送拒绝副本并显示可操作的管理错误。认证
路由检查:docker exec ai-mms-web-1 php /var/www/html/scripts/local-dev/test-flyer-claude-auth.php。
提供商检查:docker exec ai-mms-web-1 php /var/www/html/scripts/local-dev/test-ai-provider.php。
| 图层 | 技术 |
|---|---|
| 平台 | OpenMage LTS v20.12.0 (Magento 1.x) |
| 语言 | PHP 8.2 |
| 数据库 | MySQL 5.7 |
| 网络服务器 | 阿帕奇2.4 |
| 前端主题 | Infortis Ultimo(响应式) |
| 缓存 | Redis(配置/整页/块) |
| 付款 | 条纹,HitPay,PayNow,银彳 |
| 电子邮件 | 阿施罗德 SMTP Pro |
| 集装箱化 | Docker 组合 |
| 部署 | Coolify(推送到 main 时自动部署)+ Cloudflare R2(媒体) |
建筑
FRANCHISE PARTNERS — same codebase, each on its own server + DB
com.sg com.my com.gh
(one store per site · independent · no cross-site redirects)
│
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ STOREFRONT (Ultimo theme · course-registration portal) │
│ Browse courses → register (cart/checkout) → pay → confirmation email │
└──────────────────────────────────────────────────────────────────────────┘
│ order = registration
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ BACKEND (cron, every 1 min — out-of-band, frontend untouched) │
│ ClassFormation → CourseRunEnrolmentService │
│ │ │ │
│ ▼ ▼ │
│ course_runs (class instance, course_run_enrolments (roster, │
│ class_id = C000042 …) idempotent INSERT IGNORE) │
└──────────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ ADMIN (Training Management System · dark theme · six-role ACL) │
│ Classes · Rosters · Trainers · Attendance · Certificates · Pro Formas │
└──────────────────────────────────────────────────────────────────────────┘
特许经营数据模型 - 六个公理: 产品 = 课程 · 班级标识 = (course_code, title, start_date) · 班级存储 = 一行 course_runs (class_id 与 C000042 类似 - 每个站点的统一序列) · 订单 = 注册 · 花名册 = course_run_enrolments · 用户 = 六角色联盟具有统一账户。
项目结构
ai-mms/
├── app/
│ ├── code/
│ │ ├── core/Mage/ # OpenMage LTS core
│ │ ├── local/MMD/ # Custom franchise modules (see below)
│ │ └── community/ # Stripe, HitPay
│ ├── design/ # Storefront + admin templates (.phtml)
│ └── etc/ # local.xml, modules/
├── skin/ # Ultimo theme + dark admin theme (CSS/JS)
├── lib/ # Varien / Zend / Magento libraries
├── migrations/ # Numbered *.sql applied by apply.php on deploy
├── scripts/ # local-dev fixups + maintenance scripts
├── docker/ # entrypoint.sh, php.ini, Apache config
├── docker-compose.yml # Local dev stack (web + MySQL)
└── Dockerfile # Production image
自定义模块 ( app/code/local/MMD/ )
| 模块 | 目的 |
|---|---|
| RoleManager | 六角色管理系统+class/roster管理+班级ID生成+角色感知班级日历(trainer/learner 我的日历,管理培训日历)。 |
| 形式 | 按需形式发票 PDF(自费 SFC 索赔;WSQ 资金明细)。 |
| CourseImage | AI 封面图像渲染器 + 资金徽章标签(相同的标签驱动店面芯片、封面、WSQ 资金卡和免费 AI 订阅福利卡)。 |
| EmailLogin | 仅电子邮件管理员登录。 |
| FlatCategoryUrl | 所有商店均采用统一类别 URLs (/<url_key>.html)。 |
| CustomOptions | 通过 SKU 升级策略增强了产品选项。 |
| 增强的销售网格 | 管理销售网格过滤器和渲染。 |
| BankPayment | 银彳付款方式。 |
| 分支范围 | 传统的按国家/地区商店视图切换器 — 被每个站点一商店特许经营模式所取代;保留是为了向后兼容。 |
| 证书/出席 | 成就证书+电子考勤。 |
| AccountSync | 统一学习者 ↔ 影子管理员帐户。 |
| 重新安排 | 面向学习者的课程重新安排申请表 (/class-reschedule.html) — 电子邮件 OTP 验证、注册课程选择器 (MMS course_runs + LMS 查找) 以及针对没有匹配注册的学习者的手动回退。保存重新安排线索,通知工作人员,并将 WSQ 请求推送到 LMS(非致命;回退到 pending_push)。 |
| MagentoCaptcha | 由店面 lead/reschedule 表单共享的 Cloudflare Turnstile 垃圾邮件防护。 |
| 课程/线索 | 课程 CRUD + 管理网格;只读 catalog/schedule/search JSON APIs(api_wsq、api_nonwsq、api_courses、api_schedule、api_search、 api_faq、api_contact)通过Helper/Catalogfeed.php共享一个授权+信封;带有自动回复功能的联系表单潜在客户捕获,AI-为每种潜在客户类型起草回复 - 一般查询、企业培训、特许经营查询和定制培训(克劳德起草每个回复并附有特定类型的简介,审阅者通过发送前确认链接批准,批准自动发送;所有回复均以统一的支持签名和可点击的 email/WhatsApp 联系人签署)和 MailerLite 在捕获时自动订阅(选择退出永远不会重新添加),以及潜在客户网格中的“发送到 MailerLite”大规模操作和每潜在客户同步复选框。 |
| 营销 | 自主代理传单新闻通讯管道 - cron 设计(Mon/Thu 上午 10 点)、签名电子邮件 + 后端经理批准、受保护的 MailerLite 调度(Blastguard:2 blasts/week、Mon/Thu 上午 8 点)、订阅者增长 + 活动KPIs。还托管每日凌晨 4 点订单电子邮件 → MailerLite 订户同步(Model/Cron/Subscribersync.php,回填 scripts/maintenance/mailerlite-import-order-emails.php) - 每个站点配置,选择退出永远不会重新添加。 |
| 评论 | 作为店面推荐的特色评论 - 库存 review 表上的 is_featured 标志(无并行推荐表),由所有评论网格驱动(特色列 + 过滤器 +“标记为特色”批量操作)、评论编辑表单和专用的 课程评论 → 特色评论 管理页面(精选列表 + KPIs +一键删除)。在博客文章之后在主页上呈现 4 条随机精选评论,所有评论均位于 /testimonials。 |
| 博客 | CMS-style 磁力博客 — 营销 → 具有代理管道时间线的博客管理(研究代理 → 作家 + 汽车英雄 → 批准 → Tue/Fri 上午 9 点时段 → LinkedIn/ 分享)、最近帖子表(标题、链接的课程代码、阶段、时间表、喜欢、preview/approve 操作)、拖动重新排序下一课程队列,以及丰富的管理内文章预览模式(desktop/mobile 视口,适用于未发布的帖子); /blog/<slug> 店面点攒+分享。 |
开始使用
先决条件
courses_mysql2.sql)安装(推荐:Docker Compose)
# 1. Clone
git clone https://github.com/alfredang/ai-mms.git
cd ai-mms
# 2. Configure environment
cp .env.example .env # set MySQL passwords + API keys
cp app/etc/local.xml.example app/etc/local.xml # match DB credentials to .env
# 3. Build and start the stack
docker compose up -d --build
# 4. Import the base database
docker exec -i ai-mms-db_mysql-1
mysql -u root -p"$MYSQL_ROOT_PASSWORD" "$MYSQL_DATABASE" < courses_mysql2.sql
# 5. Apply migrations (schema + data) via the real runner
docker exec ai-mms-web-1 php /var/www/html/migrations/apply.php
# 6. Apply local-dev fixups (localhost URLs, disable admin captcha, enable products)
for f in scripts/local-dev/*.sql; do
docker exec -i ai-mms-db_mysql-1 mysql -u root -p"$MYSQL_ROOT_PASSWORD" "$MYSQL_DATABASE" < "$f"
done
# 7. Install Composer dependencies + clear cache
docker exec ai-mms-web-1 bash -c 'cd /var/www/html && composer install --no-dev --optimize-autoloader'
docker exec ai-mms-web-1 bash -c 'rm -rf /var/www/html/var/cache/* /var/www/html/var/full_page_cache/*'
访问
| 服务 | URL |
|---|---|
| 店面 | http://localhost:8080/ |
| 管理面板 | http://localhost:8080/<frontName>/(frontName设置在app/etc/local.xml中) |
| MySQL | localhost:3307(.env中的凭证) |
码头服务
| 服务 | 图片 | 港口 |
|---|---|---|
web |
PHP 8.2 / 阿帕奇 2.4 | 8080 |
db_mysql |
MySQL 5.7 | 3307 |
部署
每个特许经营合作伙伴的服务器都会在每次推送到 main 时通过其 自己的 Coolify 实例 自动部署(每个都通过 Coolify 的 GitHub 应用程序 git 源连接):
docker/entrypoint.sh 清除 Magento 运行时缓存,然后运行 migrations/apply.php(当 DB 出现时使用 retry/backoff)。/version.txt;公共迁移状态位于 /media/migrations-status.json。用户上传的媒体(目录 product/category 画廊)由 Cloudflare R2 提供;主题烘焙的资源在图像内传送。
贡献者注意: 在验证本地主机无错误之前,切勿使用
git push— 每次推送时都会重新部署生产。 Lint 更改了 PHP,确认重写实例化,命中受影响的路由,并在推送之前通过migrations/apply.php(不是mysql客户端)试运行新迁移。
开发者
高等教育信息科技学院私人有限公司有限公司 tertiarycourses.com.sg · ✉ 询问@tertiaryinfotech.com · ☎ +65 6100 0613