Pharmacy operations, built for Moroccan public healthcare.
PharmSaf is a full-stack pharmacy management system designed to help provincial healthcare facilities manage medical stock, track distributions, generate delivery notes, and maintain complete operational visibility.
⚠️ Status: Work in Progress PharmSaf is actively under development. Some features, modules, and integrations are still being refined.
Managing pharmaceutical stock across multiple healthcare facilities requires more than spreadsheets and manual records.
PharmSaf brings inventory management, hospital distributions, delivery documentation, annual allocations, and activity tracking into one centralized platform.
The project is designed around the operational workflows of the Pharmacie Provinciale d'Essaouira and the needs of Moroccan public healthcare facilities.
Manage stock. Track distributions. Stay in control.
| Module | Description |
|---|---|
| 📦 Stock Management | Track medical inventory, batch numbers, quantities, and expiry dates |
| 🏥 Hospital Distribution | Manage and track stock distributions to hospitals and healthcare centers |
| 📄 Delivery Notes | Automatically generate and print official delivery documents |
| 💉 Insulin On-Demand | Dedicated distribution workflow for insulin with per-unit tracking |
| 🎁 Birth Kits | Assemble and distribute birth kits to healthcare facilities |
| 📊 Annual Allocations | Manage yearly allocations by hospital and product category |
| 📈 Dashboard & Reports | Monitor stock consumption, movements, and operational trends |
| 📥 Excel Import | Bulk import products and stock data from Excel files |
| 🔍 Audit Trail | Maintain a complete record of CRUD and print operations |
| 🌐 French Interface | Fully localized interface for day-to-day operations |
PharmSaf provides a centralized view of the main workflows involved in provincial pharmacy management.
From incoming stock to hospital distribution, every major movement can be recorded and tracked in one place.
- Keep inventory organized by product, batch, and expiry date
- Record incoming and outgoing stock movements
- Track distributions across healthcare facilities
- Generate official delivery documentation
- Monitor annual allocations
- Review activity through a complete audit trail
- Framework — Next.js 16 (App Router, Server Actions)
- Language — TypeScript
- Database — MySQL / MariaDB via Prisma ORM
- Authentication — Clerk (with optional demo/mock mode)
- UI — Tailwind CSS v4 + shadcn/ui
- Icons — Tabler Icons + Lucide React
- Charts — Recharts + Tremor
- PDF Generation — @react-pdf/renderer
- Excel Processing — ExcelJS
- Package Manager — Bun / npm
Before running PharmSaf, make sure you have:
git clone https://github.com/yassinidyhya/PharmSaf.git
cd PharmSafnpm install
# or
bun installcp .env.local.example .env.localEdit .env.local with your values.
See Environment Variables below.
You can explore PharmSaf without configuring a database.
Set the following value in .env.local:
USE_MOCK_DATA="true"Then start the development server:
npm run devSign in at http://localhost:3000 using the demo credentials defined in your .env.local.
To connect PharmSaf to MySQL or MariaDB:
- Set
USE_MOCK_DATA="false" - Add your
DATABASE_URLto.env.local - Run Prisma migrations:
npx prisma migrate dev- Optionally seed the database:
npm run db:seed- Start the development server:
npm run devOpen http://localhost:3000 in your browser.
Copy .env.local.example to .env.local and configure the required values.
| Variable | Required | Description |
|---|---|---|
USE_MOCK_DATA |
✅ | "true" for demo mode or "false" for a real database |
DATABASE_URL |
Database mode | MySQL/MariaDB connection string used by Prisma |
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY |
Authentication mode | Clerk publishable key |
CLERK_SECRET_KEY |
Authentication mode | Clerk secret key |
NEXT_PUBLIC_CLERK_SIGN_IN_URL |
Authentication mode | Sign-in route (default /sign-in) |
NEXT_PUBLIC_CLERK_SIGN_UP_URL |
Authentication mode | Sign-up route (default /sign-up) |
CLERK_WEBHOOK_SIGNING_SECRET |
Authentication mode | Clerk webhook signing secret |
CLERK_WEBHOOK_SECRET |
Authentication mode | Clerk webhook secret |
DEMO_EMAIL |
Mock mode | Demo login email |
DEMO_PASSWORD |
Mock mode | Demo login password |
DEMO_SESSION_SECRET |
Mock mode | Secret used to sign the demo session cookie |
NEXT_PUBLIC_APP_NAME |
Optional | Pharmacy name displayed in the application |
NEXT_PUBLIC_APP_LOCALE |
Optional | Interface locale (default fr) |
The Prisma schema is located at prisma/schema.prisma.
The core data model covers the main parts of provincial pharmacy operations:
User — Clerk-synced user accounts
Hospital — Healthcare facilities
Product — Medical products and packaging information
Batch — Product batches, quantities, and expiry dates
StockEntry — Incoming stock records
StockExit — Outgoing distributions to healthcare facilities
AnnualAllocation — Yearly allocations by hospital and category
DeliveryNote — Official delivery documents
BirthKit — Birth kit assemblies and distributions
ActivityLog — Complete operational audit trail
| Command | Description |
|---|---|
npm run dev |
Start the development server |
npm run build |
Generate Prisma files and build for production |
npm run start |
Start the production server |
npm run lint |
Run ESLint |
npm run db:seed |
Seed the database with sample data |
npm run db:reset |
Reset and re-seed the database |
PharmSaf/
├── app/
│ ├── (auth)/ # Authentication pages
│ ├── (dashboard)/ # Main application modules
│ │ ├── actions.ts # Server actions
│ │ ├── page.tsx # Dashboard
│ │ ├── produits/ # Product management
│ │ ├── distributions/ # Stock distribution
│ │ ├── bons-livraison/ # Delivery notes
│ │ ├── hopitaux/ # Healthcare facilities
│ │ ├── insuline/ # Insulin distribution
│ │ ├── kits/ # Birth kits
│ │ ├── inventaire/ # Inventory
│ │ ├── import/ # Excel imports
│ │ └── rapports/ # Reports
│ ├── api/ # API routes and webhooks
│ ├── globals.css
│ └── layout.tsx
├── components/ # Reusable interface components
├── lib/
│ ├── db.ts # Prisma client
│ ├── auth.ts # Authentication helpers
│ └── mock-data.ts # In-memory demo data
├── prisma/
│ ├── schema.prisma # Database schema
│ └── seed.ts # Database seeding
├── hooks/ # Custom React hooks
├── public/ # Static assets
├── .env.local.example # Environment variable template
└── package.json
PharmSaf is an active work in progress.
The project is being developed around real provincial pharmacy workflows, with ongoing work on features, operational processes, integrations, and production readiness.
Contributions, issues, and suggestions are welcome.
If you'd like to contribute to PharmSaf, feel free to open an issue or submit a pull request.
This project is publicly available on GitHub.
Please refer to the repository's LICENSE file for licensing information.