pharmacy-erp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +34 -0
- package/LICENSE +21 -0
- package/README.md +479 -0
- package/backend/Dockerfile +44 -0
- package/backend/app/__init__.py +1 -0
- package/backend/app/core/__init__.py +1 -0
- package/backend/app/core/audit.py +33 -0
- package/backend/app/core/config.py +16 -0
- package/backend/app/core/database.py +26 -0
- package/backend/app/core/deps.py +49 -0
- package/backend/app/core/exceptions.py +43 -0
- package/backend/app/core/security.py +32 -0
- package/backend/app/main.py +54 -0
- package/backend/app/modules/__init__.py +0 -0
- package/backend/app/modules/admin/__init__.py +1 -0
- package/backend/app/modules/admin/models.py +15 -0
- package/backend/app/modules/admin/router.py +353 -0
- package/backend/app/modules/auth/__init__.py +0 -0
- package/backend/app/modules/auth/models.py +16 -0
- package/backend/app/modules/auth/router.py +73 -0
- package/backend/app/modules/auth/schemas.py +29 -0
- package/backend/app/modules/cash_sessions/__init__.py +0 -0
- package/backend/app/modules/cash_sessions/models.py +19 -0
- package/backend/app/modules/cash_sessions/router.py +85 -0
- package/backend/app/modules/cash_sessions/schemas.py +31 -0
- package/backend/app/modules/customers/__init__.py +0 -0
- package/backend/app/modules/customers/models.py +37 -0
- package/backend/app/modules/customers/router.py +296 -0
- package/backend/app/modules/customers/schemas.py +72 -0
- package/backend/app/modules/inventory/__init__.py +0 -0
- package/backend/app/modules/inventory/models.py +16 -0
- package/backend/app/modules/inventory/router.py +150 -0
- package/backend/app/modules/inventory/schemas.py +24 -0
- package/backend/app/modules/medicines/__init__.py +0 -0
- package/backend/app/modules/medicines/models.py +54 -0
- package/backend/app/modules/medicines/router.py +631 -0
- package/backend/app/modules/medicines/schemas.py +153 -0
- package/backend/app/modules/medicines/template_generator.py +118 -0
- package/backend/app/modules/notifications/__init__.py +1 -0
- package/backend/app/modules/notifications/models.py +15 -0
- package/backend/app/modules/notifications/router.py +89 -0
- package/backend/app/modules/notifications/schemas.py +22 -0
- package/backend/app/modules/organizations/__init__.py +0 -0
- package/backend/app/modules/organizations/models.py +16 -0
- package/backend/app/modules/organizations/router.py +49 -0
- package/backend/app/modules/organizations/schemas.py +31 -0
- package/backend/app/modules/reports/__init__.py +0 -0
- package/backend/app/modules/reports/router.py +409 -0
- package/backend/app/modules/roles/__init__.py +1 -0
- package/backend/app/modules/roles/models.py +43 -0
- package/backend/app/modules/roles/router.py +89 -0
- package/backend/app/modules/roles/schemas.py +55 -0
- package/backend/app/modules/sales/__init__.py +0 -0
- package/backend/app/modules/sales/models.py +44 -0
- package/backend/app/modules/sales/router.py +63 -0
- package/backend/app/modules/sales/schemas.py +42 -0
- package/backend/app/modules/sales/service.py +128 -0
- package/backend/app/modules/suppliers/__init__.py +0 -0
- package/backend/app/modules/suppliers/models.py +14 -0
- package/backend/app/modules/suppliers/router.py +56 -0
- package/backend/app/modules/suppliers/schemas.py +27 -0
- package/backend/app/modules/users/__init__.py +0 -0
- package/backend/app/modules/users/router.py +74 -0
- package/backend/app/seed.py +275 -0
- package/backend/data/.gitkeep +1 -0
- package/backend/requirements.txt +17 -0
- package/bin/cli.js +288 -0
- package/docker-compose.dev.yml +42 -0
- package/docker-compose.yml +59 -0
- package/frontend/Dockerfile +56 -0
- package/frontend/next.config.ts +19 -0
- package/frontend/package.json +60 -0
- package/frontend/pnpm-lock.yaml +5678 -0
- package/frontend/pnpm-workspace.yaml +6 -0
- package/frontend/postcss.config.mjs +6 -0
- package/frontend/public/logo.png +0 -0
- package/frontend/src/app/[locale]/(app)/admin/page.tsx +1426 -0
- package/frontend/src/app/[locale]/(app)/catalog/products/[id]/page.tsx +505 -0
- package/frontend/src/app/[locale]/(app)/catalog/products/page.tsx +753 -0
- package/frontend/src/app/[locale]/(app)/customers/[id]/page.tsx +500 -0
- package/frontend/src/app/[locale]/(app)/customers/page.tsx +538 -0
- package/frontend/src/app/[locale]/(app)/dashboard/page.tsx +175 -0
- package/frontend/src/app/[locale]/(app)/inventory/page.tsx +765 -0
- package/frontend/src/app/[locale]/(app)/layout.tsx +60 -0
- package/frontend/src/app/[locale]/(app)/purchasing/page.tsx +1 -0
- package/frontend/src/app/[locale]/(app)/reports/page.tsx +794 -0
- package/frontend/src/app/[locale]/(app)/sales/page.tsx +296 -0
- package/frontend/src/app/[locale]/(auth)/login/page.tsx +100 -0
- package/frontend/src/app/[locale]/(pos)/layout.tsx +33 -0
- package/frontend/src/app/[locale]/(pos)/pos/page.tsx +463 -0
- package/frontend/src/app/[locale]/(pos)/pos/pos-data.ts +89 -0
- package/frontend/src/app/[locale]/layout.tsx +30 -0
- package/frontend/src/app/[locale]/page.tsx +6 -0
- package/frontend/src/app/globals.css +77 -0
- package/frontend/src/app/layout.tsx +23 -0
- package/frontend/src/app/print.css +18 -0
- package/frontend/src/components/pos/CartPanel.tsx +525 -0
- package/frontend/src/components/pos/CashSessionGuard.tsx +255 -0
- package/frontend/src/components/pos/CloseSessionModal.tsx +160 -0
- package/frontend/src/components/pos/PaymentModal.tsx +266 -0
- package/frontend/src/components/pos/PaymentSettingsModal.tsx +472 -0
- package/frontend/src/components/pos/ProductCatalog.tsx +140 -0
- package/frontend/src/components/pos/SaleReceipt.tsx +133 -0
- package/frontend/src/components/ui/badge.tsx +28 -0
- package/frontend/src/components/ui/bulk-import-modal.tsx +400 -0
- package/frontend/src/components/ui/button.tsx +60 -0
- package/frontend/src/components/ui/card.tsx +13 -0
- package/frontend/src/components/ui/confirm-dialog.tsx +50 -0
- package/frontend/src/components/ui/input.tsx +32 -0
- package/frontend/src/components/ui/notification-center.tsx +228 -0
- package/frontend/src/components/ui/select.tsx +59 -0
- package/frontend/src/components/ui/sidebar.tsx +91 -0
- package/frontend/src/components/ui/slide-over.tsx +43 -0
- package/frontend/src/components/ui/stat-card.tsx +40 -0
- package/frontend/src/components/ui/switch.tsx +38 -0
- package/frontend/src/components/ui/topbar.tsx +97 -0
- package/frontend/src/i18n/request.ts +13 -0
- package/frontend/src/i18n/routing.ts +9 -0
- package/frontend/src/lib/api.ts +240 -0
- package/frontend/src/lib/constants.ts +30 -0
- package/frontend/src/lib/utils.ts +32 -0
- package/frontend/src/messages/ar.json +106 -0
- package/frontend/src/messages/en.json +106 -0
- package/frontend/src/middleware.ts +8 -0
- package/frontend/src/store/app-store.ts +37 -0
- package/frontend/src/store/auth-store.ts +52 -0
- package/frontend/src/store/payment-methods-store.ts +144 -0
- package/frontend/src/store/pos-store.ts +344 -0
- package/frontend/tailwind.config.ts +85 -0
- package/frontend/tsconfig.json +27 -0
- package/img/backgraund-logo.png +0 -0
- package/img/full-logo.png +0 -0
- package/img/logo.png +0 -0
- package/nginx/nginx.conf +67 -0
- package/package.json +88 -0
- package/start.bat +90 -0
- package/start.sh +64 -0
package/nginx/nginx.conf
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
events {
|
|
2
|
+
worker_connections 1024;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
http {
|
|
6
|
+
upstream api {
|
|
7
|
+
server api:8000;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
upstream web {
|
|
11
|
+
server web:3000;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
server {
|
|
15
|
+
listen 80;
|
|
16
|
+
server_name _;
|
|
17
|
+
|
|
18
|
+
# API routes
|
|
19
|
+
location /api/ {
|
|
20
|
+
proxy_pass http://api;
|
|
21
|
+
proxy_set_header Host $host;
|
|
22
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
23
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
24
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
25
|
+
|
|
26
|
+
# WebSocket support
|
|
27
|
+
proxy_http_version 1.1;
|
|
28
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
29
|
+
proxy_set_header Connection "upgrade";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# API docs
|
|
33
|
+
location /docs {
|
|
34
|
+
proxy_pass http://api;
|
|
35
|
+
proxy_set_header Host $host;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
location /openapi.json {
|
|
39
|
+
proxy_pass http://api;
|
|
40
|
+
proxy_set_header Host $host;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# Frontend (everything else)
|
|
44
|
+
location / {
|
|
45
|
+
proxy_pass http://web;
|
|
46
|
+
proxy_set_header Host $host;
|
|
47
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
48
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
49
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# Static files caching
|
|
53
|
+
location /_next/static/ {
|
|
54
|
+
proxy_pass http://web;
|
|
55
|
+
proxy_cache_valid 200 365d;
|
|
56
|
+
add_header Cache-Control "public, immutable";
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# File uploads
|
|
60
|
+
client_max_body_size 10M;
|
|
61
|
+
|
|
62
|
+
# Gzip
|
|
63
|
+
gzip on;
|
|
64
|
+
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
|
|
65
|
+
gzip_min_length 1000;
|
|
66
|
+
}
|
|
67
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pharmacy-erp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Pharmacy ERP & POS System — Enterprise-grade pharmacy management with full Arabic (RTL) and English support",
|
|
5
|
+
"bin": {
|
|
6
|
+
"pharmacy-erp": "./bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"author": "omersx",
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/**",
|
|
11
|
+
"backend/app/**",
|
|
12
|
+
"backend/requirements.txt",
|
|
13
|
+
"backend/Dockerfile",
|
|
14
|
+
"backend/data/.gitkeep",
|
|
15
|
+
"frontend/src/**",
|
|
16
|
+
"frontend/public/**",
|
|
17
|
+
"frontend/package.json",
|
|
18
|
+
"frontend/pnpm-lock.yaml",
|
|
19
|
+
"frontend/Dockerfile",
|
|
20
|
+
"frontend/next.config.ts",
|
|
21
|
+
"frontend/tailwind.config.ts",
|
|
22
|
+
"frontend/tsconfig.json",
|
|
23
|
+
"frontend/postcss.config.mjs",
|
|
24
|
+
"frontend/pnpm-workspace.yaml",
|
|
25
|
+
"docker-compose.yml",
|
|
26
|
+
"docker-compose.dev.yml",
|
|
27
|
+
"nginx/**",
|
|
28
|
+
"img/**",
|
|
29
|
+
".env.example",
|
|
30
|
+
"start.bat",
|
|
31
|
+
"start.sh",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"setup": "pnpm run setup:frontend && pnpm run setup:backend",
|
|
37
|
+
"setup:frontend": "cd frontend && pnpm install --force --no-frozen-lockfile",
|
|
38
|
+
"setup:backend:win": "cd backend && python -m venv venv && .\\venv\\Scripts\\pip install -r requirements.txt",
|
|
39
|
+
"setup:backend:unix": "cd backend && python3 -m venv venv && ./venv/bin/pip install -r requirements.txt",
|
|
40
|
+
"setup:backend": "node -e \"process.platform==='win32'?require('child_process').execSync('pnpm run setup:backend:win',{stdio:'inherit'}):require('child_process').execSync('pnpm run setup:backend:unix',{stdio:'inherit'})\"",
|
|
41
|
+
"dev": "concurrently -n API,WEB -c blue,green \"pnpm run dev:api\" \"pnpm run dev:web\"",
|
|
42
|
+
"dev:api:win": "cd backend && .\\venv\\Scripts\\python -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8000",
|
|
43
|
+
"dev:api:unix": "cd backend && ./venv/bin/python -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8000",
|
|
44
|
+
"dev:api": "node -e \"process.platform==='win32'?require('child_process').execSync('pnpm run dev:api:win',{stdio:'inherit'}):require('child_process').execSync('pnpm run dev:api:unix',{stdio:'inherit'})\"",
|
|
45
|
+
"dev:web": "cd frontend && pnpm run dev",
|
|
46
|
+
"build": "cd frontend && pnpm build",
|
|
47
|
+
"seed:win": "cd backend && .\\venv\\Scripts\\python -m app.seed",
|
|
48
|
+
"seed:unix": "cd backend && ./venv/bin/python -m app.seed",
|
|
49
|
+
"seed": "node -e \"process.platform==='win32'?require('child_process').execSync('pnpm run seed:win',{stdio:'inherit'}):require('child_process').execSync('pnpm run seed:unix',{stdio:'inherit'})\"",
|
|
50
|
+
"db:migrate:win": "cd backend && .\\venv\\Scripts\\python -m alembic upgrade head",
|
|
51
|
+
"db:migrate:unix": "cd backend && ./venv/bin/python -m alembic upgrade head",
|
|
52
|
+
"db:migrate": "node -e \"process.platform==='win32'?require('child_process').execSync('pnpm run db:migrate:win',{stdio:'inherit'}):require('child_process').execSync('pnpm run db:migrate:unix',{stdio:'inherit'})\""
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"concurrently": "^9.1.0"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=18.0.0",
|
|
59
|
+
"pnpm": ">=9.0.0"
|
|
60
|
+
},
|
|
61
|
+
"packageManager": "pnpm@9.15.0",
|
|
62
|
+
"repository": {
|
|
63
|
+
"type": "git",
|
|
64
|
+
"url": "https://github.com/omersx/pharmacy-erp.git"
|
|
65
|
+
},
|
|
66
|
+
"keywords": [
|
|
67
|
+
"pharmacy",
|
|
68
|
+
"erp",
|
|
69
|
+
"pos",
|
|
70
|
+
"point-of-sale",
|
|
71
|
+
"inventory",
|
|
72
|
+
"fastapi",
|
|
73
|
+
"nextjs",
|
|
74
|
+
"react",
|
|
75
|
+
"typescript",
|
|
76
|
+
"python",
|
|
77
|
+
"arabic",
|
|
78
|
+
"rtl",
|
|
79
|
+
"bilingual",
|
|
80
|
+
"mena",
|
|
81
|
+
"healthcare"
|
|
82
|
+
],
|
|
83
|
+
"license": "MIT",
|
|
84
|
+
"bugs": {
|
|
85
|
+
"url": "https://github.com/omersx/pharmacy-erp/issues"
|
|
86
|
+
},
|
|
87
|
+
"homepage": "https://github.com/omersx/pharmacy-erp#readme"
|
|
88
|
+
}
|
package/start.bat
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
title Pharmacy ERP
|
|
3
|
+
color 0A
|
|
4
|
+
|
|
5
|
+
echo.
|
|
6
|
+
echo ====================================================
|
|
7
|
+
echo Pharmacy ERP - One-Click Setup ^& Launch
|
|
8
|
+
echo ====================================================
|
|
9
|
+
echo.
|
|
10
|
+
|
|
11
|
+
REM ── Step 1: Environment File ──────────────────────────
|
|
12
|
+
if not exist ".env" (
|
|
13
|
+
echo [1/4] Creating .env file from .env.example...
|
|
14
|
+
copy .env.example .env >nul
|
|
15
|
+
) else (
|
|
16
|
+
echo [1/4] .env file already exists, skipping...
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
REM ── Step 2: Frontend Dependencies ─────────────────────
|
|
20
|
+
echo [2/4] Installing frontend dependencies...
|
|
21
|
+
cd frontend
|
|
22
|
+
call pnpm install --force --no-frozen-lockfile 2>nul
|
|
23
|
+
if errorlevel 1 (
|
|
24
|
+
echo.
|
|
25
|
+
echo ERROR: Frontend install failed. Make sure pnpm is installed:
|
|
26
|
+
echo npm install -g pnpm
|
|
27
|
+
echo.
|
|
28
|
+
pause
|
|
29
|
+
exit /b 1
|
|
30
|
+
)
|
|
31
|
+
cd ..
|
|
32
|
+
|
|
33
|
+
REM ── Step 3: Backend Setup ─────────────────────────────
|
|
34
|
+
echo [3/4] Setting up Python backend...
|
|
35
|
+
cd backend
|
|
36
|
+
|
|
37
|
+
if not exist "venv" (
|
|
38
|
+
echo Creating virtual environment...
|
|
39
|
+
python -m venv venv
|
|
40
|
+
if errorlevel 1 (
|
|
41
|
+
echo.
|
|
42
|
+
echo ERROR: Python venv creation failed. Make sure Python 3.12+ is installed.
|
|
43
|
+
echo Download from: https://python.org
|
|
44
|
+
echo.
|
|
45
|
+
pause
|
|
46
|
+
exit /b 1
|
|
47
|
+
)
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
echo Installing Python dependencies...
|
|
51
|
+
call .\venv\Scripts\pip install -q -r requirements.txt
|
|
52
|
+
if errorlevel 1 (
|
|
53
|
+
echo.
|
|
54
|
+
echo ERROR: Python dependency install failed.
|
|
55
|
+
echo.
|
|
56
|
+
pause
|
|
57
|
+
exit /b 1
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
cd ..
|
|
61
|
+
|
|
62
|
+
REM ── Step 4: Seed Database ─────────────────────────────
|
|
63
|
+
if not exist "backend\data\pharmacy.db" (
|
|
64
|
+
echo [4/4] Seeding the database with demo data...
|
|
65
|
+
cd backend
|
|
66
|
+
call .\venv\Scripts\python -m app.seed
|
|
67
|
+
cd ..
|
|
68
|
+
echo.
|
|
69
|
+
echo ====================================================
|
|
70
|
+
echo Demo login: admin@pharmacy.com / admin123
|
|
71
|
+
echo ====================================================
|
|
72
|
+
) else (
|
|
73
|
+
echo [4/4] Database already exists, skipping seed...
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
REM ── Start Servers ─────────────────────────────────────
|
|
77
|
+
echo.
|
|
78
|
+
echo ====================================================
|
|
79
|
+
echo Starting Pharmacy ERP...
|
|
80
|
+
echo ====================================================
|
|
81
|
+
echo.
|
|
82
|
+
echo Frontend: http://localhost:3000
|
|
83
|
+
echo Backend: http://localhost:8000
|
|
84
|
+
echo API Docs: http://localhost:8000/docs
|
|
85
|
+
echo.
|
|
86
|
+
echo Press Ctrl+C to stop both servers.
|
|
87
|
+
echo ====================================================
|
|
88
|
+
echo.
|
|
89
|
+
|
|
90
|
+
call pnpm dev
|
package/start.sh
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
echo "===================================================="
|
|
5
|
+
echo " Pharmacy ERP - One-Click Setup & Launch"
|
|
6
|
+
echo "===================================================="
|
|
7
|
+
echo ""
|
|
8
|
+
|
|
9
|
+
# ── Step 1: Environment File ──────────────────────────
|
|
10
|
+
if [ ! -f ".env" ]; then
|
|
11
|
+
echo "[1/4] Creating .env file from .env.example..."
|
|
12
|
+
cp .env.example .env
|
|
13
|
+
else
|
|
14
|
+
echo "[1/4] .env file already exists, skipping..."
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# ── Step 2: Frontend Dependencies ─────────────────────
|
|
18
|
+
echo "[2/4] Installing frontend dependencies..."
|
|
19
|
+
cd frontend
|
|
20
|
+
pnpm install --force --no-frozen-lockfile
|
|
21
|
+
cd ..
|
|
22
|
+
|
|
23
|
+
# ── Step 3: Backend Setup ─────────────────────────────
|
|
24
|
+
echo "[3/4] Setting up Python backend..."
|
|
25
|
+
cd backend
|
|
26
|
+
if [ ! -d "venv" ]; then
|
|
27
|
+
echo " Creating virtual environment..."
|
|
28
|
+
python3 -m venv venv
|
|
29
|
+
fi
|
|
30
|
+
echo " Installing Python dependencies..."
|
|
31
|
+
source venv/bin/activate
|
|
32
|
+
pip install -q -r requirements.txt
|
|
33
|
+
cd ..
|
|
34
|
+
|
|
35
|
+
# ── Step 4: Seed Database ─────────────────────────────
|
|
36
|
+
if [ ! -f "backend/data/pharmacy.db" ]; then
|
|
37
|
+
echo "[4/4] Seeding the database with demo data..."
|
|
38
|
+
cd backend
|
|
39
|
+
source venv/bin/activate
|
|
40
|
+
python -m app.seed
|
|
41
|
+
cd ..
|
|
42
|
+
echo ""
|
|
43
|
+
echo "===================================================="
|
|
44
|
+
echo " Demo login: admin@pharmacy.com / admin123"
|
|
45
|
+
echo "===================================================="
|
|
46
|
+
else
|
|
47
|
+
echo "[4/4] Database already exists, skipping seed..."
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# ── Start Servers ─────────────────────────────────────
|
|
51
|
+
echo ""
|
|
52
|
+
echo "===================================================="
|
|
53
|
+
echo " Starting Pharmacy ERP..."
|
|
54
|
+
echo "===================================================="
|
|
55
|
+
echo ""
|
|
56
|
+
echo " Frontend: http://localhost:3000"
|
|
57
|
+
echo " Backend: http://localhost:8000"
|
|
58
|
+
echo " API Docs: http://localhost:8000/docs"
|
|
59
|
+
echo ""
|
|
60
|
+
echo " Press Ctrl+C to stop both servers."
|
|
61
|
+
echo "===================================================="
|
|
62
|
+
echo ""
|
|
63
|
+
|
|
64
|
+
pnpm dev
|