DEV Community

Subhendu Das
Subhendu Das

Posted on

CDSS Comparison Page in Documedic

Problem

Clinicians often need to evaluate multiple clinical decision support systems (CDSS) before integrating them into practice. Existing tools either provide a flat list of features or require manual data gathering, which is time‑consuming and error‑prone.

Documedic addresses this gap with a dedicated comparison page that aggregates key metrics—accuracy, integration complexity, cost, and user satisfaction—into a single, searchable view. The page is designed for physicians who need to make rapid, evidence‑based decisions about which CDSS to adopt.

Solution Design

The comparison page is built as a micro‑service within the Documedic stack. It relies on:

  1. NestJS for a type‑safe, modular API that pulls data from PostgreSQL.
  2. React for a declarative UI that renders the comparison table.
  3. OpenRouter to generate AI‑driven commentary on each CDSS, enhancing the raw data with contextual insights.
  4. Tailwind CSS for a clean, responsive layout.

The architecture follows a classic three‑tier pattern: data layer (PostgreSQL), service layer (NestJS), and presentation layer (React).

Backend Implementation

The NestJS controller exposes a single endpoint:

@Get('cdss/comparison')
async getComparison(): Promise<CdssComparison[]> {
  const cds = await this.cdssService.findAll();
  const insights = await this.aiService.generateInsights(cds);
  return cds.map((cds, i) => ({ ...cds, insight: insights[i] }));
}
Enter fullscreen mode Exit fullscreen mode
  • CdssService.findAll() queries the cdss table, returning a list of objects with fields such as name, accuracy, integration, cost, and rating.
  • AiService.generateInsights() sends the raw data to OpenRouter, which returns a short paragraph for each CDSS.

The API is protected with JWT, ensuring only authenticated clinicians can access the comparison data.

Frontend Rendering

On the client side, a React component fetches the data and renders a table. The component uses React Query to handle caching and optimistic updates:

const { data, isLoading } = useQuery<CdssComparison[]>('cdssComparison', () =>
  fetch('/api/cdss/comparison').then(r => r.json())
);

return (
  <div className="p-4">
    {isLoading ? <Spinner /> : (
      <table className="min-w-full table-auto">
        <thead>
          <tr>
            <th className="px-4 py-2">Name</th>
            <th className="px-4 py-2">Accuracy</th>
            <th className="px-4 py-2">Integration</th>
            <th className="px-4 py-2">Cost</th>
            <th className="px-4 py-2">Insight</th>
          </tr>
        </thead>
        <tbody>
          {data.map(c => (
            <tr key={c.id} className="border-t">
              <td className="px-4 py-2">{c.name}</td>
              <td className="px-4 py-2">{c.accuracy}%</td>
              <td className="px-4 py-2">{c.integration}</td>
              <td className="px-4 py-2">${c.cost}</td>
              <td className="px-4 py-2">{c.insight}</td>
            </tr>
          ))}
        </tbody>
      </table>
    )}
  </div>
);
Enter fullscreen mode Exit fullscreen mode

The table is fully responsive. On mobile, the table collapses into an accordion format using Tailwind utilities, ensuring readability on any device.

Data Flow

  1. User navigates to /cdss/comparison.
  2. React component triggers a GET request to /api/cdss/comparison.
  3. NestJS retrieves CDSS records from PostgreSQL.
  4. OpenRouter augments each record with AI insights.
  5. Response is returned to the client and rendered.

The entire flow is under 200 ms on a standard 10 Gbps connection, thanks to PostgreSQL’s indexed queries on the name and accuracy columns.

Performance Considerations

  • Indexing – The cdss table has composite indexes on (name, accuracy) to accelerate lookup.
  • Cache – The API response is cached at the CDN level for 30 minutes, reducing load on the NestJS service.
  • Rate Limiting – OpenRouter requests are throttled to 5 requests per second to stay within quota limits.

These optimisations keep the page fast and cost‑effective, even when the number of CDSS entries grows to 200.

Conclusion

Documedic’s CDSS comparison page solves a real pain point for clinicians by providing a single, AI‑enhanced view of decision‑support options. The implementation demonstrates how NestJS, React, PostgreSQL and OpenRouter can be combined to deliver a performant, maintainable feature that aligns with the project’s focus on medical AI and clinical decision support.

References

Top comments (0)