package storage import "context" type BookingDay struct { Date string `json:"date"` DoctorIDs []int64 `json:"doctor_ids"` } // PublicBookingDays returns only dates and public doctor IDs, never patient data. // Keep the occupancy rules identical to FreeOnecSlots, including cross-branch reservations. func (s *Storage) PublicBookingDays(ctx context.Context) ([]BookingDay, error) { rows, err := s.pool.Query(ctx, ` SELECT to_char(sl.start_at AT TIME ZONE 'Europe/Moscow','YYYY-MM-DD'), array_agg(DISTINCT d.id ORDER BY d.id) FROM onec_slots sl JOIN onec_doctors od ON od.onec_id=sl.doctor_onec_id JOIN doctors d ON d.id=od.doctor_id WHERE sl.status='free' AND sl.start_at>now() AND od.active AND d.published AND d.deleted_at IS NULL AND NOT d.absent AND d.booking_provider='native' AND NOT EXISTS(SELECT 1 FROM onec_appointments a WHERE a.doctor_onec_id=sl.doctor_onec_id AND a.status IN('pending','booked','arrived') AND a.start_atsl.start_at) GROUP BY 1 ORDER BY 1`) if err != nil { return nil, err } defer rows.Close() out := []BookingDay{} for rows.Next() { var day BookingDay if err := rows.Scan(&day.Date, &day.DoctorIDs); err != nil { return nil, err } out = append(out, day) } return out, rows.Err() }