Dashboard
📅
14
Today's Appointments
↑ 3 more than yesterday
💰
₹42,800
Revenue This Month
↑ 12% vs last month
📦
3
Low Stock Alerts
⚠ Requires attention
💳
₹8,400
Pending Payments
4 invoices outstanding
Today's Schedule
09:00
Priya Mehta
Laser Hair Removal · Dr. Kapoor
Confirmed
10:00
Anjali Singh
Skin Brightening · Dr. Reena
Scheduled
11:30
Neha Patel
Hair PRP · Dr. Kapoor
Completed
14:00
Ritika Joshi
Consultation · Dr. Reena
Scheduled
16:00
Sunita Rao
Botox · Dr. Reena
Confirmed
⚠ Low Stock Alerts
🧴
Vitamin C Serum
Only 3 units left · Reorder at 5
💊
Hydroquinone Cream
Only 2 units left · Reorder at 5
Laser Cooling Gel
4 units left · Reorder at 10
Pending Payments
PatientAmountAction
Anjali Singh ₹2,400
Neha Patel ₹3,200
Sunita Rao ₹2,800
March 2026
Mon
02
Tue
03
Wed
04
Thu
05
Fri
06
Sat
07
Time
Slots
09:00
✓ Priya Mehta — Laser (Dr. Kapoor)
10:00
◷ Anjali Singh — Skin Brightening
11:00
11:30
✓ Neha Patel — PRP (Done)
12:00
13:00
Lunch Break
14:00
◷ Ritika Joshi — Consultation
15:00
⚑ Kavya Nair — Hair Treatment (No-show)
16:00
✓ Sunita Rao — Botox
17:00
18:00
Customer Phone Age / Gender Blood Type Active Packages Last Visit Action
PM
Priya Mehta
+91 98765 43210 28 / Female O+ 2 Active Mar 03, 2026
AS
Anjali Singh
+91 87654 32109 34 / Female A+ 1 Active Feb 28, 2026
NP
Neha Patel
+91 76543 21098 42 / Female B+ Mar 03, 2026
Customers / Priya Mehta
PM

Priya Mehta

[email protected] · +91 98765 43210

Female 28 yrs Blood: O+ Mumbai
Personal Information
Full NamePriya Mehta
Phone+91 98765 43210
Date of Birth15 Apr 1997 (28 yrs)
GenderFemale
Blood TypeO+
AddressBandra, Mumbai 400050
Medical Notes
AllergiesNone known
Skin TypeCombination, Sensitive
Chief ConcernHyperpigmentation, Hair removal
NotesPrefers morning slots. Reacts to fragrance-based products.
Laser Hair Removal — Full Body
8-Session Package · Enrolled: Jan 15, 2026
5 / 8
Sessions done
SESSION TRACKER
1
2
3
4
5
6
7
8
5 sessions completed 3 sessions remaining
Skin Brightening Program
6-Session Package · Enrolled: Feb 10, 2026
2 / 6
1
2
3
4
5
6
DateTimeTreatmentDoctorStatusActions
Mar 03, 202609:00 AMLaser Hair RemovalDr. KapoorConfirmed
Feb 17, 202610:00 AMLaser Session 3Dr. KapoorCompleted
Feb 03, 202610:00 AMLaser Session 2Dr. KapoorCompleted
Invoice #DateAmountStatusAction
INV-2026-0042Mar 03₹4,500Paid
INV-2026-0031Feb 17₹4,500Paid
INV-2026-0018Feb 03₹2,800Pending
📂

No files uploaded

Upload before/after photos, reports, or consent forms

35 Total Enrollments
28 Active
6 Nearly Done
7 Completed
PM
Priya Mehta
Laser Hair Removal — Full Body Active
⚡ Diode Laser + Cooling Therapy + SPF Shield Add-on
EnrolledJan 15, 2026
Next SessionMar 10
DoctorDr. Kapoor
1
2
3
4
5
6
7
8
5 / 8
AS
Anjali Singh
Skin Brightening Program Active
✨ Vitamin C Peel 🌿 Kojic Acid Serum + LED Therapy Add-on
EnrolledFeb 10, 2026
Next SessionMar 14
DoctorDr. Reena
1
2
3
4
5
6
2 / 6
NP
Neha Patel
Hair PRP Therapy Nearly Done
💉 PRP Injection 🌱 Mesotherapy + Scalp Massage Add-on
EnrolledJan 5, 2026
Next SessionMar 20
DoctorDr. Reena
1
2
3
4
5
4 / 5
RJ
Ritika Joshi
Acne Treatment Plan Completed
🧴 Salicylic Peel 💡 Blue Light Therapy + Spot Gel Add-on
EnrolledOct 12, 2025
CompletedFeb 28, 2026
DoctorDr. Reena
1
2
3
4
5
6
7
8
8 / 8 ✓
SR
Sunita Rao
Anti-Aging Facial Program Active
💧 Hydra Facial 🌟 Collagen Booster + Microcurrent Add-on + RF Tightening Add-on
EnrolledFeb 20, 2026
Next SessionMar 06
DoctorDr. Reena
1
2
3
4
5
6
7
8
9
10
2 / 10
Product Category Stock Batch # Expiry Vendor Status Actions
Vitamin C Serum 20% Serum
3
B2025-447 Sep 2026 Cosmo Labs ⚠ Low Stock
Hydroquinone 4% Cream Cream
2
B2025-321 Dec 2026 DermaCo ⚠ Low Stock
Hyaluronic Acid Serum Serum
24
B2025-501 Mar 2027 Cosmo Labs ✓ In Stock
Laser Cooling Gel Consumable
4
B2026-012 Jul 2027 LaserTech ⚠ Low Stock
Glycolic Acid 10% Medicine
18
B2025-388 Jun 2027 AlphaChem ✓ In Stock
New Invoice

Line Items
₹4,500

Charges & Adjustments
— ₹0
₹0
(Optional)
₹0

Subtotal₹4,500
Discount— ₹0
Total₹4,500

Payment Mode
14-B, MG Road, Bengaluru 560001
+91 98100 55555
GSTIN: 29AABCL1234A1Z5
INVOICE #INV-2026-0043
Date: Mar 03, 2026
Due: Mar 03, 2026
Bill To
Priya Mehta
Bandra, Mumbai 400050
+91 98765 43210
Treatment Details
Package: Laser Hair Removal
Session #6 of 8 · Dr. Kapoor
#DescriptionQtyRateAmount
1Laser Hair Removal — Session 61₹4,500₹4,500
Subtotal₹4,500
Discount— ₹0

Total Due₹4,500
✓ PAID — Cash
Thank you for choosing Linqs Cosmetology Clinic!
This is a computer-generated invoice.
RS
Dr. Reena Sharma
Admin · Dermatologist
Active
VK
Dr. Vivek Kapoor
Doctor · Laser Specialist
Active
MJ
Meena Joshi
Receptionist
Active
RP
Ritu Pillai
Therapist
Inactive
🏥 Clinic Information
Clinic Name
Appears on all invoices and communications
Logo
Address
Phone
💰 GST & Billing
GSTIN
GST Identification Number
Default GST Rate
Invoice Prefix
🕐 Working Hours
Monday – Saturday
to
Sunday
Appointment Slot Duration

Complete relational database schema for the LinqsClinic ERP system. All tables use UUID primary keys.

👤 customers
Column
Type
Key
Notes
id
UUID
PK
Primary key
name
VARCHAR(100)
NOT NULL
phone
VARCHAR(15)
IDX
Unique, indexed
email
VARCHAR(100)
Optional
gender
ENUM
Male/Female/Other
date_of_birth
DATE
blood_type
VARCHAR(5)
A+, O-, etc.
address
TEXT
skin_type
VARCHAR(50)
allergies
TEXT
notes
TEXT
Clinical notes
created_at
TIMESTAMP
DEFAULT NOW()
📅 appointments
Column
Type
Key
Notes
id
UUID
PK
customer_id
UUID
FK
→ customers.id
staff_id
UUID
FK
→ staff.id
treatment_type
VARCHAR(100)
Hair/Skin/Laser
appointment_date
DATE
IDX
Indexed for queries
start_time
TIME
duration_mins
INT
Default 30
status
ENUM
IDX
scheduled/confirmed/completed/cancelled/no-show
session_id
UUID
FK
→ package_sessions.id (nullable)
notes
TEXT
📦 package_plans
Column
Type
Key
Notes
id
UUID
PK
name
VARCHAR(150)
NOT NULL
description
TEXT
session_count
INT
Total sessions
price
DECIMAL(10,2)
is_active
BOOLEAN
DEFAULT true
📋 package_enrollments
Column
Type
Key
Notes
id
UUID
PK
customer_id
UUID
FK
→ customers.id
plan_id
UUID
FK
→ package_plans.id
enrolled_at
DATE
sessions_completed
INT
Computed field
status
ENUM
active/completed/cancelled
bill_id
UUID
FK
→ bills.id
🎯 package_sessions
Column
Type
Key
Notes
id
UUID
PK
enrollment_id
UUID
FK
→ package_enrollments.id
session_number
INT
1, 2, 3...
staff_id
UUID
FK
Assigned staff
status
ENUM
pending/completed
completed_at
TIMESTAMP
Nullable
notes
TEXT
Per-session notes
👩‍⚕️ staff
Column
Type
Key
Notes
id
UUID
PK
name
VARCHAR(100)
role
ENUM
admin/doctor/receptionist
phone
VARCHAR(15)
email
VARCHAR(100)
UNIQ
Login email
password_hash
VARCHAR(255)
bcrypt
specialization
VARCHAR(100)
is_active
BOOLEAN
DEFAULT true
🧴 inventory_items
Column
Type
Key
Notes
id
UUID
PK
name
VARCHAR(150)
category
ENUM
IDX
medicine/serum/cream/consumable
quantity
INT
Current stock
reorder_threshold
INT
Alert trigger
batch_number
VARCHAR(50)
expiry_date
DATE
IDX
For expiry alerts
vendor
VARCHAR(100)
unit_cost
DECIMAL(10,2)
📊 inventory_logs
Column
Type
Key
Notes
id
UUID
PK
item_id
UUID
FK
→ inventory_items.id
type
ENUM
stock_in / stock_out
quantity_change
INT
+/- value
bill_id
UUID
FK
Nullable, auto-deduct
staff_id
UUID
FK
Who made change
created_at
TIMESTAMP
Audit trail
💳 bills
Column
Type
Key
Notes
id
UUID
PK
invoice_number
VARCHAR(30)
UNIQ
INV-2026-0001
customer_id
UUID
FK
→ customers.id
subtotal
DECIMAL(10,2)
gst_amount
DECIMAL(10,2)
discount
DECIMAL(10,2)
total
DECIMAL(10,2)
payment_status
ENUM
IDX
paid/partial/pending
payment_mode
ENUM
cash/upi/card
created_by
UUID
FK
→ staff.id
created_at
TIMESTAMP
IDX
📝 bill_items
Column
Type
Key
Notes
id
UUID
PK
bill_id
UUID
FK
→ bills.id
description
VARCHAR(200)
item_type
ENUM
service/product/package
quantity
INT
unit_price
DECIMAL(10,2)
inventory_item_id
UUID
FK
Nullable, triggers deduction

REST API — Base URL: https://api.linqsclinic.in/v1 · Auth: Bearer JWT

Customers
GET /customers List all customers with filters
Query Params
?search=priya&page=1&limit=20
Response 200
{
  "data": [
    {
      "id": "uuid",
      "name": "Priya Mehta",
      "phone": "+91 98765 43210",
      "active_packages": 2,
      "last_visit": "2026-03-03"
    }
  ],
  "total": 48,
  "page": 1
}
POST /customers Create new customer profile
Request Body
{
  "name": "Anjali Singh",
  "phone": "+91 87654 32109",
  "email": "[email protected]",
  "gender": "female",
  "date_of_birth": "1990-06-15",
  "blood_type": "A+",
  "address": "Andheri, Mumbai",
  "notes": "Sensitive skin"
}
Response 201
{ "id": "uuid-here", "message": "Customer created" }
Appointments
GET /appointments List appointments by date/doctor
Query Params
?date=2026-03-03&staff_id=uuid&status=confirmed
Response 200
{
  "appointments": [
    {
      "id": "uuid",
      "customer": { "name": "Priya Mehta", "phone": "+91..." },
      "staff": { "name": "Dr. Kapoor" },
      "treatment_type": "Laser",
      "appointment_date": "2026-03-03",
      "start_time": "09:00",
      "status": "confirmed"
    }
  ]
}
POST /appointments Book a new appointment
Request Body
{
  "customer_id": "uuid",
  "staff_id": "uuid",
  "treatment_type": "Laser",
  "appointment_date": "2026-03-10",
  "start_time": "10:00",
  "duration_mins": 45,
  "session_id": "uuid-or-null"
}
PATCH /appointments/:id/status Update appointment status
Request Body
{
  "status": "completed"   // scheduled|confirmed|completed|cancelled|no-show
}
Response 200
{ "message": "Status updated", "whatsapp_url": "https://wa.me/919876543210?text=..." }
Packages
POST /packages/enroll Enroll customer in a package plan
Request Body
{
  "customer_id": "uuid",
  "plan_id": "uuid",
  "bill_id": "uuid"   // Link payment
}
Response 201
{
  "enrollment_id": "uuid",
  "sessions_created": 8,
  "message": "Enrolled in Laser Hair Removal — 8 sessions created"
}
PATCH /packages/sessions/:id/complete Mark a session as completed
Request Body
{
  "staff_id": "uuid",
  "notes": "Used 3 passes, full coverage"
}
Response 200
{
  "session_number": 6,
  "sessions_remaining": 2,
  "whatsapp_url": "https://wa.me/91...?text=Session+6+completed..."
}
Inventory
POST /inventory/stock-in Add stock for an inventory item
Request Body
{
  "item_id": "uuid",
  "quantity": 20,
  "batch_number": "B2026-055",
  "expiry_date": "2027-09-01",
  "vendor": "Cosmo Labs"
}
Response 200
{ "new_quantity": 23, "low_stock": false }
Billing
POST /billing Create a bill and auto-deduct inventory
Request Body
{
  "customer_id": "uuid",
  "items": [
    {
      "description": "Laser Session 6",
      "item_type": "service",
      "quantity": 1,
      "unit_price": 4500
    },
    {
      "description": "Cooling Gel",
      "item_type": "product",
      "inventory_item_id": "uuid",
      "quantity": 1,
      "unit_price": 500
    }
  ],
  "discount": 0,
  "gst_percent": 18,
  "payment_mode": "cash",
  "payment_status": "paid"
}
Response 201
{
  "bill_id": "uuid",
  "invoice_number": "INV-2026-0043",
  "total": 5900,
  "inventory_deducted": [{ "item": "Cooling Gel", "qty": 1, "new_stock": 3 }],
  "low_stock_alerts": [{ "item": "Cooling Gel", "quantity": 3 }]
}
🏗 System Architecture
# Recommended Tech Stack Frontend Framework: React 18 + Vite Routing: React Router v6 State: Zustand (simple) UI: Tailwind CSS Icons: Lucide React Tables: TanStack Table Print: browser print API Backend Runtime: Node.js + Express ORM: Prisma (PostgreSQL) Auth: JWT + bcrypt Validation: Zod Upload: Multer + S3/local Database PostgreSQL 15 Redis (sessions + alerts) Deployment Docker Compose Nginx reverse proxy PM2 process manager
📁 Folder Structure
linqs/ ├── frontend/ │ ├── src/ │ │ ├── pages/ │ │ │ ├── Dashboard.jsx │ │ │ ├── Appointments.jsx │ │ │ ├── Customers.jsx │ │ │ ├── CustomerDetail.jsx │ │ │ ├── Packages.jsx │ │ │ ├── Inventory.jsx │ │ │ ├── Billing.jsx │ │ │ ├── Staff.jsx │ │ │ └── Settings.jsx │ │ ├── components/ │ │ │ ├── AppointmentGrid.jsx │ │ │ ├── PackageTracker.jsx │ │ │ ├── InvoicePreview.jsx │ │ │ ├── SessionDots.jsx │ │ │ └── StockBadge.jsx │ │ ├── store/ │ │ │ └── useClinicStore.js │ │ └── api/ │ │ └── client.js │ ├── backend/ │ ├── routes/ │ │ ├── customers.js │ │ ├── appointments.js │ │ ├── packages.js │ │ ├── inventory.js │ │ ├── billing.js │ │ ├── staff.js │ │ └── settings.js │ ├── middleware/ │ │ ├── auth.js │ │ └── rbac.js │ ├── services/ │ │ ├── whatsapp.js │ │ ├── inventory.js │ │ └── billing.js │ └── prisma/ │ └── schema.prisma │ └── docker-compose.yml
🔐 RBAC Design
ModuleAdminDoctorRecept.
Dashboard✓ Full✓ View✓ View
Appointments✓ Full✓ Full✓ Full
Customers✓ Full✓ Full✓ Full
Packages✓ Full✓ View✓ Enroll
Inventory✓ FullView
Billing✓ FullView✓ Full
Staff✓ Full
Settings✓ Full
🔮 Future-Ready Design
Multi-Branch: Add branch_id FK to all entities
Revenue Reports: Pre-aggregate daily into report_snapshots
SMS/Email: Hook into queue on appointment create
Real PDF: Replace print with Puppeteer / pdf-lib
Real-time: Add WebSocket via Socket.io for live calendar
Analytics: Materialized views for slow queries
Audit Log: audit_logs table captures all mutations
📱 WhatsApp Integration
Current (Free): wa.me deep links with pre-filled messages.

The API returns whatsapp_url on key events:
· Appointment booked → reminder
· Appointment confirmed
· Session completed → confirmation
· Package nearly complete

Future (Paid): Upgrade to WhatsApp Business Cloud API for automated sends — no code changes needed, just swap the whatsapp.js service.