Case Study

Building a Smart Task Bank for Teachers: Lessons from 7 Months in Production

QuackStack Team
February 9, 2026
12 min read
AngularSpring BootOCRAIEducationArchitecture

Building a Smart Task Bank for Teachers: Lessons from 7 Months in Production

There’s a running joke among teachers: “What do teachers do in their free time?” The answer is usually a sad laugh, because most teachers don’t have free time. They’re grading, planning, preparing materials—and probably spending way too much time on the most mundane task of all: finding or creating worksheets.

We sat down with the teaching staff at St. Sofia in early 2025, and the pain was obvious. Materials lived across notebooks, shared drives, and PDFs. Great exercises were hard to find and even harder to reuse consistently. Many teachers recreated similar worksheets each term because there wasn’t a central place to draw from.

They wanted a platform where the collective knowledge of the entire teaching staff—all those great exercises, all that curriculum experience—could live in one place and scale. They wanted to spend less time finding tasks and more time actually teaching.

That became our mission: build a system that makes worksheet creation feel less like admin work and more like actual teaching.

Understanding the Problem (The Hard Way)

We spent the first weeks just observing. We sat in the staff room. We asked questions. We learned:

  • Teachers had thousands of worksheets, many in paper form only
  • Good exercises got lost (or hoarded) because there was no central place to store them
  • Creating a new worksheet meant either hunting through folders or starting from scratch
  • Differentiation (varying difficulty levels) meant doing even more work
  • Most worksheets ended up as PDFs that were rarely reused
  • Teachers needed to collaborate, but existing tools were either too simple or too complex

Existing tools hadn’t fit their workflow. They were powerful, but they didn’t make everyday tasks faster for teachers.

The Vision

By late June 2025, the vision was clear. We needed:

  1. A shared task bank — every exercise the school has ever created, searchable and tagged
  2. A worksheet builder — Microsoft Word-like experience because teachers were most familiar with it, not complex form-filling
  3. OCR ingestion — scan old paper worksheets and automatically extract tasks
  4. AI generation — “I like this exercise, give me 5 more like it at varying difficulty levels”
  5. Version control — track changes, maintain history, enable collaboration
  6. PDF/Word export — beautiful, print-ready worksheets the instant they’re done

The Technical Stack

We knew this needed to scale and be maintainable. Here’s what we chose:

Frontend

  • Angular 13 with TypeScript for a responsive, fast SPA
  • Angular Material for consistent UI components
  • Quill Editor for rich text editing
  • RxJS for reactive state management
  • Angular CDK for drag-and-drop functionality

Backend

  • Spring Boot 3.5.3 (Java 21) for a rock-solid backend API
  • Spring Security with JWT and OAuth2 for authentication
  • JPA/Hibernate for ORM
  • Liquibase for database migrations

Infrastructure

  • PostgreSQL for complex queries (find exercises by subject, difficulty, grade level)
  • Redis for caching and session management (the task bank gets queried a lot)
  • RabbitMQ with STOMP for asynchronous OCR and AI task processing via WebSockets
  • FTP Server for file uploads and management
  • Docker & Docker Compose for containerization
  • Tesseract OCR for converting paper to text
  • OpenAI API for generating task variations

The tech stack looked heavy on paper, but each piece had a reason. We needed performance and reliability over cleverness.

The Build Process: A Reality Check

July 2025: Discovery and Foundation (Weeks 1-4)

Project start: July 1, 2025. First commit: Database structure and Docker setup.

We mapped out every workflow:

  • How does a teacher create a new worksheet?
  • How does the OCR import flow work?
  • What happens when the AI generates tasks?
  • How do teachers collaborate without stepping on each other’s work?
  • How do we handle versioning?

We built wireframes. A lot of them. We also learned that teachers think in terms of subjects and grade levels, not technical categories. So our data model needed to reflect that.

The database schema was more complex than we initially thought. Tasks have:

  • Multiple subjects and grade levels
  • Difficulty ratings (but from multiple teachers—averaging helps)
  • Related tasks and parent-child relationships
  • File attachments (images, documents)
  • Usage statistics
  • Revision history
  • Skills/learning objectives

By mid-July, we had:

  • Basic DB structure
  • Docker environment
  • Google OAuth2 authentication working
  • Admin panel foundation

August 2025: Core Features (Weeks 5-8)

This is where we built the meat of the system:

  • Weeks 5-6: Admin panel, user management, subject/theme management
  • Weeks 7-8: Task creation, worksheet builder, FTP integration for file uploads

The worksheet builder was designed to feel like Microsoft Word—because that’s what teachers know. They didn’t want to learn a new paradigm; they wanted something familiar. Grab tasks from the left sidebar, drop them on a canvas that looks and behaves like a Word document. But then we realized teachers needed even more:

  • Reorder tasks with drag-and-drop (just like moving paragraphs in Word)
  • Add custom text and notes between tasks (rich text editing with familiar formatting)
  • Group tasks by sections with headings
  • Preview exactly how it would print (WYSIWYG)
  • Save drafts and create versions
  • Export to PDF and Word with proper formatting that preserved their layout

The key insight: familiarity reduces friction. Teachers didn’t need to read a manual. They already knew how to use it because it felt like Word. So the UI evolved constantly based on that principle. Teachers would use it, break it, and tell us what was wrong. We’d fix it overnight.

September-October 2025: The Great Backend Rebuild

Here’s the truth: we knew from day one the existing architecture was problematic. The previous system used MongoDB, which sounds modern, but for this use case—complex relational queries across subjects, grades, themes, tasks, and worksheets—it was the wrong choice. We needed joins, transactions, and complex filtering. NoSQL was fighting us at every turn.

By September, we had 282 commits and teachers were using the system. But we’d been building on a foundation we knew had to be replaced. The decision point came in mid-October: keep patching or rebuild it right.

We chose to rebuild. From the ground up:

The Big Switch: MongoDB → PostgreSQL

This was the core decision. PostgreSQL gave us:

  • Proper relational modeling (tasks ↔ subjects ↔ themes ↔ worksheets)
  • ACID transactions (critical when teachers are collaborating)
  • Complex queries that were simple in SQL but nightmares in MongoDB
  • Foreign key constraints that prevented data corruption
  • Full-text search built-in

The migration took weeks. We had to:

  • Redesign the entire schema
  • Migrate existing data without losing anything
  • Rewrite every repository layer
  • Add proper indexing for performance

Everything Else We Fixed:

  • Clear service layer separation (no more business logic in controllers)
  • Consistent caching strategy with Redis
  • Proper message broker integration (switched from Spring’s built-in broker to RabbitMQ)
  • Comprehensive E2E test suite with Selenide (browser-based testing)
  • Better error handling and logging
  • Liquibase for database migrations (version control for the schema)

Was it painful? Absolutely. Did it delay features? By at least a month. Was it worth it? 100%. This decision saved the project.

The refactored system with PostgreSQL handles 10x more concurrent users, queries that took seconds now take milliseconds, and we can actually reason about the data model.

November-December 2025: OCR and AI (Weeks 16-24)

360 commits in these two months alone. This is where things got interesting (and frustrating).

We tested OCR on different worksheet types: typed, handwritten, scanned badly, scanned well, faxed, etc. Results ranged from perfect to completely wrong.

  • Typed documents? 95%+ accuracy
  • Handwritten? 20-40%
  • Old faxes or bad scans? Forget it

We had to make a call: auto-import works great for typed worksheets, but handwritten or poor-quality scans need human review. So we built a semi-automated flow:

  1. Upload/scan the worksheet
  2. OCR extracts the text
  3. Show the teacher what OCR found
  4. Let them correct it before adding to the bank
  5. Save the corrected version

This took longer than expected because we had to build not just OCR, but:

  • A UI for reviewing and editing OCR output
  • Quick correction tools for fixing extracted text
  • Batch processing for multiple files
  • WebSocket integration for real-time progress updates

The AI part was more straightforward. A teacher selects a task and says “Generate 3 easier versions and 2 harder versions.” The API understands the context and creates new tasks.

Of course, AI isn’t perfect. Sometimes the generated tasks were weird, mathematically incorrect, or grammatically off. We built an approval workflow so teachers could rate suggested tasks (good/bad), and over time the AI got better.

January 2026: Polish and Real-World Usage (Weeks 25-28)

By January, we had:

  • Full-text search across all tasks
  • Advanced filtering by subject, grade, difficulty, type, theme
  • Folder organization for personal collections
  • Like/dislike system for community feedback
  • Usage analytics (which tasks are most popular?)
  • Theme periods for organizing by academic calendar
  • Source attribution for tracking where tasks came from
  • Comprehensive export options (PDF, Word)

February 2026: Refinements (Ongoing)

We’re now at 7 months in production. Recent work includes:

  • Source management for tracking material origins
  • Alphabetical sorting improvements
  • Deactivation impact assessment (understanding dependencies before deleting)
  • Enhanced error handling and user feedback
  • Performance optimizations

The Challenges We Didn’t Expect

Challenge 1: Data Quality and Migration

When we migrated old worksheets into the system, we found:

  • Duplicate tasks with slight variations
  • Tasks missing difficulty ratings or subjects
  • Subjects that didn’t match the school’s current taxonomy
  • Broken file references
  • Inconsistent formatting

We had to go back and do manual cleanup. It took weeks, but it was necessary. Garbage in, garbage out.

Challenge 2: Choosing the Right Database (MongoDB vs PostgreSQL)

We mentioned this earlier, but it deserves emphasis. The original architecture used MongoDB—a decision that sounded modern but was fundamentally wrong for this problem.

Educational content is inherently relational:

  • Tasks belong to multiple subjects and themes
  • Worksheets contain tasks with specific ordering
  • Users create folders that organize tasks
  • Everything needs to be filtered by grade, difficulty, subject, source

In MongoDB, every query was a nightmare of aggregations and manual joins. In PostgreSQL, it’s just SQL.

Making the call to pause features and migrate databases mid-project was hard. Teachers were using the system. But we knew: keep building on MongoDB and we’d be rewriting queries forever, or bite the bullet and migrate to PostgreSQL.

We chose PostgreSQL. The migration took a month. Every piece of data had to be transformed, relationships had to be restructured, and we had to ensure nothing was lost.

But it was the right call:

  • Queries that took 2-3 seconds in MongoDB now take 50-100ms in PostgreSQL
  • Complex filtering (“show me grade 5 math tasks from source X, difficulty medium”) went from painful aggregations to a simple WHERE clause
  • Data integrity issues (orphaned references, duplicate entries) disappeared with foreign keys
  • The codebase became drastically simpler—SQL is more maintainable than MongoDB aggregations

Challenge 3: AI Hallucination

The AI would sometimes generate tasks that were mathematically incorrect, factually wrong, or grammatically weird. We didn’t ship auto-generation immediately.

First release: “AI suggests tasks, teachers review them.” Only after teachers validated that the quality was acceptable did we consider more automation.

Lessons from Building Educational Software

1. Teachers know what they need. Listen to them. Really listen.

Don’t impose workflows. Observe how they actually work, then build tools that fit their process, not your idea of their process.

2. Automation should never require perfection

Semi-automated workflows (human-in-the-loop) beat fully automated garbage. OCR with review beats OCR with blind trust.

3. Adoption takes time and hand-holding

We built a great tool, but teachers needed to be shown it was worth learning. That’s not their fault; it’s ours. Budget time for training and support.

4. Choose the right database for your problem. Not the trendy one.

We started with MongoDB because it seemed modern. Big mistake. Educational content is relational. PostgreSQL was the right choice from day one. Migrating mid-project was painful, but necessary. If your data has relationships, use a relational database. It’s not sexy, but it works.

5. Real data is messy

Assume your migration will uncover weird stuff. Budget time for cleanup. Old systems accumulate cruft, and you’ll inherit it.

6. Asynchronous processing needs proper infrastructure

Using WebSockets with RabbitMQ for OCR and AI processing was more complex than expected. Session management, message serialization, and handling long-running tasks required careful architecture.

7. AI is powerful but needs guardrails

Don’t ship AI features without human review. Teachers need to trust the system, and one bad AI-generated task can destroy that trust.

8. Differentiation is a superpower

One of the biggest insights: teachers want to differentiate but rarely do because it’s too much work. Make it easy, and they’ll do it every time.

Final Thoughts

Seven months in, we’ve learned that building educational software is different from building other types of software. The users are busy, the stakes are high (this affects actual students), and the workflows are complex.

We made mistakes:

  • Started with the wrong database (MongoDB for a relational problem—rookie mistake)
  • Underestimated how painful the MongoDB → PostgreSQL migration would be
  • Didn’t plan enough time for data cleanup during migration
  • Had to rebuild messaging infrastructure mid-project (Spring broker → RabbitMQ)

But we also got a lot right:

  • Listened to teachers constantly
  • Built features they actually needed (not what we thought was cool)
  • Made hard calls (architecture refactor) when necessary
  • Focused on reliability over cleverness

If you’re building educational tools, here’s our advice: Spend time with teachers. Watch them work. Build what makes their lives easier, not what wins hackathons.


Building educational tools? Want to talk architecture, OCR, or AI integration? We’d love to help. Get in touch.

Enjoyed This Article?

Check out our other posts or get in touch to discuss your next project.