2026-02-28|10 min read|--xulang-edu--build-in-public--firebase--education-tech--indie-making

Building XuLang-Edu: When Your Friend's Excel Hell Becomes Your Next Project

Building XuLang-Edu: When Your Friend's Excel Hell Becomes Your Next Project

My friend Dũng runs an education center in Lạng Sơn, Vietnam.

26 classes. 100+ students. 8 teachers. Revenue tracking. Attendance. Salary calculations. Payment monitoring.

All in Excel.

And he manages it from his phone while drinking with clients.

Spoiler: Excel doesn't work well on phones.

So I'm building him a proper web app. Here's the journey.

## The Problem

Dũng's pain points were brutally simple:

1. Excel is unusable on mobile He's a business owner. He's out meeting clients, networking, closing deals. He needs to check:

  • >Which classes are running right now?
  • >How many students showed up today?
  • >Is revenue on track this month?
  • >Did teacher X submit attendance?

Excel on iPhone = pinch, zoom, scroll sideways, lose context, curse, give up.

2. No real-time visibility When he's out, he's blind. Teachers mark attendance in their own copies. He consolidates data later. By "later," I mean hours or days later.

Zero real-time monitoring = zero control.

3. Manual calculations everywhere

  • >Teacher salary = count attendance rows × rate
  • >Student fees = calculate manually, track in separate sheet
  • >Monthly reports = export, pivot table, pray

One wrong formula = wrong payment = angry teacher or parent.

4. Reports are a nightmare He needs reports for:

  • >Accountant (monthly revenue/expenses)
  • >Tax (quarterly)
  • >Analysis (which classes profitable? which teachers best?)

Current process: Manually aggregate data from 26 sheets. Takes hours. Error-prone.

5. Teachers hate it too They have to:

  • >Open shared Excel
  • >Find their sheet
  • >Mark attendance (1/K/P/m/DB codes)
  • >Hope no one else is editing
  • >Hope they don't break formulas

They want a simple app. Not spreadsheet gymnastics.

## The Requirements

After talking with Dũng, I mapped out what he actually needs:

Must-have (Phase 1):

  • >Mobile-first dashboard
  • >CRUD for Students, Teachers, Classes, Rooms
  • >Import existing Excel data (26 classes worth)
  • >Authentication (Admin vs Teacher roles)

Critical (Phase 2):

  • >Attendance interface (fast, mobile-friendly)
  • >Teacher dashboard (my classes, my salary)
  • >Live monitoring (which classes running now?)
  • >Auto-calculate salary from attendance

Nice-to-have (Phase 3):

  • >Reports with charts
  • >Export Excel for accountant
  • >Payment tracking
  • >Notifications (học phí due, absences)

## The Architecture

I chose a stack optimized for solo developer + real-time needs:

Frontend:

  • >Next.js 14 (App Router)
  • >TypeScript
  • >Tailwind CSS
  • >Shadcn/ui components

Backend:

  • >Firebase Firestore (NoSQL, real-time)
  • >Firebase Auth
  • >Cloud Functions (planned)

Hosting:

  • >Vercel (frontend)
  • >Firebase (backend)
  • >Domain: xulangeducation.com

Why Firebase?

  1. >

    Real-time by default. When teacher marks attendance, Dũng sees it instantly on his phone. No polling. No refresh.

  2. >

    Free tier is generous. For 100 students + 8 teachers + 1 admin, we're nowhere near limits.

  3. >

    Built-in auth. Email/password auth in 5 lines of code.

  4. >

    Offline support. Teachers can mark attendance even with spotty connection. Syncs when back online.

  5. >

    I can build it fast. Solo developer. Tight timeline. Firebase = less backend code.

## The Database Schema

10 collections, carefully designed:

// Core entities
students (id, name, grade, parentPhone, status, fees)
teachers (id, name, phone, subjects, salaryRate)
classes (id, name, subject, grade, schedule, roomId, teacherId)
rooms (id, name, capacity, floor, status)

// Operational data
attendance (id, classId, studentId, date, status, note)
teacherSessions (id, teacherId, classId, date, hours, rate)
expenses (id, category, amount, date, note)
payments (id, studentId, amount, date, month, method)

// System
users (id, email, role, teacherId/studentId)
settings (id, key, value)

Key design decisions:

1. Denormalization where it matters Classes store teacherName directly, not just teacherId. Why? Because dashboard needs to show teacher names instantly. No joins in NoSQL.

2. Attendance vs TeacherSessions Separate collections. Attendance = student-level. TeacherSessions = teacher-level for salary calculation. Different use cases, different structures.

3. Status enums everywhere Student status: active/graduated/withdrawn Attendance: 1 (full), K (late), P (absent approved), m (absent unapproved), DB (sick) Payment: pending/paid/overdue

Clear states = clear logic = fewer bugs.

## The Attendance Logic

This was the trickiest part. Vietnamese education centers have specific attendance codes:

  • >1 = Full attendance (học đủ)
  • >K = Late (đi trễ)
  • >P = Absent with permission (nghỉ phép)
  • >m = Absent without permission (nghỉ không phép)
  • >DB = Sick leave (đau bệnh)

Why it matters:

Teacher salary calculation:

  • >1 or K = count as taught = pay full rate
  • >P or m or DB = didn't teach = no pay

Student fee calculation:

  • >Tracks attendance for refunds/adjustments
  • >P/DB might get makeup classes

The app auto-calculates both. Teacher submits attendance → system updates:

  1. >Teacher session record (for salary)
  2. >Student attendance record (for tracking)
  3. >Class statistics (for monitoring)

All in one transaction.

## The Teacher Dashboard

Teachers get a dead-simple interface:

Landing page shows:

  • >My classes today
  • >Students enrolled
  • >Attendance submitted? (Yes/No)
  • >This month's salary estimate

Attendance flow:

  1. >Tap "Mark Attendance"
  2. >See list of students
  3. >Tap each name → toggle status (1/K/P/m/DB)
  4. >Submit
  5. >Done

No Excel. No formulas. No confusion.

On submit, the system:

  • >Saves attendance records
  • >Creates teacher session entry
  • >Calculates session payment
  • >Updates class stats
  • >Notifies admin (optional)

Teacher sees updated salary instantly.

## The Admin Dashboard (Mobile-First)

Dũng's phone shows:

Live monitor:

  • >Classes running now (green)
  • >Classes scheduled soon (yellow)
  • >Classes finished (gray)
  • >Tap to see attendance status

Quick stats:

  • >Total students active
  • >Revenue this month
  • >Pending payments
  • >Teacher sessions completed

Drill-down:

  • >Tap class → see full attendance
  • >Tap teacher → see all sessions
  • >Tap student → see payment history

Everything real-time. No refresh needed.

## The Import Challenge

Current state: 26 Excel sheets, one per class.

Each sheet has:

  • >Student list (rows)
  • >Dates (columns)
  • >Attendance codes (cells)
  • >Formulas for totals

I built an import script:

// Pseudocode
for each sheet:
  1. Extract class info (name, teacher, schedule)
  2. Create class document
  3. Extract student list
  4. Create student documents
  5. Parse attendance grid
  6. Create attendance records (one per student per date)
  7. Calculate teacher sessions from attendance
  8. Create session records

Complexity: Mapping messy Excel data to clean database structure.

Solution: Lots of data validation, edge case handling, manual QA.

Once imported, historical data is preserved. Going forward, everything is entered in the app.

## Current Progress (Feb 28, 2026)

### ✅ Built

  • >Project structure (Next.js + TypeScript + Tailwind)
  • >Database schema designed
  • >TypeScript interfaces for all entities
  • >Admin layout with sidebar navigation
  • >Firebase config (template)
  • >Import script (ready to test)

### 🚧 In Progress

  • >UI integration (dark theme, shadcn components)
  • >Firebase setup (credentials, init)
  • >Dashboard mockup (static data)

### ⏳ Coming Next

  • >CRUD pages (Students, Teachers, Classes, Rooms)
  • >Firebase connection
  • >Import Excel data
  • >Authentication
  • >Attendance interface
  • >Teacher dashboard
  • >Reports

Timeline: 2-3 weeks to MVP.

## The Technical Challenges

Challenge 1: Mobile-first tables

How do you show a table with 10+ columns on a 375px screen?

Options:

  • >Horizontal scroll (bad UX)
  • >Card view (loses table context)
  • >Responsive columns (hide less important data)
  • >Modal drill-down (tap row → see full details)

I'm going with: Card view on mobile + table on desktop. Best of both worlds.

Challenge 2: Real-time without overwhelming

Firestore sends updates on every change. If 8 teachers mark attendance simultaneously, dashboard could re-render 8 times in 2 seconds.

Solution: Debouncing + optimistic updates. UI updates instantly (optimistic). Backend syncs in background. Conflicts resolved with timestamps.

Challenge 3: Offline support

Teachers might mark attendance in classrooms with poor WiFi.

Firebase Firestore has offline persistence built-in. Changes sync when connection returns.

But: Need to handle conflicts if two teachers edit same data offline. Firestore uses last-write-wins + timestamps.

Challenge 4: Salary calculations edge cases

What if:

  • >Teacher marks attendance, then edits it later?
  • >Student was marked present, then withdrawn mid-month?
  • >Class was cancelled, no students showed up?

Solution: Audit trail. Every attendance change creates a log entry. Salary calculation uses latest data but shows edit history.

## The Business Logic

Student fees:

  • >Grade 1-5: 70,000 VND/month
  • >Grade 6-9: 80,000 VND/month
  • >Grade 10-12: 100,000 VND/month
  • >Calculated monthly, tracked per student

Teacher salary:

  • >Rate varies by teacher (25k-40k per session)
  • >Sessions = attendance rows where student attended
  • >Formula: sessions × rate
  • >Paid monthly

Expenses:

  • >Rent, utilities, supplies, etc.
  • >Tracked separately
  • >Categories for reporting

Reports:

  • >Revenue = student payments
  • >Expenses = tracked expenses
  • >Profit = revenue - expenses
  • >Teacher cost = sum of salaries
  • >Gross margin = (revenue - teacher cost) / revenue

All auto-calculated. Dũng just checks the dashboard.

## Why Build This In Public?

1. Accountability to Dũng He's my friend. I promised him an app. Public progress = I can't ghost.

2. Template for similar businesses Vietnam has thousands of small education centers. Same pain points. This could be a template.

3. Learning case study Building real-world apps with real requirements. Not todo apps. Actual business logic.

4. Portfolio piece Shows I can:

  • >Gather requirements
  • >Design architecture
  • >Handle complexity
  • >Ship products

## The Meta-Learning

Building XuLang-Edu is teaching me:

1. Users don't care about tech Dũng doesn't care if I use Next.js or Vue or plain HTML. He cares:

  • >Can I check on my phone?
  • >Is it fast?
  • >Does it save me time?

2. Real-time is a killer feature For business owners, real-time visibility = control = peace of mind.

Firebase makes it trivial. Worth learning.

3. Import is harder than greenfield Building new features is easy. Importing messy legacy Excel data? Pain.

But necessary. No one wants to re-enter 100 students manually.

4. Mobile-first is non-negotiable Desktop is nice. Mobile is essential. Design for 375px first.

5. Simple UX beats feature-rich Teachers want: Open app → Mark attendance → Done.

Not: Navigate 5 menus → Find class → Load students → Click edit → Save changes → Confirm.

Less is more.

## What Success Looks Like

Phase 1 (Week 1): CRUD everything. Import Excel. Auth working.

Phase 2 (Week 2): Teachers can mark attendance. Dũng can monitor live.

Phase 3 (Week 3): Reports ready. Export Excel for accountant. Deploy to production.

Long-term:

  • >All 8 teachers use it daily
  • >Dũng checks his phone instead of Excel
  • >Salary calculations automated
  • >Reports generated in 1 click
  • >Excel completely replaced

Revenue? Not charging Dũng. He's a friend. But if this works, I might:

  • >Open-source the code
  • >Offer as SaaS for other centers ($50-100/month)
  • >Build a template for "Excel → Web App" migrations

## Follow The Build

I'm documenting progress in the Kai folder (my 5-file system):

  • >QUICK.md - Current status, next tasks
  • >Features.md - Architecture, roadmap
  • >Tasks.md - 30 tasks breakdown
  • >Progress.md - Full changelog

Next update: After Phase 1 CRUD is done.

If you run an education center (or any small business drowning in Excel), this might be useful.


Current status: 40% through Phase 0 (setup + UI)

Next milestone: Firebase connected, CRUD working

Timeline: MVP in 2-3 weeks

Will it work? Ask me in a month. Right now, Dũng is still using Excel.

Soon, he won't need to.

P.S. Yes, this is a real project for a real friend. Yes, I'm building it solo with Claude Code CLI. Yes, it's faster than hiring a team.

P.P.S. If you're in Lạng Sơn and need tutoring for your kids, hit up Dũng at Xứ Lạng Education. Once this app is live, he'll have the best-run center in town.