Index: springapp/pom.xml
===================================================================
--- springapp/pom.xml	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/pom.xml	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -30,4 +30,5 @@
 			<artifactId>spring-boot-starter-web</artifactId>
 		</dependency>
+
 		<dependency>
 			<groupId>org.postgresql</groupId>
@@ -62,5 +63,4 @@
 			<scope>compile</scope>
 		</dependency>
-		
 	</dependencies>
 
Index: springapp/src/main/java/mk/profesori/springapp/Controller/PublicController.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Controller/PublicController.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Controller/PublicController.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,8 +1,3 @@
 package mk.profesori.springapp.Controller;
-
-import mk.profesori.springapp.Model.*;
-import mk.profesori.springapp.Service.MainService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
 
 import java.util.Collections;
@@ -11,7 +6,22 @@
 import java.util.Optional;
 
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import mk.profesori.springapp.Model.City;
+import mk.profesori.springapp.Model.Faculty;
+import mk.profesori.springapp.Model.Professor;
+import mk.profesori.springapp.Model.StudyProgramme;
+import mk.profesori.springapp.Model.University;
+import mk.profesori.springapp.Service.MainService;
+
 @RestController
 @RequestMapping("/public")
-@CrossOrigin(origins = { "http://192.168.1.108:3000", "http://192.168.0.28:3000" })
+@CrossOrigin(origins = { "http://192.168.0.17:3000", "http://192.168.0.24:3000" })
 public class PublicController {
 
@@ -30,11 +40,6 @@
     @RequestMapping(value = "/professors/nameContains/{contained}", method = RequestMethod.GET)
     public List<Professor> getProfessorsByNameContains(@PathVariable String contained) {
-        return mainService.getProfessorsByNameContains(contained); // vrakja profesori sto sodrzat "contained" vo imeto
-
-    }
-
-    @RequestMapping(value = "/subjects/nameContains/{contained}", method = RequestMethod.GET)
-    public List<Subject> getSubjectsByNameContains(@PathVariable String contained) {
-        return mainService.getSubjectsByNameContains(contained); // vrakja predmeti sto sodrzat "contained" vo imeto
+        return mainService.getProfessorsByNameContains(contained); // vrakja profesori sto sodrzat "contained" vo
+                                                                   // professorName
     }
 
@@ -42,9 +47,4 @@
     public Professor getProfessorById(@PathVariable Long professorId) {
         return mainService.getProfessorById(professorId); // vrakja profesor spored id
-    }
-
-    @RequestMapping(value="/professor/{professorId}/relatedOpinions", method = RequestMethod.GET)
-    public List<Opinion> getRelatedOpinions(@PathVariable Long professorId) {
-        return mainService.getRelatedOpinions(professorId);
     }
 
@@ -98,19 +98,4 @@
     }
 
-    @RequestMapping(value = "/subject/{subjectId}", method = RequestMethod.GET)
-    public Subject getSubjectById(@PathVariable Long subjectId) {
-        return mainService.getSubjectById(subjectId); // vrakja predmet spored id
-    }
-
-    @RequestMapping(value = "/subjects", method = RequestMethod.GET)
-    public List<Subject> getSubjectsByStudyProgramme(@RequestParam Long studyProgrammeId) {
-        return mainService.getSubjectsByStudyProgramme(studyProgrammeId);
-    }
-
-    @RequestMapping(value = "/thread/{postId}", method = RequestMethod.GET)
-    public _Thread getThreadById(@PathVariable Long postId) {
-        return mainService.get_ThreadById(postId); // vrakja thread (tema) spored id
-    }
-
     @RequestMapping(value = "/loginSuccessRegular", method = RequestMethod.GET)
     public Map<String, String> loginSuccessRegular(@RequestParam String sessionId) {
@@ -122,39 +107,3 @@
         return Collections.singletonMap("sessionId", sessionId);
     }
-
-    @RequestMapping(value = "/latest10opinions", method = RequestMethod.GET)
-    public List<Opinion> latest10opinions() {
-        return mainService.getLatest10Opinions();
-    }
-
-    @RequestMapping(value = "/latest10threads", method = RequestMethod.GET)
-    public List<_Thread> latest10threads() {
-        return mainService.getLatest10Threads();
-    }
-
-    @RequestMapping(value = "/subject/{id}/threads")
-    public List<_Thread> getThreadsBySubject(@PathVariable Long id) {
-        return mainService.getThreadsBySubject(id);
-    }
-
-    @RequestMapping(value = "/university/{id}/sectionAndPostCount")
-    public List<String> getUniversitySectionCount(@PathVariable Long id) {
-        return mainService.getUniversitySectionAndPostCount();
-    }
-
-    @RequestMapping(value = "/faculty/{id}/opinionCountForEachProfessor")
-    public List<String> getOpinionCountForEachProfessorInFaculty(@PathVariable Long id) {
-        return mainService.getOpinionCountForEachProfessorInFaculty(id);
-    }
-
-    @RequestMapping(value = "/study_programme/{id}/threadCountForEachSubject")
-    public List<String> getThreadCountForEachSubjectInStudyProgramme(@PathVariable Long id) {
-        return mainService.getThreadCountForEachSubjectInStudyProgramme(id);
-    }
-
-    @RequestMapping(value = "/user/{id}")
-    public CustomUserDetails getPublicUserProfile(@PathVariable Long id) {
-        return mainService.getPublicUserProfile(id);
-    }
-
 }
Index: springapp/src/main/java/mk/profesori/springapp/Controller/SecureController.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Controller/SecureController.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Controller/SecureController.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,43 +1,47 @@
 package mk.profesori.springapp.Controller;
 
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import mk.profesori.springapp.Model.CustomUserDetails;
-import mk.profesori.springapp.Model.Post;
-import mk.profesori.springapp.Model.PostReport;
-import mk.profesori.springapp.Model.UserRole;
-import mk.profesori.springapp.Service.CustomUserDetailsService;
-import mk.profesori.springapp.Service.Exception.DisallowedOperationException;
-import mk.profesori.springapp.Service.Exception.IncompatiblePostId;
-import mk.profesori.springapp.Service.MainService;
-import org.apache.tomcat.websocket.AuthenticationException;
+import java.util.Collections;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.annotation.CurrentSecurityContext;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 
-import java.util.List;
-import java.util.Set;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import mk.profesori.springapp.Model.CustomUserDetails;
+import mk.profesori.springapp.Service.CustomUserDetailsService;
+import mk.profesori.springapp.Service.MainService;
 
 @RestController
 @RequestMapping("/secure")
-@CrossOrigin(origins = { "http://192.168.1.108:3000", "http://192.168.0.28:3000" })
+@CrossOrigin(origins = { "http://192.168.0.17:3000", "http://192.168.0.24:3000" })
 public class SecureController {
 
-    private final MainService mainService;
-    final CustomUserDetailsService customUserDetailsService;
-
-    public SecureController(MainService mainService, CustomUserDetailsService customUserDetailsService) {
-        this.mainService = mainService;
-        this.customUserDetailsService = customUserDetailsService;
-    }
+    @Autowired
+    private MainService mainService;
+    @Autowired
+    CustomUserDetailsService customUserDetailsService;
 
     @RequestMapping(value = "/professor/{professorId}/addOpinion", method = RequestMethod.POST)
     public void addOpinion(@RequestBody ObjectNode objectNode, @PathVariable Long professorId,
             @CurrentSecurityContext SecurityContext context) {
+
         Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
+
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails) {
+            CustomUserDetails currentUser = (CustomUserDetails) authentication.getPrincipal();
+            String title = objectNode.get("title").asText();
             String content = objectNode.get("content").asText();
-            mainService.addOpinion(content, professorId, currentUser);
+            mainService.addOpinion(title, content, professorId, currentUser);
         }
     }
@@ -46,6 +50,9 @@
     public void replyToOpinion(@RequestBody ObjectNode objectNode, @PathVariable Long professorId,
             @PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
+
         Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
+
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails) {
+            CustomUserDetails currentUser = (CustomUserDetails) authentication.getPrincipal();
             String content = objectNode.get("content").asText();
             mainService.replyToOpinion(content, professorId, postId, currentUser);
@@ -53,110 +60,11 @@
     }
 
-    @RequestMapping(value = "/subject/{subjectId}/addThread", method = RequestMethod.POST)
-    public void addThread(@RequestBody ObjectNode objectNode, @PathVariable Long subjectId,
-            @CurrentSecurityContext SecurityContext context) {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
-            String title = objectNode.get("title").asText();
-            String content = objectNode.get("content").asText();
-            mainService.addThread(title, content, subjectId, currentUser);
-        }
-    }
-
-    @RequestMapping(value = "/subject/{subjectId}/replyToThread/{postId}", method = RequestMethod.POST)
-    public void replyToThread(@RequestBody ObjectNode objectNode, @PathVariable Long subjectId,
-            @PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
-            String content = objectNode.get("content").asText();
-            mainService.replyToThread(content, subjectId, postId, currentUser);
-        }
-    }
-
     @RequestMapping(value = "/currentUser", method = RequestMethod.GET)
     public UserDetails getUserDetails(@CurrentSecurityContext SecurityContext context) {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
-            return customUserDetailsService.loadUserByUsername(currentUser.getEmail());
-        }
-        return null;
-    }
-
-    @RequestMapping(value = "/currentUser/posts", method = RequestMethod.GET)
-    public Set<Post> getPostsByUser(@CurrentSecurityContext SecurityContext context) {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
-            return mainService.getPostsByUser(currentUser.getEmail());
-        }
-        return null;
-    }
-
-    @RequestMapping(value = "/upvoteOpinion/{postId}", method = RequestMethod.GET)
-    public void upvoteOpinion(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
-            mainService.upvoteOpinion(postId, currentUser);
-        }
-    }
-
-    @RequestMapping(value = "/downvoteOpinion/{postId}", method = RequestMethod.GET)
-    public void downvoteOpinion(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
-            mainService.downvoteOpinion(postId, currentUser);
-        }
-    }
-
-    @RequestMapping(value = "/upvoteThread/{postId}", method = RequestMethod.GET)
-    public void upvoteThread(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
-            mainService.upvote_Thread(postId, currentUser);
-        }
-    }
-
-    @RequestMapping(value = "/downvoteThread/{postId}", method = RequestMethod.GET)
-    public void downvoteThread(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
 
         Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
-            mainService.downvote_Thread(postId, currentUser);
-        }
-    }
-
-    @RequestMapping(value = "/deleteOpinion/{postId}", method = RequestMethod.DELETE)
-    public void deleteOpinion(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context)
-            throws Exception {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
-                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
-            mainService.deleteOpinion(postId);
-        } else
-            throw new AuthenticationException("Auth exception");
-    }
-
-    @RequestMapping(value = "/deleteThread/{postId}", method = RequestMethod.DELETE)
-    public void deleteThread(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
-                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
-            mainService.delete_Thread(postId);
-        }
-    }
-
-    @RequestMapping(value = "/updateOpinion/{postId}", method = RequestMethod.PUT)
-    public String updateOpinion(@RequestBody ObjectNode objectNode, @PathVariable Long postId,
-            @CurrentSecurityContext SecurityContext context) {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
-                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
-            String newContent = objectNode.get("newContent").asText();
-            Long newTargetProfessorId = objectNode.get("newTargetProfessorId").asLong();
-            Long newParentPostId = objectNode.get("newParentPostId").asLong();
-            try {
-                mainService.updateOpinion(newContent, newTargetProfessorId, newParentPostId, postId);
-            } catch (IncompatiblePostId | DisallowedOperationException e) {
-                return e.getMessage();
-            }
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails) {
+            CustomUserDetails currentUser = (CustomUserDetails) authentication.getPrincipal();
+            return customUserDetailsService.loadUserByUsername(currentUser.getEmail());
         }
 
@@ -164,102 +72,27 @@
     }
 
-    @RequestMapping(value = "/updateThread/{postId}", method = RequestMethod.PUT)
-    public String updateThread(@RequestBody ObjectNode objectNode, @PathVariable Long postId,
-            @CurrentSecurityContext SecurityContext context) {
+    @RequestMapping(value = "/professor/{professorId}/upvoteOpinion/{postId}", method = RequestMethod.GET)
+    public void upvoteOpinion(@PathVariable Long professorId,
+            @PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
+
         Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
-                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
-            String newTitle = objectNode.get("newTitle").asText();
-            String newContent = objectNode.get("newContent").asText();
-            Long newTargetSubjectId = objectNode.get("newTargetSubjectId").asLong();
-            Long newParentThreadId = objectNode.get("newParentThreadId").asLong();
-            try {
-                mainService.update_Thread(newTitle, newContent, newTargetSubjectId, newParentThreadId, postId);
-            } catch (IncompatiblePostId | DisallowedOperationException e) {
-                return e.getMessage();
-            }
-        }
 
-        return null;
-    }
-
-    @RequestMapping(value = "/lockUser/{userId}", method = RequestMethod.GET)
-    public void lockUser(@PathVariable Long userId, @CurrentSecurityContext SecurityContext context) {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
-                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
-            mainService.lockUser(userId);
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails) {
+            CustomUserDetails currentUser = (CustomUserDetails) authentication.getPrincipal();
+            mainService.upvoteOpinion(postId, currentUser);
         }
     }
 
-    @RequestMapping(value = "/deleteUser/{userId}", method = RequestMethod.DELETE)
-    public void deleteUser(@PathVariable Long userId, @CurrentSecurityContext SecurityContext context) {
+    @RequestMapping(value = "/professor/{professorId}/downvoteOpinion/{postId}", method = RequestMethod.GET)
+    public void downvoteOpinion(@PathVariable Long professorId,
+            @PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
+
         Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
-                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
-            mainService.deleteUser(userId);
+
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails) {
+            CustomUserDetails currentUser = (CustomUserDetails) authentication.getPrincipal();
+            mainService.downvoteOpinion(postId, currentUser);
         }
     }
 
-    @RequestMapping(value = "/updateUserFullName/{userId}", method = RequestMethod.PUT)
-    public void updateUserFullName(@RequestBody ObjectNode objectNode, @PathVariable Long userId,
-            @CurrentSecurityContext SecurityContext context) {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
-                && (currentUser.getUserRole().equals(UserRole.MODERATOR) || currentUser.getId().equals(userId))) {
-            String newFullName = objectNode.get("newFullName").asText();
-            mainService.updateUserFullName(newFullName, userId);
-        }
-    }
-
-    @RequestMapping(value = "/updateUserUsername/{userId}", method = RequestMethod.PUT)
-    public void updateUserUsername(@RequestBody ObjectNode objectNode, @PathVariable Long userId,
-            @CurrentSecurityContext SecurityContext context) {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
-                && (currentUser.getUserRole().equals(UserRole.MODERATOR) || currentUser.getId().equals(userId))) {
-            String newUsername = objectNode.get("newUsername").asText();
-            mainService.updateUserUsername(newUsername, userId);
-        }
-    }
-
-    @RequestMapping(value = "/reportOpinion/{postId}", method = RequestMethod.POST)
-    public void reportOpinion(@RequestBody ObjectNode objectNode, @PathVariable Long postId,
-                              @CurrentSecurityContext SecurityContext context) {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
-            String description = objectNode.get("description").asText();
-            mainService.reportOpinion(postId, currentUser, description);
-        }
-    }
-
-    @RequestMapping(value = "/reportThread/{postId}", method = RequestMethod.POST)
-    public void reportThread(@RequestBody ObjectNode objectNode, @PathVariable Long postId,
-                              @CurrentSecurityContext SecurityContext context) {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
-            String description = objectNode.get("description").asText();
-            mainService.reportThread(postId, currentUser, description);
-        }
-    }
-
-    @RequestMapping(value = "/markReportResolved/{postReportId}/{action}", method = RequestMethod.GET)
-    public void markReportResolved(@PathVariable Long postReportId, @PathVariable String action, @CurrentSecurityContext SecurityContext context) {
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser &&
-                currentUser.getUserRole().equals(UserRole.MODERATOR)) {
-            mainService.markReport(postReportId, action);
-        }
-    }
-
-    @RequestMapping(value = "/getAllPostReports", method = RequestMethod.GET)
-    public List<PostReport> getAllPostReports(@CurrentSecurityContext SecurityContext context) throws AuthenticationException{
-        Authentication authentication = context.getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
-                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
-            return mainService.getAllPostReports();
-        } else throw new AuthenticationException("Invalid role");
-     }
-
-
 }
Index: springapp/src/main/java/mk/profesori/springapp/Model/City.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/City.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Model/City.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,16 +1,21 @@
 package mk.profesori.springapp.Model;
 
-import com.fasterxml.jackson.annotation.JsonIdentityInfo;
-import com.voodoodyne.jackson.jsog.JSOGGenerator;
-import lombok.Data;
-
-import javax.persistence.*;
 import java.util.HashSet;
 import java.util.Set;
 
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+
 @Entity
-@Data
 @Table(name = "city")
-@JsonIdentityInfo(generator = JSOGGenerator.class)
+@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "cityId")
 public class City {
 
@@ -23,7 +28,19 @@
     private String cityName;
 
-    @Transient
     @OneToMany(mappedBy = "city")
     private Set<University> universities = new HashSet<>();
 
+    // getters
+    public Long getCityId() {
+        return cityId;
+    }
+
+    public String getCityName() {
+        return cityName;
+    }
+
+    public Set<University> getUniversities() {
+        return universities;
+    }
+
 }
Index: springapp/src/main/java/mk/profesori/springapp/Model/ConfirmationToken.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/ConfirmationToken.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Model/ConfirmationToken.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -12,7 +12,4 @@
 import javax.persistence.SequenceGenerator;
 
-import com.fasterxml.jackson.annotation.JsonIdentityInfo;
-import com.voodoodyne.jackson.jsog.JSOGGenerator;
-
 import lombok.Getter;
 import lombok.NoArgsConstructor;
@@ -23,7 +20,6 @@
 @NoArgsConstructor
 @Entity
-@JsonIdentityInfo(generator = JSOGGenerator.class)
 public class ConfirmationToken {
-
+    
     @Id
     @SequenceGenerator(name = "confirmation_token_sequence", sequenceName = "confirmation_token_sequence", allocationSize = 1)
@@ -46,7 +42,7 @@
     private CustomUserDetails customUserDetails;
 
-    public ConfirmationToken(String token, LocalDateTime createdAt, LocalDateTime expiredAt,
-            CustomUserDetails customUserDetails) {
-
+    public ConfirmationToken(String token, LocalDateTime createdAt, LocalDateTime expiredAt, 
+    CustomUserDetails customUserDetails) {
+        
         this.token = token;
         this.createdAt = createdAt;
Index: springapp/src/main/java/mk/profesori/springapp/Model/CustomUserDetails.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/CustomUserDetails.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Model/CustomUserDetails.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,20 +1,36 @@
 package mk.profesori.springapp.Model;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinTable;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToMany;
+import javax.persistence.SequenceGenerator;
+
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
 import com.fasterxml.jackson.annotation.JsonIdentityInfo;
-import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.voodoodyne.jackson.jsog.JSOGGenerator;
+
 import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
-import javax.persistence.*;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
 
 @Getter
@@ -30,39 +46,23 @@
     @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_sequence")
     private Long id;
-    private String fullName;
+    private String fullName; // opcionalno, smee da e prazno
     private String username;
-    @JsonIgnore
     private String email;
-    @JsonIgnore
-    private String password;
-    /*  UseCases
-        го уредува својот кориснички профил
-        го верификува својот кориснички профил todo...
-    */
+    private String password; // TODO dont expose password in api
     @Enumerated(EnumType.STRING)
     private UserRole userRole;
     private Boolean locked = false;
     private Boolean enabled = false;
-    @Transient
-    @OneToMany(mappedBy = "customUserDetails", orphanRemoval = true)
+    @OneToMany(mappedBy = "customUserDetails", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
     private Set<ConfirmationToken> confirmationTokens = new HashSet<>();
-    @Transient
-    @OneToMany(mappedBy = "author", orphanRemoval = true)
+    @OneToMany(mappedBy = "author", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
     private Set<Post> authoredPosts = new HashSet<>();
     private Integer karma = 0;
-
-    @Transient
-    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
-    private Set<PostVote> votes = new HashSet<>();
-
-    @Transient
-    @OneToMany(mappedBy = "user", cascade = {CascadeType.PERSIST})
-    private Set<PostReport> reportsSubmitted = new HashSet<>();
-    @PreRemove
-    public void preRemove() {
-        reportsSubmitted.forEach(report -> {
-            report.setUser(null);
-        });
-    }
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(name = "post_like", joinColumns = @JoinColumn(name = "custom_user_details_id"), inverseJoinColumns = @JoinColumn(name = "post_id"))
+    Set<Post> likedPosts;
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(name = "post_dislike", joinColumns = @JoinColumn(name = "custom_user_details_id"), inverseJoinColumns = @JoinColumn(name = "post_id"))
+    Set<Post> dislikedPosts;
 
     public CustomUserDetails(String fullName, String username, String email, String password, UserRole userRole) {
@@ -110,7 +110,30 @@
     }
 
-    @Override
-    public String toString() {
-        return this.id.toString();
+    public Set<Post> getAuthoredPosts() {
+        return this.authoredPosts;
+    }
+
+    public Integer getKarma() {
+        return this.karma;
+    }
+
+    public void setKarma(Integer karma) {
+        this.karma = karma;
+    }
+
+    public Set<Post> getLikedPosts() {
+        return this.likedPosts;
+    }
+
+    public void setLikedPosts(Set<Post> likedPosts) {
+        this.likedPosts = likedPosts;
+    }
+
+    public Set<Post> getDislikedPosts() {
+        return this.dislikedPosts;
+    }
+
+    public void setDislikedPosts(Set<Post> dislikedPosts) {
+        this.likedPosts = dislikedPosts;
     }
 }
Index: springapp/src/main/java/mk/profesori/springapp/Model/Faculty.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/Faculty.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Model/Faculty.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,14 +1,21 @@
 package mk.profesori.springapp.Model;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
 
 import com.fasterxml.jackson.annotation.JsonIdentityInfo;
 import com.voodoodyne.jackson.jsog.JSOGGenerator;
-import lombok.Data;
-
-import javax.persistence.*;
-import java.util.HashSet;
-import java.util.Set;
 
 @Entity
-@Data
 @Table(name = "faculty")
 @JsonIdentityInfo(generator = JSOGGenerator.class)
@@ -27,11 +34,30 @@
     private University university;
 
-    @Transient
     @OneToMany(mappedBy = "faculty")
     private Set<Professor> professors = new HashSet<>();
 
-    @Transient
     @OneToMany(mappedBy = "faculty")
     private Set<StudyProgramme> studyProgrammes = new HashSet<>();
 
+    // getters
+    public Long getFacultyId() {
+        return facultyId;
+    }
+
+    public String getFacultyName() {
+        return facultyName;
+    }
+
+    public University getUniversity() {
+        return university;
+    }
+
+    public Set<Professor> getProfessors() {
+        return professors;
+    }
+
+    public Set<StudyProgramme> getStudyProgrammes() {
+        return studyProgrammes;
+    }
+
 }
Index: springapp/src/main/java/mk/profesori/springapp/Model/Opinion.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/Opinion.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Model/Opinion.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,6 +1,6 @@
 package mk.profesori.springapp.Model;
 
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import java.time.LocalDateTime;
+import java.util.List;
 
 import javax.persistence.DiscriminatorValue;
@@ -8,9 +8,8 @@
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
-import java.time.LocalDateTime;
-import java.util.List;
+
+import lombok.NoArgsConstructor;
 
 @Entity
-@Data
 @DiscriminatorValue("opinion")
 @NoArgsConstructor
@@ -36,3 +35,12 @@
         this.targetProfessor = targetProfessor;
     }
+
+    // getters and setters
+    public Professor getTargetProfessor() {
+        return targetProfessor;
+    }
+
+    public void setTargetProfessor(Professor targetProfessor) {
+        this.targetProfessor = targetProfessor;
+    }
 }
Index: springapp/src/main/java/mk/profesori/springapp/Model/Post.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/Post.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Model/Post.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,18 +1,30 @@
 package mk.profesori.springapp.Model;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
 
 import com.fasterxml.jackson.annotation.JsonIdentityInfo;
 import com.voodoodyne.jackson.jsog.JSOGGenerator;
-import lombok.Data;
+
 import lombok.NoArgsConstructor;
 
-import javax.persistence.*;
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 @Entity(name = "post")
-@Data
 @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
 @DiscriminatorColumn(name = "post_type", discriminatorType = DiscriminatorType.STRING)
@@ -43,22 +55,96 @@
 
     @ManyToOne
-    @JoinColumn(name = "parent_post_id")
+    @JoinColumn(name = "parent_post_id", nullable = true)
     private Post parent;
 
-    @OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
-    private Set<PostVote> votes = new HashSet<>();
+    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
+    private List<Post> children = new ArrayList<>();
 
-    @OneToMany(mappedBy = "post", cascade={CascadeType.PERSIST}, fetch = FetchType.EAGER)
-    private Set<PostReport> reports = new HashSet<>();
+    @ManyToMany(mappedBy = "likedPosts")
+    Set<CustomUserDetails> likes;
 
-    @PreRemove
-    public void preRemove() {
-        reports.forEach(report -> {
-            report.setPost(null);
-            report.setResolved(true);
-        });
+    @ManyToMany(mappedBy = "dislikedPosts")
+    Set<CustomUserDetails> dislikes;
+
+    // getters and setters
+    public Long getPostId() {
+        return postId;
     }
-    @OneToMany(mappedBy = "parent", orphanRemoval = true, fetch = FetchType.EAGER)
-    private List<Post> children = new ArrayList<>();
+
+    public void setPostId(Long postId) {
+        this.postId = postId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public CustomUserDetails getAuthor() {
+        return author;
+    }
+
+    public void setAuthor(CustomUserDetails author) {
+        this.author = author;
+    }
+
+    public LocalDateTime getTimePosted() {
+        return timePosted;
+    }
+
+    public void setTimePosted(LocalDateTime timePosted) {
+        this.timePosted = timePosted;
+    }
+
+    public LocalDateTime getTimeLastEdited() {
+        return timeLastEdited;
+    }
+
+    public void setTimeLastEdited(LocalDateTime timeLastEdited) {
+        this.timeLastEdited = timeLastEdited;
+    }
+
+    public Post getParent() {
+        return parent;
+    }
+
+    public void setParent(Post parent) {
+        this.parent = parent;
+    }
+
+    public List<Post> getChildren() {
+        return children;
+    }
+
+    public void setChildren(List<Post> children) {
+        this.children = children;
+    }
+
+    public Set<CustomUserDetails> getLikes() {
+        return likes;
+    }
+
+    public void setLikes(Set<CustomUserDetails> likes) {
+        this.likes = likes;
+    }
+
+    public Set<CustomUserDetails> getDislikes() {
+        return dislikes;
+    }
+
+    public void setDislikes(Set<CustomUserDetails> dislikes) {
+        this.dislikes = dislikes;
+    }
 
     // konstruktor so parent (koga e reply)
@@ -88,9 +174,3 @@
     }
 
-    @Override
-    public String toString() {
-        return this.postId.toString();
-    }
-
-
 }
Index: springapp/src/main/java/mk/profesori/springapp/Model/PostReport.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/PostReport.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ 	(revision )
@@ -1,42 +1,0 @@
-package mk.profesori.springapp.Model;
-
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import javax.persistence.*;
-import java.time.LocalDateTime;
-
-@Entity
-@Data
-@NoArgsConstructor
-public class PostReport {
-
-    @Id
-    @SequenceGenerator(name = "post_report_sequence", sequenceName = "post_report_sequence", allocationSize = 1)
-    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "post_report_sequence")
-    private Long postReportId;
-
-    @ManyToOne
-    @JoinColumn(name = "custom_user_details_id")
-    private CustomUserDetails user;
-
-    @ManyToOne
-    @JoinColumn(name = "post_id")
-    private Post post;
-
-    LocalDateTime time;
-
-    @Column(name = "description", columnDefinition = "TEXT")
-    private String description;
-
-    @Column(name = "resolved")
-    private boolean resolved;
-
-    public PostReport(CustomUserDetails user, Post post, String description) {
-        this.user = user;
-        this.post = post;
-        this.time = LocalDateTime.now();
-        this.description = description;
-        this.resolved=false;
-    }
-}
Index: springapp/src/main/java/mk/profesori/springapp/Model/PostVote.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/PostVote.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ 	(revision )
@@ -1,38 +1,0 @@
-package mk.profesori.springapp.Model;
-
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import javax.persistence.*;
-import java.time.LocalDateTime;
-
-@Entity
-@Data
-@NoArgsConstructor
-public class PostVote {
-
-    @Id
-    @SequenceGenerator(name = "post_vote_sequence", sequenceName = "post_vote_sequence", allocationSize = 1)
-    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "post_vote_sequence")
-    private Long postVoteId;
-
-    @ManyToOne
-    @JoinColumn(name = "custom_user_details_id")
-    private CustomUserDetails user;
-
-    @ManyToOne
-    @JoinColumn(name = "post_id")
-    private Post post;
-
-    LocalDateTime time;
-
-    @Enumerated(EnumType.STRING)
-    private VoteType vote;
-
-    public PostVote(CustomUserDetails user, Post post, VoteType vote) {
-        this.user = user;
-        this.post = post;
-        this.time = LocalDateTime.now();
-        this.vote = vote;
-    }
-}
Index: springapp/src/main/java/mk/profesori/springapp/Model/Professor.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/Professor.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Model/Professor.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,14 +1,21 @@
 package mk.profesori.springapp.Model;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
 
 import com.fasterxml.jackson.annotation.JsonIdentityInfo;
 import com.voodoodyne.jackson.jsog.JSOGGenerator;
-import lombok.Data;
-
-import javax.persistence.*;
-import java.util.ArrayList;
-import java.util.List;
 
 @Entity
-@Data
 @Table(name = "professor")
 @JsonIdentityInfo(generator = JSOGGenerator.class)
@@ -27,6 +34,22 @@
     private Faculty faculty;
 
-    @Transient
     @OneToMany(mappedBy = "targetProfessor", cascade = CascadeType.ALL)
-    private List<Opinion> relatedOpinions = new ArrayList<>();
+    private List<Opinion> relatedOpinions = new ArrayList<Opinion>();
+
+    // getters
+    public Long getProfessorId() {
+        return professorId;
+    }
+
+    public String getProfessorName() {
+        return professorName;
+    }
+
+    public Faculty getFaculty() {
+        return faculty;
+    }
+
+    public List<Opinion> getRelatedOpinions() {
+        return relatedOpinions;
+    }
 }
Index: springapp/src/main/java/mk/profesori/springapp/Model/Section.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/Section.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
+++ springapp/src/main/java/mk/profesori/springapp/Model/Section.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -0,0 +1,69 @@
+package mk.profesori.springapp.Model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+
+@Entity
+@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "sectionId")
+public class Section {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    private Long sectionId;
+
+    @Column(name = "name")
+    private String name;
+
+    @OneToMany(mappedBy = "parentSection", cascade = CascadeType.ALL)
+    private List<_Thread> threads = new ArrayList<>();
+
+    @OneToOne
+    @JoinColumn(name = "study_programme_id", referencedColumnName = "id")
+    private StudyProgramme relatedStudyProgramme;
+
+    // getters and setters
+    public Long getSectionId() {
+        return sectionId;
+    }
+
+    public void setSectionId(Long sectionId) {
+        this.sectionId = sectionId;
+    }
+
+    public List<_Thread> getThreads() {
+        return threads;
+    }
+
+    public void setThreads(List<_Thread> threads) {
+        this.threads = threads;
+    }
+
+    public StudyProgramme getRelatedStudyProgramme() {
+        return relatedStudyProgramme;
+    }
+
+    public void setRelatedStudyProgramme(StudyProgramme relatedStudyProgramme) {
+        this.relatedStudyProgramme = relatedStudyProgramme;
+    }
+
+    public Section(Long sectionId, List<_Thread> threads, StudyProgramme relatedStudyProgramme) {
+        this.sectionId = sectionId;
+        this.threads = threads;
+        this.relatedStudyProgramme = relatedStudyProgramme;
+    }
+
+}
Index: springapp/src/main/java/mk/profesori/springapp/Model/StudyProgramme.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/StudyProgramme.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Model/StudyProgramme.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,16 +1,24 @@
 package mk.profesori.springapp.Model;
 
-import com.fasterxml.jackson.annotation.JsonIdentityInfo;
-import com.voodoodyne.jackson.jsog.JSOGGenerator;
-import lombok.Data;
-
-import javax.persistence.*;
 import java.util.HashSet;
 import java.util.Set;
 
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+
 @Entity
-@Data
 @Table(name = "study_programme")
-@JsonIdentityInfo(generator = JSOGGenerator.class)
+@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "studyProgrammeId")
 public class StudyProgramme {
 
@@ -30,7 +38,33 @@
     private Faculty faculty;
 
-    @Transient
     @OneToMany(mappedBy = "studyProgramme")
     private Set<Subject> subjects = new HashSet<>();
 
+    @OneToOne(mappedBy = "relatedStudyProgramme")
+    private Section relatedSection;
+
+    // getters
+    public Long getStudyProgrammeId() {
+        return studyProgrammeId;
+    }
+
+    public String getStudyProgrammeName() {
+        return studyProgrammeName;
+    }
+
+    public int getCycle() {
+        return cycle;
+    }
+
+    public Faculty getFaculty() {
+        return faculty;
+    }
+
+    public Set<Subject> getSubjects() {
+        return subjects;
+    }
+
+    public Section getRelatedSection() {
+        return relatedSection;
+    }
 }
Index: springapp/src/main/java/mk/profesori/springapp/Model/Subject.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/Subject.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Model/Subject.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,16 +1,23 @@
 package mk.profesori.springapp.Model;
 
-import com.fasterxml.jackson.annotation.JsonIdentityInfo;
-import com.voodoodyne.jackson.jsog.JSOGGenerator;
-import lombok.Data;
-
-import javax.persistence.*;
 import java.util.ArrayList;
 import java.util.List;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
 
 @Entity
-@Data
 @Table(name = "subject")
-@JsonIdentityInfo(generator = JSOGGenerator.class)
+@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "subjectId")
 public class Subject {
 
@@ -27,7 +34,23 @@
     private StudyProgramme studyProgramme;
 
-    @Transient
     @OneToMany(mappedBy = "targetSubject", cascade = CascadeType.ALL)
     private List<_Thread> threads = new ArrayList<>();
 
+    // getters
+    public Long getSubjectId() {
+        return subjectId;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public StudyProgramme getStudyProgramme() {
+        return studyProgramme;
+    }
+
+    public List<_Thread> getThreads() {
+        return threads;
+    }
+
 }
Index: springapp/src/main/java/mk/profesori/springapp/Model/University.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/University.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Model/University.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,16 +1,23 @@
 package mk.profesori.springapp.Model;
 
-import com.fasterxml.jackson.annotation.JsonIdentityInfo;
-import com.voodoodyne.jackson.jsog.JSOGGenerator;
-import lombok.Data;
-
-import javax.persistence.*;
 import java.util.HashSet;
 import java.util.Set;
 
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+
 @Entity
-@Data
 @Table(name = "university")
-@JsonIdentityInfo(generator = JSOGGenerator.class)
+@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "universityId")
 public class University {
 
@@ -27,6 +34,23 @@
     private City city;
 
-    @Transient
     @OneToMany(mappedBy = "university")
     private Set<Faculty> faculties = new HashSet<>();
+
+    // getters
+    public Long getUniversityId() {
+        return universityId;
+    }
+
+    public String getUniversityName() {
+        return universityName;
+    }
+
+    public City getCity() {
+        return city;
+    }
+
+    public Set<Faculty> getFaculties() {
+        return faculties;
+    }
+
 }
Index: springapp/src/main/java/mk/profesori/springapp/Model/VoteType.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/VoteType.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ 	(revision )
@@ -1,6 +1,0 @@
-package mk.profesori.springapp.Model;
-
-public enum VoteType {
-    UPVOTE,
-    DOWNVOTE
-}
Index: springapp/src/main/java/mk/profesori/springapp/Model/_Thread.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/_Thread.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Model/_Thread.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,19 +1,25 @@
 package mk.profesori.springapp.Model;
 
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import java.util.ArrayList;
+import java.util.List;
 
+import javax.persistence.Column;
 import javax.persistence.DiscriminatorValue;
+import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
-import java.time.LocalDateTime;
-import java.util.List;
 
 @Entity
-@Data
 @DiscriminatorValue("thread")
-@NoArgsConstructor
 public class _Thread extends Post {
+
+    @Column(name = "tags")
+    @ElementCollection
+    private List<String> tags = new ArrayList<>();
+
+    @ManyToOne
+    @JoinColumn(name = "section_id")
+    private Section parentSection;
 
     @ManyToOne
@@ -21,17 +27,27 @@
     private Subject targetSubject;
 
-    // konstruktor so parent (koga e reply)
-    public _Thread(String title, String content, CustomUserDetails author, LocalDateTime timePosted,
-            LocalDateTime timeLastEdited,
-            Post parent, List<Post> children, Subject targetSubject) {
-        super(title, content, author, timePosted, timeLastEdited, parent, children);
-        this.targetSubject = targetSubject;
+    // TODO threadovi
+    /*
+     * public _Thread(String title, String content, List<String> tags, Section
+     * parentSection, Subject targetSubject) {
+     * super(title, content);
+     * this.tags = tags;
+     * this.parentSection = parentSection;
+     * this.targetSubject = targetSubject;
+     * }
+     */
+
+    // getters
+    public List<String> getTags() {
+        return tags;
     }
 
-    // konstruktor bez parent (koga NE e reply)
-    public _Thread(String title, String content, CustomUserDetails author, LocalDateTime timePosted,
-            LocalDateTime timeLastEdited, List<Post> children, Subject targetSubject) {
-        super(title, content, author, timePosted, timeLastEdited, children);
-        this.targetSubject = targetSubject;
+    public Section getParentSection() {
+        return parentSection;
     }
+
+    public Subject getTargetSubject() {
+        return targetSubject;
+    }
+
 }
Index: springapp/src/main/java/mk/profesori/springapp/Repository/CityRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/CityRepository.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Repository/CityRepository.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,13 +1,15 @@
 package mk.profesori.springapp.Repository;
 
-import mk.profesori.springapp.Model.City;
+import java.util.List;
+
 import org.springframework.data.repository.CrudRepository;
 import org.springframework.stereotype.Repository;
 
-import java.util.List;
+import mk.profesori.springapp.Model.City;
 
 @Repository
 public interface CityRepository extends CrudRepository<City, Long>{
-    List<City> findAll();
-    City findByCityId(Long id);
+
+    public List<City> findAll();
+    public City findByCityId(Long id);
 }
Index: springapp/src/main/java/mk/profesori/springapp/Repository/FacultyRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/FacultyRepository.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Repository/FacultyRepository.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,23 +1,17 @@
 package mk.profesori.springapp.Repository;
+
+import java.util.List;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
 
 import mk.profesori.springapp.Model.Faculty;
 import mk.profesori.springapp.Model.University;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.CrudRepository;
-import org.springframework.data.repository.query.Param;
-import org.springframework.stereotype.Repository;
-
-import java.util.List;
 
 @Repository
 public interface FacultyRepository extends CrudRepository<Faculty, Long>{
-    List<Faculty> findAll();
-    Faculty findByFacultyId(Long id);
-    List<Faculty> findByUniversity(University university);
-    @Query(value = "select professor.id, count(p.*)\n" +
-            "from professor left join post p on professor.id = p.professor_id\n" +
-            "where professor.faculty_id = :facultyId\n" +
-            "group by professor.id\n" +
-            "order by professor.id;", nativeQuery = true)
-    List<String> getOpinionCountForEachProfessorInFaculty(@Param("facultyId") Long id);
+
+    public List<Faculty> findAll();
+    public Faculty findByFacultyId(Long id);
+    public List<Faculty> findByUniversity(University university);
 }
Index: springapp/src/main/java/mk/profesori/springapp/Repository/OpinionRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/OpinionRepository.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Repository/OpinionRepository.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,15 +1,11 @@
 package mk.profesori.springapp.Repository;
 
-import mk.profesori.springapp.Model.Opinion;
-import mk.profesori.springapp.Model.Professor;
 import org.springframework.data.repository.CrudRepository;
 import org.springframework.stereotype.Repository;
 
-import java.util.List;
+import mk.profesori.springapp.Model.Opinion;
 
 @Repository
-public interface OpinionRepository extends CrudRepository<Opinion,Long> {
-    Opinion findByPostId(Long postId);
-    List<Opinion> findByTargetProfessor(Professor p);
-    List<Opinion> findTop10ByOrderByTimePosted();
+public interface OpinionRepository extends CrudRepository<Opinion, Long> {
+    public Opinion findByPostId(Long id);
 }
Index: springapp/src/main/java/mk/profesori/springapp/Repository/PostReportRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/PostReportRepository.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ 	(revision )
@@ -1,13 +1,0 @@
-package mk.profesori.springapp.Repository;
-
-import mk.profesori.springapp.Model.PostReport;
-import org.springframework.data.repository.CrudRepository;
-import org.springframework.stereotype.Repository;
-
-import java.util.List;
-
-@Repository
-public interface PostReportRepository extends CrudRepository<PostReport,Long> {
-    PostReport findByPostReportId(Long id);
-    List<PostReport> findAll();
-}
Index: springapp/src/main/java/mk/profesori/springapp/Repository/PostRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/PostRepository.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ 	(revision )
@@ -1,13 +1,0 @@
-package mk.profesori.springapp.Repository;
-
-import mk.profesori.springapp.Model.CustomUserDetails;
-import mk.profesori.springapp.Model.Post;
-import org.springframework.data.repository.CrudRepository;
-import org.springframework.stereotype.Repository;
-
-import java.util.Set;
-
-@Repository
-public interface PostRepository extends CrudRepository<Post, Long> {
-    Set<Post> findByAuthor(CustomUserDetails c);
-}
Index: springapp/src/main/java/mk/profesori/springapp/Repository/PostVoteRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/PostVoteRepository.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ 	(revision )
@@ -1,14 +1,0 @@
-package mk.profesori.springapp.Repository;
-
-import mk.profesori.springapp.Model.Post;
-import mk.profesori.springapp.Model.PostVote;
-import org.springframework.data.repository.CrudRepository;
-import org.springframework.stereotype.Repository;
-
-import java.util.List;
-
-@Repository
-public interface PostVoteRepository extends CrudRepository<PostVote,Long> {
-    PostVote findByPostVoteId(Long id);
-    List<PostVote> findByPost(Post post);
-}
Index: springapp/src/main/java/mk/profesori/springapp/Repository/ProfessorRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/ProfessorRepository.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Repository/ProfessorRepository.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,18 +1,22 @@
 package mk.profesori.springapp.Repository;
 
-import mk.profesori.springapp.Model.Faculty;
-import mk.profesori.springapp.Model.Professor;
+import java.util.List;
+
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.repository.CrudRepository;
 import org.springframework.stereotype.Repository;
 
-import java.util.List;
+import mk.profesori.springapp.Model.Faculty;
+import mk.profesori.springapp.Model.Professor;
 
 @Repository
 public interface ProfessorRepository extends CrudRepository<Professor, Long>, JpaSpecificationExecutor<Professor> {
 
-    List<Professor> findAll();
-    Professor findByProfessorId(Long id);
-    List<Professor> findByFaculty(Faculty faculty);
-    List<Professor> findByProfessorNameContainingIgnoreCase(String name);
+    public List<Professor> findAll();
+
+    public Professor findByProfessorId(Long id);
+
+    public List<Professor> findByFaculty(Faculty faculty);
+
+    public List<Professor> findByProfessorNameContainingIgnoreCase(String name);
 }
Index: springapp/src/main/java/mk/profesori/springapp/Repository/StudyProgrammeRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/StudyProgrammeRepository.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Repository/StudyProgrammeRepository.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,24 +1,18 @@
 package mk.profesori.springapp.Repository;
+
+import java.util.List;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
 
 import mk.profesori.springapp.Model.Faculty;
 import mk.profesori.springapp.Model.StudyProgramme;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.CrudRepository;
-import org.springframework.data.repository.query.Param;
-import org.springframework.stereotype.Repository;
-
-import java.util.List;
 
 
 @Repository
 public interface StudyProgrammeRepository extends CrudRepository<StudyProgramme, Long>{
-    List<StudyProgramme> findAll();
-    StudyProgramme findByStudyProgrammeId(Long id);
-    List<StudyProgramme> findByFaculty(Faculty faculty);
-    @Query(value = "select subject.id, count(p.*)\n" +
-            "from subject left join post p on subject.id = p.subject_id\n" +
-            "where subject.study_programme_id = :studyProgrammeId\n" +
-            "group by subject.id\n" +
-            "order by subject.id;", nativeQuery = true)
-    List<String> getThreadCountForEachSubjectInStudyProgramme(@Param("studyProgrammeId") Long id);
+    
+    public List<StudyProgramme> findAll();
+    public StudyProgramme findByStudyProgrammeId(Long id);
+    public List<StudyProgramme> findByFaculty(Faculty faculty);
 }
Index: springapp/src/main/java/mk/profesori/springapp/Repository/SubjectRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/SubjectRepository.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ 	(revision )
@@ -1,15 +1,0 @@
-package mk.profesori.springapp.Repository;
-
-import mk.profesori.springapp.Model.StudyProgramme;
-import mk.profesori.springapp.Model.Subject;
-import org.springframework.data.repository.CrudRepository;
-import org.springframework.stereotype.Repository;
-
-import java.util.List;
-
-@Repository
-public interface SubjectRepository extends CrudRepository<Subject, Long> {
-    Subject findBySubjectId(Long id);
-    List<Subject> findByStudyProgramme(StudyProgramme studyProgramme);
-    List<Subject> findBySubjectNameContainingIgnoreCase(String name);
-}
Index: springapp/src/main/java/mk/profesori/springapp/Repository/UniversityRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/UniversityRepository.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Repository/UniversityRepository.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,39 +1,19 @@
 package mk.profesori.springapp.Repository;
+
+import java.util.List;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
 
 import mk.profesori.springapp.Model.City;
 import mk.profesori.springapp.Model.University;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.CrudRepository;
-import org.springframework.stereotype.Repository;
-
-import java.util.List;
 
 @Repository
 public interface UniversityRepository extends CrudRepository<University, Long> {
-    List<University> findAll();
 
-    University findByUniversityId(Long id);
-    List<University> findByCity(City city);
-    
-    @Query(value = "select facultyid, sectioncount, opinioncount from\n" +
-            "(select faculty_id as facultyid, t1.subject_count+t2.professor_count as sectioncount\n" +
-            "from (select sp.faculty_id, count(*) as subject_count\n" +
-            "      from subject s join study_programme sp on s.study_programme_id = sp.id\n" +
-            "      group by sp.faculty_id) as t1\n" +
-            "         natural join\n" +
-            "     (select count(*) as professor_count, f.id as faculty_id\n" +
-            "      from professor p join faculty f on f.id = p.faculty_id\n" +
-            "      group by f.id) as t2) as q1\n" +
-            "natural join\n" +
-            "(select facultyid, count1+count2 as opinioncount from\n" +
-            "    (select pr.faculty_id as facultyid, count(*) as count1\n" +
-            "    from post po join professor pr on po.professor_id = pr.id\n" +
-            "    where professor_id is not null\n" +
-            "    group by pr.faculty_id) as t3\n" +
-            "    natural join\n" +
-            "    (select sp.faculty_id as facultyid, count(*) as count2\n" +
-            "    from post po join subject s on po.subject_id = s.id join study_programme sp on s.study_programme_id = sp.id\n" +
-            "    where po.subject_id is not null\n" +
-            "    group by sp.faculty_id) as t4) as q2;", nativeQuery = true)
-    List<String> findSectionAndPostCount();
+    public List<University> findAll();
+
+    public University findByUniversityId(Long id);
+
+    public List<University> findByCity(City city);
 }
Index: springapp/src/main/java/mk/profesori/springapp/Repository/UserRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/UserRepository.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Repository/UserRepository.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,5 +1,6 @@
 package mk.profesori.springapp.Repository;
 
-import mk.profesori.springapp.Model.CustomUserDetails;
+import java.util.Optional;
+
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Modifying;
@@ -8,5 +9,5 @@
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Optional;
+import mk.profesori.springapp.Model.CustomUserDetails;
 
 @Repository
@@ -15,5 +16,4 @@
     Optional<CustomUserDetails> findByEmail(String email);
     Optional<CustomUserDetails> findByUsername(String username);
-    Optional<CustomUserDetails> findById(Long id);
 
     @Transactional
Index: springapp/src/main/java/mk/profesori/springapp/Repository/_ThreadRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/_ThreadRepository.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ 	(revision )
@@ -1,15 +1,0 @@
-package mk.profesori.springapp.Repository;
-
-import mk.profesori.springapp.Model.Subject;
-import mk.profesori.springapp.Model._Thread;
-import org.springframework.data.repository.CrudRepository;
-import org.springframework.stereotype.Repository;
-
-import java.util.List;
-
-@Repository
-public interface _ThreadRepository extends CrudRepository<_Thread,Long> {
-    _Thread findByPostId(Long postId);
-    List<_Thread> findTop10ByOrderByTimePosted();
-    List<_Thread> findByTargetSubject(Subject s);
-}
Index: springapp/src/main/java/mk/profesori/springapp/Security/SecurityConfiguration.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Security/SecurityConfiguration.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Security/SecurityConfiguration.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -37,5 +37,5 @@
             @Override
             public void addCorsMappings(CorsRegistry registry) {
-                registry.addMapping("/**").allowedOrigins("http://192.168.1.108:3000", "http://192.168.0.28:3000")
+                registry.addMapping("/**").allowedOrigins("http://192.168.0.17:3000", "http://192.168.0.24:3000")
                         .allowCredentials(true);
             }
Index: springapp/src/main/java/mk/profesori/springapp/Service/CustomUserDetailsService.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Service/CustomUserDetailsService.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Service/CustomUserDetailsService.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,8 +1,7 @@
 package mk.profesori.springapp.Service;
 
-import lombok.AllArgsConstructor;
-import mk.profesori.springapp.Model.ConfirmationToken;
-import mk.profesori.springapp.Model.CustomUserDetails;
-import mk.profesori.springapp.Repository.UserRepository;
+import java.time.LocalDateTime;
+import java.util.UUID;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.core.userdetails.UserDetails;
@@ -13,6 +12,8 @@
 import org.springframework.stereotype.Service;
 
-import java.time.LocalDateTime;
-import java.util.UUID;
+import lombok.AllArgsConstructor;
+import mk.profesori.springapp.Model.ConfirmationToken;
+import mk.profesori.springapp.Model.CustomUserDetails;
+import mk.profesori.springapp.Repository.UserRepository;
 
 @Service
@@ -42,5 +43,7 @@
         userRepository.save(customUserDetails);
 
-        return createToken(customUserDetails);
+        String token = createToken(customUserDetails);
+
+        return token;
     }
 
@@ -57,6 +60,6 @@
     }
 
-    public void enableUser(String email) {
-        userRepository.enableUser(email);
+    public int enableUser(String email) {
+        return userRepository.enableUser(email);
     }
 }
Index: springapp/src/main/java/mk/profesori/springapp/Service/EmailValidator.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Service/EmailValidator.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Service/EmailValidator.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -13,5 +13,5 @@
     public boolean test(String email) {
         
-        String regex = "^(.+)@(.+)$"; //TODO bilosto@@ ->> illegal address exception od mailsender
+        String regex = "^(.+)@(.+)$";
 
         Pattern pattern = Pattern.compile(regex);
Index: springapp/src/main/java/mk/profesori/springapp/Service/Exception/DisallowedOperationException.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Service/Exception/DisallowedOperationException.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.profesori.springapp.Service.Exception;
-
-public class DisallowedOperationException extends RuntimeException{
-    public DisallowedOperationException(String message) {
-        super(message);
-    }
-}
Index: springapp/src/main/java/mk/profesori/springapp/Service/Exception/IncompatiblePostId.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Service/Exception/IncompatiblePostId.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.profesori.springapp.Service.Exception;
-
-public class IncompatiblePostId extends RuntimeException{
-    public IncompatiblePostId(String message) {
-        super(message);
-    }
-}
Index: springapp/src/main/java/mk/profesori/springapp/Service/MainService.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Service/MainService.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Service/MainService.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,50 +1,48 @@
 package mk.profesori.springapp.Service;
 
-import mk.profesori.springapp.Model.*;
-import mk.profesori.springapp.Repository.*;
-import mk.profesori.springapp.Service.Exception.DisallowedOperationException;
-import mk.profesori.springapp.Service.Exception.IncompatiblePostId;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
+import mk.profesori.springapp.Repository.CityRepository;
+import mk.profesori.springapp.Repository.FacultyRepository;
+import mk.profesori.springapp.Repository.OpinionRepository;
+import mk.profesori.springapp.Repository.ProfessorRepository;
+import mk.profesori.springapp.Repository.StudyProgrammeRepository;
+import mk.profesori.springapp.Repository.UniversityRepository;
+import mk.profesori.springapp.Repository.UserRepository;
+import mk.profesori.springapp.Model.City;
+import mk.profesori.springapp.Model.CustomUserDetails;
+import mk.profesori.springapp.Model.Faculty;
+import mk.profesori.springapp.Model.Opinion;
+import mk.profesori.springapp.Model.Professor;
+import mk.profesori.springapp.Model.StudyProgramme;
+import mk.profesori.springapp.Model.University;
 
 @Service
 public class MainService {
 
-    private final ProfessorRepository professorRepository;
-    private final StudyProgrammeRepository studyProgrammeRepository;
-    private final FacultyRepository facultyRepository;
-    private final UniversityRepository universityRepository;
-    private final CityRepository cityRepository;
-    private final OpinionRepository opinionRepository;
-    private final _ThreadRepository _threadRepository;
-    private final SubjectRepository subjectRepository;
-    private final PostVoteRepository postVoteRepository;
-    private final UserRepository userRepository;
-    private final PostReportRepository postReportRepository;
-    private final PostRepository postRepository;
-
-    public MainService(ProfessorRepository professorRepository, StudyProgrammeRepository studyProgrammeRepository, FacultyRepository facultyRepository, UniversityRepository universityRepository, CityRepository cityRepository, OpinionRepository opinionRepository, _ThreadRepository _threadRepository, SubjectRepository subjectRepository, PostVoteRepository postVoteRepository, UserRepository userRepository, PostReportRepository postReportRepository, PostRepository postRepository) {
-        this.professorRepository = professorRepository;
-        this.studyProgrammeRepository = studyProgrammeRepository;
-        this.facultyRepository = facultyRepository;
-        this.universityRepository = universityRepository;
-        this.cityRepository = cityRepository;
-        this.opinionRepository = opinionRepository;
-        this._threadRepository = _threadRepository;
-        this.subjectRepository = subjectRepository;
-        this.postVoteRepository = postVoteRepository;
-        this.userRepository = userRepository;
-        this.postReportRepository = postReportRepository;
-        this.postRepository = postRepository;
-    }
+    @Autowired
+    private ProfessorRepository professorRepository;
+    @Autowired
+    private StudyProgrammeRepository studyProgrammeRepository;
+    @Autowired
+    private FacultyRepository facultyRepository;
+    @Autowired
+    private UniversityRepository universityRepository;
+    @Autowired
+    private CityRepository cityRepository;
+    @Autowired
+    private OpinionRepository opinionRepository;
+    @Autowired
+    private UserRepository userRepository;
 
     public List<Professor> getAllProfessors() {
 
-        return new ArrayList<>(professorRepository.findAll());
+        List<Professor> list = new ArrayList<>();
+        professorRepository.findAll().forEach(list::add);
+        return list;
     }
 
@@ -58,18 +56,20 @@
         Faculty faculty = facultyRepository.findByFacultyId(facultyId);
 
-        return new ArrayList<>(professorRepository.findByFaculty(faculty));
+        List<Professor> list = new ArrayList<>();
+        professorRepository.findByFaculty(faculty).forEach(list::add);
+        return list;
     }
 
     public List<Professor> getProfessorsByNameContains(String contained) {
-        return new ArrayList<>(professorRepository.findByProfessorNameContainingIgnoreCase(contained));
-    }
-
-    public List<Subject> getSubjectsByNameContains(String contained) {
-        return new ArrayList<>(subjectRepository.findBySubjectNameContainingIgnoreCase(contained));
+        List<Professor> list = new ArrayList<>();
+        professorRepository.findByProfessorNameContainingIgnoreCase(contained).forEach(list::add);
+        return list;
     }
 
     public List<StudyProgramme> getAllStudyProgrammes() {
 
-        return new ArrayList<>(studyProgrammeRepository.findAll());
+        List<StudyProgramme> list = new ArrayList<>();
+        studyProgrammeRepository.findAll().forEach(list::add);
+        return list;
     }
 
@@ -83,9 +83,13 @@
         Faculty faculty = facultyRepository.findByFacultyId(facultyId);
 
-        return new ArrayList<>(studyProgrammeRepository.findByFaculty(faculty));
+        List<StudyProgramme> list = new ArrayList<>();
+        studyProgrammeRepository.findByFaculty(faculty).forEach(list::add);
+        return list;
     }
 
     public List<Faculty> getAllFaculties() {
-        return new ArrayList<>(facultyRepository.findAll());
+        List<Faculty> list = new ArrayList<>();
+        facultyRepository.findAll().forEach(list::add);
+        return list;
     }
 
@@ -98,9 +102,13 @@
         University university = universityRepository.findByUniversityId(universityId);
 
-        return new ArrayList<>(facultyRepository.findByUniversity(university));
+        List<Faculty> list = new ArrayList<>();
+        facultyRepository.findByUniversity(university).forEach(list::add);
+        return list;
     }
 
     public List<University> getAllUniversities() {
-        return new ArrayList<>(universityRepository.findAll());
+        List<University> list = new ArrayList<>();
+        universityRepository.findAll().forEach(list::add);
+        return list;
     }
 
@@ -113,9 +121,13 @@
         City city = cityRepository.findByCityId(cityId);
 
-        return new ArrayList<>(universityRepository.findByCity(city));
+        List<University> list = new ArrayList<>();
+        universityRepository.findByCity(city).forEach(list::add);
+        return list;
     }
 
     public List<City> getAllCities() {
-        return new ArrayList<>(cityRepository.findAll());
+        List<City> list = new ArrayList<>();
+        cityRepository.findAll().forEach(list::add);
+        return list;
     }
 
@@ -124,9 +136,9 @@
     }
 
-    public void addOpinion(String content, Long professorId, CustomUserDetails currentUser) {
+    public void addOpinion(String title, String content, Long professorId, CustomUserDetails currentUser) {
 
         Professor targetProfessor = professorRepository.findByProfessorId(professorId);
 
-        Opinion opinionToAdd = new Opinion(null, content, currentUser, null, null,
+        Opinion opinionToAdd = new Opinion(title, content, currentUser, null, null,
                 null, targetProfessor);
 
@@ -143,236 +155,38 @@
         opinionRepository.save(opinionToAdd);
 
-        //mozda ne treba
         targetOpinion.getChildren().add(opinionToAdd);
         opinionRepository.save(targetOpinion);
     }
 
-    public void addThread(String title, String content, Long subjectId, CustomUserDetails currentUser) {
-        Subject targetSubject = subjectRepository.findBySubjectId(subjectId);
-        String titleToSet = title.equals("") ? null : title;
+    public void upvoteOpinion(Long postId, CustomUserDetails currentUser) {
+        Opinion targetOpinion = opinionRepository.findByPostId(postId);
 
-        _Thread _threadToAdd = new _Thread(titleToSet, content, currentUser, null, null, null, targetSubject);
-        _threadRepository.save(_threadToAdd);
-    }
+        if (!targetOpinion.getLikes().contains(currentUser)) {
 
-    public void replyToThread(String content, Long subjectId, Long postId, CustomUserDetails currentUser) {
-        Subject targetSubject = subjectRepository.findBySubjectId(subjectId);
-        _Thread target_Thread = _threadRepository.findByPostId(postId);
+            targetOpinion.getLikes().add(currentUser);
+            // opinionRepository.save(targetOpinion);
 
-        _Thread _threadToAdd = new _Thread(null, content, currentUser, null, null, target_Thread, null, targetSubject);
-        _threadRepository.save(_threadToAdd);
+            targetOpinion.getAuthor().setKarma(targetOpinion.getAuthor().getKarma() + 1);
+            userRepository.save(targetOpinion.getAuthor());
 
-        //mozda ne treba
-        target_Thread.getChildren().add(_threadToAdd);
-        _threadRepository.save(target_Thread);
-    }
-
-    public Subject getSubjectById(Long subjectId) {
-        return subjectRepository.findBySubjectId(subjectId);
-    }
-
-    public _Thread get_ThreadById(Long postId) {
-        return _threadRepository.findByPostId(postId);
-    }
-
-    public void upvoteOpinion(Long postId, CustomUserDetails currentUser) {
-        Post targetPost = opinionRepository.findByPostId(postId);
-        PostVote voteToAdd = new PostVote(currentUser, targetPost, VoteType.UPVOTE);
-        postVoteRepository.save(voteToAdd);
-        targetPost.getAuthor().setKarma(targetPost.getAuthor().getKarma()+1);
-        userRepository.save(targetPost.getAuthor());
-    }
-    public void downvoteOpinion(Long postId, CustomUserDetails currentUser) {
-        Post targetPost = opinionRepository.findByPostId(postId);
-        PostVote voteToAdd = new PostVote(currentUser, targetPost, VoteType.DOWNVOTE);
-        postVoteRepository.save(voteToAdd);
-        targetPost.getAuthor().setKarma(targetPost.getAuthor().getKarma()-1);
-        userRepository.save(targetPost.getAuthor());
-    }
-
-    public void upvote_Thread(Long postId, CustomUserDetails currentUser) {
-        Post targetPost = _threadRepository.findByPostId(postId);
-        PostVote voteToAdd = new PostVote(currentUser, targetPost, VoteType.UPVOTE);
-        postVoteRepository.save(voteToAdd);
-        targetPost.getAuthor().setKarma(targetPost.getAuthor().getKarma()+1);
-        userRepository.save(targetPost.getAuthor());
-    }
-    public void downvote_Thread(Long postId, CustomUserDetails currentUser) {
-        Post targetPost = _threadRepository.findByPostId(postId);
-        PostVote voteToAdd = new PostVote(currentUser, targetPost, VoteType.DOWNVOTE);
-        postVoteRepository.save(voteToAdd);
-        targetPost.getAuthor().setKarma(targetPost.getAuthor().getKarma()-1);
-        userRepository.save(targetPost.getAuthor());
-    }
-
-    public void deleteOpinion(Long postId) {opinionRepository.deleteById(postId);}
-    public void delete_Thread(Long postId) {_threadRepository.deleteById(postId);}
-
-    public void updateOpinion(String newContent, Long newTargetProfessorId, Long newParentPostId, Long postId) {
-        Opinion opinionToUpdate = opinionRepository.findByPostId(postId);
-
-        opinionToUpdate.setContent(newContent);
-
-        Professor newTargetProfessor = professorRepository.findByProfessorId(newTargetProfessorId);
-        opinionToUpdate.setTargetProfessor(newTargetProfessor);
-
-        Opinion newParentOpinion = null;
-        if (newParentPostId != -1) {
-            newParentOpinion = opinionRepository.findByPostId(newParentPostId);
-            if (!newParentOpinion.getTargetProfessor().equals(newTargetProfessor))
-                throw new IncompatiblePostId("Мислењето не припаѓа во специфицираната секција за дискусија.");
-            if (opinionToUpdate.getChildren().contains(newParentOpinion))
-                throw new DisallowedOperationException("Мислењето не може да се постави како дете на негово дете (бесконечна рекурзија)");
-        }
-        opinionToUpdate.setParent(newParentOpinion);
-
-        propagateNewTargetProfessorToChildren(opinionToUpdate, newTargetProfessor);
-
-        opinionToUpdate.setTimeLastEdited(LocalDateTime.now());
-        opinionRepository.save(opinionToUpdate);
-    }
-
-    public void propagateNewTargetProfessorToChildren(Opinion opinionToUpdate, Professor newTargetProfessor) {
-        for(Post p : opinionToUpdate.getChildren()) {
-            // direct children
-            Opinion o = (Opinion) p;
-            o.setTargetProfessor(newTargetProfessor);
-            // ancestors
-            if(o.getChildren().isEmpty()) return;
-            propagateNewTargetProfessorToChildren(o, newTargetProfessor);
+            currentUser.getLikedPosts().add(targetOpinion);
+            userRepository.save(currentUser);
         }
     }
 
-    public void update_Thread(String newTitle, String newContent, Long newTargetSubjectId, Long newParentThreadId, Long postId) {
-        _Thread _threadToUpdate = _threadRepository.findByPostId(postId);
+    public void downvoteOpinion(Long postId, CustomUserDetails currentUser) {
+        Opinion targetOpinion = opinionRepository.findByPostId(postId);
 
-        _threadToUpdate.setContent(newContent);
+        if (!targetOpinion.getDislikes().contains(currentUser)) {
 
-        Subject newTargetSubject = subjectRepository.findBySubjectId(newTargetSubjectId);
-        _threadToUpdate.setTargetSubject(newTargetSubject);
+            targetOpinion.getDislikes().add(currentUser);
+            // opinionRepository.save(targetOpinion);
 
-        _Thread newParentThread = null;
-        if(newParentThreadId != -1) {
-            newParentThread = _threadRepository.findByPostId(newParentThreadId);
-            if (!newParentThread.getTargetSubject().equals(newTargetSubject))
-                throw new IncompatiblePostId("Мислењето не припаѓа во специфицираната секција за дискусија.");
-            if (_threadToUpdate.getChildren().contains(newParentThread))
-                throw new DisallowedOperationException("Мислењето не може да се постави како дете на негово дете (бесконечна рекурзија)");
-        }
-        _threadToUpdate.setParent(newParentThread);
+            targetOpinion.getAuthor().setKarma(targetOpinion.getAuthor().getKarma() - 1);
+            userRepository.save(targetOpinion.getAuthor());
 
-            if(_threadToUpdate.getParent() == null) {
-             _threadToUpdate.setTitle(newTitle);
-            } else {
-                _threadToUpdate.setTitle(null);
-            }
-
-         propagateNewTargetSubjectToChildren(_threadToUpdate, newTargetSubject);
-
-         _threadToUpdate.setTimeLastEdited(LocalDateTime.now());
-          _threadRepository.save(_threadToUpdate);
-    }
-
-    public void propagateNewTargetSubjectToChildren(_Thread _threadToUpdate, Subject newTargetSubject) {
-        for(Post p : _threadToUpdate.getChildren()) {
-            // direct children
-            _Thread t = (_Thread) p;
-            t.setTargetSubject(newTargetSubject);
-            // ancestors
-            if (t.getChildren().isEmpty()) return;
-            propagateNewTargetSubjectToChildren(t, newTargetSubject);
+            currentUser.getDislikedPosts().add(targetOpinion);
+            userRepository.save(currentUser);
         }
     }
-
-    public void lockUser(Long userId) {
-        CustomUserDetails user = userRepository.findById(userId).orElseThrow(() -> new UsernameNotFoundException("Invalid userId"));
-        user.setLocked(true);
-        userRepository.save(user);
-    }
-
-    public void deleteUser(Long userId) {
-        userRepository.deleteById(userId);
-    }
-
-
-    public void updateUserFullName(String newFullName, Long userId) {
-        CustomUserDetails user = userRepository.findById(userId).orElseThrow(() -> new UsernameNotFoundException("Invalid userId"));
-        user.setFullName(newFullName);
-        userRepository.save(user);
-    }
-
-    public void updateUserUsername(String newUsername, Long userId) {
-        CustomUserDetails user = userRepository.findById(userId).orElseThrow(() -> new UsernameNotFoundException("Invalid userId"));
-        user.setUsername(newUsername);
-        userRepository.save(user);
-    }
-
-
-    public void reportOpinion(Long postId, CustomUserDetails currentUser, String description) {
-            Post targetPost = opinionRepository.findByPostId(postId);
-            PostReport reportToAdd = new PostReport(currentUser, targetPost, description);
-            postReportRepository.save(reportToAdd);
-    }
-
-    public void markReport(Long postReportId, String action) {
-        PostReport report = postReportRepository.findByPostReportId(postReportId);
-        if (action.equals("resolve")) report.setResolved(true);
-        else if (action.equals("open")) report.setResolved(false);
-        postReportRepository.save(report);
-     }
-
-    public List<PostReport> getAllPostReports() {
-        return postReportRepository.findAll();
-    }
-
-    public void reportThread(Long postId, CustomUserDetails currentUser, String description) {
-        Post targetPost = _threadRepository.findByPostId(postId);
-        PostReport reportToAdd = new PostReport(currentUser, targetPost, description);
-        postReportRepository.save(reportToAdd);
-    }
-
-    public List<Opinion> getRelatedOpinions(Long professorId) {
-        Professor p = professorRepository.findByProfessorId(professorId);
-        return opinionRepository.findByTargetProfessor(p);
-    }
-
-    public List<Opinion> getLatest10Opinions() {
-        return opinionRepository.findTop10ByOrderByTimePosted();
-    }
-    public List<_Thread> getLatest10Threads() {
-        return _threadRepository.findTop10ByOrderByTimePosted();
-    }
-
-    public List<String> getUniversitySectionAndPostCount() {
-        return universityRepository.findSectionAndPostCount();
-    }
-
-    public List<Subject> getSubjectsByStudyProgramme(Long studyProgrammeId) {
-        StudyProgramme sp = studyProgrammeRepository.findByStudyProgrammeId(studyProgrammeId);
-        return subjectRepository.findByStudyProgramme(sp);
-    }
-
-    public List<String> getOpinionCountForEachProfessorInFaculty(Long id) {
-        return facultyRepository.getOpinionCountForEachProfessorInFaculty(id);
-    }
-
-    public List<_Thread> getThreadsBySubject(Long id) {
-        Subject s = subjectRepository.findBySubjectId(id);
-        return _threadRepository.findByTargetSubject(s);
-    }
-
-    public List<String> getThreadCountForEachSubjectInStudyProgramme(Long id) {
-        return studyProgrammeRepository.getThreadCountForEachSubjectInStudyProgramme(id);
-    }
-
-    public Set<Post> getPostsByUser(String email) {
-        CustomUserDetails u = userRepository.findByEmail(email).orElseThrow(
-                () -> new UsernameNotFoundException(String.format("User with email %s not found", email)));
-        return postRepository.findByAuthor(u);
-    }
-
-    public CustomUserDetails getPublicUserProfile(Long id) {
-        return userRepository.findById(id).orElseThrow(
-                () -> new UsernameNotFoundException(String.format("User with id %d not found", id)));
-    }
 }
Index: springapp/src/main/java/mk/profesori/springapp/Service/RegistrationService.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Service/RegistrationService.java	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/java/mk/profesori/springapp/Service/RegistrationService.java	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -45,5 +45,5 @@
                 String tokenToResend = customUserDetailsService
                         .createToken(userRepository.findByEmail(request.getEmail()).get());
-                String link = "http://192.168.1.108:8080/registration/confirm?token=" + tokenToResend;
+                String link = "http://192.168.0.17:8080/registration/confirm?token=" + tokenToResend;
                 emailSender.send(request.getEmail(), emailSender.buildEmail(request.getUsername(), link));
                 return tokenToResend;
@@ -66,5 +66,5 @@
                         UserRole.REGULAR));
 
-        String link = "http://192.168.1.108:8080/registration/confirm?token=" + token;
+        String link = "http://192.168.0.17:8080/registration/confirm?token=" + token;
 
         emailSender.send(request.getEmail(), emailSender.buildEmail(request.getUsername(), link));
Index: springapp/src/main/resources/application.properties
===================================================================
--- springapp/src/main/resources/application.properties	(revision 8dffe022a42c8c6fdea90df3276eb16b6610b51f)
+++ springapp/src/main/resources/application.properties	(revision ebc51762bbd1b4345d8908789af87bdc49aad058)
@@ -1,13 +1,13 @@
-spring.datasource.url=jdbc:postgresql://localhost:5432/profesorimk
+spring.datasource.url=jdbc:postgresql://localhost:5432/profesori.mk
+spring.datasource.connectionProperties=useUnicode=true;characterEncoding=utf-8;
 spring.datasource.username=postgres
-spring.datasource.password=postgres
+spring.datasource.password=1win7337
 spring.jpa.hibernate.ddl-auto=update
+spring.jpa.show-sql=false
 spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
-spring.jpa.show-sql=false
 spring.jpa.properties.hibernate.format_sql=true
-server.address=192.168.1.108
-spring.mail.host=192.168.1.108
+server.address=192.168.0.17
+spring.mail.host=192.168.0.24
 spring.mail.username=mailuser
 spring.mail.password=mailpass
 spring.mail.port=1025
-spring.jpa.open-in-view=false
