Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8cd4392
filter main menu choice based on user role
MennaSrour May 5, 2025
882a6fd
refactor MainMenuUI test cases
MennaSrour May 6, 2025
e196278
chage user cache to class ,add single from it to data module and refa…
MennaSrour May 6, 2025
d40a12d
refactor main test,main menu ui
MennaSrour May 6, 2025
dd5d079
Merge branch 'development' into refactor/MainMenu
MennaSrour May 6, 2025
4516320
resolve import problem
MennaSrour May 6, 2025
62935e8
resolve conflict
MennaSrour May 6, 2025
c864908
implement create state ui and test cases
MennaSrour May 6, 2025
f7851e0
implement ui and unit test to update state and get all states
MennaSrour May 7, 2025
6989f85
Merge remote-tracking branch 'origin/refactor/MainMenu' into development
May 8, 2025
38f141c
Merge remote-tracking branch 'origin/development' into development
May 8, 2025
36dc81e
add audit log to the project and task entities and fix some issues in…
May 8, 2025
7cfc53a
add test cases to update state
MennaSrour May 8, 2025
995c3af
refactor the test cases of CreateStateUiTest.kt
Abdulrahman-Ragab-01 May 8, 2025
041d2b7
Merge remote-tracking branch 'origin/feature/stateUi' into feature/st…
MennaSrour May 8, 2025
2fe507a
apply unit test and implement ui for update state and get state by id
MennaSrour May 8, 2025
9f0bb5b
refactor test cases of get task by state id ,get state by task id and…
MennaSrour May 8, 2025
c8a4f98
resolve test cases problems in update state ui
MennaSrour May 8, 2025
6451439
Merge branch 'development' into feature/stateUi
MennaSrour May 8, 2025
ff31507
resolve ui module error
MennaSrour May 8, 2025
9967751
fix test cases at task usecases and task ui and task repo
May 9, 2025
3c2dada
implement ui and test cases for get all states by project
MennaSrour May 9, 2025
a7b2ddb
improve state ui test cases readability
MennaSrour May 9, 2025
3193000
Merge branch 'refs/heads/feature/stateUi' into feature/add-audit-func…
MennaSrour May 9, 2025
febbc41
temp
May 9, 2025
12511f1
fix project uesecase test cases and project ui tests
May 9, 2025
0340e47
handle the exception thrown when cancelling create state
Abdulrahman-Ragab-01 May 9, 2025
ae21cd4
Merge remote-tracking branch 'origin/feature/add-audit-functionalty' …
MennaSrour May 9, 2025
98e02be
solve cancellation exception in update state ui
MennaSrour May 9, 2025
3464db8
Merge branch 'feature/stateUi' into feature/add-audit-functionalty
MennaSrour May 9, 2025
8e29789
merge state ui to this branch and resolve conflict
MennaSrour May 9, 2025
527dbbb
fix errors in audit log
marwanqashwa May 9, 2025
7572de7
merge all test cases for the usecases and the ui
May 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,5 @@ tasks.test {
}

kotlin {
jvmToolchain(23)
jvmToolchain(22)
}
7 changes: 7 additions & 0 deletions csv_files/audit.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"Audit Id","Timestamp","CreatedBy","Audit Action","Changes Description","Entity Type","Entity Id"
"AUDITDD_52700","1746681952700","user1234","CREATE","","TASK","titlett_52651"
"AUDITDD_16009","1746682016009","user1234","UPDATE","","TASK","titlett_52651"
"AUDITDD_26796","1746682026796","user1234","DELETE","","TASK","titlett_52651"
"AUDITDDDD_29153","1746685829153","user1234","CREATE","","TASK","titlett_29143"
"AUDITDD_39457","1746685839457","user1234","UPDATE","","TASK","titlett_29143""AUDITDD_97145","1746688997145","user1234","CREATE","","PROJECT","taskmangermmmm_97132"
"AUDITDDDD_44756","1746689044756","user1234","UPDATE","","PROJECT","taskmangermmmm_97132"
2 changes: 2 additions & 0 deletions csv_files/project.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
"Project Id","Project Name","Description","States","Tasks"
"taskmangermmmm_97132","title updated","the ultimate project","[]","[]"
1 change: 1 addition & 0 deletions csv_files/task.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
"Task Id","Project Id","Title","Description","State Id","Assigned To User Id","Create By User Id"
"dfgsdgfdd_66055","P1","dfgsdgfd","gasdfgfdaf","S1","U1","U1"
"titlett_29143","P1","title","description","S1","U2","user1234"
2 changes: 2 additions & 0 deletions csv_files/user.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
"User Id","UserName","Password","User Role"
"ahmadmmmm_70365","ahmad","d2dfac4d62e5470ab0c92d6f425b977d","MATE"
7 changes: 4 additions & 3 deletions src/main/kotlin/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.berlin.di.uiModule
import com.berlin.di.useCaseModule
import com.berlin.di.*
import com.berlin.presentation.MainMenuUI
import com.berlin.presentation.authService.AuthenticateUserUi
import org.koin.core.context.startKoin
import org.koin.mp.KoinPlatform.getKoin

Expand All @@ -14,8 +13,10 @@ fun main() {
printLogger()
modules(dataModule, appModule, useCaseModule, uiModule)
}

val mainMenu: MainMenuUI = getKoin().get()
mainMenu.run()

}
}


// autit -> project [tasks]
1 change: 1 addition & 0 deletions src/main/kotlin/data/DummyData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ object DummyData : BaseDataSource<Task> {
)

val states = mutableListOf(
State("Q1","Menna","P5"),
State("S1", "TODO", "P1"),
State("S2", "IN_PROGRESS", "P1"),
State("S3", "REVIEW", "P1"),
Expand Down
6 changes: 4 additions & 2 deletions src/main/kotlin/data/UserCache.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package data

import com.berlin.domain.model.User

object UserCache {
var currentUser: User? = null
class UserCache(
admin: User
) {
var currentUser: User = admin
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,14 @@ package com.berlin.data.authentication
import com.berlin.data.BaseDataSource
import com.berlin.domain.exception.UserNotFoundException
import com.berlin.domain.exception.UserNotLoggedInException
import com.berlin.domain.hashPassword.HashingPassword
import com.berlin.domain.hashPassword.MD5Hasher
import com.berlin.domain.helper.IdGenerator
import com.berlin.domain.helper.IdGeneratorImplementation
import com.berlin.domain.model.User
import com.berlin.domain.model.UserRole
import com.berlin.domain.repository.AuthenticationRepository
import data.UserCache
import kotlin.Result.Companion.failure


class AuthenticationRepositoryImpl(
private val userCache: UserCache,
private val userDataSource: BaseDataSource<User>
): AuthenticationRepository {

Expand Down Expand Up @@ -45,11 +41,11 @@ class AuthenticationRepositoryImpl(


override fun getCurrentUser(): Result<User> {
val user = UserCache.currentUser
val user = userCache.currentUser
return if (user != null) {
Result.success(user)
} else {
Result.failure(UserNotLoggedInException("No one logged in"))
failure(UserNotLoggedInException("No one logged in"))

}

Expand Down
66 changes: 36 additions & 30 deletions src/main/kotlin/data/state/StateRepositoryImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,60 @@ package com.berlin.data.state

import com.berlin.data.BaseDataSource
import com.berlin.domain.exception.InvalidStateException
import com.berlin.domain.exception.StateNotFoundException
import com.berlin.domain.model.State
import com.berlin.domain.model.Task
import com.berlin.domain.repository.StateRepository
import kotlin.Result.Companion.failure
import kotlin.Result.Companion.success

class StateRepositoryImpl(
private val stateDataSource: BaseDataSource<State>,
private val taskDataSource: BaseDataSource<Task>
):StateRepository {
override fun addState(state: State): Result<String> {
return if (stateDataSource.write(state))
Result.success(state.id)
private val taskDataSource: BaseDataSource<Task>,
) : StateRepository {
override fun addState(state: State): Result<String> =
if (stateDataSource.write(state))
success(state.id)
else
Result.failure(InvalidStateException("can not add state"))
}
failure(InvalidStateException("can not add state"))

override fun getStatesByProjectId(projectId: String): List<State>? {
return stateDataSource.getAll()
.filter { it.projectId == projectId }
.takeIf { it.isNotEmpty() }
}

override fun getTasksByStateId(stateId: String): List<Task>? {
return taskDataSource.getAll()
override fun getStatesByProjectId(projectId: String): Result<List<State>> =
success(stateDataSource.getAll().filter { it.projectId == projectId })


override fun getTasksByStateId(stateId: String): List<Task>? =
taskDataSource.getAll()
.filter { it.stateId == stateId }
.takeIf { it.isNotEmpty() }
}

override fun deleteState(stateId: String): Result<String> {
return if (stateDataSource.delete(stateId))
Result.success(stateId)

override fun deleteState(stateId: String): Result<String> =
if (stateDataSource.delete(stateId))
success(stateId)
else
Result.failure(InvalidStateException("can not delete state"))
}
failure(InvalidStateException("can not delete state"))

override fun updateState(state: State): Result<String> {
return if (stateDataSource.update(state.id,state))
Result.success(state.id)

override fun updateState(state: State): Result<String> =
if (stateDataSource.update(state.id, state))
success(state.id)
else
Result.failure(InvalidStateException("can not update state"))
}
failure(InvalidStateException("can not update state"))


override fun getStateByTaskId(taskId: String): State? {
return taskDataSource
.getById(taskId)
?.let { stateDataSource.getById(it.stateId) }
return taskDataSource
.getById(taskId)
?.let { stateDataSource.getById(it.stateId) }
}

override fun getStateById(stateId: String): State? {
return stateDataSource.getById(stateId)
override fun getStateById(stateId: String): Result<State> =
stateDataSource.getById(stateId)
?.let { success(it) }
?: failure(StateNotFoundException(stateId))

override fun getAllStates(): List<State> {
return stateDataSource.getAll()
}
}
2 changes: 1 addition & 1 deletion src/main/kotlin/data/task/TaskRepositoryImpl.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.berlin.data.memory
package com.berlin.data.task

import com.berlin.data.BaseDataSource
import com.berlin.domain.exception.InvalidTaskException
Expand Down
18 changes: 14 additions & 4 deletions src/main/kotlin/di/appModule.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package com.berlin.di


import com.berlin.domain.hashPassword.HashingPassword
import com.berlin.domain.hashPassword.HashingString
import com.berlin.domain.hashPassword.MD5Hasher
import com.berlin.domain.helper.IdGeneratorImplementation
import com.berlin.domain.helper.IdGenerator
import com.berlin.domain.model.User
import com.berlin.domain.model.UserRole
import com.berlin.domain.usecase.utils.IDGenerator.IdGeneratorImplementation
import com.berlin.domain.usecase.utils.IDGenerator.IdGenerator
import com.berlin.presentation.io.ConsoleReader
import com.berlin.presentation.io.ConsoleViewer
import com.berlin.presentation.io.Reader
import com.berlin.presentation.io.Viewer
import data.UserCache
import org.koin.dsl.module


Expand All @@ -17,5 +20,12 @@ val appModule = module {
single<Reader> { ConsoleReader() }
single<IdGenerator> { IdGeneratorImplementation() }
single<IdGeneratorImplementation> { IdGeneratorImplementation() }
single <HashingPassword> { MD5Hasher() }
single <HashingString> { MD5Hasher() }

single {
UserCache(
User("user1234", "admin", "1212", UserRole.ADMIN)
)
}

}
69 changes: 27 additions & 42 deletions src/main/kotlin/di/dataModule.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
package com.berlin.di

import com.berlin.data.Audit.AuditRepositoryImpl
import com.berlin.data.BaseDataSource
import com.berlin.data.BaseSchema
import com.berlin.data.authentication.AuthenticationRepositoryImpl
import com.berlin.data.csv_data_source.CsvDataSource
import com.berlin.data.memory.TaskRepositoryImpl
import com.berlin.data.task.TaskRepositoryImpl
import com.berlin.data.project.ProjectRepositoryImpl
import com.berlin.data.schema.*
import com.berlin.data.state.StateRepositoryImpl
import com.berlin.domain.model.*
import com.berlin.domain.repository.AuditRepository
import com.berlin.domain.repository.AuthenticationRepository
import com.berlin.domain.repository.ProjectRepository
import com.berlin.domain.repository.StateRepository
import com.berlin.domain.repository.TaskRepository
import com.berlin.domain.repository.*
import org.koin.core.qualifier.named
import org.koin.dsl.module

Expand All @@ -22,61 +19,49 @@ val dataModule = module {

single<BaseSchema<User>>(named("UserSchema")) {
UserSchema(
fileName = "user.csv",
header = listOf("User Id", "UserName", "Password", "User Role")
fileName = "user.csv", header = listOf("User Id", "UserName", "Password", "User Role")
)
}
single<BaseSchema<Project>>(named("ProjectSchema")) {
ProjectSchema(
fileName = "project.csv",
header = listOf("Project Id", "Project Name", "Description", "States", "Tasks")
fileName = "project.csv", header = listOf("Project Id", "Project Name", "Description", "States", "Tasks")
)
}
single<BaseSchema<AuditLog>>(named("AuditSchema")) {
AuditSchema(
fileName = "audit.csv",
header = listOf(
"Audit Id",
"Timestamp",
"CreatedBy",
"Audit Action",
"Changes Description",
"Entity Type",
"Entity Id"
fileName = "audit.csv", header = listOf(
"Audit Id", "Timestamp", "CreatedBy", "Audit Action", "Changes Description", "Entity Type", "Entity Id"
)
)
}
single<BaseSchema<State>>(named("StateSchema")) {
StateSchema(fileName = "state.csv",
header = listOf("State Id", "Name", "Project Id")) }
StateSchema(
fileName = "state.csv", header = listOf("State Id", "Name", "Project Id")
)
}
single<BaseSchema<Task>>(named("TaskSchema")) {
TaskSchema(
fileName = "task.csv",
header = listOf(
"Task Id",
"Project Id",
"Title",
"Description",
"State Id",
"Assigned To User Id",
"Create By User Id"
fileName = "task.csv", header = listOf(
"Task Id", "Project Id", "Title", "Description", "State Id", "Assigned To User Id", "Create By User Id"
)
)
}

single<BaseDataSource<User>>(named("UserDataSource")){ CsvDataSource("csv_files", get(named("UserSchema"))) }
single<BaseDataSource<Project>>(named("ProjectDataSource")){ CsvDataSource("csv_files", get(named("ProjectSchema"))) }
single<BaseDataSource<Task>>(named("TaskDataSource")){ CsvDataSource("csv_files", get(named("TaskSchema"))) }
single<BaseDataSource<State>>(named("StateDataSource")){ CsvDataSource("csv_files", get(named("StateSchema"))) }
single<BaseDataSource<AuditLog>>(named("AuditDataSource")){ CsvDataSource("csv_files", get(named("AuditSchema"))) }

single<BaseDataSource<User>>(named("UserDataSource")) { CsvDataSource("csv_files", get(named("UserSchema"))) }
single<BaseDataSource<Project>>(named("ProjectDataSource")) {
CsvDataSource(
"csv_files", get(named("ProjectSchema"))
)
}
single<BaseDataSource<Task>>(named("TaskDataSource")) { CsvDataSource("csv_files", get(named("TaskSchema"))) }
single<BaseDataSource<State>>(named("StateDataSource")) { CsvDataSource("csv_files", get(named("StateSchema"))) }
single<BaseDataSource<AuditLog>>(named("AuditDataSource")) { CsvDataSource("csv_files", get(named("AuditSchema"))) }


single <ProjectRepository> { ProjectRepositoryImpl(get(named("ProjectDataSource"))) }
single <TaskRepository> { TaskRepositoryImpl(get(named("TaskDataSource"))) }
single <AuditRepository>{ AuditRepositoryImpl(get(named("AuditDataSource"))) }
single <StateRepository>{ StateRepositoryImpl(get(named("StateDataSource")),get(named("TaskDataSource"))) }
single <AuthenticationRepository> { AuthenticationRepositoryImpl(get(named("UserDataSource"))) }

single <AuthenticationRepository>{ AuthenticationRepositoryImpl(get(named("UserDataSource"))) }
single<ProjectRepository> { ProjectRepositoryImpl(get(named("ProjectDataSource"))) }
single<TaskRepository> { TaskRepositoryImpl(get(named("TaskDataSource"))) }
single<AuditRepository> { AuditRepositoryImpl(get(named("AuditDataSource"))) }
single<StateRepository> { StateRepositoryImpl(get(named("StateDataSource")), get(named("TaskDataSource"))) }
single<AuthenticationRepository> { AuthenticationRepositoryImpl(get(), get(named("UserDataSource"))) }
}
Loading