Index: .run/Clean DB.run.xml
===================================================================
--- .run/Clean DB.run.xml	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
+++ .run/Clean DB.run.xml	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -0,0 +1,74 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="Clean DB" type="MavenRunConfiguration" factoryName="Maven" focusToolWindowBeforeRun="true">
+    <MavenSettings>
+      <option name="myGeneralSettings">
+        <MavenGeneralSettings>
+          <option name="alwaysUpdateSnapshots" value="false" />
+          <option name="checksumPolicy" value="NOT_SET" />
+          <option name="customMavenHome" />
+          <option name="emulateTerminal" value="false" />
+          <option name="failureBehavior" value="NOT_SET" />
+          <option name="localRepository" value="" />
+          <option name="mavenHome" value="Bundled (Maven 3)" />
+          <option name="mavenHomeTypeForPersistence" value="BUNDLED3" />
+          <option name="nonRecursive" value="false" />
+          <option name="outputLevel" value="INFO" />
+          <option name="printErrorStackTraces" value="false" />
+          <option name="showDialogWithAdvancedSettings" value="false" />
+          <option name="threads" />
+          <option name="useMavenConfig" value="true" />
+          <option name="userSettingsFile" value="" />
+          <option name="workOffline" value="false" />
+        </MavenGeneralSettings>
+      </option>
+      <option name="myRunnerSettings">
+        <MavenRunnerSettings>
+          <option name="delegateBuildToMaven" value="false" />
+          <option name="environmentProperties">
+            <map>
+              <entry key="POSTGRES_DB" value="build_board" />
+              <entry key="POSTGRES_PASSWORD" value="lajno123L" />
+              <entry key="POSTGRES_USER" value="viki" />
+            </map>
+          </option>
+          <option name="jreName" value="#USE_PROJECT_JDK" />
+          <option name="mavenProperties">
+            <map />
+          </option>
+          <option name="passParentEnv" value="true" />
+          <option name="runMavenInBackground" value="true" />
+          <option name="skipTests" value="false" />
+          <option name="vmOptions" value="" />
+        </MavenRunnerSettings>
+      </option>
+      <option name="myRunnerParameters">
+        <MavenRunnerParameters>
+          <option name="cmdOptions" />
+          <option name="profiles">
+            <set />
+          </option>
+          <option name="goals">
+            <list>
+              <option value="flyway:clean" />
+              <option value="-Dflyway.user=${POSTGRES_USER}" />
+              <option value="-Dflyway.password=${POSTGRES_PASSWORD}" />
+              <option value="-Dflyway.url=jdbc:postgresql://localhost:5432/${POSTGRES_DB}" />
+              <option value="-Dflyway.cleanDisabled=false" />
+            </list>
+          </option>
+          <option name="multimoduleDir" />
+          <option name="pomFileName" />
+          <option name="profilesMap">
+            <map />
+          </option>
+          <option name="projectsCmdOptionValues">
+            <list />
+          </option>
+          <option name="resolveToWorkspace" value="false" />
+          <option name="workingDirPath" value="$PROJECT_DIR$" />
+        </MavenRunnerParameters>
+      </option>
+    </MavenSettings>
+    <method v="2" />
+  </configuration>
+</component>
Index: compose.yml
===================================================================
--- compose.yml	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
+++ compose.yml	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -0,0 +1,8 @@
+services:
+  db:
+    ports:
+      - '5432:5432'
+    image: postgres
+    env_file:
+      - env
+    container_name: build_board_db
Index: docs/test-data.sql
===================================================================
--- docs/test-data.sql	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ docs/test-data.sql	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -17,8 +17,13 @@
     ('Further discussion on topic 2', 5);
 
-INSERT INTO topic_thread (id, title, guidelines, parent_id)
+INSERT INTO topic_thread (id, title, parent_id)
 VALUES
-    (1, 'Topic 1', '{"rule1": "Follow guidelines"}', NULL),
-    (2, 'Topic 2', '{"rule2": "Be respectful"}', NULL);
+    (1, 'Topic 1' , NULL),
+    (2, 'Topic 2', NULL);
+
+insert into topic_guidelines(topic_id,description)
+values
+    (1,'Follow guidelines'),
+    ( 2,'Be respectful');
 
 INSERT INTO discussion_thread (id, parent_id)
Index: env
===================================================================
--- env	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
+++ env	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -0,0 +1,3 @@
+POSTGRES_USER=viki
+POSTGRES_DB=build_board
+POSTGRES_PASSWORD=lajno123L
Index: pom.xml
===================================================================
--- pom.xml	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ pom.xml	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -26,11 +26,8 @@
 <!--            <version>6.4.1</version>-->
 <!--        </dependency>-->
-
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-security</artifactId>
         </dependency>
-
-
         <dependency>
             <groupId>org.springframework.boot</groupId>
@@ -46,5 +43,6 @@
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
-            <optional>true</optional>
+            <version>1.18.30</version>
+            <scope>provided</scope>
         </dependency>
         <dependency>
@@ -74,29 +72,10 @@
         <plugins>
             <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <annotationProcessorPaths>
-                        <path>
-                            <groupId>org.projectlombok</groupId>
-                            <artifactId>lombok</artifactId>
-                        </path>
-                    </annotationProcessorPaths>
-                </configuration>
-            </plugin>
-            <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
                 <configuration>
-                    <excludes>
-                        <exclude>
-                            <groupId>org.projectlombok</groupId>
-                            <artifactId>lombok</artifactId>
-                        </exclude>
-                    </excludes>
                 </configuration>
             </plugin>
         </plugins>
     </build>
-
 </project>
Index: src/main/java/com/db/finki/www/build_board/config/WebSecurityConfig.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/config/WebSecurityConfig.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/config/WebSecurityConfig.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -1,10 +1,4 @@
 package com.db.finki.www.build_board.config;
 
-import com.db.finki.www.build_board.entity.BBUser;
-import com.db.finki.www.build_board.service.AuthenticationSuccessHandlerImpl;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -12,17 +6,12 @@
 import org.springframework.security.authentication.AuthenticationProvider;
 import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
-import org.springframework.security.config.Customizer;
 import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
-import org.springframework.security.core.Authentication;
 import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
-
-import java.io.IOException;
 
 @Configuration
Index: src/main/java/com/db/finki/www/build_board/controller/ProjectController.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/controller/ProjectController.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/controller/ProjectController.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -1,21 +1,110 @@
 package com.db.finki.www.build_board.controller;
 
+import com.db.finki.www.build_board.entity.threads.Project;
+import com.db.finki.www.build_board.entity.user_types.BBUser;
+import com.db.finki.www.build_board.service.threads.impl.ProjectService;
+import com.db.finki.www.build_board.service.threads.impl.TagServiceImpl;
+import com.db.finki.www.build_board.service.threads.itfs.TagService;
+import org.hibernate.Hibernate;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.*;
 
 @Controller
-@RequestMapping("/projects")
+@RequestMapping("/project")
 public class ProjectController {
-    @GetMapping()
-    public String getProjectsPage(Model model) {
-        return "project";
-    }
-    @GetMapping("{pid}")
-    public String getProjectPage(@PathVariable Long pid, Model model) {
-        return "project";
+
+    private final ProjectService projectService;
+    private final TagService topicService;
+
+    public ProjectController(ProjectService projectService, TagServiceImpl topicService) {
+        this.projectService = projectService;
+        this.topicService = topicService;
     }
 
+    @GetMapping("/{title}")
+    public String getProjectPage(@PathVariable String title, Model model) {
+        Project project = projectService.findByTitle(title);
+
+        model.addAttribute("project", project);
+        model.addAttribute("tags", topicService.findAll());
+        Hibernate.initialize(project.getTags());
+
+        return "project_pages/show-project";
+    }
+
+    @GetMapping("/create")
+    public String getCreateProjectPage(Model model) {
+        model.addAttribute("project", new Project());
+        model.addAttribute("isCreatingProject", topicService.findAll());
+        return "project_pages/project-create";
+    }
+
+
+    @GetMapping("{title}/topic/add")
+    public String getAddTopicPage(
+            @PathVariable String title,
+            Model model
+    ){
+        model.addAttribute("project_title",title);
+        return "create-topic" ;
+    }
+
+    @GetMapping("/{pr_title}/modify")
+    public String getModifyPage(
+            @PathVariable(name = "pr_title") String title,
+            Model model
+    ) {
+        model.addAttribute("project", projectService.findByTitle(title));
+        return "project_pages/project-create";
+    }
+
+    @PostMapping("/{title}/modify")
+    public String modifyProject(
+            @PathVariable String title,
+            @RequestParam(name = "title") String newTitle,
+            @RequestParam(name = "repo_url") String repoUrl,
+            @RequestParam String description
+    ){
+        return "redirect:/project/" +  projectService.updateProject(title,repoUrl,description,newTitle).getTitle();
+    }
+
+    @PostMapping("/add")
+    public String createProject(
+            @RequestParam String title,
+            @RequestParam(required = false, name = "repo_url") String repoUrl,
+            @RequestParam(required = false) String description,
+            @SessionAttribute BBUser user
+    ) {
+        projectService.create(title,repoUrl,description,user);
+        return "redirect:/";
+    }
+
+    @PostMapping("/topic/add")
+    public String addTopic(
+            @RequestParam(name = "project_title") String projectTitle,
+            @RequestParam(name = "title") String topicsTitle,
+            @RequestParam String description,
+            @SessionAttribute BBUser user
+    ){
+        projectService.addToProjectWithIdNewTopic(projectTitle, topicsTitle,description,user);
+        return "redirect:/project/" + projectTitle;
+    }
+
+    @PostMapping("/delete/*")
+    public String delete(@RequestParam Long id) {
+        projectService.deleteById(id);
+        return "redirect:/" ;
+    }
+
+    @PostMapping("/{title}/add-tag")
+    public String addTag(
+            @PathVariable String title,
+            @RequestParam(name = "tagName") String tagName
+    )
+    {
+        projectService.addTagToProjectWithTitle(title,tagName);
+        return "redirect:/project/" + title;
+    }
 }
+///projects/topics/add
Index: src/main/java/com/db/finki/www/build_board/controller/TopicController.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/controller/TopicController.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/controller/TopicController.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -1,5 +1,5 @@
 package com.db.finki.www.build_board.controller;
 
-import com.db.finki.www.build_board.entity.BBUser;
+import com.db.finki.www.build_board.entity.user_types.BBUser;
 import com.db.finki.www.build_board.entity.threads.Topic;
 import com.db.finki.www.build_board.service.threads.itfs.TagService;
Index: c/main/java/com/db/finki/www/build_board/entity/BBUser.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/entity/BBUser.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ 	(revision )
@@ -1,73 +1,0 @@
-package com.db.finki.www.build_board.entity;
-
-import com.db.finki.www.build_board.entity.threads.BBThread;
-import jakarta.persistence.*;
-import lombok.Getter;
-import lombok.Setter;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
-import java.io.Serializable;
-import java.time.LocalDateTime;
-import java.util.Collection;
-import java.util.List;
-@Entity
-@Table(name = "users")
-@Getter @Setter
-@Inheritance(strategy = InheritanceType.JOINED)
-public class BBUser implements UserDetails, Serializable {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private int id;
-    private String username;
-    private String password;
-    private String description;
-    @Column(name = "registered_at")
-    private LocalDateTime registeredAt;
-    @Column(name = "is_activate")
-    private boolean isEnabled;
-    private String sex;
-
-    @OneToMany(mappedBy = "user")
-    private List<BBThread> threads;
-
-    @Override
-    public boolean isEnabled() {
-        return isEnabled;
-    }
-
-    @Override
-    public String getUsername() {
-        return username;
-    }
-    @Override
-    public String getPassword() {
-        return password;
-    }
-    @Override
-    public Collection<? extends GrantedAuthority> getAuthorities() {
-        return List.of();
-    }
-
-
-    public int getId() {
-        return id;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public LocalDateTime getRegisteredAt() {
-        return registeredAt;
-    }
-
-    public String getSex() {
-        return sex;
-    }
-
-    public List<BBThread> getThreads() {
-        return threads;
-    }
-}
Index: c/main/java/com/db/finki/www/build_board/entity/Moderator.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/entity/Moderator.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ 	(revision )
@@ -1,10 +1,0 @@
-package com.db.finki.www.build_board.entity;
-
-import jakarta.persistence.Entity;
-import jakarta.persistence.Table;
-
-@Entity
-@Table(name = "moderator")
-public class Moderator extends BBUser {
-
-}
Index: src/main/java/com/db/finki/www/build_board/entity/threads/BBThread.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/entity/threads/BBThread.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/entity/threads/BBThread.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -1,9 +1,7 @@
 package com.db.finki.www.build_board.entity.threads;
 
-import com.db.finki.www.build_board.entity.BBUser;
+import com.db.finki.www.build_board.entity.user_types.BBUser;
 import jakarta.persistence.*;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
+import lombok.*;
 
 import java.util.ArrayList;
@@ -11,7 +9,5 @@
 
 @Entity
-@Getter
-@Setter
-@NoArgsConstructor
+@Data
 @Table(name = "thread")
 @Inheritance(strategy = InheritanceType.JOINED)
@@ -34,29 +30,3 @@
     )
     protected List<Tag> tags = new ArrayList<>();
-
-    public Integer getId() {return id;}
-
-    public void setContent(String content) {
-        this.content = content;
-    }
-
-    public void setTags(List<Tag> tags) {
-        this.tags = tags;
-    }
-
-    public void setUser(BBUser user) {
-        this.user = user;
-    }
-
-    public String getContent() {
-        return content;
-    }
-
-    public BBUser getUser() {
-        return user;
-    }
-
-    public List<Tag> getTags() {
-        return tags;
-    }
 }
Index: src/main/java/com/db/finki/www/build_board/entity/threads/Project.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/entity/threads/Project.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/entity/threads/Project.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -1,9 +1,16 @@
 package com.db.finki.www.build_board.entity.threads;
 
+import com.db.finki.www.build_board.entity.user_types.BBUser;
 import com.db.finki.www.build_board.entity.threads.interfaces.NamedThread;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.Table;
+import jakarta.persistence.*;
+import lombok.*;
 
+import java.util.ArrayList;
+import java.util.List;
+
+//TODO: implement crud opertaions on project and associated features
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = false)
 @Entity
 @Table(name = "project_thread")
@@ -11,11 +18,22 @@
 
     private String title;
+
     @Column(name = "repo_url")
     private String repoUrl;
 
-    @Override
-    public String getTitle() {
-        return title;
+    public Project(String title, String repoUrl, String description, BBUser user){
+        setTitle(title);
+        setRepoUrl(repoUrl);
+        setDescription(description);
+        setUser(user);
     }
+
+    @OneToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE})
+    @JoinTable(
+            name = "topic_belongs_to_project",
+            joinColumns = @JoinColumn(name = "project_id", referencedColumnName = "id"),
+            inverseJoinColumns = @JoinColumn(name = "topic_id")
+    )
+    private List<Topic> topics = new ArrayList<>();
 
     @Override
@@ -23,3 +41,6 @@
         return "project";
     }
+    public String getDescription() {return content;}
+    public void setDescription(String description) {this.content = description;}
+
 }
Index: src/main/java/com/db/finki/www/build_board/entity/threads/Tag.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/entity/threads/Tag.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/entity/threads/Tag.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -6,9 +6,14 @@
 import jakarta.persistence.Table;
 import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
 
 import java.util.ArrayList;
 import java.util.List;
 
+@Data
 @Entity
+@NoArgsConstructor
 @Table(name = "tag")
 public class Tag {
@@ -16,16 +21,6 @@
     String name;
 
-
     public Tag(String name) {
         this.name = name;
-    }
-    public Tag(){}
-
-    public List<BBThread> getThreads() {
-        return threads;
-    }
-
-    public String getName() {
-        return name;
     }
 
Index: src/main/java/com/db/finki/www/build_board/entity/threads/Topic.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/entity/threads/Topic.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/entity/threads/Topic.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -2,26 +2,20 @@
 
 import com.db.finki.www.build_board.entity.threads.interfaces.NamedThread;
-import jakarta.persistence.Entity;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
-import lombok.Data;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-import org.hibernate.annotations.JdbcTypeCode;
-import org.hibernate.type.SqlTypes;
+import com.db.finki.www.build_board.entity.threads.multi_valued_attributes.Guideline;
+import jakarta.persistence.*;
+import lombok.*;
 
 import java.util.Map;
+import java.util.List;
 
+@Data
+@EqualsAndHashCode(callSuper = false)
 @Entity
-@NoArgsConstructor
 @Table(name = "topic_thread")
 public class Topic extends BBThread implements NamedThread {
-
     private String title;
 
-    @JdbcTypeCode(SqlTypes.JSON)
-    private Map<String,String> guidelines;
+    @OneToMany(mappedBy = "topic")
+    private List<Guideline> guidelines;
 
     @ManyToOne
@@ -31,8 +25,3 @@
     @Override
     public String getTypeName() {return "topic";}
-    @Override
-    public Integer getId() {return super.getId();}
-    @Override
-    public String getTitle() {return this.title;}
-    public void setTitle(String title) {this.title = title;}
 }
Index: src/main/java/com/db/finki/www/build_board/entity/threads/multi_valued_attributes/Guideline.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/entity/threads/multi_valued_attributes/Guideline.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
+++ src/main/java/com/db/finki/www/build_board/entity/threads/multi_valued_attributes/Guideline.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -0,0 +1,20 @@
+package com.db.finki.www.build_board.entity.threads.multi_valued_attributes;
+
+import com.db.finki.www.build_board.entity.threads.Topic;
+import jakarta.persistence.*;
+import lombok.Data;
+
+@Data
+@Entity
+@Table(name = "topic_guidelines")
+public class Guideline {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "topic_id")
+    private Topic topic;
+
+    private String description;
+}
Index: src/main/java/com/db/finki/www/build_board/entity/user_types/BBUser.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/entity/user_types/BBUser.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
+++ src/main/java/com/db/finki/www/build_board/entity/user_types/BBUser.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -0,0 +1,48 @@
+package com.db.finki.www.build_board.entity.user_types;
+
+import com.db.finki.www.build_board.entity.threads.BBThread;
+import jakarta.persistence.*;
+import lombok.Data;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.Collection;
+import java.util.List;
+
+@Data
+@Entity
+@Table(name = "users")
+@Inheritance(strategy = InheritanceType.JOINED)
+public class BBUser implements UserDetails, Serializable {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private int id;
+    private String username;
+    private String password;
+    private String description;
+
+    @Column(name = "registered_at")
+    private LocalDateTime registeredAt;
+
+    @Column(name = "is_activate")
+    private boolean isEnabled;
+    private String sex;
+
+    @OneToMany(mappedBy = "user")
+    private List<BBThread> threads;
+
+    @Override
+    public boolean isEnabled() {
+        return isEnabled;
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        return List.of();
+    }
+
+
+}
Index: src/main/java/com/db/finki/www/build_board/entity/user_types/Moderator.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/entity/user_types/Moderator.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
+++ src/main/java/com/db/finki/www/build_board/entity/user_types/Moderator.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -0,0 +1,10 @@
+package com.db.finki.www.build_board.entity.user_types;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "moderator")
+public class Moderator extends BBUser {
+
+}
Index: src/main/java/com/db/finki/www/build_board/entity/user_types/ProjectOwner.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/entity/user_types/ProjectOwner.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
+++ src/main/java/com/db/finki/www/build_board/entity/user_types/ProjectOwner.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -0,0 +1,11 @@
+package com.db.finki.www.build_board.entity.user_types;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+import lombok.Data;
+
+@Data
+@Entity
+@Table(name = "project_manager")
+public class ProjectOwner extends BBUser{
+}
Index: src/main/java/com/db/finki/www/build_board/repository/UserRepository.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/repository/UserRepository.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/repository/UserRepository.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -1,5 +1,5 @@
 package com.db.finki.www.build_board.repository;
 
-import com.db.finki.www.build_board.entity.BBUser;
+import com.db.finki.www.build_board.entity.user_types.BBUser;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
Index: src/main/java/com/db/finki/www/build_board/repository/threads/ProjectRepository.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/repository/threads/ProjectRepository.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/repository/threads/ProjectRepository.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -7,4 +7,5 @@
 @Repository
 public interface ProjectRepository extends JpaRepository<Project, Long> {
-
+    Project findByTitleStartingWith(String title);
+    void deleteByTitle(String title);
 }
Index: src/main/java/com/db/finki/www/build_board/service/AuthenticationSuccessHandlerImpl.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/service/AuthenticationSuccessHandlerImpl.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/service/AuthenticationSuccessHandlerImpl.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -1,13 +1,11 @@
 package com.db.finki.www.build_board.service;
 
-import com.db.finki.www.build_board.entity.BBUser;
+import com.db.finki.www.build_board.entity.user_types.BBUser;
 import jakarta.servlet.ServletException;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpSession;
-import org.springframework.context.annotation.Primary;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
-import org.springframework.stereotype.Component;
 
 import java.io.IOException;
Index: src/main/java/com/db/finki/www/build_board/service/UserService.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/service/UserService.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/service/UserService.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -1,5 +1,5 @@
 package com.db.finki.www.build_board.service;
 
-import com.db.finki.www.build_board.entity.BBUser;
+import com.db.finki.www.build_board.entity.user_types.BBUser;
 
 public interface UserService {
Index: src/main/java/com/db/finki/www/build_board/service/threads/impl/NamedThreadService.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/service/threads/impl/NamedThreadService.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/service/threads/impl/NamedThreadService.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -2,22 +2,22 @@
 
 import com.db.finki.www.build_board.entity.threads.interfaces.NamedThread;
+import com.db.finki.www.build_board.service.threads.itfs.TopicService;
 import org.springframework.stereotype.Service;
 
-import java.util.Collections;
 import java.util.List;
 
 @Service
 public class NamedThreadService {
-    //TODO: Add project support also
-     private final TopicServiceImpl topicsService;
+    private final TopicService topicService;
+    private final ProjectService projectService;
 
-    public NamedThreadService(TopicServiceImpl topicsService) {
-        this.topicsService = topicsService;
+    public NamedThreadService(TopicServiceImpl topicService, ProjectService projectService) {
+        this.topicService = topicService;
+        this.projectService = projectService;
     }
 
     public List<NamedThread> findAll(){
-        List<NamedThread> results = (List<NamedThread>) (List<?>) topicsService.getAll();
-
-        Collections.shuffle(results);
+        List<NamedThread> results = (List<NamedThread>) (List<?>) topicService.getAll();
+        results.addAll((List<NamedThread>)(List<?>) projectService.getAll());
         return results;
     }
Index: src/main/java/com/db/finki/www/build_board/service/threads/impl/ProjectService.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/service/threads/impl/ProjectService.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
+++ src/main/java/com/db/finki/www/build_board/service/threads/impl/ProjectService.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -0,0 +1,70 @@
+package com.db.finki.www.build_board.service.threads.impl;
+
+import java.util.List;
+
+import com.db.finki.www.build_board.entity.threads.Tag;
+import com.db.finki.www.build_board.entity.user_types.BBUser;
+import com.db.finki.www.build_board.entity.threads.Project;
+import com.db.finki.www.build_board.repository.threads.ProjectRepository;
+import com.db.finki.www.build_board.service.threads.itfs.TagService;
+import com.db.finki.www.build_board.service.threads.itfs.TopicService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ProjectService {
+    private final ProjectRepository projectRepository;
+    private final TopicService topicService;
+    private final TagService tagService;
+
+    public ProjectService(ProjectRepository projectRepository, TopicServiceImpl topicService, TagServiceImpl tagService) {
+        this.projectRepository = projectRepository;
+        this.topicService = topicService;
+        this.tagService = tagService;
+    }
+
+    public List<Project> getAll(){
+        return projectRepository.findAll();
+    }
+
+    public void create(String title, String repoUrl, String description, BBUser user) {
+        projectRepository.save(
+                new Project(title, repoUrl, description, user)
+        );
+    }
+
+    public Project findByTitle(String title) {
+        return projectRepository.findByTitleStartingWith(title);
+    }
+
+    public void addToProjectWithIdNewTopic(String projectTitle, String title, String description, BBUser user) {
+        Project project = findByTitle(projectTitle);
+        project.getTopics().add(
+                topicService.create(title, description, user)
+        );
+        projectRepository.save(project);
+    }
+
+    public void deleteById(Long id) {
+        projectRepository.deleteById(id);
+    }
+
+    public void addTagToProjectWithTitle(String title, String tagName) {
+        Project project = findByTitle(title);
+        Tag tag = null ;
+        try{
+            tag=tagService.findByName(tagName);
+        }catch (IllegalArgumentException ignore){
+             tag=tagService.create(tagName);
+        }
+        project.getTags().add(tag);
+        projectRepository.save(project);
+    }
+
+    public Project updateProject(String projectTitle, String repoUrl, String description, String newTitle) {
+        Project project = findByTitle(projectTitle);
+        project.setRepoUrl(repoUrl);
+        project.setDescription(description);
+        project.setTitle(newTitle);
+        return projectRepository.save(project);
+    }
+}
Index: src/main/java/com/db/finki/www/build_board/service/threads/impl/TagServiceImpl.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/service/threads/impl/TagServiceImpl.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/service/threads/impl/TagServiceImpl.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -25,3 +25,6 @@
         return tagRepository.findAll();
     }
+    public Tag create(String tagName){
+        return tagRepository.save(new Tag(tagName));
+    }
 }
Index: src/main/java/com/db/finki/www/build_board/service/threads/impl/TopicServiceImpl.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/service/threads/impl/TopicServiceImpl.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/service/threads/impl/TopicServiceImpl.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -1,5 +1,5 @@
 package com.db.finki.www.build_board.service.threads.impl;
 
-import com.db.finki.www.build_board.entity.BBUser;
+import com.db.finki.www.build_board.entity.user_types.BBUser;
 import com.db.finki.www.build_board.entity.threads.Tag;
 import com.db.finki.www.build_board.entity.threads.Topic;
@@ -24,10 +24,10 @@
 
     @Override
-    public void create(String title, String description, BBUser user) {
+    public Topic create(String title, String description, BBUser user) {
         Topic topic = new Topic();
         topic.setTitle(title);
         topic.setContent(description);
         topic.setUser(user);
-        topicRepository.save(topic);
+        return topicRepository.save(topic);
     }
 
Index: src/main/java/com/db/finki/www/build_board/service/threads/itfs/TagService.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/service/threads/itfs/TagService.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/service/threads/itfs/TagService.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -9,3 +9,4 @@
     Tag findByName(String name);
     List<Tag> findAll();
+    Tag create(String name);
 }
Index: src/main/java/com/db/finki/www/build_board/service/threads/itfs/TopicService.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/service/threads/itfs/TopicService.java	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/java/com/db/finki/www/build_board/service/threads/itfs/TopicService.java	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -1,10 +1,10 @@
 package com.db.finki.www.build_board.service.threads.itfs;
 
-import com.db.finki.www.build_board.entity.BBUser;
+import com.db.finki.www.build_board.entity.user_types.BBUser;
 import com.db.finki.www.build_board.entity.threads.Topic;
 
 import java.util.List;
 public interface TopicService {
-    void create(String title, String description, BBUser user);
+    Topic create(String title, String description, BBUser user);
     List<Topic> getAll();
     Topic getByTitle(String title);
@@ -12,5 +12,4 @@
     void deleteTopicByTitle(String title);
     Topic getById(Long id);
-
     void addTagToTopic(Topic topic, String tagName);
 }
Index: src/main/resources/application.properties
===================================================================
--- src/main/resources/application.properties	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/resources/application.properties	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -8,2 +8,3 @@
 spring.flyway.user=${POSTGRES_USER}
 spring.jpa.hibernate.ddl-auto=validate
+spring.jpa.show-sql=true
Index: src/main/resources/db/migration/V1__init_ddl.sql
===================================================================
--- src/main/resources/db/migration/V1__init_ddl.sql	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/resources/db/migration/V1__init_ddl.sql	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -55,13 +55,13 @@
 CREATE TABLE moderator
 (
-    id INT PRIMARY KEY REFERENCES users (id)  on delete cascade
+    id INT PRIMARY KEY REFERENCES users (id) on delete cascade
 );
 CREATE TABLE developer
 (
-    id INT PRIMARY KEY REFERENCES users (id)  on delete cascade
+    id INT PRIMARY KEY REFERENCES users (id) on delete cascade
 );
 CREATE TABLE project_manager
 (
-    id INT PRIMARY KEY REFERENCES users (id)  on delete cascade
+    id INT PRIMARY KEY REFERENCES users (id) on delete cascade
 );
 CREATE TABLE thread
@@ -73,13 +73,19 @@
 CREATE TABLE topic_thread
 (
-    title           VARCHAR(256) NOT NULL,
-    guidelines      jsonb,
+    title     VARCHAR(256) NOT NULL,
     parent_id INT REFERENCES thread (id),
-    id              INT PRIMARY KEY REFERENCES thread (id) on delete cascade
+    id        INT PRIMARY KEY REFERENCES thread (id) on delete cascade
+);
+create table topic_guidelines
+(
+    id          serial,
+    topic_id    int references topic_thread (id),
+    description text,
+    PRIMARY KEY (id, topic_id)
 );
 CREATE TABLE discussion_thread
 (
-    parent_id           INT REFERENCES thread (id) on delete cascade NOT NULL,
-    id                  INT PRIMARY KEY REFERENCES thread (id) on delete cascade
+    parent_id INT REFERENCES thread (id) on delete cascade NOT NULL,
+    id        INT PRIMARY KEY REFERENCES thread (id) on delete cascade
 );
 CREATE TABLE project_thread
@@ -107,5 +113,5 @@
 CREATE TABLE tag_threads
 (
-    thread_id INT REFERENCES thread (id) ON DELETE CASCADE ,
+    thread_id INT REFERENCES thread (id) ON DELETE CASCADE,
     tag_name  VARCHAR(64) REFERENCES tag (name) ON DELETE CASCADE,
     PRIMARY KEY (thread_id, tag_name)
@@ -205,4 +211,6 @@
     PRIMARY KEY (channel_name, project_id, sent_at, sent_by)
 );
+
+
 ------------------------VIEWS-----------------------------
 CREATE OR REPLACE VIEW v_project_thread
@@ -214,5 +222,5 @@
 CREATE OR REPLACE VIEW v_discussion_thread
 AS
-SELECT thread.id, content, user_id,parent_id
+SELECT thread.id, content, user_id, parent_id
 FROM discussion_thread discussion
          JOIN thread
@@ -220,5 +228,5 @@
 CREATE OR REPLACE VIEW v_topic_thread
 AS
-SELECT thread.id, content, user_id, title, guidelines, parent_id
+SELECT thread.id, content, user_id, title, parent_id
 FROM topic_thread topic
          JOIN thread
@@ -267,9 +275,10 @@
         FROM topic_thread
                  AS t
-        WHERE t.parent_id = new.parent_id OR (t.parent_id IS NULL AND new.parent_id IS NULL))
+        WHERE t.parent_id = new.parent_id
+           OR (t.parent_id IS NULL AND new.parent_id IS NULL))
     THEN
         RAISE EXCEPTION 'There already exists a topic with title % in parent topic with id %',new.title,new.parent_id;
-END IF;
-RETURN new;
+    END IF;
+    RETURN new;
 END;
 $$;
@@ -280,34 +289,35 @@
 $$
 DECLARE
-v_user_id INT;
+    v_user_id INT;
 BEGIN
-SELECT v_topic_thread.user_id
-INTO v_user_id
-FROM v_topic_thread
-WHERE v_topic_thread.id = new.id;
-INSERT INTO topic_threads_moderators(thread_id, user_id) VALUES (new.id, v_user_id);
-RETURN NEW;
+    SELECT v_topic_thread.user_id
+    INTO v_user_id
+    FROM v_topic_thread
+    WHERE v_topic_thread.id = new.id;
+    INSERT INTO topic_threads_moderators(thread_id, user_id) VALUES (new.id, v_user_id);
+    RETURN NEW;
 END;
 $$;
 
 CREATE OR REPLACE FUNCTION fn_insert_project_manager()
-RETURNS TRIGGER
-LANGUAGE plpgsql
-AS
-    $$
-    DECLARE usrId INT;
+    RETURNS TRIGGER
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    usrId INT;
 BEGIN
-SELECT user_id INTO usrId FROM v_project_thread p WHERE NEW.id = p.id;
-INSERT INTO developer VALUES (usrId);
-INSERT INTO project_manager VALUES (usrId);
-RETURN NEW;
+    SELECT user_id INTO usrId FROM v_project_thread p WHERE NEW.id = p.id;
+    INSERT INTO developer VALUES (usrId);
+    INSERT INTO project_manager VALUES (usrId);
+    RETURN NEW;
 END;
-    $$;
+$$;
 -------------------------- TRIGGERS ----------------------
 CREATE OR REPLACE TRIGGER tr_check_topic_name
     BEFORE INSERT OR UPDATE
-                                ON topic_thread
-                                FOR EACH ROW
-                                EXECUTE FUNCTION fn_validate_topic_title();
+    ON topic_thread
+    FOR EACH ROW
+EXECUTE FUNCTION fn_validate_topic_title();
 CREATE OR REPLACE TRIGGER tr_insert_topics_creator_as_moderator
     AFTER INSERT
@@ -319,3 +329,5 @@
     ON project_thread
     FOR EACH ROW
-    EXECUTE FUNCTION fn_insert_project_manager();
+EXECUTE FUNCTION fn_insert_project_manager();
+
+---TODO: trigeri za trgnanje na project_owner ako se trgnit project i nekoj takvi dependencies
Index: src/main/resources/db/migration/V2__add_test_data.sql
===================================================================
--- src/main/resources/db/migration/V2__add_test_data.sql	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
+++ src/main/resources/db/migration/V2__add_test_data.sql	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -0,0 +1,102 @@
+INSERT INTO users (username, is_activate, password, description, registered_at, sex)
+VALUES
+    ('user1', true, '$2a$12$0f.x7aBM2wFBZBXoLPj0BObVsk.J1kXFYo5nb4niAWkI4hk5tHvDy', 'First user', NOW(), 'M'),
+    ('user2', true, '$2a$12$VkR0a47LDVM6aUqFcEJGSu9jhZCz.05tCoyiRicFObt4f2x2gijKa', 'Second user', NOW(), 'F'),
+    ('user3', true, '$2a$12$eSLdHHJ1KFgv.dOupmloXeItjrt2o1IB6ER6Nq7WYj9Jfr2bEwK2a', 'Third user', NOW(), 'M'),
+    ('user4', true, '$2a$12$dF5SXcNhMulgU3Qre3nh1e.aatRiJZsnfoBSqReGnXe9rIbHYVWhe', 'Fourth user', NOW(), 'F'),
+    ('user5', true, '$2a$12$zHrloz8WG2zo5S6MTf1C0ez1raMlmDJdB8OOa2I1S2pVy9oI76YTa', 'Fifth user', NOW(), 'M');
+
+INSERT INTO thread (content, user_id)
+VALUES
+    ('Main content for topic thread 1', 1),
+    ('Main content for topic thread 2', 2),
+    ('Discussion content for topic 1', 1),
+    ('Discussion content for topic 2', 2),
+    ('Project-specific thread content', 3),
+    ('Reply to topic 1', 4),
+    ('Further discussion on topic 2', 5);
+
+INSERT INTO topic_thread (id, title, parent_id)
+VALUES
+    (1, 'Topic 1' , NULL),
+    (2, 'Topic 2', NULL);
+
+insert into topic_guidelines(topic_id,description)
+values
+    (1,'Follow guidelines'),
+    ( 2,'Be respectful');
+
+INSERT INTO discussion_thread (id, parent_id)
+VALUES
+    (3, 1),
+    (4, 2),
+    (6, 3),
+    (7, 4);
+
+INSERT INTO project_thread (id, title, repo_url)
+VALUES
+    (5, 'Project 1 Thread', 'http://github.com/project1');
+
+INSERT INTO likes (user_id, thread_id)
+VALUES
+    (1, 3),
+    (2, 4),
+    (3, 5),
+    (4, 6),
+    (5, 7);
+INSERT INTO topic_belongs_to_project (topic_id, project_id)
+VALUES
+    (1, 5),
+    (2, 5);
+
+INSERT INTO blacklisted_user (topic_id, user_id, moderator_id, start_date, end_date, reason)
+VALUES
+    (1, 2, 1, NOW(), NOW() + INTERVAL '7 days', 'Spamming'),
+    (2, 3, 4, NOW(), NOW() + INTERVAL '3 days', 'Offensive language');
+
+INSERT INTO developer_associated_with_project (project_id, developer_id, started_at)
+VALUES
+    (5, 2, NOW()),
+    (5, 3, NOW());
+
+INSERT INTO permissions (name)
+VALUES
+    ('Create Thread'),
+    ('Delete Thread');
+
+INSERT INTO project_roles (name, project_id, description)
+VALUES
+    ('Admin', 5, 'Admin role for the project'),
+    ('Developer', 5, 'Developer role for the project');
+
+INSERT INTO users_project_roles (user_id, project_id, role_name)
+VALUES
+    (3, 5, 'Admin'),
+    (2, 5, 'Developer'),
+    (4, 5, 'Developer');
+
+INSERT INTO project_roles_permissions (permission_name, role_name, project_id)
+VALUES
+    ('Create Thread', 'Admin', 5),
+    ('Delete Thread', 'Admin', 5);
+
+INSERT INTO project_request (description, status, user_id, project_id)
+VALUES
+    ('Request to join Project 1', 'PENDING', 2, 5),
+    ('Request to join Project 1', 'ACCEPTED', 4, 5);
+
+INSERT INTO report (created_at, description, status, thread_id, for_user_id, by_user_id)
+VALUES
+    (NOW(), 'Inappropriate content', 'PENDING', 3, 2, 1),
+    (NOW(), 'Spam content', 'DENIED', 6, 4, 3);
+
+INSERT INTO channel (name, description, project_id, developer_id)
+VALUES
+    ('General', 'General discussion channel', 5, 2),
+    ('Updates', 'Project updates channel', 5, 3);
+
+INSERT INTO messages (sent_at, content, sent_by, project_id, channel_name)
+VALUES
+    (NOW(), 'Hello, team!', 2, 5, 'General'),
+    (NOW(), 'We need to push the deadline.', 3, 5, 'Updates');
+
Index: src/main/resources/templates/create-topic.html
===================================================================
--- src/main/resources/templates/create-topic.html	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/resources/templates/create-topic.html	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -9,5 +9,5 @@
 <body>
 
-<main class="container mt-5">
+<main th:with="prefix=${project_title==null ? '' : '/project'}" class="container mt-5">
   <div class="card shadow-sm">
     <div class="card-header bg-primary text-white">
@@ -15,5 +15,5 @@
     </div>
     <div class="card-body">
-      <form action="/topic/add" method="post">
+      <form th:action="@{{prfx}/topic/add(prfx=${prefix})}" method="post">
         <div class="mb-3">
           <label for="title" class="form-label">Title</label>
@@ -25,4 +25,5 @@
         </div>
         <button type="submit" class="btn btn-primary w-100">Submit</button>
+        <input th:if="${!#strings.isEmpty(prefix)}" type="hidden" name="project_title" th:value="${project_title}"/>
       </form>
     </div>
Index: src/main/resources/templates/home.html
===================================================================
--- src/main/resources/templates/home.html	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ src/main/resources/templates/home.html	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -24,5 +24,8 @@
     <div class="d-flex justify-content-between align-items-center mb-3">
         <h1 class="h4">Threads</h1>
-        <a href="/topic/create" class="btn btn-success btn-sm">Create Topic</a>
+        <div>
+            <a href="/topic/create" class="btn btn-success btn-sm">Create Topic</a>
+            <a href="project/create" class="btn btn-success btn-sm">Create Project</a>
+        </div>
     </div>
     <div class="list-group">
@@ -33,8 +36,8 @@
                        th:text="${thread.getTitle()}" class="text-decoration-none"></a>
                 </h5>
-<!--                <small th:text="${thread.getFormattedDate()}">Date</small>-->
+                <!--                <small th:text="${thread.getFormattedDate()}">Date</small>-->
             </div>
-<!--            <p class="mb-1 text-muted" th:text="${thread.getDescription()}">Thread description here...</p>-->
-<!--            <small th:text="${thread.getAuthor()}">Posted by Author</small>-->
+            <!--            <p class="mb-1 text-muted" th:text="${thread.getDescription()}">Thread description here...</p>-->
+            <!--            <small th:text="${thread.getAuthor()}">Posted by Author</small>-->
         </div>
     </div>
Index: c/main/resources/templates/project.html
===================================================================
--- src/main/resources/templates/project.html	(revision 00915a327e7a579b2a064e365bc1cf9f78a4a128)
+++ 	(revision )
@@ -1,136 +1,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <title>Projects</title>
-  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
-  <style>
-    body {
-      background-color: #f8f9fa; /* Light background for the whole page */
-    }
-    .card {
-      background-color: #ffffff; /* White background for the cards */
-      border: 1px solid #dde2e6; /* Light grey border */
-      box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); /* Subtle shadow */
-      transition: transform 0.3s ease, box-shadow 0.3s ease;
-      height: 350px; /* Fixed height for larger cards */
-    }
-    .card:hover {
-      transform: translateY(-5px); /* Slight lift on hover */
-      box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); /* Stronger shadow on hover */
-    }
-    .card-header {
-      background-color: #007bff; /* Blue header color */
-      color: #ffffff; /* White text */
-      font-weight: bold;
-    }
-    .card-body {
-      background-color: #f1f3f5; /* Light grey background */
-      color: #495057; /* Dark text */
-      height: 200px; /* Larger height for the card body */
-      overflow-y: auto; /* Allow scrolling if content exceeds height */
-    }
-    .card-footer {
-      background-color: #f8f9fa;
-      color: #495057;
-    }
-    .card-title {
-      color: #000000; /* Dark text color for card title */
-    }
-    .card-text {
-      color: #6c757d; /* Grey text for descriptions */
-    }
-    .btn-link {
-      color: #007bff; /* Blue accent for buttons */
-    }
-    .container-header {
-      margin-top: 50px;
-      text-align: center;
-    }
-  </style>
-</head>
-<body>
-
-<header class="container container-header">
-  <h1 class="text-primary">Projects</h1>
-  <h2 class="text-muted">View All Projects</h2>
-</header>
-
-<div class="container pt-5">
-  <!-- Card 1 -->
-  <div class="card mb-4">
-    <div class="card-header">
-      <h2 class="card-title">Project 1</h2>
-    </div>
-    <div class="card-body">
-      <p class="card-text">Short description of Project 1.</p>
-      <button class="btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#collapseProject1" aria-expanded="false" aria-controls="collapseProject1">
-        Learn More
-      </button>
-      <div class="collapse mt-3" id="collapseProject1">
-        <div class="card card-body">
-          <p>More detailed information about Project 1...</p>
-        </div>
-      </div>
-    </div>
-  </div>
-
-  <!-- Card 2 -->
-  <div class="card mb-4">
-    <div class="card-header">
-      <h2 class="card-title">Project 2</h2>
-    </div>
-    <div class="card-body">
-      <p class="card-text">Short description of Project 2.</p>
-      <button class="btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#collapseProject2" aria-expanded="false" aria-controls="collapseProject2">
-        Learn More
-      </button>
-      <div class="collapse mt-3" id="collapseProject2">
-        <div class="card card-body">
-          <p>More detailed information about Project 2...</p>
-        </div>
-      </div>
-    </div>
-  </div>
-
-  <!-- Card 3 -->
-  <div class="card mb-4">
-    <div class="card-header">
-      <h2 class="card-title">Project 3</h2>
-    </div>
-    <div class="card-body">
-      <p class="card-text">Short description of Project 3.</p>
-      <button class="btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#collapseProject3" aria-expanded="false" aria-controls="collapseProject3">
-        Learn More
-      </button>
-      <div class="collapse mt-3" id="collapseProject3">
-        <div class="card card-body">
-          <p>More detailed information about Project 3...</p>
-        </div>
-      </div>
-    </div>
-  </div>
-
-  <!-- Card 4 -->
-  <div class="card mb-4">
-    <div class="card-header">
-      <h2 class="card-title">Project 4</h2>
-    </div>
-    <div class="card-body">
-      <p class="card-text">Short description of Project 4.</p>
-      <button class="btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#collapseProject4" aria-expanded="false" aria-controls="collapseProject4">
-        Learn More
-      </button>
-      <div class="collapse mt-3" id="collapseProject4">
-        <div class="card card-body">
-          <p>More detailed information about Project 4...</p>
-        </div>
-      </div>
-    </div>
-  </div>
-
-</div>
-
-<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
-</body>
-</html>
Index: src/main/resources/templates/project_pages/project-create.html
===================================================================
--- src/main/resources/templates/project_pages/project-create.html	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
+++ src/main/resources/templates/project_pages/project-create.html	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Add project</title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
+</head>
+<body>
+
+<main class="container mt-5">
+    <div class="card shadow-sm">
+        <div class="card-header bg-primary text-white">
+            <h4 class="mb-0">Create new project</h4>
+        </div>
+        <div class="card-body">
+            <form th:action="${isCreatingProject==null} ? '/project/' + ${project.getTitle()} + '/modify' : '/project/add'" method="post">
+                <div class="mb-3">
+                    <label for="title" class="form-label">Title</label>
+                    <input type="text" id="title" name="title" th:value="${project.getTitle()}" class="form-control" placeholder="Enter projects title" required>
+                </div>
+                <div class="mb-3">
+                    <label for="repo_url" class="form-label">Repository url</label>
+                    <input type="text" id="repo_url" name="repo_url"
+                           th:value="${project.getRepoUrl()}"
+                           class="form-control" placeholder="Enter url to your repository">
+                </div>
+                <div class="mb-3">
+                    <label for="description" class="form-label">Description</label>
+                    <textarea id="description"
+                              th:text="${project.getDescription()}"
+                              placeholder="Write a short description"
+                              name="description" class="form-control" rows="3" ></textarea>
+                </div>
+                <button type="submit" class="btn btn-primary w-100">Submit</button>
+            </form>
+        </div>
+    </div>
+</main>
+
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+</body>
+</html>
Index: src/main/resources/templates/project_pages/project.html
===================================================================
--- src/main/resources/templates/project_pages/project.html	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
+++ src/main/resources/templates/project_pages/project.html	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -0,0 +1,136 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>Projects</title>
+  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
+  <style>
+    body {
+      background-color: #f8f9fa; /* Light background for the whole page */
+    }
+    .card {
+      background-color: #ffffff; /* White background for the cards */
+      border: 1px solid #dde2e6; /* Light grey border */
+      box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); /* Subtle shadow */
+      transition: transform 0.3s ease, box-shadow 0.3s ease;
+      height: 350px; /* Fixed height for larger cards */
+    }
+    .card:hover {
+      transform: translateY(-5px); /* Slight lift on hover */
+      box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); /* Stronger shadow on hover */
+    }
+    .card-header {
+      background-color: #007bff; /* Blue header color */
+      color: #ffffff; /* White text */
+      font-weight: bold;
+    }
+    .card-body {
+      background-color: #f1f3f5; /* Light grey background */
+      color: #495057; /* Dark text */
+      height: 200px; /* Larger height for the card body */
+      overflow-y: auto; /* Allow scrolling if content exceeds height */
+    }
+    .card-footer {
+      background-color: #f8f9fa;
+      color: #495057;
+    }
+    .card-title {
+      color: #000000; /* Dark text color for card title */
+    }
+    .card-text {
+      color: #6c757d; /* Grey text for descriptions */
+    }
+    .btn-link {
+      color: #007bff; /* Blue accent for buttons */
+    }
+    .container-header {
+      margin-top: 50px;
+      text-align: center;
+    }
+  </style>
+</head>
+<body>
+
+<header class="container container-header">
+  <h1 class="text-primary">Projects</h1>
+  <h2 class="text-muted">View All Projects</h2>
+</header>
+
+<div class="container pt-5">
+  <!-- Card 1 -->
+  <div class="card mb-4">
+    <div class="card-header">
+      <h2 class="card-title">Project 1</h2>
+    </div>
+    <div class="card-body">
+      <p class="card-text">Short description of Project 1.</p>
+      <button class="btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#collapseProject1" aria-expanded="false" aria-controls="collapseProject1">
+        Learn More
+      </button>
+      <div class="collapse mt-3" id="collapseProject1">
+        <div class="card card-body">
+          <p>More detailed information about Project 1...</p>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <!-- Card 2 -->
+  <div class="card mb-4">
+    <div class="card-header">
+      <h2 class="card-title">Project 2</h2>
+    </div>
+    <div class="card-body">
+      <p class="card-text">Short description of Project 2.</p>
+      <button class="btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#collapseProject2" aria-expanded="false" aria-controls="collapseProject2">
+        Learn More
+      </button>
+      <div class="collapse mt-3" id="collapseProject2">
+        <div class="card card-body">
+          <p>More detailed information about Project 2...</p>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <!-- Card 3 -->
+  <div class="card mb-4">
+    <div class="card-header">
+      <h2 class="card-title">Project 3</h2>
+    </div>
+    <div class="card-body">
+      <p class="card-text">Short description of Project 3.</p>
+      <button class="btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#collapseProject3" aria-expanded="false" aria-controls="collapseProject3">
+        Learn More
+      </button>
+      <div class="collapse mt-3" id="collapseProject3">
+        <div class="card card-body">
+          <p>More detailed information about Project 3...</p>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <!-- Card 4 -->
+  <div class="card mb-4">
+    <div class="card-header">
+      <h2 class="card-title">Project 4</h2>
+    </div>
+    <div class="card-body">
+      <p class="card-text">Short description of Project 4.</p>
+      <button class="btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#collapseProject4" aria-expanded="false" aria-controls="collapseProject4">
+        Learn More
+      </button>
+      <div class="collapse mt-3" id="collapseProject4">
+        <div class="card card-body">
+          <p>More detailed information about Project 4...</p>
+        </div>
+      </div>
+    </div>
+  </div>
+
+</div>
+
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+</body>
+</html>
Index: src/main/resources/templates/project_pages/show-project.html
===================================================================
--- src/main/resources/templates/project_pages/show-project.html	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
+++ src/main/resources/templates/project_pages/show-project.html	(revision d60b887949461dff7713c1aa4c50fbb14a62e80d)
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title th:text="${project.getTitle()}"></title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
+</head>
+<body>
+
+<main th:with="isManager=${session.user.getId()==project.getUser().getId()}" class="container mt-5">
+    <div class="card shadow-sm mb-4">
+        <div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
+            <h3 th:text="${project.getTitle()}">Project Title</h3>
+            <div th:if="${isManager}" class="d-flex flex-row gap-2">
+                <button
+                        class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">Add Tag
+                </button>
+                <button class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">
+                    <a class="text-decoration-none text-reset"
+                       th:href="@{/project/{pr_title}/topic/add(pr_title=${project.getTitle()})}">Add Topic</a>
+                </button>
+                <button class="btn btn-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">
+                    <a class="text-decoration-none text-reset"
+                       th:href="@{/project/{pr_title}/modify(pr_title=${project.getTitle()})}">Modify topic</a>
+                </button>
+            </div>
+        </div>
+        <div class="card-body">
+            <p th:text="${project.getContent()}">Description of the project goes here.</p>
+            <div th:if="${!project.getTags().isEmpty()}">
+                <h6>Tags:</h6>
+                <ul class="list-inline">
+                    <li th:each="tag : ${project.getTags()}" class="list-inline-item">
+                        <span class="badge bg-info text-dark" th:text="${tag.getName()}">Tag Name</span>
+                    </li>
+                </ul>
+            </div>
+            <div th:if="${!project.getTopics().isEmpty()}">
+                <h4>Topics:</h4>
+                <div class="list-group">
+                    <div class="list-group-item" th:each="topic : ${project.getTopics()}">
+                        <div class="d-flex w-100 justify-content-between">
+                            <h5 class="mb-1">
+                                <a th:href="@{/topic/{name} (name=${topic.getTitle()})}"
+                                   th:text="${topic.getTitle()}" class="text-decoration-none"></a>
+                            </h5>
+                            <!--                <small th:text="${thread.getFormattedDate()}">Date</small>-->
+                        </div>
+                        <!--            <p class="mb-1 text-muted" th:text="${thread.getDescription()}">Thread description here...</p>-->
+                        <!--            <small th:text="${thread.getAuthor()}">Posted by Author</small>-->
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div th:if="${isManager}" class="card-footer d-flex justify-content-between">
+            <form th:action="@{/project/delete/{title} (title=${project.getTitle()})}" method="post" style="display:inline;">
+                <input type="hidden" name="id" th:value="${project.getId()}"/>
+                <button type="submit" class="btn btn-danger btn-sm">Delete Project</button>
+            </form>
+        </div>
+    </div>
+
+</main>
+
+<!-- Add Tag Modal -->
+<div class="modal fade" id="addTagModal" tabindex="-1" aria-labelledby="addTagModalLabel" aria-hidden="true">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="addTagModalLabel">Add a Tag</h5>
+                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
+            </div>
+            <div class="modal-body">
+                <form th:action="@{/project/{title}/add-tag(title=${project.getTitle()})}" method="post" id="addTagForm">
+                    <div class="mb-3">
+                        <label for="existingTags" class="form-label">Tag Name</label>
+                        <select id="existingTags" class="form-select mb-3" name="tagName">
+                            <option value="" selected disabled>Select an existing tag</option>
+                            <option th:each="tag : ${tags}" th:value="${tag.getName()}" th:text="${tag.getName()}">Example Tag</option>
+                            <option value="custom">Enter a custom tag...</option>
+                        </select>
+                        <input type="text" id="customTag" class="form-control d-none" placeholder="Enter custom tag name" />
+                    </div>
+                    <button type="submit" class="btn btn-primary w-100">Add Tag</button>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script>
+    document.addEventListener("DOMContentLoaded", function () {
+        const existingTags = document.getElementById("existingTags");
+        const customTagInput = document.getElementById("customTag");
+
+        existingTags.addEventListener("change", function () {
+            if (this.value === "custom") {
+                customTagInput.classList.remove("d-none");
+                customTagInput.required = true;
+                customTagInput.name = "tagName";
+                existingTags.name = "";
+            } else {
+                customTagInput.classList.add("d-none");
+                customTagInput.required = false;
+                customTagInput.name = "";
+                existingTags.name = "tagName";
+                customTagInput.value = "";
+            }
+        });
+    });
+
+</script>
+
+
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+</body>
+</html>
