:PROPERTIES:
:ID:       4a8edaed-9ebd-402b-9c5f-7a0cb4399102
:END:
#+title: uml_fyp
#+filetags: :uni:


* Class diagram
** class 2:
@startuml
skinparam classAttributeIconSize 0
skinparam packageStyle rectangle
skinparam linetype ortho
left to right direction

' Entity Layer
rectangle "Entity Layer" as EntityLayer #E3F2FD {
  class User {
    +id: Long
    +roles: Set<String>
    +firstName: String
    +lastName: String
    +username: String
    +password: String
    +confirmPassword: String
    +email: String
    +phoneNumber: String
    +picture: byte[]
  }

  class Workspace {
    +id: Long
    +name: String
    +description: String
    +fileCount: int
    +noteCount: int
    +lastAccessed: LocalDateTime
    +dateCreated: LocalDateTime
  }

  class Library {
    +id: Long
    +name: String
    +description: String
    +dateCreated: LocalDateTime
    +lastAccessed: LocalDateTime
  }

  class Page {
    +id: Long
    +name: String
    +workspaceId: Long
    +content: Text
    +height: int
    +width: int
  }

  class FileMetadata {
    +id: Long
    +fileUrl: String
    +userId: String
    +description: String
    +fileData: byte[]
    +fileName: String
    +fileType: String
  }

  class AiChat {
    +id: Long
    +name: String
    +workspaceId: Long
    +createdAt: LocalDateTime
    +messages: List<AIChatMessage>
  }
}

' Repository Layer
rectangle "Repository Layer" as RepositoryLayer #E8F5E9 {
  class AiChatRepository
  class FileMetadataRepository
  class LibraryRepository
  class PageRepository
  class UserRepository
  class WorkspaceRepository
  class RegisterRepository
  class AuthRepository
}

' Service Layer
rectangle "Service Layer" as ServiceLayer #FFF3E0 {
  class AiChatService
  class AuthService
  class FileMetadataService
  class LibraryService
  class PageService
  class RegisterService
  class UserService
  class WorkspaceService
}

' Controller Layer
rectangle "Controller Layer" as ControllerLayer #F3E5F5 {
  class AiChatController
  class AiChatWebSocketController
  class AuthController
  class FileMetadataController
  class LibraryController
  class PageController
  class RegisterController
  class UserController
  class WorkspaceController
}

' External Python Microservice
rectangle "External NLP Module (Python FastAPI)" as ExternalNLP #FCE4EC {
  class FastAPINLPServer {
    +/extract_text
    +/keywords
    +/tfidf_keywords
    +/summarize
    +/ner
  }
}



  rectangle "Frontend Core" as FrontendCore {
    class AboutComponent
    class AccessibilityComponent
    class ContactComponent
    class ForgotPasswordComponent
    class LoginComponent
    class LoginService
    class PrivacyComponent
    class RegisterComponent
    class RegisterService
    class SecurityComponent
    class TermsComponent

    LoginComponent --> LoginService
    RegisterComponent --> RegisterService

    LoginService ..> AuthController : REST
    RegisterService ..> RegisterController : REST
  }

  rectangle "Frontend Entities" as FrontendEntities {
    class AiChatComponent
    class DashboardComponent
    class DefaultLayoutComponent
    class HomeComponent
    class LibraryComponent
    class ProfileComponent
    class WorkspacePageComponent
    class WorkspacesComponent

    class AiChatServiceFE
    class DashboardServiceFE
    class LayoutServiceFE
    class HomeServiceFE
    class LibraryServiceFE
    class ProfileServiceFE
    class WorkspacePageServiceFE
    class WorkspacesServiceFE

    AiChatComponent --> AiChatServiceFE
    DashboardComponent --> DashboardServiceFE
    DefaultLayoutComponent --> LayoutServiceFE
    DefaultLayoutComponent --> LoginComponent
    DefaultLayoutComponent --> RegisterComponent
    HomeComponent --> HomeServiceFE
    LibraryComponent --> LibraryServiceFE
    ProfileComponent --> ProfileServiceFE
    WorkspacePageComponent --> WorkspacePageServiceFE
    WorkspacesComponent --> WorkspacesServiceFE

    ForgotPasswordComponent ..> UserController : REST
    AiChatServiceFE ..> AiChatController : REST
    AiChatServiceFE ..> AiChatWebSocketController : WebSocket

    DashboardServiceFE ..> WorkspaceController : REST
    DashboardServiceFE ..> PageController : REST
    DashboardServiceFE ..> AiChatController : REST

    LayoutServiceFE ..> UserController : REST

    HomeServiceFE ..> AuthController : REST

    LibraryServiceFE ..> LibraryController : REST
    LibraryServiceFE ..> FileMetadataController : REST

    ProfileServiceFE ..> UserController : REST

    WorkspacePageServiceFE ..> PageController : REST
    WorkspacePageServiceFE ..> FileMetadataController : REST
    WorkspacePageServiceFE ..> AiChatController : REST

    WorkspacesServiceFE ..> WorkspaceController : REST
    AboutComponent --> ContactComponent
    AboutComponent --> TermsComponent
    AboutComponent --> PrivacyComponent
  }

  class AngularClient
  AngularClient --> FrontendCore
  AngularClient --> FrontendEntities
  AngularClient ..> FastAPINLPServer : REST


' Entity Relationships
User "1" --> "many" Library
User "1" --> "many" Workspace
Library "1" --> "many" Workspace
Library "1" --> "many" FileMetadata
Workspace "1" --> "many" Page
Workspace "1" --> "many" FileMetadata
Workspace "1" --> "many" AiChat

' Controller → Service
AiChatController --> AiChatService
AiChatWebSocketController --> AiChatService
AuthController --> AuthService
FileMetadataController --> FileMetadataService
LibraryController --> LibraryService
PageController --> PageService
RegisterController --> RegisterService
UserController --> UserService
WorkspaceController --> WorkspaceService

' Service → Repository
AiChatService --> AiChatRepository
AuthService --> AuthRepository
FileMetadataService --> FileMetadataRepository
LibraryService --> LibraryRepository
PageService --> PageRepository
RegisterService --> RegisterRepository
UserService --> UserRepository
WorkspaceService --> WorkspaceRepository

' Repository → Entity
AiChatRepository --> AiChat
FileMetadataRepository --> FileMetadata
LibraryRepository --> Library
PageRepository --> Page
UserRepository --> User
WorkspaceRepository --> Workspace
RegisterRepository --> User
AuthRepository --> User

@enduml

** authentication sequence diagram:
@startuml
title Full Authentication Flow - Registration to Secured Access

skinparam shadowing true
skinparam packageStyle rectangle
skinparam handwritten false
skinparam linetype polyline
skinparam ParticipantPadding 20
skinparam maxMessageSize 150

actor User

== Registration Process ==

box "Client" #E3F2FD
    participant UserClient as "User"
end box

box "Backend - Registration" #E8F5E9
    participant RegisterController
    participant UserService
end box

UserClient -> RegisterController : POST /register\n(username, password, confirmPassword)
RegisterController -> RegisterController : Check if passwords match
alt Passwords do not match
    RegisterController --> UserClient : 400 Bad Request (Passwords mismatch)
    return
end
RegisterController -> RegisterController : Hash password (BCrypt)
RegisterController -> RegisterController : Load default profile image
RegisterController -> UserService : createUser(user)
RegisterController --> UserClient : 200 OK (User Created)

== Authentication Process ==

box "Backend - Authentication" #FFF3E0
    participant AuthController
    participant AuthenticationManager
    participant JwtUtil
end box

UserClient -> AuthController : POST /auth/login\n(username, password)
AuthController -> AuthenticationManager : Authenticate credentials
alt Valid credentials
    AuthController -> JwtUtil : generateToken(userDetails, userId)
    AuthController --> UserClient : 200 OK + JWT
else Invalid credentials
    AuthController --> UserClient : 401 Unauthorized
    return
end

== Accessing a Protected API ==

box "Security Filter Chain" #F3E5F5
    participant JwtRequestFilter
    participant UserDetailsService
    participant JwtUtilFilter as "JwtUtil"
end box

UserClient -> JwtRequestFilter : Request with Authorization header
JwtRequestFilter -> JwtUtilFilter : extractUsername(jwt)
JwtRequestFilter -> UserDetailsService : loadUserByUsername
JwtRequestFilter -> JwtUtilFilter : validateToken(jwt, userDetails)
alt Valid token
    JwtRequestFilter -> SecurityContext : Set authentication
else Invalid token
    JwtRequestFilter -> JwtRequestFilter : Log and skip authentication
end
JwtRequestFilter --> UserClient : Continue filter chain

== @JwtRequired Secured Method Access ==

box "AOP - Method Security" #E1F5FE
    participant JwtAspect
    participant JwtUtilAspect as "JwtUtil"
end box

UserClient -> JwtAspect : Call method annotated with @JwtRequired
JwtAspect -> JwtAspect : Extract JWT from header
JwtAspect -> JwtUtilAspect : extractUsername(jwt)
JwtAspect -> SecurityContext : Get UserDetails
JwtAspect -> JwtUtilAspect : validateToken(jwt, userDetails)
alt Token valid and user matches
    JwtAspect --> UserClient : Proceed to method execution
else Invalid/mismatched token
    JwtAspect --> UserClient : Unauthorized exception
    return
end

@enduml

** class
@startuml
skinparam classAttributeIconSize 0
skinparam packageStyle rectangle

package "High-Level Overview" {

  ' Controller Layer
  package "Controller Layer" {
    class AiChatController
    class AiChatWebSocketController
    class AuthController
    class FileMetadataController
    class LibraryController
    class PageController
    class RegisterController
    class UserController
    class WorkspaceController
  }

  ' Service Layer
  package "Service Layer" {
    class AiChatService
    class AuthService
    class FileMetadataService
    class LibraryService
    class PageService
    class RegisterService
    class UserService
    class WorkspaceService
  }

  ' Repository Layer
  package "Repository Layer" {
    class AiChatRepository
    class FileMetadataRepository
    class LibraryRepository
    class PageRepository
    class UserRepository
    class WorkspaceRepository
    class RegisterRepository
    class AuthRepository
  }

  ' Entity Layer
  package "Entity Layer" {

    class User {
      +id: Long
      +roles: Set<String>
      +firstName: String
      +lastName: String
      +username: String
      +password: String
      +confirmPassword: String
      +email: String
      +phoneNumber: String
      +picture: byte[]
    }

    class Workspace {
      +id: Long
      +name: String
      +description: String
      +fileCount: int
      +noteCount: int
      +lastAccessed: LocalDateTime
      +dateCreated: LocalDateTime
    }

    class Library {
      +id: Long
      +name: String
      +description: String
      +dateCreated: LocalDateTime
      +lastAccessed: LocalDateTime
    }

    class Page {
      +id: Long
      +name: String
      +workspaceId: Long
      +content: Text
      +height: int
      +width: int
    }

    class FileMetadata {
      +id: Long
      +fileUrl: String
      +userId: String
      +description: String
      +fileData: byte[]
      +fileName: String
      +fileType: String
    }

    class AiChat {
      +id: Long
      +name: String
      +workspaceId: Long
      +createdAt: LocalDateTime
      +messages: List<AIChatMessage>
    }
  }

  ' Python NLP Microservice
  package "External NLP Module (Python FastAPI)" {
    class FastAPINLPServer {
      +/extract_text
      +/keywords
      +/tfidf_keywords
      +/summarize
      +/ner
    }
  }

  ' Entity Relationships
  User "1" --> "many" Library
  User "1" --> "many" Workspace
  Library "1" --> "many" Workspace
  Library "1" --> "many" FileMetadata
  Workspace "1" --> "many" Page
  Workspace "1" --> "many" FileMetadata
  Workspace "1" --> "many" AiChat

  ' Controller → Service
  AiChatController --> AiChatService
  AiChatWebSocketController --> AiChatService
  AuthController --> AuthService
  FileMetadataController --> FileMetadataService
  LibraryController --> LibraryService
  PageController --> PageService
  RegisterController --> RegisterService
  UserController --> UserService
  WorkspaceController --> WorkspaceService

  ' Service → Repository
  AiChatService --> AiChatRepository
  AuthService --> AuthRepository
  FileMetadataService --> FileMetadataRepository
  LibraryService --> LibraryRepository
  PageService --> PageRepository
  RegisterService --> RegisterRepository
  UserService --> UserRepository
  WorkspaceService --> WorkspaceRepository

  ' Repository → Entity
  AiChatRepository --> AiChat
  FileMetadataRepository --> FileMetadata
  LibraryRepository --> Library
  PageRepository --> Page
  UserRepository --> User
  WorkspaceRepository --> Workspace
  RegisterRepository --> User
  AuthRepository --> User

  ' Frontend → NLP Server

}

' Frontend Component
package "Frontend" {
  class AngularClient
}

' Angular communicates with both backends
AngularClient ..> AiChatController : REST
AngularClient ..> AiChatWebSocketController : WebSocket
AngularClient ..> AuthController : REST
AngularClient ..> PageController : REST
AngularClient ..> FileMetadataController : REST
AngularClient ..> WorkspaceController : REST
AngularClient ..> LibraryController : REST
AngularClient ..> RegisterController : REST
AngularClient ..> UserController : REST
AngularClient ..> FastAPINLPServer : REST

@enduml
** client-server
@startuml
!pragma layout smetana

actor User

package "Client Side (Angular)" {
  [Angular App] as Frontend
}

package "Spring Boot Backend" {
  [Auth Controller]
  [Note Controller]
  [NLP Proxy Service]
  [Spring Boot App] as Backend
}

package "Database Layer" {
  database "PostgreSQL Database" as DB
}

package "FastAPI NLP Server (Port 9010)" {
  [FastAPI NLP Service] as NLP
  [Summarisation Endpoint] as SumEndpoint
  [Keyword Extraction] as KeywordEndpoint
  [NER Endpoint] as NEREndpoint
}

package "External API" {
  [OpenAI API]
}

' Interactions
User --> Frontend : Uses Web Interface
Frontend --> Backend : REST API Calls
Backend --> [Auth Controller] : Handles Auth
Backend --> [Note Controller] : Handles Notes
Backend --> [NLP Proxy Service] : Handles NLP Requests
[Auth Controller] --> DB : Access users table
[Note Controller] --> DB : Access notes table
[NLP Proxy Service] --> NLP : HTTP (port 9010)
NLP --> SumEndpoint : /summarise
NLP --> KeywordEndpoint : /keywords
NLP --> NEREndpoint : /ner
SumEndpoint --> [OpenAI API] : API call for contextual help

note right of Frontend
  Angular app includes:
  - Note Editor
  - Summary View
  - Keyword Panel
end note

note right of Backend
  Spring Boot includes:
  - Auth Controller
  - Note Controller
  - NLP Proxy Service (calls FastAPI)
end note

note right of NLP
  FastAPI exposes endpoints for:
  - Summarisation (Pegasus)
  - Keyword Extraction (TF-IDF, YAKE)
  - NER (spaCy)
end note
@enduml
** high level:
@startuml
skinparam componentStyle uml2
skinparam packageStyle rectangle

package "Client (Frontend)" {
  [Angular UI]
}

package "Java Backend (Spring Boot)" {
  [REST API Controller Layer]
  [WebSocket Controller]
  [Service Layer]
  [Repository Layer]
  [JPA Entities]
}

package "Python NLP Service" {
  [FastAPI Server]
  [Summarizer (Pegasus)]
  [Keyword Extractor (YAKE / TF-IDF)]
  [NER (spaCy)]
  [Extract Text (Canvas Object)]
}

package "External Services" {
  [OpenAI API]
  [PostgreSQL DB]
}

' Communication Arrows
[Angular UI] --> [REST API Controller Layer] : REST API (JSON)
[Angular UI] --> [WebSocket Controller] : WebSocket

[REST API Controller Layer] --> [Service Layer]
[WebSocket Controller] --> [Service Layer]
[Service Layer] --> [Repository Layer]
[Repository Layer] ..> [JPA Entities] : uses
[Service Layer] --> [OpenAI API] : API calls

[Service Layer] --> [FastAPI Server] : REST (NLP Requests)
[FastAPI Server] --> [Summarizer (Pegasus)]
[FastAPI Server] --> [Keyword Extractor (YAKE / TF-IDF)]
[FastAPI Server] --> [NER (spaCy)]
[FastAPI Server] --> [Extract Text (Canvas Object)]

[Repository Layer] --> [PostgreSQL DB] : Hibernate ORM
@enduml

** title AI Chat + Workspace Workflow
@startuml
title AI Chat + Workspace Workflow

skinparam shadowing true
skinparam packageStyle rectangle
skinparam handwritten false
skinparam linetype polyline
skinparam ParticipantPadding 20
skinparam maxMessageSize 150

actor User

== AI Chat Session Creation ==

box "Client" #E3F2FD
    participant AngularClient as "User"
end box

box "Backend - AI Chat" #E8F5E9
    participant AiChatController
    participant AiChatService
    participant AiChatRepository
end box

box "External NLP Service" #FCE4EC
    participant FastAPINLPServer as "FastAPI NLP"
end box

User -> AngularClient : Open AI Chat page
AngularClient -> AiChatController : POST /ai-chat\n(chat metadata)
AiChatController -> AiChatService : createChat(chatDto)
AiChatService -> AiChatRepository : save(chat)
AiChatService --> AiChatController : chatId
AiChatController --> AngularClient : 200 OK + chatId

User -> AngularClient : Send message via WebSocket
AngularClient -> AiChatWebSocketController : message
AiChatWebSocketController -> AiChatService : handleMessage()

alt Message requires NLP
    AiChatService -> FastAPINLPServer : POST /summarize or /ner
    FastAPINLPServer --> AiChatService : NLP result
end

AiChatService -> AiChatRepository : update(chat with message)
AiChatWebSocketController --> AngularClient : Message response

== Workspace Creation ==

box "Backend - Workspace" #FFF3E0
    participant WorkspaceController
    participant WorkspaceService
    participant WorkspaceRepository
end box

User -> AngularClient : Create Workspace
AngularClient -> WorkspaceController : POST /workspace\n(name, description)
WorkspaceController -> WorkspaceService : createWorkspace(dto)
WorkspaceService -> WorkspaceRepository : save(workspace)
WorkspaceService --> WorkspaceController : workspaceId
WorkspaceController --> AngularClient : 200 OK + workspaceId

@enduml

* Screenshots:
** Draft 1:
[[file:~/master-folder/FYP/uml/draft1.png]]

