Repository navigation
Developer Reference Guide
Last Updated: 2026-05-22 | For: Developers working in C:\dev\MoFaCTS
This is the canonical developer doc for the wiki. It replaces the previous map, architecture, data model, API-contract, API-index, and card/state-machine reference pages.
- Use Local Install for the default local setup.
- Read the code in
mofacts/before changing runtime behavior. - Use this page as the stable reference for architecture, data model, runtime boundaries, and high-risk areas.
- The wiki is canonical for stable contributor guidance.
- The code is canonical for exact runtime behavior.
- Public release-facing docs live in the repository root
docs/folder; longer operational/user guidance lives in this wiki.
MoFaCTS application source still lives primarily under mofacts/, while contributor-facing learning-system code is being extracted to root learning-components/.
MoFaCTS/
mofacts/ Meteor app shell, UI, server, common collections, custom Meteor packages
learning-components/ unit engines, adaptive model code, content interpretation, runtime contracts
examples/ typed contributor examples
deploy/ canonical Docker Compose, hotfix, and deployment workflow
app/ target app-shell architecture map during migration
packages/ target public API packages during migration
Browser UI (Blaze + some Svelte)
-> Meteor DDP / HTTP
Meteor app server
-> MongoDB
-> Dynamic assets / file storage
Key patterns:
- Meteor methods handle writes and business logic.
- Publications handle reactive reads.
- Shared collections are defined in
mofacts/common/Collections.ts. - The experiment runtime is still centered on the Blaze-based card flow, with Svelte work alongside it rather than replacing it everywhere.
The current experiment runtime uses a history-first persistence model:
-
Historiesis the canonical committed interaction log for learning, assessment, hidden-item actions, and video checkpoint question progress. - Learning resume reconstructs model state from history, then recomputes the next best card at resume time instead of restoring a persisted per-card cache.
- Assessment resume derives question position from completed history count plus the persisted schedule artifact.
- Video resume derives checkpoint position from completed history count plus checkpoint metadata in the TDF.
-
GlobalExperimentStatesis now sparse control-plane state only: unit bootstrap, mapping/signature setup, schedule artifact storage, and other non-trial resume metadata. - Ordinary per-trial or per-question experiment-state writes are intentionally avoided.
Use these first when you need to understand behavior:
mofacts/server/methods/mofacts/server/publications.tsmofacts/common/Collections.tsmofacts/client/views/experiment/svelte/components/CardScreen.svelte-
mofacts/client/views/experiment/unitEngine.ts(Meteor-facing compatibility facade) learning-components/units/createUnitEngine.tslearning-components/units/UnitEngineRegistry.tslearning-components/models/selection/selectionPolicy.tslearning-components/models/probability/probabilityCalculation.tsmofacts/client/views/experiment/modules/cardStore.tsmofacts/client/views/experimentSetup/contentUpload.tsmofacts/client/views/experimentSetup/apkgWizard.ts
Primary collection groups:
- learning and course data:
Tdfs,Items,Histories,Assignments,Courses,Sections,SectionUserMap - experiment/session state:
GlobalExperimentStates,UserTimesLog,UserMetrics,UserDashboardCache - content/assets/config:
Stims,itemSourceSentences,DynamicAssets,DynamicSettings,DynamicConfig - security/audit/utility:
PasswordResetTokens,AuditLog,ErrorReports,UserUploadQuota,ScheduledTurkMessages,ClozeEditHistory
Important relationships:
- course -> section -> assignment
- TDF -> items -> histories
- user <-> section through
SectionUserMap - per-user runtime control state lives separately from lesson definition data, but committed trial/question behavior should be recoverable from
Histories
Notes:
- Meteor 3 server code should prefer async collection APIs.
- JS variable names and Mongo collection names do not always match.
-
DynamicSettingsstill uses the historical collection namedynaminc_settings.
The raw method/publication inventory is large and not useful as a separate wiki page. The practical split is:
- auth/user management
- content upload and editing
- assignments and class management
- experiment/runtime state
- reporting and data export
- theme/help-page/admin utilities
High-value methods to know:
processPackageUploadanalyzeApkgFilegenerateTdfsFromApkgsaveTdfStimulisaveTdfContentcopyTdftdfUpdateConfirmeddownloadDataByTeacherdownloadDataByFiledownloadDataByIdgetTdfsAssignedToStudentgetAllCourseAssignmentsForInstructorinsertHistory
Server-internal reporting helper:
-
getHistoryByTDFIDis exported for server-only reporting code and should not be treated as a public Meteor method.
Important publication groups:
- content listing and editing:
allTdfsListing,dashboardTdfsListing,tdfForEdit,ownedTdfs - runtime/session:
userExperimentState,currentTdf - assets/settings/theme:
assets,settings,theme,themeLibrary
When documenting or changing a method, capture:
- auth/roles required
- input shape
- return shape
- side effects
- failure cases
The experiment card flow is a high-risk area. Treat changes here as architectural work, not routine UI polish.
Runtime unit resolution recognizes assessmentsession as a schedule unit, learningsession as a model/adaptive unit, videosession as a video unit, and instruction-only units when instruction fields exist without a session object. Do not treat learning and assessment sessions as the only unit types.
Core flow:
-
prepareCard()selects and prepares the next trial - content preloads and display state is set up
- the question starts fading in; trial timers are anchored here, before input may open
- input is processed through
handleUserInput() - feedback/study/transition logic runs
-
cardEnd()returns to the next-trial path
Important trial states:
IDLEPRESENTING_LOADINGPRESENTING_FADING_INPRESENTING_DISPLAYINGPRESENTING_AWAITINGSTUDY_SHOWINGFEEDBACK_SHOWINGTRANSITION_STARTTRANSITION_FADING_OUTTRANSITION_CLEARING
Use these rules when editing trial behavior:
- input should only be accepted in input-accepting states
- speech recognition should not restart during feedback or transition phases
- fade-out/fade-in boundaries are part of runtime correctness, not just animation
- response timeout resets are explicit user-activity events, such as text input activity, voice start, and speech-recognition retry/error activity
- TTS may extend an expired timer until active playback completes, but it must not restart a full configured timer
- duplicated cleanup and fallback guards in
card.jsshould be verified against real execution flow before keeping them
CardStore is the intended facade for card-scoped state. Avoid adding fresh direct state mutations in unrelated modules.
State buckets you should think in:
- card UI state
- speech-recognition state
- trial-state-machine state
- timeout/timer state
- shared Session-backed lesson/runtime state
If you need a new state value, prefer:
- an existing store or facade
- a narrowly scoped new accessor
- direct raw Session usage only if there is a clear reason
- server methods are split under
mofacts/server/methods/, but runtime-facing method changes are still high-risk -
card.jsremains one of the highest-risk files in the codebase - Blaze and Svelte coexist, which makes contribution targeting non-obvious
- root
learning-components/is now executable TypeScript, but some public API packages remain migration targets rather than stable extension APIs - some older planning docs in the repo describe future intent, not current truth
- use
npm ci, notnpm install, for reproducible installs - keep dependency updates focused
- prefer explicit image/version tags over floating
latest - run
npm run lintandnpm run typecheckbefore merging TypeScript-bearing app changes - root
learning-components/**/*.tsandexamples/**/*.tsare included in the repository checks - treat auth, upload, export, and runtime-trial changes as high-verification areas
- default new UI work to the active Svelte direction only when the feature area already lives there
- if behavior still runs through Blaze/card runtime, document and test against the Blaze path instead of pretending the migration is complete
- for content/import/export changes, update the user-facing wiki pages in the same change when behavior changes
Getting Started
- Teacher: First Hour
- Quick Start: Content Creation
- Class Setup and Assignment Workflow
- Anki Import Guide
Authoring Reference
- Introduction to TutorScript
- Content Creation Reference Tables
- Stimulus Files (Content)
- Trial Types Reference
- Audio and Speech Settings
Advanced Authoring
Reports and Help
- Researcher Guide
- TDF field tables
- Gaze tracking prototype
- Data Output and Reports
- Data Privacy, IRB, and FERPA Notes
- Experiment Routes
- SPARC Instructional Cycles
- Public Demonstrations
- Learning Algorithms Reference
- Video Units and Adaptive Logic
- AutoTutor Sessions
- Deployment Guide
- Security Audit Operations
- Remote Install
- Runtime Settings Reference
- Admin Features Reference
- Custom Help Page Setup
- Troubleshooting
- Local Install
- Developer Reference Guide
- Learning Algorithms Reference
- Introduction to TutorScript
- AutoTutor Sessions
- Runtime Settings Reference
- Deployment Guide
- Glossary
- FAQ
- Screenshots
- License Guidance
- Implementation Cost Analysis
- GitHub Repository
- GitHub Issues