ganada.mn, one operations portal for a school with 10,000+ learners
- 10,000+
- learners since 2017 (company figure)
- ~15
- roles mapped from job titles via SSO
- 100
- database migrations, plus 69+ test files
TL;DR
- In 2022 I automated Ganada's back office on Power Automate. In 2026, as contract CTO, I built ganada.mn, one portal for contracts, classes, attendance, grades and finance.
- Microsoft Entra SSO maps job titles to about 15 roles, and Postgres row-level security enforces them. 100 migrations and 69+ test files protect the live system.
- An OpenAI admissions assistant answers only from approved facts, so it never invents prices, and a Messenger/Instagram bot hands leads to a human.
- My role
- Contract CTO (2026 – present); automation consultant on the 2022 back-office project
- Year
- 2022, 2026
- Stack
- Next.js 15 · React 19 · Supabase Postgres · Row-level security · Microsoft Entra SSO · OpenAI · Meta Messenger/Instagram API · QPay · Bunny Stream · Microsoft Teams
- Live site
- ganada.mn
Context
Ganada Mongolia is a Korean-language school and study-abroad agency in Ulaanbaatar. It has taught more than 10,000 learners since 2017 and works with 6 partner universities in Korea.
I have worked with Ganada twice: in 2022 as an automation consultant, and since 2026 as its contract CTO.
Round one: automating the back office (2022)
The first project automated Ganada’s back office on Power Automate, over a 5-month plan (June to October 2022):
- e-signature for contracts,
- a contract archive with a role matrix,
- monthly invoices,
- automatic document translation,
- class enrolment.
Round two: one operations portal (2026)
As contract CTO I built, and now run, ganada.mn, the school’s operations portal. It puts contracts (with e-signature), classes, attendance, grades and finance into one system.
Key decisions
- Identity from Microsoft Entra, not new passwords. Staff sign in with Microsoft Entra SSO (PKCE). The portal maps each person’s job title to one of about 15 roles.
- Security in the database. Supabase Postgres with row-level security, so the rules about who sees what live next to the data.
- An assistant that cannot make up prices. The OpenAI admissions assistant answers only from approved facts, so it never invents prices.
- Humans stay in the loop. The Messenger and Instagram lead bot hands the conversation to a person when needed, so enquiries are answered 24/7.
- Payments where students already are. I integrated online payments (QPay) and contract billing into the portal, so students can pay from their bank app.
- Connected to the tools staff already use. Bunny Stream serves lesson video, and Microsoft Teams receives alerts.
Keeping a live system safe
The portal is in daily use, so changes must not break it. The system is protected by 100 database migrations and 69+ automated test files.
Beyond the code
- Admissions-funnel report. I designed a monthly report for the admissions manager (leads → meetings → level test → contract), so drop-off at each stage is visible.
- ISO readiness. I wrote 16 ISO 9001/27001 procedures and a master document register: risk assessment, information security, internal audit, nonconformity, complaints, procurement and HR. This prepares the company for certification.
- Training. In September 2026 I trained staff in six roles on the new system, with a role-by-role training deck.
Result
- One system for contracts, classes, attendance, grades and finance.
- Enquiries on Messenger and Instagram are answered 24/7, with hand-off to a person.
- Staff in six roles trained on the portal, and 16 ISO procedures in place for certification.
My role
Contract CTO: I built the portal and run it, wrote the ISO procedures, and trained the staff. In 2022 I delivered the Power Automate back-office project as an automation consultant.
Stack
Next.js 15 · React 19 · Supabase Postgres (row-level security) · Microsoft Entra SSO (PKCE) · OpenAI · Meta Messenger/Instagram API · QPay · Bunny Stream · Microsoft Teams
Proof
The school’s site is live at ganada.mn. The staff portal is private; I can demo it in an interview.