Skip to content

feat: add profile option in local server#369

Merged
yogeshpaliyal merged 3 commits intomasterfrom
addProfileInLocalServer
Feb 8, 2026
Merged

feat: add profile option in local server#369
yogeshpaliyal merged 3 commits intomasterfrom
addProfileInLocalServer

Conversation

@yogeshpaliyal
Copy link
Owner

This pull request introduces a new "Profile" feature to the Deepr application, allowing users to manage multiple link profiles and switch between them. The changes include frontend UI enhancements and backend API support for profile creation, selection, and association with links.

Profile Management Feature

  • Added a profile selector dropdown and "New Profile" button to the header UI, enabling users to choose or create profiles directly from the main page.
  • Implemented an "Add Profile" modal dialog for creating new profiles, including form handling and toast notifications for success/error feedback.

Frontend Integration

  • Introduced JavaScript functions to load profiles from the backend, handle profile selection changes, and create new profiles via API calls. The selected profile is now tracked in the UI state and triggers link reloads.
  • Updated link loading and creation logic to associate links with the selected profile by passing profileId in API requests. [1] [2]
  • Registered event listeners for profile controls and ensured that profiles are loaded before links on page initialization. [1] [2]

Backend API Support

  • Added /api/profiles GET and POST endpoints for retrieving all profiles and creating new profiles, respectively.
  • Modified /api/links endpoint and link creation logic to support filtering and associating links by profileId. [1] [2]
  • Introduced new data classes ProfileResponse and AddProfileRequest, and updated AddLinkRequest to include profileId.

Copilot AI review requested due to automatic review settings February 7, 2026 19:35
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds multi-profile support to Deepr’s local server UI and API so users can create and switch between link profiles when using the embedded web interface.

Changes:

  • Added /api/profiles GET/POST endpoints and extended link APIs to accept/filter by profileId.
  • Updated local server HTML UI with a profile dropdown and “New Profile” modal.
  • Updated link load/create requests to include the selected profileId.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
app/src/main/java/com/yogeshpaliyal/deepr/server/LocalServerRepositoryImpl.kt Adds profiles API endpoints and threads profileId through link listing/creation.
app/src/main/assets/index.html Adds profile selector + modal and passes profileId in link API calls.

Comment on lines +169 to +173
deeprQueries.insertProfile(request.name)
call.respond(
HttpStatusCode.Created,
SuccessResponse("Profile created successfully"),
)
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

POST /api/profiles writes directly via deeprQueries.insertProfile(), which bypasses the usual repository/viewmodel side effects (e.g., auto-backup scheduling in LinkRepositoryImpl.insertProfile() and analytics in AccountViewModel.insertProfile()). Also, because insertProfile is INSERT OR IGNORE (name is UNIQUE), this handler will always return 201 Created even when nothing is inserted; consider returning 409 Conflict/200 OK for existing profiles and returning the created/existing profile (including id) in the response so the UI doesn't have to re-fetch and guess.

Suggested change
deeprQueries.insertProfile(request.name)
call.respond(
HttpStatusCode.Created,
SuccessResponse("Profile created successfully"),
)
// Check if a profile with the same name already exists
val existingProfiles = deeprQueries.getAllProfiles().executeAsList()
val existingProfile = existingProfiles.find { it.name == request.name }
if (existingProfile != null) {
val response =
ProfileResponse(
id = existingProfile.id,
name = existingProfile.name,
createdAt = existingProfile.createdAt,
)
call.respond(HttpStatusCode.OK, response)
} else {
// Use AccountViewModel to ensure side effects (backup, analytics, etc.) are applied
accountViewModel.insertProfile(request.name)
// Fetch the newly created profile
val updatedProfiles = deeprQueries.getAllProfiles().executeAsList()
val createdProfile = updatedProfiles.find { it.name == request.name }
if (createdProfile != null) {
val response =
ProfileResponse(
id = createdProfile.id,
name = createdProfile.name,
createdAt = createdProfile.createdAt,
)
call.respond(HttpStatusCode.Created, response)
} else {
call.respond(
HttpStatusCode.InternalServerError,
ErrorResponse("Profile was not found after creation"),
)
}
}

Copilot uses AI. Check for mistakes.
Comment on lines +145 to +156
get("/api/profiles") {
try {
val profiles = deeprQueries.getAllProfiles().executeAsList()
val response =
profiles.map { profile ->
ProfileResponse(
id = profile.id,
name = profile.name,
createdAt = profile.createdAt,
)
}
call.respond(HttpStatusCode.OK, response)
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GET /api/profiles can legitimately return an empty list (e.g., on a fresh DB before the async default-profile initialization completes). Since the UI replaces the <select> options with the returned list, an empty response leaves the profile selector blank. Consider ensuring a default profile exists synchronously before responding, or returning a non-empty list by creating/including a default profile when none exist.

Copilot uses AI. Check for mistakes.
Comment on lines +396 to +404
// Populate profile dropdown
function populateProfileSelect() {
const profileSelect = document.getElementById('profileSelect');
profileSelect.innerHTML = profiles.map(profile => `
<option value="${profile.id}" ${profile.id === selectedProfileId ? 'selected' : ''}>
${escapeHtml(profile.name)}
</option>
`).join('');
}
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

populateProfileSelect() fully replaces the <select> options with profiles. If the backend returns an empty list (or the default profile’s id isn’t 1), the selector becomes empty and selectedProfileId may no longer match any option. Consider keeping a fallback option when profiles.length === 0, and/or updating selectedProfileId to the first returned profile id before rendering so subsequent /api/links?profileId=... requests stay consistent.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link

github-actions bot commented Feb 7, 2026

🧪 Integrated Test Results

The integrated UI tests have completed.

View full test results: Test Run #21785706752

Test reports are available in the artifacts section of the workflow run.

@github-actions
Copy link

github-actions bot commented Feb 8, 2026

📱 APK Build Complete!

Your debug APK has been built successfully and is ready for testing.

📥 Download APK

Download app-debug.apk

Note: Click the link above, scroll down to the "Artifacts" section, and download the app-debug artifact.

Retention: This artifact will be available for 3 days.

@github-actions
Copy link

github-actions bot commented Feb 8, 2026

🧪 Integrated Test Results

The integrated UI tests have completed.

View full test results: Test Run #21793605978

Test reports are available in the artifacts section of the workflow run.

@yogeshpaliyal yogeshpaliyal merged commit bf7ae6d into master Feb 8, 2026
1 of 2 checks passed
@yogeshpaliyal yogeshpaliyal deleted the addProfileInLocalServer branch February 8, 2026 06:39
@github-actions
Copy link

github-actions bot commented Feb 8, 2026

📱 APK Build Complete!

Your debug APK has been built successfully and is ready for testing.

📥 Download APK

Download app-debug.apk

Note: Click the link above, scroll down to the "Artifacts" section, and download the app-debug artifact.

Retention: This artifact will be available for 3 days.

@github-actions
Copy link

github-actions bot commented Feb 8, 2026

🧪 Integrated Test Results

The integrated UI tests have completed.

View full test results: Test Run #21793792273

Test reports are available in the artifacts section of the workflow run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant