Index: petify-backend/sql/ddl.sql
===================================================================
--- petify-backend/sql/ddl.sql	(revision ae836471908c8a67e8fc2a25ad6c445b1c867e48)
+++ petify-backend/sql/ddl.sql	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -107,4 +107,7 @@
                              city      VARCHAR(80)  NOT NULL,
                              address   VARCHAR(200) NOT NULL,
+                             work_days VARCHAR(120),
+                             start_time TIME,
+                             end_time   TIME,
                              user_id   BIGINT       UNIQUE,
                              application_id BIGINT UNIQUE,
@@ -227,4 +230,5 @@
                               review_id      BIGINT,
                               target_user_id BIGINT NOT NULL,
+                              interaction_type VARCHAR(40) NOT NULL,
 
                               CONSTRAINT user_reviews_PK PRIMARY KEY (review_id),
@@ -234,5 +238,8 @@
                               CONSTRAINT user_reviews_target_FK FOREIGN KEY (target_user_id)
                                   REFERENCES users(user_id)
-                                  ON DELETE RESTRICT
+                                  ON DELETE RESTRICT,
+                              CONSTRAINT user_reviews_interaction_type_CHK CHECK (
+                                  interaction_type IN ('EVENT', 'PERSONAL_INTERACTION', 'ONLINE', 'PHONE_CALL', 'OTHER')
+                              )
 );
 
Index: petify-backend/sql/dml.sql
===================================================================
--- petify-backend/sql/dml.sql	(revision ae836471908c8a67e8fc2a25ad6c445b1c867e48)
+++ petify-backend/sql/dml.sql	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -116,7 +116,7 @@
 VALUES (1, (SELECT clinic_id FROM vet_clinics WHERE name='Happy Paws Clinic'));
 
-INSERT INTO user_reviews (review_id, target_user_id) VALUES
-                                                         (2, (SELECT user_id FROM users WHERE username='client.igor')),
-                                                         (3, (SELECT user_id FROM users WHERE username='client.mila'));
+INSERT INTO user_reviews (review_id, target_user_id, interaction_type) VALUES
+                                                         (2, (SELECT user_id FROM users WHERE username='client.igor'), 'PERSONAL_INTERACTION'),
+                                                         (3, (SELECT user_id FROM users WHERE username='client.mila'), 'ONLINE');
 
 INSERT INTO health_records (animal_id, appointment_id, type, description, date) VALUES
Index: petify-backend/src/main/java/com/petify/petify/api/VetClinicsController.java
===================================================================
--- petify-backend/src/main/java/com/petify/petify/api/VetClinicsController.java	(revision ae836471908c8a67e8fc2a25ad6c445b1c867e48)
+++ petify-backend/src/main/java/com/petify/petify/api/VetClinicsController.java	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -2,12 +2,19 @@
 
 import com.petify.petify.domain.VetClinic;
+import com.petify.petify.dto.UpdateClinicScheduleRequest;
 import com.petify.petify.dto.VetClinicDTO;
 import com.petify.petify.repo.VetClinicRepository;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestHeader;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.time.LocalTime;
+import java.time.format.DateTimeParseException;
+import java.util.Arrays;
+import java.util.Set;
 import java.util.List;
 import java.util.Map;
@@ -17,4 +24,8 @@
 @RequestMapping("/api/clinics")
 public class VetClinicsController {
+
+    private static final Set<String> ALLOWED_WORK_DAYS = Set.of(
+        "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"
+    );
 
     private final VetClinicRepository vetClinicRepository;
@@ -40,4 +51,34 @@
     }
 
+    @PutMapping("/my/schedule")
+    public ResponseEntity<?> updateMyClinicSchedule(
+        @RequestHeader("X-User-Id") Long userId,
+        @RequestBody UpdateClinicScheduleRequest request) {
+        try {
+            VetClinic clinic = vetClinicRepository.findByUserId(userId)
+                .orElseThrow(() -> new RuntimeException("User is not linked to a clinic"));
+
+            String workDays = normalizeWorkDays(request.getWorkDays());
+            LocalTime startTime = parseTime(request.getStartTime(), "Start time");
+            LocalTime endTime = parseTime(request.getEndTime(), "End time");
+
+            if (!startTime.isBefore(endTime)) {
+                throw new RuntimeException("Start time must be before end time");
+            }
+
+            if (java.time.Duration.between(startTime, endTime).toMinutes() < 30) {
+                throw new RuntimeException("Clinic schedule must contain at least one 30-minute slot");
+            }
+
+            clinic.setWorkDays(workDays);
+            clinic.setStartTime(startTime);
+            clinic.setEndTime(endTime);
+
+            return ResponseEntity.ok(mapToDTO(vetClinicRepository.save(clinic)));
+        } catch (RuntimeException e) {
+            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
+        }
+    }
+
     private VetClinicDTO mapToDTO(VetClinic clinic) {
         return new VetClinicDTO(
@@ -45,6 +86,46 @@
             clinic.getName(),
             clinic.getCity(),
-            clinic.getAddress()
+            clinic.getAddress(),
+            clinic.getWorkDays(),
+            clinic.getStartTime() != null ? clinic.getStartTime().toString() : null,
+            clinic.getEndTime() != null ? clinic.getEndTime().toString() : null
         );
+    }
+
+    private String normalizeWorkDays(String workDays) {
+        if (workDays == null || workDays.isBlank()) {
+            throw new RuntimeException("Choose at least one working day");
+        }
+
+        List<String> normalized = Arrays.stream(workDays.split(","))
+            .map(String::trim)
+            .filter(day -> !day.isBlank())
+            .map(String::toUpperCase)
+            .distinct()
+            .toList();
+
+        if (normalized.isEmpty()) {
+            throw new RuntimeException("Choose at least one working day");
+        }
+
+        for (String day : normalized) {
+            if (!ALLOWED_WORK_DAYS.contains(day)) {
+                throw new RuntimeException("Invalid working day: " + day);
+            }
+        }
+
+        return String.join(",", normalized);
+    }
+
+    private LocalTime parseTime(String value, String label) {
+        if (value == null || value.isBlank()) {
+            throw new RuntimeException(label + " is required");
+        }
+
+        try {
+            return LocalTime.parse(value);
+        } catch (DateTimeParseException e) {
+            throw new RuntimeException(label + " must be in HH:mm format");
+        }
     }
 }
Index: petify-backend/src/main/java/com/petify/petify/config/SecurityConfig.java
===================================================================
--- petify-backend/src/main/java/com/petify/petify/config/SecurityConfig.java	(revision ae836471908c8a67e8fc2a25ad6c445b1c867e48)
+++ petify-backend/src/main/java/com/petify/petify/config/SecurityConfig.java	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -96,4 +96,5 @@
                         .requestMatchers(HttpMethod.GET, "/api/clinics").permitAll()
                         .requestMatchers(HttpMethod.GET, "/api/clinics/my").permitAll()
+                        .requestMatchers(HttpMethod.PUT, "/api/clinics/my/schedule").permitAll()
                         .requestMatchers(HttpMethod.GET, "/api/notifications/my").permitAll()
 
Index: petify-backend/src/main/java/com/petify/petify/domain/UserReview.java
===================================================================
--- petify-backend/src/main/java/com/petify/petify/domain/UserReview.java	(revision ae836471908c8a67e8fc2a25ad6c445b1c867e48)
+++ petify-backend/src/main/java/com/petify/petify/domain/UserReview.java	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -19,9 +19,13 @@
     private Long targetUserId;
 
+    @Column(name = "interaction_type", nullable = false, length = 40)
+    private String interactionType;
+
     public UserReview() {}
 
-    public UserReview(Review review, Long targetUserId) {
+    public UserReview(Review review, Long targetUserId, String interactionType) {
         this.review = review;        // DO NOT set reviewId
         this.targetUserId = targetUserId;
+        this.interactionType = interactionType;
     }
 
@@ -51,4 +55,12 @@
         this.targetUserId = targetUserId;
     }
+
+    public String getInteractionType() {
+        return interactionType;
+    }
+
+    public void setInteractionType(String interactionType) {
+        this.interactionType = interactionType;
+    }
 }
 
Index: petify-backend/src/main/java/com/petify/petify/domain/VetClinic.java
===================================================================
--- petify-backend/src/main/java/com/petify/petify/domain/VetClinic.java	(revision ae836471908c8a67e8fc2a25ad6c445b1c867e48)
+++ petify-backend/src/main/java/com/petify/petify/domain/VetClinic.java	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -4,4 +4,6 @@
 import lombok.Getter;
 import lombok.Setter;
+
+import java.time.LocalTime;
 
 @Setter
@@ -37,4 +39,13 @@
     private String address;
 
+    @Column(name = "work_days")
+    private String workDays;
+
+    @Column(name = "start_time")
+    private LocalTime startTime;
+
+    @Column(name = "end_time")
+    private LocalTime endTime;
+
     public VetClinic() {}
 
Index: petify-backend/src/main/java/com/petify/petify/dto/CreateReviewRequest.java
===================================================================
--- petify-backend/src/main/java/com/petify/petify/dto/CreateReviewRequest.java	(revision ae836471908c8a67e8fc2a25ad6c445b1c867e48)
+++ petify-backend/src/main/java/com/petify/petify/dto/CreateReviewRequest.java	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -9,4 +9,5 @@
     private Integer rating;
     private String comment;
+    private String interactionType;
 
     public CreateReviewRequest() {
@@ -18,3 +19,9 @@
     }
 
+    public CreateReviewRequest(Integer rating, String comment, String interactionType) {
+        this.rating = rating;
+        this.comment = comment;
+        this.interactionType = interactionType;
+    }
+
 }
Index: petify-backend/src/main/java/com/petify/petify/dto/UpdateClinicScheduleRequest.java
===================================================================
--- petify-backend/src/main/java/com/petify/petify/dto/UpdateClinicScheduleRequest.java	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
+++ petify-backend/src/main/java/com/petify/petify/dto/UpdateClinicScheduleRequest.java	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -0,0 +1,12 @@
+package com.petify.petify.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class UpdateClinicScheduleRequest {
+    private String workDays;
+    private String startTime;
+    private String endTime;
+}
Index: petify-backend/src/main/java/com/petify/petify/dto/VetClinicDTO.java
===================================================================
--- petify-backend/src/main/java/com/petify/petify/dto/VetClinicDTO.java	(revision ae836471908c8a67e8fc2a25ad6c445b1c867e48)
+++ petify-backend/src/main/java/com/petify/petify/dto/VetClinicDTO.java	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -11,4 +11,8 @@
     private String city;
     private String address;
+    private String workDays;
+    private String startTime;
+    private String endTime;
+    private Boolean scheduleComplete;
 
     public VetClinicDTO() {
@@ -22,4 +26,23 @@
     }
 
+    public VetClinicDTO(
+        Long clinicId,
+        String name,
+        String city,
+        String address,
+        String workDays,
+        String startTime,
+        String endTime
+    ) {
+        this.clinicId = clinicId;
+        this.name = name;
+        this.city = city;
+        this.address = address;
+        this.workDays = workDays;
+        this.startTime = startTime;
+        this.endTime = endTime;
+        this.scheduleComplete = workDays != null && !workDays.isBlank() && startTime != null && endTime != null;
+    }
+
 }
 
Index: petify-backend/src/main/java/com/petify/petify/service/AppointmentService.java
===================================================================
--- petify-backend/src/main/java/com/petify/petify/service/AppointmentService.java	(revision ae836471908c8a67e8fc2a25ad6c445b1c867e48)
+++ petify-backend/src/main/java/com/petify/petify/service/AppointmentService.java	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -31,4 +31,5 @@
 import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Set;
@@ -38,6 +39,4 @@
 
     private static final Logger logger = LoggerFactory.getLogger(AppointmentService.class);
-    private static final LocalTime CLINIC_DAY_START = LocalTime.of(9, 0);
-    private static final LocalTime CLINIC_DAY_END = LocalTime.of(17, 0);
     private static final int SLOT_MINUTES = 30;
     private static final List<String> NON_BLOCKING_STATUSES = List.of("CANCELLED", "CANCELED", "NO_SHOW");
@@ -84,10 +83,9 @@
         }
 
-        if (!vetClinicRepository.existsById(request.getClinicId())) {
-            throw new RuntimeException("Vet clinic not found");
-        }
+        VetClinic clinic = vetClinicRepository.findById(request.getClinicId())
+            .orElseThrow(() -> new RuntimeException("Vet clinic not found"));
 
         LocalDateTime appointmentTime = LocalDateTime.parse(request.getDateTime());
-        if (!isClinicSlotAvailable(request.getClinicId(), appointmentTime)) {
+        if (!isClinicSlotAvailable(clinic, appointmentTime)) {
             throw new RuntimeException("Selected appointment slot is no longer available");
         }
@@ -210,10 +208,14 @@
         }
 
-        if (!vetClinicRepository.existsById(clinicId)) {
-            throw new RuntimeException("Vet clinic not found");
-        }
-
-        LocalDateTime dayStart = date.atTime(CLINIC_DAY_START);
-        LocalDateTime dayEnd = date.atTime(CLINIC_DAY_END);
+        VetClinic clinic = vetClinicRepository.findById(clinicId)
+            .orElseThrow(() -> new RuntimeException("Vet clinic not found"));
+        requireCompleteSchedule(clinic);
+
+        if (!isWorkingDay(clinic, date)) {
+            return List.of();
+        }
+
+        LocalDateTime dayStart = date.atTime(clinic.getStartTime());
+        LocalDateTime dayEnd = date.atTime(clinic.getEndTime());
         Set<LocalDateTime> bookedSlots = appointmentRepository
             .findByClinicIdAndDateTimeBetweenAndStatusNotInOrderByDateTimeAsc(
@@ -257,10 +259,14 @@
         }
 
-        if (!vetClinicRepository.existsById(clinicId)) {
-            throw new RuntimeException("Vet clinic not found");
-        }
-
-        LocalDateTime dayStart = date.atTime(CLINIC_DAY_START);
-        LocalDateTime dayEnd = date.atTime(CLINIC_DAY_END);
+        VetClinic clinic = vetClinicRepository.findById(clinicId)
+            .orElseThrow(() -> new RuntimeException("Vet clinic not found"));
+        requireCompleteSchedule(clinic);
+
+        if (!isWorkingDay(clinic, date)) {
+            return List.of();
+        }
+
+        LocalDateTime dayStart = date.atTime(clinic.getStartTime());
+        LocalDateTime dayEnd = date.atTime(clinic.getEndTime());
 
         return unavailableSlotRepository
@@ -282,11 +288,10 @@
         }
 
-        if (!vetClinicRepository.existsById(clinicId)) {
-            throw new RuntimeException("Vet clinic not found");
-        }
+        VetClinic clinic = vetClinicRepository.findById(clinicId)
+            .orElseThrow(() -> new RuntimeException("Vet clinic not found"));
 
         LocalDateTime slotTime = LocalDateTime.parse(request.getDateTime());
-        if (!isValidWorkingSlot(slotTime)) {
-            throw new RuntimeException("Unavailable slot must be a future 30-minute slot between 09:00 and 17:00");
+        if (!isValidWorkingSlot(clinic, slotTime)) {
+            throw new RuntimeException("Unavailable slot must be a future 30-minute slot inside your clinic working schedule");
         }
 
@@ -332,24 +337,49 @@
     }
 
-    private boolean isClinicSlotAvailable(Long clinicId, LocalDateTime appointmentTime) {
-        if (!isValidWorkingSlot(appointmentTime)) {
+    private boolean isClinicSlotAvailable(VetClinic clinic, LocalDateTime appointmentTime) {
+        if (!isValidWorkingSlot(clinic, appointmentTime)) {
             return false;
         }
 
         return !appointmentRepository.existsByClinicIdAndDateTimeAndStatusNotIn(
-            clinicId,
+            clinic.getClinicId(),
             appointmentTime,
             NON_BLOCKING_STATUSES
-        ) && !unavailableSlotRepository.existsByClinicIdAndDateTime(clinicId, appointmentTime);
-    }
-
-    private boolean isValidWorkingSlot(LocalDateTime appointmentTime) {
+        ) && !unavailableSlotRepository.existsByClinicIdAndDateTime(clinic.getClinicId(), appointmentTime);
+    }
+
+    private boolean isValidWorkingSlot(VetClinic clinic, LocalDateTime appointmentTime) {
+        requireCompleteSchedule(clinic);
         LocalTime time = appointmentTime.toLocalTime();
-        return !appointmentTime.isBefore(LocalDateTime.now())
-            && !time.isBefore(CLINIC_DAY_START)
-            && time.isBefore(CLINIC_DAY_END)
-            && appointmentTime.getMinute() % SLOT_MINUTES == 0
+        long minutesFromStart = java.time.Duration.between(clinic.getStartTime(), time).toMinutes();
+
+        return isWorkingDay(clinic, appointmentTime.toLocalDate())
+            && !appointmentTime.isBefore(LocalDateTime.now())
+            && !time.isBefore(clinic.getStartTime())
+            && time.isBefore(clinic.getEndTime())
+            && minutesFromStart >= 0
+            && minutesFromStart % SLOT_MINUTES == 0
             && appointmentTime.getSecond() == 0
             && appointmentTime.getNano() == 0;
+    }
+
+    private void requireCompleteSchedule(VetClinic clinic) {
+        if (clinic.getWorkDays() == null || clinic.getWorkDays().isBlank()
+            || clinic.getStartTime() == null
+            || clinic.getEndTime() == null) {
+            throw new RuntimeException("This clinic has not added working days and hours yet");
+        }
+
+        if (!clinic.getStartTime().isBefore(clinic.getEndTime())) {
+            throw new RuntimeException("Clinic working hours are invalid");
+        }
+    }
+
+    private boolean isWorkingDay(VetClinic clinic, LocalDate date) {
+        String day = date.getDayOfWeek().name();
+        return Arrays.stream(clinic.getWorkDays().split(","))
+            .map(String::trim)
+            .map(String::toUpperCase)
+            .anyMatch(day::equals);
     }
 
Index: petify-backend/src/main/java/com/petify/petify/service/ReviewService.java
===================================================================
--- petify-backend/src/main/java/com/petify/petify/service/ReviewService.java	(revision ae836471908c8a67e8fc2a25ad6c445b1c867e48)
+++ petify-backend/src/main/java/com/petify/petify/service/ReviewService.java	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -19,4 +19,5 @@
 
 import java.time.LocalDateTime;
+import java.util.Set;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -26,4 +27,11 @@
 
     private static final Logger logger = LoggerFactory.getLogger(ReviewService.class);
+    private static final Set<String> USER_REVIEW_INTERACTION_TYPES = Set.of(
+            "EVENT",
+            "PERSONAL_INTERACTION",
+            "ONLINE",
+            "PHONE_CALL",
+            "OTHER"
+    );
 
     private final ReviewRepository reviewRepository;
@@ -58,9 +66,6 @@
     public ReviewDTO createReview(Long reviewerId, Long targetUserId, CreateReviewRequest request) {
         logger.info("==== START createReview ====");
-        // Validate rating
-        if (request.getRating() == null || request.getRating() < 1 || request.getRating() > 5) {
-            logger.error(" VALIDATION FAILED: Invalid rating: {}", request.getRating());
-            throw new RuntimeException("Rating must be between 1 and 5");
-        }
+        validateReviewRequest(request);
+        String interactionType = normalizeUserReviewInteractionType(request.getInteractionType());
 
 
@@ -118,4 +123,5 @@
 
         userReview.setTargetUserId(targetUserId);
+        userReview.setInteractionType(interactionType);
 
         // Save UserReview to database with flush
@@ -285,4 +291,17 @@
     }
 
+    private String normalizeUserReviewInteractionType(String interactionType) {
+        if (interactionType == null || interactionType.isBlank()) {
+            throw new RuntimeException("Please choose how you interacted with this user");
+        }
+
+        String normalized = interactionType.trim().toUpperCase();
+        if (!USER_REVIEW_INTERACTION_TYPES.contains(normalized)) {
+            throw new RuntimeException("Interaction type must be one of: EVENT, PERSONAL_INTERACTION, ONLINE, PHONE_CALL, OTHER");
+        }
+
+        return normalized;
+    }
+
     private User getReviewer(Long reviewerId) {
         return userRepository.findById(reviewerId)
Index: petify-backend/src/main/resources/db/migration/V11__Add_user_review_interaction_type.sql
===================================================================
--- petify-backend/src/main/resources/db/migration/V11__Add_user_review_interaction_type.sql	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
+++ petify-backend/src/main/resources/db/migration/V11__Add_user_review_interaction_type.sql	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -0,0 +1,17 @@
+ALTER TABLE user_reviews
+    ADD COLUMN IF NOT EXISTS interaction_type VARCHAR(40);
+
+UPDATE user_reviews
+SET interaction_type = 'OTHER'
+WHERE interaction_type IS NULL;
+
+ALTER TABLE user_reviews
+    ALTER COLUMN interaction_type SET NOT NULL;
+
+ALTER TABLE user_reviews
+    DROP CONSTRAINT IF EXISTS user_reviews_interaction_type_CHK;
+
+ALTER TABLE user_reviews
+    ADD CONSTRAINT user_reviews_interaction_type_CHK CHECK (
+        interaction_type IN ('EVENT', 'PERSONAL_INTERACTION', 'ONLINE', 'PHONE_CALL', 'OTHER')
+    );
Index: petify-backend/src/main/resources/db/migration/V12__Add_clinic_work_schedule.sql
===================================================================
--- petify-backend/src/main/resources/db/migration/V12__Add_clinic_work_schedule.sql	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
+++ petify-backend/src/main/resources/db/migration/V12__Add_clinic_work_schedule.sql	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -0,0 +1,8 @@
+ALTER TABLE vet_clinics
+    ADD COLUMN IF NOT EXISTS work_days VARCHAR(120);
+
+ALTER TABLE vet_clinics
+    ADD COLUMN IF NOT EXISTS start_time TIME;
+
+ALTER TABLE vet_clinics
+    ADD COLUMN IF NOT EXISTS end_time TIME;
Index: petify-frontend/src/api/profile.ts
===================================================================
--- petify-frontend/src/api/profile.ts	(revision ae836471908c8a67e8fc2a25ad6c445b1c867e48)
+++ petify-frontend/src/api/profile.ts	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -35,4 +35,8 @@
   city: string
   address: string
+  workDays?: string
+  startTime?: string
+  endTime?: string
+  scheduleComplete?: boolean
 }
 
@@ -464,4 +468,30 @@
 }
 
+export async function updateMyClinicSchedule(
+  userId: number,
+  data: {
+    workDays: string
+    startTime: string
+    endTime: string
+  }
+): Promise<VetClinic> {
+  const url = joinUrl(getBaseUrl(), `/api/clinics/my/schedule`)
+  const response = await fetch(url, {
+    method: 'PUT',
+    headers: {
+      'Content-Type': 'application/json',
+      'X-User-Id': String(userId),
+    },
+    body: JSON.stringify(data),
+  })
+
+  if (!response.ok) {
+    const error = await response.json()
+    throw new Error(error.error || `Failed to update clinic schedule: ${response.statusText}`)
+  }
+
+  return await response.json()
+}
+
 export async function getClinicAvailableSlots(clinicId: number, date: string): Promise<AppointmentSlot[]> {
   const url = joinUrl(getBaseUrl(), `/api/appointments/clinics/${clinicId}/available-slots?date=${encodeURIComponent(date)}`)
Index: petify-frontend/src/api/reviews.ts
===================================================================
--- petify-frontend/src/api/reviews.ts	(revision ae836471908c8a67e8fc2a25ad6c445b1c867e48)
+++ petify-frontend/src/api/reviews.ts	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -20,9 +20,17 @@
 }
 
+export type UserReviewInteractionType =
+  | 'EVENT'
+  | 'PERSONAL_INTERACTION'
+  | 'ONLINE'
+  | 'PHONE_CALL'
+  | 'OTHER'
+
 export async function createReview(
   targetUserId: number,
   userId: number,
   rating: number,
-  comment: string
+  comment: string,
+  interactionType: UserReviewInteractionType
 ): Promise<Review> {
   const url = joinUrl(getBaseUrl(), `/api/reviews/${targetUserId}`)
@@ -36,4 +44,5 @@
       rating,
       comment,
+      interactionType,
     }),
   })
Index: petify-frontend/src/views/ClinicDashboardView.vue
===================================================================
--- petify-frontend/src/views/ClinicDashboardView.vue	(revision ae836471908c8a67e8fc2a25ad6c445b1c867e48)
+++ petify-frontend/src/views/ClinicDashboardView.vue	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -8,5 +8,5 @@
           <p v-if="clinic" class="clinic-subtitle">{{ clinic.name }} - {{ clinic.city }}, {{ clinic.address }}</p>
         </div>
-        <div class="toolbar">
+        <div v-if="canUseSchedule" class="toolbar">
           <button class="btn btn-outline-secondary btn-sm" type="button" @click="goToPreviousDay">
             Previous day
@@ -34,4 +34,45 @@
 
       <template v-else>
+        <section v-if="clinic && !canUseSchedule" class="setup-panel">
+          <div>
+            <p class="eyebrow">Required setup</p>
+            <h2>Add your working schedule</h2>
+            <p class="setup-copy">
+              Users can book appointment slots only after your clinic adds working days and opening hours.
+            </p>
+          </div>
+
+          <form class="schedule-form" @submit.prevent="saveSchedule">
+            <fieldset class="days-fieldset">
+              <legend>Working days</legend>
+              <label v-for="day in workDayOptions" :key="day.value" class="day-check">
+                <input
+                  v-model="scheduleForm.workDays"
+                  type="checkbox"
+                  :value="day.value"
+                />
+                <span>{{ day.label }}</span>
+              </label>
+            </fieldset>
+
+            <div class="time-grid">
+              <div class="form-group">
+                <label class="form-label" for="startTime">Start time</label>
+                <input id="startTime" v-model="scheduleForm.startTime" class="form-control" type="time" required />
+              </div>
+              <div class="form-group">
+                <label class="form-label" for="endTime">End time</label>
+                <input id="endTime" v-model="scheduleForm.endTime" class="form-control" type="time" required />
+              </div>
+            </div>
+
+            <div v-if="scheduleSetupError" class="alert alert-danger">{{ scheduleSetupError }}</div>
+            <button class="btn btn-primary" type="submit" :disabled="isSavingSchedule">
+              {{ isSavingSchedule ? 'Saving...' : 'Save schedule' }}
+            </button>
+          </form>
+        </section>
+
+        <template v-else>
         <div class="summary-strip">
           <div class="summary-item">
@@ -59,4 +100,7 @@
 
             <div class="slot-grid">
+              <div v-if="daySlots.length === 0" class="panel-empty full-width">
+                This is not a working day for your clinic.
+              </div>
               <div
                 v-for="slot in daySlots"
@@ -131,4 +175,5 @@
           </aside>
         </div>
+        </template>
       </template>
     </section>
@@ -147,4 +192,5 @@
   getMyNotifications,
   markMyClinicAppointmentNoShow,
+  updateMyClinicSchedule,
   type AppNotification,
   type AppointmentSlot,
@@ -174,7 +220,9 @@
 const notifications = ref<AppNotification[]>([])
 const isLoading = ref(false)
+const isSavingSchedule = ref(false)
 const updatingAppointmentId = ref<number | null>(null)
 const accessError = ref('')
 const scheduleError = ref('')
+const scheduleSetupError = ref('')
 const notificationsError = ref('')
 const NON_BLOCKING_STATUSES = new Set(['CANCELLED', 'CANCELED', 'NO_SHOW'])
@@ -182,4 +230,19 @@
 
 const canUseDashboard = computed(() => auth.isAuthenticated && auth.user?.userType === 'CLINIC')
+const canUseSchedule = computed(() => Boolean(clinic.value?.scheduleComplete))
+const scheduleForm = ref({
+  workDays: [] as string[],
+  startTime: '09:00',
+  endTime: '17:00',
+})
+const workDayOptions = [
+  { value: 'MONDAY', label: 'Mon' },
+  { value: 'TUESDAY', label: 'Tue' },
+  { value: 'WEDNESDAY', label: 'Wed' },
+  { value: 'THURSDAY', label: 'Thu' },
+  { value: 'FRIDAY', label: 'Fri' },
+  { value: 'SATURDAY', label: 'Sat' },
+  { value: 'SUNDAY', label: 'Sun' },
+]
 
 const appointmentsByDateTime = computed(() => {
@@ -205,8 +268,7 @@
   const now = new Date()
 
-  for (let hour = 9; hour < 17; hour += 1) {
-    for (const minute of [0, 30]) {
-      const dateTime = `${selectedDate.value}T${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`
-      const label = `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`
+  for (const time of getClinicTimesForDate(selectedDate.value)) {
+      const dateTime = `${selectedDate.value}T${time}`
+      const label = time
       const key = normalizeDateTime(dateTime)
       const appointment = appointmentsByDateTime.value.get(key)
@@ -252,5 +314,4 @@
         })
       }
-    }
   }
 
@@ -274,7 +335,6 @@
   const slots: AppointmentSlot[] = []
 
-  for (let hour = 9; hour < 17; hour += 1) {
-    for (const minute of [0, 30]) {
-      const dateTime = `${date}T${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`
+  for (const time of getClinicTimesForDate(date)) {
+      const dateTime = `${date}T${time}`
       const key = normalizeDateTime(dateTime)
       if (new Date(dateTime).getTime() < now.getTime()) continue
@@ -282,7 +342,6 @@
       slots.push({
         dateTime,
-        label: `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`,
+        label: time,
       })
-    }
   }
 
@@ -291,5 +350,5 @@
 
 async function loadSchedule() {
-  if (!auth.user?.userId || !canUseDashboard.value || !selectedDate.value) return
+  if (!auth.user?.userId || !canUseDashboard.value || !canUseSchedule.value || !selectedDate.value) return
 
   const requestId = ++latestScheduleRequest
@@ -319,4 +378,38 @@
 }
 
+async function saveSchedule() {
+  if (!auth.user?.userId) return
+  if (scheduleForm.value.workDays.length === 0) {
+    scheduleSetupError.value = 'Choose at least one working day'
+    return
+  }
+
+  if (!scheduleForm.value.startTime || !scheduleForm.value.endTime) {
+    scheduleSetupError.value = 'Start and end time are required'
+    return
+  }
+
+  if (scheduleForm.value.startTime >= scheduleForm.value.endTime) {
+    scheduleSetupError.value = 'Start time must be before end time'
+    return
+  }
+
+  try {
+    isSavingSchedule.value = true
+    scheduleSetupError.value = ''
+    clinic.value = await updateMyClinicSchedule(auth.user.userId, {
+      workDays: scheduleForm.value.workDays.join(','),
+      startTime: scheduleForm.value.startTime,
+      endTime: scheduleForm.value.endTime,
+    })
+    hydrateScheduleForm()
+    await loadSchedule()
+  } catch (error) {
+    scheduleSetupError.value = error instanceof Error ? error.message : 'Failed to save clinic schedule'
+  } finally {
+    isSavingSchedule.value = false
+  }
+}
+
 async function loadNotifications() {
   if (!auth.user?.userId || !canUseDashboard.value) return
@@ -417,4 +510,45 @@
 }
 
+function hydrateScheduleForm() {
+  scheduleForm.value = {
+    workDays: clinic.value?.workDays ? clinic.value.workDays.split(',').map((day) => day.trim()).filter(Boolean) : [],
+    startTime: clinic.value?.startTime?.slice(0, 5) || '09:00',
+    endTime: clinic.value?.endTime?.slice(0, 5) || '17:00',
+  }
+}
+
+function getClinicTimesForDate(date: string): string[] {
+  if (!clinic.value?.workDays || !clinic.value.startTime || !clinic.value.endTime) return []
+  if (!isClinicWorkingDay(date)) return []
+
+  const times: string[] = []
+  const start = timeToMinutes(clinic.value.startTime)
+  const end = timeToMinutes(clinic.value.endTime)
+
+  for (let minutes = start; minutes < end; minutes += 30) {
+    times.push(minutesToTime(minutes))
+  }
+
+  return times
+}
+
+function isClinicWorkingDay(date: string): boolean {
+  const day = new Date(`${date}T00:00:00`).toLocaleDateString('en-US', { weekday: 'long' }).toUpperCase()
+  return clinic.value?.workDays?.split(',').map((item) => item.trim().toUpperCase()).includes(day) ?? false
+}
+
+function timeToMinutes(time: string): number {
+  const parts = time.slice(0, 5).split(':').map(Number)
+  const hours = parts[0] ?? 0
+  const minutes = parts[1] ?? 0
+  return hours * 60 + minutes
+}
+
+function minutesToTime(total: number): string {
+  const hours = Math.floor(total / 60)
+  const minutes = total % 60
+  return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`
+}
+
 function formatDateTime(value: string): string {
   return new Date(value).toLocaleString('en-US', {
@@ -439,4 +573,5 @@
   try {
     clinic.value = await getMyClinic(auth.user.userId)
+    hydrateScheduleForm()
     accessError.value = ''
   } catch (error) {
@@ -445,5 +580,9 @@
   }
 
-  await Promise.all([loadSchedule(), loadNotifications()])
+  if (canUseSchedule.value) {
+    await Promise.all([loadSchedule(), loadNotifications()])
+  } else {
+    await loadNotifications()
+  }
 })
 
@@ -510,5 +649,6 @@
 .summary-strip,
 .schedule-section,
-.appointments-panel {
+.appointments-panel,
+.setup-panel {
   background: white;
   border: 1px solid #e2e8f0;
@@ -529,4 +669,75 @@
   color: #718096;
   margin: 0;
+}
+
+.setup-panel {
+  display: grid;
+  gap: 24px;
+  padding: 28px;
+}
+
+.setup-panel h2 {
+  color: #1a202c;
+  font-size: 1.45rem;
+  margin: 0 0 8px;
+}
+
+.setup-copy {
+  color: #718096;
+  margin: 0;
+}
+
+.schedule-form {
+  display: grid;
+  gap: 20px;
+  max-width: 720px;
+}
+
+.days-fieldset {
+  border: 0;
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px;
+  margin: 0;
+  padding: 0;
+}
+
+.days-fieldset legend {
+  color: #2d3748;
+  font-weight: 700;
+  margin-bottom: 8px;
+  width: 100%;
+}
+
+.day-check {
+  align-items: center;
+  border: 1px solid #cbd5e0;
+  border-radius: 8px;
+  cursor: pointer;
+  display: inline-flex;
+  gap: 8px;
+  padding: 9px 12px;
+}
+
+.day-check:has(input:checked) {
+  background: #fff7ed;
+  border-color: #f97316;
+  color: #9a3412;
+}
+
+.time-grid {
+  display: grid;
+  grid-template-columns: repeat(2, minmax(0, 180px));
+  gap: 16px;
+}
+
+.form-group {
+  display: grid;
+  gap: 8px;
+}
+
+.form-label {
+  color: #2d3748;
+  font-weight: 700;
 }
 
@@ -625,4 +836,8 @@
 }
 
+.full-width {
+  grid-column: 1 / -1;
+}
+
 .slot-card {
   border: 1px solid #e2e8f0;
Index: petify-frontend/src/views/OwnerProfileView.vue
===================================================================
--- petify-frontend/src/views/OwnerProfileView.vue	(revision ae836471908c8a67e8fc2a25ad6c445b1c867e48)
+++ petify-frontend/src/views/OwnerProfileView.vue	(revision f6ed6e478015d417b9610fe651dfccdc3e22dc89)
@@ -208,4 +208,23 @@
 
                   <div class="form-group">
+                    <label class="form-label" for="interactionType">How did you interact?</label>
+                    <select
+                      id="interactionType"
+                      v-model="newReview.interactionType"
+                      class="form-control"
+                      required
+                    >
+                      <option value="" disabled>Select an option</option>
+                      <option
+                        v-for="option in interactionTypeOptions"
+                        :key="option.value"
+                        :value="option.value"
+                      >
+                        {{ option.label }}
+                      </option>
+                    </select>
+                  </div>
+
+                  <div class="form-group">
                     <label class="form-label" for="comment">Comment</label>
                     <textarea
@@ -226,5 +245,5 @@
                       type="submit"
                       class="btn btn-primary"
-                      :disabled="isSubmittingReview || newReview.rating === 0"
+                      :disabled="isSubmittingReview || newReview.rating === 0 || !newReview.interactionType"
                     >
                       <span v-if="isSubmittingReview">Submitting...</span>
@@ -287,5 +306,10 @@
 import { useRoute, RouterLink } from 'vue-router'
 import { getUserProfile, getUserListings, getUserPets, loadUserVerificationStatus } from '../api/profile'
-import { createReview, getReviewsByOwner, deleteReview as deleteReviewAPI } from '../api/reviews'
+import {
+  createReview,
+  getReviewsByOwner,
+  deleteReview as deleteReviewAPI,
+  type UserReviewInteractionType,
+} from '../api/reviews'
 import { useAuthStore } from '../stores/auth'
 
@@ -305,7 +329,20 @@
 const isSubmittingReview = ref(false)
 const reviewError = ref<string | null>(null)
-const newReview = ref({
+const interactionTypeOptions: Array<{ value: UserReviewInteractionType; label: string }> = [
+  { value: 'EVENT', label: 'Met at an event' },
+  { value: 'PERSONAL_INTERACTION', label: 'Personal interaction' },
+  { value: 'ONLINE', label: 'Online interaction' },
+  { value: 'PHONE_CALL', label: 'Phone call' },
+  { value: 'OTHER', label: 'Other' },
+]
+
+const newReview = ref<{
+  rating: number
+  comment: string
+  interactionType: UserReviewInteractionType | ''
+}>({
   rating: 0,
   comment: '',
+  interactionType: '',
 })
 
@@ -445,4 +482,9 @@
   }
 
+  if (!newReview.value.interactionType) {
+    reviewError.value = 'Please choose how you interacted with this user'
+    return
+  }
+
   isSubmittingReview.value = true
   reviewError.value = null
@@ -453,5 +495,6 @@
       auth.user.userId,
       newReview.value.rating,
-      newReview.value.comment
+      newReview.value.comment,
+      newReview.value.interactionType
     )
 
@@ -459,4 +502,5 @@
     newReview.value.rating = 0
     newReview.value.comment = ''
+    newReview.value.interactionType = ''
     await loadReviews()
   } catch (err) {
