This document provides the technical setup and architectural workflow for the Long Chau Pharmacy Management System.
- Frontend: ReactJS (Vite), Tailwind CSS, React Router
- Backend: Node.js, ExpressJS
- Database: MySQL
- Authentication: JWT with bcrypt hashing
- Start Services: Launch XAMPP and start the Apache & MySQL services.
- Create Database: In phpMyAdmin, create a new database named
longchau_db. - Import Schema: Select
longchau_db, go to the "Import" tab, and importschema.sql. - Seed Data: Go to the "SQL" tab and execute the
seed.sqlscript to populate tables.
- Navigate to the backend directory:
cd backend - Install dependencies:
npm install
- Configure environment variables in a
.envfile:DB_HOST=localhost DB_USER=root DB_PASSWORD= DB_NAME=longchau_db JWT_SECRET=your_super_secret_key_for_jwt_tokens - Start the server:
The backend will run on
node server.js
http://localhost:5000.
- In a new terminal, navigate to the frontend directory:
cd frontend - Install dependencies:
npm install
- Start the development server:
The frontend will run on
npm run dev
http://localhost:5173.
All test accounts use the password: password123
| Role | Username |
|---|---|
| Customer | customer |
| Pharmacist | pharmacist |
| Cashier | cashier |
| Branch Manager | manager |
| Warehouse | warehouse |
The application operates on a decoupled client-server model. The flow for any given feature follows this sequence:
- View (React Component): A user interaction triggers an event handler within a component (e.g.,
handleSubmitinLoginPage.jsx). - API Client (
apiClient.js): The event handler calls a corresponding function in theapiClient. This client is the sole point of contact with the backend. It constructs thefetchrequest, sets the appropriateContent-Typeheader, and attaches the JWT fromlocalStorageto theAuthorizationheader for protected routes. - Server Entry & Routing (Express): The Express server receives the HTTP request. Based on the URL prefix (e.g.,
/api/auth),server.jspasses the request to the relevant router (e.g.,authRoutes.js). - Middleware (
authMiddleware.js): If the route is protected, theprotectmiddleware is executed first. It verifies the JWT. If the token is valid, it decodes the payload (containingidandrole) and attaches it to thereq.userobject. If invalid, it terminates the request with a401 Unauthorizederror. - Controller (
*Controller.js): The router calls the appropriate controller function. The controller is the core of the business logic. It destructures necessary data fromreq.bodyorreq.paramsand uses thereq.userobject for authorization checks (e.g.,if (req.user.role !== 'pharmacist')). - Database Query (
db.js): The controller function uses the promise-wrappeddbconnection pool to execute SQL queries. All queries use prepared statements (e.g.,WHERE id = ?) to prevent SQL injection. - Response: The controller sends a JSON response back to the client with either the requested data (
status 200 OK) or a descriptive error message (status 400, 401, 403, 404, 500). - State Update (React Context/State): The
apiClientreceives the response. The original component then uses this data to update its state viauseStateor a context function likelogin(). This state change triggers a re-render of the UI, displaying the new data or view to the user.