GSoC 2026: Service Queues Improvements - Architecture & Requirement Gathering

Hi everyone,

I’m Sankalpa Sarkar, a dev/1 developer. I’m very interested in the “Service Queues Improvements” project on this year’s GSoC list.

Over the past few months, I set up the O3 frontend (esm-service-queues-app) and the queue module backend locally to trace exactly how data flows in the service queues app. I noticed a few architectural details that I wanted to clarify before finalizing my proposal, so I’m starting this thread to gather some requirements and feedback.

From my code review, I saw that the current app relies on some really heavy data fetching. For example, the repString in useQueueEntries.tspulls the entire patient graph, visit history, encounters, observation data, and diagnoses for every single patient in the queue. However, the actual queue table only renders about 10 basic columns (patient name, age, queue status, wait time, etc.). This mismatch seems to be triggering a massive join explosion on the backend due to the 11 JPA relations inQueueEntry.java.

I read through the project description where Ian mentioned building a specific REST endpoint to solve this, following a recent similar backend API update. (I looked at PR #250 for EA-207 in the emrapi module and assumed that custom Spring controller + flat DTO pattern is what we want here).

I have a few doubts I’d love some guidance on:

  1. Scope of the new endpoint: Should the proposed custom REST controller return only the flat fields needed for the main table listing? If so, is the expectation that we would then lazy-load the deeper expanded row data (like current visit encounters/vitals) via a separate call only when a user clicks to expand a row?

  2. Overlap with existing PRs: I noticed there is an open PR ( #92) in the queue module trying to optimize getQueueEntries by reducing the number of SQL joins. If we build a brand new custom DTO and endpoint for the frontend, does that make the optimization in PR #92 unnecessary, or should I treat them as complementary in my proposal?

  3. UI Standardization: To fix the UI design inconsistencies, the project mentions creating “standard widgets” (like for numeric obs). Is there a specific O3 app - perhaps the Patient Chart - that I should use as the “gold standard” visual reference to align the queue screen with?

I’ve been working on a few frontend tickets (like O3-5299 and O3-5298 etc) recently to get more comfortable with the O3 React stack, but I want to make sure my architectural approach for the queues backend aligns with the core team’s vision.

cc: @ibacher @jayasanka @beryl

Thanks in advance for your time and advice!

1 Like

Probably, mostly because the other components probably ought to be relatively independent (e.g., we embed vitals and med lists in other parts of the app).

Up to you, I think

Ideally, that’s the styleguide. But some of those components (like the numeric obs) are literally part of the framework.

1 Like

That makes sense on keeping the components independent, so for the main table listing endpoint, I’m thinking it returns just the flat fields needed for the queue row

1 Like

Thanks for clarifying! That confirms the two-tier approach. I will design the new QueueEntryListingRestController to return only the flat fields that the queue table needs. The expanded-row components (like vitals and med lists) will remain completely independent and handle their own data fetching, which is perfect since they are shared across the O3 app.

Got it. I’ll treat them as complementary in my proposal. The custom endpoint will eliminate the unnecessary data over-fetching at the API layer, while the DAO-level join optimizations (like in PR #92) can further reduce the database overhead underneath. They both tackle the performance issue from different angles.

Sure sir! Thank You. I was originally thinking of building new widgets, but I will adjust my proposal to focus on adopting and integrating the existing O3 framework components (like the numeric obs) into the queue screen, rather than reinventing the wheel.

Exactly! My thought is to map the backend response to a flat DTO with just the ~15 fields (patient name, age, queue status, wait time, etc.) that correspond directly to the 12 columns in columns.resource.ts. This bypasses the heavy DelegatingCrudResource entirely for the main listing, and we rely on the independent components for the deeper Visit data only when a row is expanded.

1 Like

Hi @ibacher and everyone,

I’m Naema Mohmed, and I’m applying for the Service Queues project this year. I’ve spent the last few days digging into the esm-service-queues-app and openmrs-module-queue locally to get a better feel for those ‘unwieldy representations’ mentioned in the project brief.

I’ve been following the discussion here regarding the two-tier approach and the move toward a QueueEntryListingRestController. After tracing the repString in useQueueEntries.ts and comparing it against the actual requirements in columns.resource.ts, I’ve already mapped out about 16 essential fields for a flat DTO.

What I found during my deep-dive: It’s clear the current repString is doing a lot of heavy lifting that the UI just doesn’t need. Right now, we’re fetching full Concept objects and entire encounter histories for every single patient in the list. However, the table columns only really consume about 9 flat fields. Since the expanded row components (like <CurrentVisit>) are already set up to fetch their own data independently, all that extra info we’re grabbing upfront is basically dead weight.

My plan to fix this: I want to take a ‘performance-first’ approach:

  1. On the Backend: I’m proposing a new QueueEntryListingRestController. By moving away from the generic resource, we can return a lean, flat DTO. This should shrink the payload from about 10KB per patient down to roughly 0.5KB—which would be a massive win for speed in a busy clinic.

  2. On the Frontend: I’ll refactor the hooks to use this new endpoint and officially implement lazy-loading for the expanded rows by leveraging the existing self-fetching components.

  3. UI/UX: I’ll focus on bringing everything in line with the O3/Carbon style guide while building on the great work already started in O3-3096 for configurability.

A couple of quick questions for the mentors:

  • The DTO: Should I include the statusUuid and priorityUuid in the flat list to keep ‘Quick Actions’ snappy, or would you prefer we fetch that data only when a specific action is triggered?

  • Priorities: For the UI phase, should I focus more on strictly fixing style inconsistencies, or is pushing the configurability/filtering logic (O3-3096) the higher priority right now?

I’ve already forked the repos and am really excited to get started. Looking forward to hearing your thoughts!

(PS: I’ve submitted my Jira access request and am just waiting for approval to grab a starter issue!) >> Thank u

Hi @sankalpasarkar, thanks for sharing this — really helpful breakdown.

I’ve been tracing the data flow in useQueueEntries as well, and noticed a similar mismatch between the data being fetched and what the queue table actually uses, so the idea of a flat listing endpoint with independent components makes a lot of sense.

For the UI side, I was also looking into how existing O3 components (like numeric obs from the framework) can be reused instead of building new widgets, to keep things consistent with the overall design system.

1 Like