EBsoft HMSBuild & Architecture Guide

Build Guide / 06

Folder structure

A single Vite project root, with the frontend under src/ and the server split into its own files at the top level so it can be bundled separately for deployment.

ebsofthms/
├── server.ts               # Dev entry: Vite middleware + cron scheduler
├── server-app.ts           # Express app: routes, Firebase Admin, Gemini proxy
├── vite.config.ts          # Vite + Tailwind plugin, "@" → src alias
├── netlify.toml            # Build command, redirects, security headers
├── netlify/
│   └── functions/
│       └── api.ts          # Wraps server-app.ts for serverless execution
├── firestore.rules         # Access control (see Database & Security)
├── storage.rules
├── test/
│   └── firestore.rules.test.ts
├── scripts/                # One-off / operational scripts (data generation,
│                           # connection checks, reminder jobs)
├── public/                 # Static assets served as-is
├── index.html              # SPA shell
└── src/
    ├── main.tsx             # React root
    ├── App.tsx              # Route table — 231 routes
    ├── index.css            # Tailwind entry + global styles
    ├── pages/               # One folder per hospital department (see
    │                        # Feature Modules) plus shared top-level pages
    ├── components/          # Shared UI: layout, dashboard widgets,
    │                        # per-domain components (billing/, opd/, lis/...),
    │                        # ui/ (shadcn primitives)
    ├── context/              # AuthContext, SettingsContext, Notification*,
    │                        # PatientPortalContext
    ├── hooks/                # Domain hooks: useIPDBilling, usePayroll,
    │                        # useAttendance, useLeave, useRoles...
    ├── lib/                  # firebase.ts, autoNumbering, auditLogger,
    │                        # dateUtils, referralCommission, sanitizeHtml...
    ├── services/             # messageService, notificationService
    ├── constants/
    ├── data/                 # Static reference data (e.g. medical_tests.json)
    ├── types/
    └── utils/

Notable conventions

  • Department-first, not layer-first. src/pages/stores/ holds every stores-related page together (inventory, suppliers, wastage, reports) rather than splitting inventory logic across a global "inventory" layer.
  • Domain components live near their domain. src/components/billing/, opd/, radiology/ etc. sit alongside the generic components/ui/ primitives.
  • The @/ import alias (configured in vite.config.ts) always resolves to src/, so imports don't accumulate long relative paths as pages get nested deeper inside module folders.