Skip to content

EMmind MTL business logic ​

This page describes the MTL edition at the repository refs listed in the project overview. The main CBT journeys were inherited from public EMmind; Google re-verification, MTL policy and messaging, the 30-day 9Q reminder, and the 10 MB upload limit are MTL changes relative to the imported public snapshots.

Actors ​

ActorSurfaceMain actions
EmployeeLINE Official Account and LIFF web appVerify identity, accept terms, complete 9Q, choose a CBT path, keep an emotion journal, plan activities, create a safety plan, request urgent support, and manage the account.
Admin or staffCMSSign in and inspect users, journals, skill progress, safety plans, 9Q records, emotions, activities, scenarios, and feedback.
LINE platformWebhook and messaging integrationVerifies LIFF identity, delivers webhook events, sends replies and push messages, and opens LIFF deep links.
Scheduled jobsCore serviceRolls recurring activities forward, sends due activity and 9Q messages, and sends emotion-journal reminders.

Onboarding and access ​

  1. LINE opens the LIFF application, optionally with a path and backToLine deep-link value.
  2. The web app exchanges the LIFF ID token at POST /line/auth.
  3. The core service verifies the ID token with LINE. A first login creates User, LineAccount, and PathSkill rows in one transaction.
  4. The web app checks Google verification. Missing or expired verification opens an external Google OAuth flow and returns to LINE.
  5. The web app requires terms acceptance, then privacy acceptance.
  6. Accepting privacy also calls POST /line/users/privacy-policy. The core service starts a short Redis conversation state and asks through LINE how the employee learned about EMmind.
  7. After all gates pass, the app restores the requested deep link. Without one, it opens the 9Q route.

The web app keeps employee authentication and the requested deep link in a Redis-backed session. The core access token identifies the employee's current LINE account on protected API calls.

LINE conversation behavior ​

The webhook processes follow and text-message events.

Input or stateCurrent behavior
Follow eventSends the identity-confirmation message and offers a DMIND prescreening link for users who are not ready to start EMmind.
Greeting keywordSends an introductory response.
Emotion keywordOffers concern-specific EMmind activities.
Danger keywordSends urgent-support copy and a LIFF link to /liff/red-case.
awaitingKnowSourceRecords a predefined referral source or moves to free-text referral-source state.
completed_quiz or asked_troubledRecords the employee's primary concern, with a free-text branch for "other".
Reminder quick repliesCan disable emotion reminders, clear currently flagged activity reminders, open the linked task, or acknowledge that the employee will find another time. The acknowledgement does not reschedule the notification.

The short conversation states use user:state:<LINE user ID> in Redis. The default lifetime is 15 minutes unless USER_STATE_EXPIRE_SECONDS is configured.

9Q questionnaire ​

The employee app asks nine questions covering the prior two weeks. Each response scores 0 to 3, for a total of 0 to 27.

TotalCurrent result copyMain action
0 to 6No or minor symptomsAcknowledge and continue.
7 to 12Relatively low to moderate symptomsAcknowledge and continue.
13 to 17Moderate to relatively high symptomsAcknowledge and continue.
18Severe-symptom copy with the medium result imageAcknowledge and continue.
19 to 27Severe symptomsOffer urgent support at /liff/red-case, with a secondary decline action.

When a quiz record is created, the core service:

  • stores the answer array and total points;
  • marks pending quiz reminders complete;
  • creates a new pending quiz notification 30 days later;
  • increments the user's quiz counter; and
  • can push the next LINE prompt that asks for the employee's primary concern.

The current employee route creates a quiz record only when the request includes backToLine. A normal /liff/quiz submission shows the result but does not call the create-quiz API.

CBT learning paths ​

The application groups work into three concern-based paths. A timestamp on PathSkill marks each completed step. The explicit learning endpoint and sentiment or activity creation append PathSkillActivity history rows. Situation and scenario survey completion updates its timestamp without appending a history row.

PathSteps in current UIStored completion fields
DepressionCheck current feeling; learn about depression; learn about treatment; keep an emotion journalemoCheckCompletedAt, learnDepCompletedAt, depTreatCompletedAt, emoJournalCompletedAt
"I do not know what I feel"Learn about emotions; separate thought from emotion; practice situation and emotion recognitionlearnEmoCompletedAt, emoThinkCompletedAt, learnSituCompletedAt
"I do not want to do anything"Learn the behavior, thought, and emotion relationship; plan activitieslearnBehavCompletedAt, actJournalCompletedAt

The user may follow a path or open individual skills directly from the path page.

Emotion journal ​

A journal is unique per user and date. It groups:

  • zero to five named emotions with intensity, reasons, optional free text, and story;
  • planned activities and their completion ratings;
  • stored situation survey forms;
  • short journal summaries; and
  • generated share-image keys.

Creating a sentiment updates path progress and history and may update the sentiment usage counter. While sentiment reminders are enabled, creation also updates the last emotion date and streak. Editing an existing sentiment changes only the sentiment fields. The core service can render the journal's emotion shapes onto a PNG, upload it to S3, add a border version, and return a shareable object URL.

Situation and thought exercises ​

The core service stores reusable Question records in emotion and situation groups. It selects random questions while tracking a per-user question pool. Situation answers are stored as SurveyForm rows linked to the current journal. Emotion or scenario answers update the question pool, scenario counter, and path timestamp without storing a SurveyForm row.

Survey-form types drive progress and usage counters. The web app uses them for thought-versus-emotion scenarios and for situation and emotion exercises, then shows a summary or lesson continuation.

Activity planning ​

Employees can create, edit, delete, and duplicate planned activities. An activity stores its date and time, activity type, free text, reminder flag, pleasure level, achievement level, and a status initialized to planned. The current service does not set the status to completed.

When a dated reminder is enabled, the core service creates a pending NotificationActivity. A midnight job copies recurring notified activities into the current day's journal. A five-minute job sends LINE reminders whose due time falls in the next five minutes. The LINE reminder can open the task or clear the employee's currently flagged activity reminders. Its postpone response does not reschedule the activity. LIFF supports editing the activity time and enabling a dated reminder.

Creating activity-journal work sets actJournalCompletedAt, appends a PathSkillActivity row, and may increment the activity feedback counter.

Safety plan and urgent support ​

Each employee has at most one safety plan. It stores arrays for warning signs, coping methods, safe places, personal contacts, professional support, and important images or notes.

The urgent-support page offers:

  • Thailand's mental-health hotline at 1323;
  • the Samaritans number configured in the UI;
  • an option to continue with EMmind support through LINE; and
  • a link to create or open the safety plan.

Danger keywords in ordinary LINE messages also route users to urgent-support choices through scripted replies and the LIFF page.

Feedback sampling ​

EMmind samples feedback after repeated use instead of asking every time. Sentiment, survey, activity, lesson, situation, and scenario counters are compared with a threshold of three. Once eligible, a random 50 percent decision determines whether to show feedback and reset that counter.

The feedback form can use an emoji rating or a short assessment. Path completion controls which assessment types are eligible for each concern path. Submitted feedback is stored in Satisfaction and appears in the CMS feedback list.

CMS behavior ​

The CMS login accepts core email/password accounts. It stores access and refresh JWTs in an HTTP-only cookie session, then calls /users/me. The application rejects a user whose role is exactly user; admin and staff continue.

Current navigation exposes:

PageAPI data
Users/admin/users, with user detail and tabs for journals, safety plan, 9Q, and skills
9Q Quiz/admin/survey-quizs
Emotions/admin/sentiments
Activities/admin/plan-activities
Scenarios/admin/survey-forms
Feedback/admin/satisfactions

The checked-out CMS server modules only issue GET requests for these pages. Edit-looking routes exist, but no corresponding create, update, or delete calls are wired in the current CMS core modules.

Scheduled behavior ​

ScheduleJobTime basis
Every day at midnightCopy recurring activities into today's journalRuntime scheduler timezone
Every five minutesSend due activity and 9Q notificationsStored due timestamps
Every day at 08:00Send streak and seven-day emotion remindersAsia/Bangkok
Every day at 03:00Re-enable emotion reminders after 14 days and reset streakAsia/Bangkok