פיתוח מערכת הזמנות מקוונת מותאמת אישית לאתר שלך
אנו מפתחים מערכות הזמנות מקוונות מותאמות אישית שמונעות כפילויות הזמנות ברמת מסד הנתונים ושומרות על עקביות גם בעומסי שיא. שגיאות כפילויות הזמנות עולות לעסקים עד 20% מההזמנות הפוטנציאליות. הפתרון שלנו מתמודד עם עד 5000 בקשות במקביל לדקה עם אפס תנאי מרוץ, באמצעות שילוב של אילוצי EXCLUDE של PostgreSQL, Redis להחזקת משבצות זמניות, והתראות אסינכרוניות.
מערכת הזמנות היא לא רק טופס בחירת תאריך. היא ניהול משבצות, בדיקות זמינות בזמן אמת, מנגנוני החזקה, טיפול בבקשות במקביל, ושרשרת התראות. יישום לקוי מוביל לכפילויות הזמנות או משבצות תקועות, ופוגע באמון הלקוחות. עם ניסיון של 5+ שנים ו-300+ פרויקטים שהושלמו, אנו יודעים כיצד להימנע מהמלכודות הללו.
לקוחות חווים לעיתים קרובות תרחיש כזה: משבצת נראית פנויה בלוח השנה, אבל אחרי מילוי הטופס היא כבר תפוסה. או להיפך, מנהל רואה הזמנה אבל הלקוח לא מקבל אישור. אנו מבטלים תרחישים אלה: נעילת משאבים שקופה, התראות בזמן אמת, והגנה מפני בקשות כפולות. המערכות שלנו זוכות לאמון של 50+ חברות בתחומי הבריאות, האירוח והשירותים המקצועיים.
כיצד פועלות בדיקות זמינות בזמן אמת
אנו מתכננים את סכמת הנתונים. ישויות מפתח: משאב, לוח זמנים והזמנה.
-- Ресурс бронирования (зал, специалист, номер, стол и т.д.)
CREATE TABLE bookable_resources (
id SERIAL PRIMARY KEY,
type VARCHAR(50) NOT NULL, -- 'specialist', 'room', 'table', 'car'
name VARCHAR(255) NOT NULL,
config JSONB,
is_active BOOLEAN DEFAULT TRUE
);
-- Расписание доступности ресурса
CREATE TABLE resource_schedules (
id SERIAL PRIMARY KEY,
resource_id INTEGER REFERENCES bookable_resources(id),
weekday SMALLINT,
specific_date DATE,
start_time TIME NOT NULL,
end_time TIME NOT NULL,
slot_duration INTERVAL,
is_available BOOLEAN DEFAULT TRUE
);
-- Собственно бронирования
CREATE TABLE bookings (
id BIGSERIAL PRIMARY KEY,
resource_id INTEGER REFERENCES bookable_resources(id),
user_id INTEGER,
guest_name VARCHAR(255),
guest_email VARCHAR(255),
guest_phone VARCHAR(50),
starts_at TIMESTAMP NOT NULL,
ends_at TIMESTAMP NOT NULL,
status VARCHAR(20) DEFAULT 'pending',
notes TEXT,
metadata JSONB,
created_at TIMESTAMP DEFAULT NOW(),
confirmed_at TIMESTAMP,
cancelled_at TIMESTAMP,
CONSTRAINT no_overlap EXCLUDE USING gist (
resource_id WITH =,
tsrange(starts_at, ends_at, '[)') WITH &&
) WHERE (status NOT IN ('cancelled'))
);
אילוץ -- Ресурс бронирования (зал, специалист, номер, стол и т.д.) CREATE TABLE bookable_resources ( id SERIAL PRIMARY KEY, type VARCHAR(50) NOT NULL, -- 'specialist', 'room', 'table', 'car' name VARCHAR(255) NOT NULL, config JSONB, is_active BOOLEAN DEFAULT TRUE ); -- Расписание доступности ресурса CREATE TABLE resource_schedules ( id SERIAL PRIMARY KEY, resource_id INTEGER REFERENCES bookable_resources(id), weekday SMALLINT, specific_date DATE, start_time TIME NOT NULL, end_time TIME NOT NULL, slot_duration INTERVAL, is_available BOOLEAN DEFAULT TRUE ); -- Собственно бронирования CREATE TABLE bookings ( id BIGSERIAL PRIMARY KEY, resource_id INTEGER REFERENCES bookable_resources(id), user_id INTEGER, guest_name VARCHAR(255), guest_email VARCHAR(255), guest_phone VARCHAR(50), starts_at TIMESTAMP NOT NULL, ends_at TIMESTAMP NOT NULL, status VARCHAR(20) DEFAULT 'pending', notes TEXT, metadata JSONB, created_at TIMESTAMP DEFAULT NOW(), confirmed_at TIMESTAMP, cancelled_at TIMESTAMP, CONSTRAINT no_overlap EXCLUDE USING gist ( resource_id WITH =, tsrange(starts_at, ends_at, '[)') WITH && ) WHERE (status NOT IN ('cancelled')) ); הוא הדרך האמינה ביותר למנוע כפילויות הזמנות ברמת מסד הנתונים. הוא פועל אטומית ואינו תלוי בלוגיקת היישום. אילוץ EXCLUDE של PostgreSQL מהיר פי 10 מנעילות ברמת היישום ומבטיח אמינות של 99.9%.
למה להשתמש באילוץ EXCLUDE?
יישום עשוי לבדוק זמינות עם SELECT, אבל בין הקריאה להוספה בקשה אחרת יכולה ליצור הזמנה. אילוץ EXCLUDE תופס את המרוץ הזה ברמת מסד הנתונים ומעלה EXCLUDE USING gist. אנו מטפלים בזה ומחזירים הודעה ברורה ללקוח. זה מבטיח ללא חפיפות ללא נעילות מבוזרות. השוואת שיטות:
| שיטה | אמינות | ביצועים | מורכבות יישום |
|---|---|---|---|
| אילוץ EXCLUDE | 99.9% | ~200 מיקרו-שניות לבדיקה | נמוכה |
| נעילה ברמת היישום | ~90% | ~10 מילי-שניות | בינונית |
| נעילה אופטימית | ~95% | ~500 מיקרו-שניות | גבוהה |
הנתונים התקבלו תחת 5000 בקשות במקביל.
אלגוריתם בדיקת זמינות
def get_available_slots(resource_id: int, date: date) -> list[TimeSlot]:
schedule = get_schedule(resource_id, date)
if not schedule or not schedule.is_available:
return []
all_slots = generate_slots(
start=schedule.start_time,
end=schedule.end_time,
duration=schedule.slot_duration or timedelta(hours=1),
)
booked = get_booked_intervals(resource_id, date)
return [
slot for slot in all_slots
if not any(slot.overlaps(b) for b in booked)
] החזקת משבצת זמנית (Hold)
בין בחירת המשבצת לתשלום עובר זמן. כדי למנוע ממשתמש אחר לתפוס את המשבצת, אנו מיישמים מנגנון החזקה על Redis. זמן ההחזקה הוא 10 דקות (600 שניות).
HOLD_TTL = 600
def hold_slot(resource_id: int, starts_at: datetime, session_id: str) -> str:
hold_key = f"hold:{resource_id}:{starts_at.isoformat()}"
success = redis.set(hold_key, session_id, nx=True, ex=HOLD_TTL)
if not success:
existing = redis.get(hold_key)
if existing and existing.decode() != session_id:
raise SlotAlreadyHeld("Слот занят другим пользователем")
return hold_key
def confirm_booking(hold_key: str, booking_data: dict) -> Booking:
session_id = redis.get(hold_key)
if not session_id:
raise HoldExpired("Время удержания слота истекло")
with db.transaction():
booking = create_booking(booking_data)
redis.delete(hold_key)
return booking
כיצד מטפלים בבקשות במקביל?
גם עם אילוץ EXCLUDE, יכול להתרחש מרוץ: שתי בקשות בודקות זמינות בו-זמנית ושתיהן רואות שהמשבצת פנויה. האילוץ תופס את ה-INSERT השני.
try:
booking = create_booking(data)
except ExclusionViolationError:
raise BookingConflict("Этот слот только что был забронирован. Выберите другое время.") התראות
| אירוע | נמען | ערוץ |
|---|---|---|
| הזמנה נוצרה | לקוח | אימייל + SMS |
| הזמנה אושרה | לקוח | אימייל |
| תזכורת 24 שעות לפני | לקוח | אימייל + SMS |
| תזכורת שעה לפני | לקוח | SMS |
| הזמנה חדשה | מנהל | אימייל |
| ביטול | לקוח + מנהל | אימייל |
תזכורות נשלחות באמצעות משימות מתוזמנות.
מדיניות ביטול ושינוי
מערכת מדיניות גמישה: ביטול חינם עד 24 שעות, החזר של 50% עד 12 שעות, ללא החזר לאחר מכן. המדיניות נשמרת ברמת המשאב ומיושמת אוטומטית. זה מפחית מחלוקות עם לקוחות ב-30%.
יישום מערכת הזמנות שלב אחר שלב
- סקירת דרישות: קביעת סוגי משאבים, מספר משבצות, עומס שיא.
- עיצוב סכמת מסד נתונים: יצירת מבנה טבלאות עם אילוץ EXCLUDE.
- הגדרת החזקות Redis: החזקות משבצות עם TTL של 10 דקות.
- פיתוח API: CRUD למשאבים, לוחות זמנים והזמנות.
- שילוב שער תשלום: Stripe עם לכידה ידנית.
- שרשרת התראות: אימייל דרך SMTP, SMS דרך API של ספק.
- לוח ניהול: ניהול הזמנות ב-React/Vue.
- בדיקות עומס: אימות תחת 5000 בקשות במקביל.
- תיעוד והדרכה.
מה כלול בעבודה
- עיצוב סכמת נתונים ובחירת טכנולוגיות (PostgreSQL, Redis, Python/Node.js)
- יישום API מסוג CRUD למשאבים, לוחות זמנים והזמנות
- מנגנון החזקת Redis עם שחרור TTL אוטומטי
- שילוב שער תשלום (Stripe או אחר)
- הגדרת שרשרת התראות
- לוח ניהול לניהול (React/Vue)
- בדיקות עומס (עד 1000 במקביל כבסיס, בפועל אנו מתמודדים עם 5000)
- תיעוד מקיף והדרכת צוות
- פריסה ותמיכה של 30 יום לאחר ההשקה
- גישה מלאה לקוד המקור ולתשתית
לוחות זמנים לאספקה והשקעה
מערכת בסיסית עם סוג משאב אחד, ללא תשלומים – 8–10 ימי עבודה, החל מ-$2,500. גרסה מורחבת עם סוגי משאבים מרובים, CMS, תשלומים, התראות SMS, מדיניות ביטול – 14–18 ימי עבודה, החל מ-$5,000. ההשקעה מחושבת באופן אישי לאחר ייעוץ. צור קשר כדי לקבל הערכה ראשונית לפרויקט שלך.
עם ניסיון של 5+ שנים, 300+ פרויקטים שהושלמו ורקורד של שירות ל-50+ חברות, יש לנו את המומחיות להפוך את מערכת ההזמנות שלך לחזקה וניתנת להרחבה. קבל הערכת פרויקט היום.
תיעוד PostgreSQL: https://www.postgresql.org/docs/current/ddl-constraints.html#DDL-CONSTRAINTS-EXCLUSION







