-
Notifications
You must be signed in to change notification settings - Fork 0
Account deletion #107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Account deletion #107
Conversation
Adds the foundational components for the account deletion feature. This includes: - A new `DeleteAccount` route. - A `DeleteAccountViewModel` with an initial `DeleteAccountUiState`. - A skeleton `DeleteAccountScreen` composable. - Registration of the new route in the navigation graph and the view model in Koin.
Adds a "Delete Account" button to the Manage Account screen. Tapping this button navigates the user to the account deletion flow.
This commit introduces the user interface for the account deletion confirmation screen. Changes include: - A new layout in `DeleteAccountScreen.kt` with text fields and a confirmation button. - The `DeleteAccountViewModel` now fetches the user's full name to pre-fill the confirmation field. - Logic is added to validate that the entered name matches the user's actual name before enabling the delete button. - New string resources for labels, instructional text, and error messages have been added.
Adds the functionality to delete a person from the local database using their GUID. This includes: - Adding `deleteByGuid` to the `PersonDataSource` interface. - Implementing the deletion logic in `PersonDataSourceDb`, which also removes related roles and relationships within a transaction. - Adding the corresponding `deleteByPersonGuidHash` query to `PersonEntityDao`. - Calling the new delete method from `DeleteAccountViewModel`.
Yet to implement
Yet to implement
This commit introduces the capability for a user to delete their account. It includes: - A new `DeleteAccountUseCase` and its client-side implementation. - A corresponding server-side endpoint (`/person/delete`) to handle the deletion request. - Integration into the `DeleteAccountViewModel` to call the use case. - Koin dependency injection wiring for the new components.
This commit introduces the capability for users to delete their accounts. - A `DeleteAccountUseCaseServer` is implemented to handle the deletion logic on the server-side, which removes the person's record from the database by their GUID hash. - A new `person/delete` endpoint is added to the server routes to expose this functionality. - The Koin dependency injection module is updated to provide the `DeleteAccountUseCase`. - The `UsernameSuggestionUseCaseServer` has been moved to a more generic `account.username` package.
# Conflicts: # respect-app-compose/src/androidMain/kotlin/world/respect/AppKoinModule.kt # respect-app-compose/src/commonMain/kotlin/world/respect/app/app/AppNavHost.kt
| respectEndpointUrl("person/delete") | ||
| ).apply | ||
| { | ||
| tokenProvider.provideToken() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should use useTokenProvider.
There is no need to include guid as a parameter.
| get<RespectTokenManager>().providerFor(id) | ||
| } | ||
|
|
||
| scoped<DeleteAccountUseCase> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should use a factory in the account scope - that will give you the authenticated person uid.
…me` package to better reflect its association with the invitation flow.
…eter from its `invoke` method. Instead of being passed in as a parameter, the user's identity is now determined from the `AuthTokenProvider` context. This change also updates the Koin module to provide `DeleteAccountUseCase` as a `factory` instead of a `scoped` dependency.
The `DeleteAccountUseCase` is updated to delete the account of the currently authenticated user, removing the need to pass a user GUID as a parameter. The implementation is changed to use the `authenticatedUser.guid` on the server side. The corresponding `person/delete` route is now placed under authentication to ensure an authenticated user context is available.
|
|
||
| route("person") { | ||
| PersonDeleteRoute( | ||
| deleteAccountUseCase = { it.getSchoolKoinScope().get() }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Mandvii this is wrong: as per call this must use the account scope, not the school scope. This should not use getSchoolKoinScope - that won't work because there won't be a delete account use case in the school scope. I think this should be moved inside the PersonRoute (where it can then use the same account scope approach to get the required use case).
|
@Mandvii :
a) The Route must be within the authenticate(AUTH_CONFIG_SCHOOL) block (should actually be part of PersonRoute) |
…` to `PersonRoute`.
Specifically, the following changes were made:
- Deleted `PersonDeleteRoute.kt` and removed its usage from `Application.kt`.
- Added a `post("person/delete")` endpoint to `PersonRoute.kt` to handle account deletion.
- Updated `DeleteAccountUseCaseClient` to use the new endpoint URL.
- Modified `PersonEntityDao.deletePerson` to return the number of rows deleted.
- Adjusted `DeleteAccountUseCaseServer` to return `true` only if the deletion was successful (rows deleted > 0).
Screencast.from.2025-11-19.14-35-06.webmThis is the current status account gets deleted and logged out but navigation after end session is not as expected. Logs ( OKHttp-CacheInterceptor: intercept: POST http://192.168.1.195:8098/api/school/respect/person/delete Person(guid=1, userActive=true, status=ACTIVE, lastModified=2025-11-19T09:03:53.260Z, stored=2025-11-19T09:04:46.127Z, metadata=null, userMasterIdentifier=null, username=admin, givenName=Admin, familyName=Admin, middleName=null, gender=UNSPECIFIED, preferredFirstName=null, preferredMiddleName=null, preferredLastName=null, pronouns=null, roles=[PersonRole(isPrimaryRole=true, roleEnum=SYSTEM_ADMINISTRATOR, beginDate=null, endDate=null)], relatedPersonUids=[], dateOfBirth=null, email=null, phoneNumber=null) No scope found for id 'http://192.168.1.195:8098/' at world.respect.shared.domain.account.RespectAccountManager.endSession(RespectAccountManager.kt:215) |
| <string name="delete_account">Delete Account</string> | ||
| <string name="permanently_delete">Permanently Delete</string> | ||
| <string name="enter_username">Enter your username</string> | ||
| <string name="delete_supporting_content">below and then tap on 'Permanently delete' button to delete your account.</string> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be one string that uses string formatting
E.g. Enter your username (%1$s) below and then tap on 'Permanently delete' button to delete your account
| val userName: String? = null, | ||
| val enteredName: String = "", | ||
| val userNameError: UiText? = null, | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please indent properly!!
|
|
||
| init { | ||
| viewModelScope.launch { | ||
| val personSelected = schoolDataSource.personDataSource.findByGuid( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the flow: so you get it fast/offline first.
| _uiState.update { | ||
| it.copy( | ||
| userName = personSelected?.fullName(), | ||
| enteredName = personSelected?.fullName().orEmpty() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should not be prefilled. Uses the username, not the person's actual name.
…string concatenation with a formatted string resource, making the code cleaner and easier to maintain.
…and updates the UI accordingly.
| import world.respect.shared.domain.account.deleteaccount.DeleteAccountUseCase | ||
|
|
||
| class DeleteAccountUseCaseServer( | ||
| private val schoolDb: RespectSchoolDatabase, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should use the SchoolDataSource NOT the database.
Adds the ability to delete a person by their GUID. - Defines `delete(guid: String)` in the `PersonDataSource` interface. - Implements the delete function in `PersonDataSourceDb` to remove a person from the local database. - Updates `DeleteAccountUseCaseServer` to use the new `PersonDataSource.delete()` method instead of directly accessing the DAO. - Adds `TODO` stubs for the HTTP and repository implementations.
The `schoolDb` parameter was unused and has been removed from the `DeleteAccountUseCaseServer` constructor. The implementation now solely relies on the `schoolDataSource` to perform the delete operation.
Account Deletion