Skip to content

fix: application user - #55

Merged
saijaku0 merged 2 commits into
mainfrom
fix/application-user
Feb 18, 2026
Merged

fix: application user#55
saijaku0 merged 2 commits into
mainfrom
fix/application-user

Conversation

@saijaku0

@saijaku0 saijaku0 commented Feb 18, 2026

Copy link
Copy Markdown
Owner

Update application user domain; add some DDD architecture. Implement code base to handler

Summary by CodeRabbit

  • Bug Fixes

    • Fixed authorization checks for doctor profile modifications to ensure only authorized users can make updates.
    • Enhanced consistency in user profile data management across patient and doctor accounts.
  • Performance

    • Improved appointment detail loading efficiency with optimized data retrieval.

@coderabbitai

coderabbitai Bot commented Feb 18, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR introduces factory methods to ApplicationUser for creating doctor and patient users, makes properties immutable with private setters, and updates command handlers to use these factory methods instead of direct object initialization. A query handler also adds eager loading for Doctor.ApplicationUser relationships.

Changes

Cohort / File(s) Summary
ApplicationUser Entity
src/Booking/Booking.Domain/Entities/ApplicationUser.cs
Introduces property encapsulation (FirstName, LastName, PhotoUrl, Address now have private setters), adds parameterless and parameterized constructors, and adds static factory methods CreateDoctor() and CreatePatient() for standardized user creation. Includes new UpdatePersonalInfo() method for updating personal details.
Command Handlers
src/Booking/Booking.Application/Doctors/Command/CreateDoctor/CreateDoctorCommandHandler.cs, src/Booking/Booking.Application/Doctors/Command/UpdateDoctor/UpdateDoctorCommandHandler.cs, src/Booking/Booking.Application/Identity/Commands/RegisterUser/RegisterUserCommandHandler.cs
Updates handlers to use factory methods (ApplicationUser.CreateDoctor(), ApplicationUser.CreatePatient()) instead of direct object initialization. UpdateDoctor handler changes authorization logic and replaces direct property assignments with UpdatePersonalInfo() call.
Query Handler
src/Booking/Booking.Application/Appointments/Queries/GetAppointmentById/GetAppointmentByIdQueryHandler.cs
Adds eager loading of Doctor's ApplicationUser via .Include(b => b.Doctor).ThenInclude(d => d.ApplicationUser) to expand Doctor-related data retrieval.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • PR #51: Modifies GetAppointmentById query handler to load and project Doctor.ApplicationUser data for DTO mapping, related to the eager loading addition in this PR.

Poem

🐰 A rabbit hops with glee, as factories emerge clean,
No more scattered setters scattered in between!
With private gates and public doors, encapsulation's grace,
Users born from methods fine—order finds its place! ✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'fix: application user' is vague and generic, lacking specificity about the actual changes made. Provide a more descriptive title that clarifies the key change, such as 'refactor: introduce factory methods and immutable properties for ApplicationUser' or 'refactor: apply DDD patterns to ApplicationUser domain entity'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/application-user

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
src/Booking/Booking.Domain/Entities/ApplicationUser.cs (2)

15-15: Address nullable warnings for EF Core constructor.

The private parameterless constructor leaves non-nullable FirstName and LastName uninitialized. While this is expected for EF Core, you can suppress the warnings by initializing with null! or adding #pragma warning disable.

♻️ Proposed fix to suppress warnings
-        public string FirstName { get; private set; }
-        public string LastName { get; private set; }
+        public string FirstName { get; private set; } = null!;
+        public string LastName { get; private set; } = null!;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Booking/Booking.Domain/Entities/ApplicationUser.cs` at line 15, The
private parameterless constructor ApplicationUser() leaves the non-nullable
properties FirstName and LastName uninitialized and triggers nullable warnings;
modify the ApplicationUser() constructor to suppress warnings by initializing
those properties with the null-forgiving operator (e.g., assign FirstName =
null! and LastName = null!) or alternatively add a scoped pragma disable/restore
for nullable warnings around the constructor, ensuring the changes reference the
ApplicationUser class and its parameterless constructor.

27-42: Consider adding input validation to factory methods.

Neither CreateDoctor nor CreatePatient validate their inputs. If UpdatePersonalInfo requires non-empty names, the factory methods should enforce the same invariants to maintain consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Booking/Booking.Domain/Entities/ApplicationUser.cs` around lines 27 - 42,
The factory methods CreateDoctor and CreatePatient currently accept any inputs;
add the same input validation/invariants used by UpdatePersonalInfo: check
email, firstName and lastName are not null/empty (and validate email format if
UpdatePersonalInfo enforces it), and validate phoneNumber if required; throw
ArgumentNullException/ArgumentException on invalid values before constructing
the ApplicationUser so the factories preserve class invariants (update
ApplicationUser.CreateDoctor and ApplicationUser.CreatePatient and add/adjust
unit tests accordingly).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@src/Booking/Booking.Application/Identity/Commands/RegisterUser/RegisterUserCommandHandler.cs`:
- Around line 23-30: The call to ApplicationUser.CreatePatient in
RegisterUserCommandHandler passes request.PhoneNumber and request.Address which
may be null while CreatePatient requires non-nullable strings; fix by either
validating these fields in the handler (e.g., ensure PhoneNumber/Address are
present and return/throw a validation error) or pass safe fallbacks (e.g.,
coalesce to string.Empty or a default value) before calling CreatePatient;
alternatively, if null is acceptable domain-wise, update
ApplicationUser.CreatePatient signature to accept string? for phoneNumber and
address and adjust its internals to handle nulls. Ensure you update the
RegisterUserCommandHandler call or the CreatePatient signature consistently and
keep all references aligned.

In `@src/Booking/Booking.Domain/Entities/ApplicationUser.cs`:
- Around line 49-52: In ApplicationUser (ApplicationUser.cs) the validation
logic is inverted: change the conditions to throw when name or lastname are
null/empty (use string.IsNullOrEmpty(name) and string.IsNullOrEmpty(lastname))
instead of the current negated checks, and throw ArgumentException with a clear
parameter name/message (e.g., "Name cannot be empty." and "Last name cannot be
empty." or use nameof(name)/nameof(lastname)) in the constructor or setter that
currently contains those lines.
- Around line 59-64: The public factory method ApplicationUser.CreatePatient has
a typo in its parameter name "adress" — rename the parameter to "address" in the
CreatePatient signature and update all uses inside the ApplicationUser class
(and any internal parameter forwarding) to use the corrected name; then update
all call sites that pass that argument to use "address" to avoid breaking the
public API surface while keeping behavior unchanged.

---

Duplicate comments:
In
`@src/Booking/Booking.Application/Doctors/Command/UpdateDoctor/UpdateDoctorCommandHandler.cs`:
- Around line 48-51: The call to doctor.ApplicationUser.UpdatePersonalInfo in
UpdateDoctorCommandHandler.cs fails because UpdatePersonalInfo in
ApplicationUser.cs has inverted validation (it throws for valid Name/Lastname
and allows invalid ones); open ApplicationUser.cs, locate the UpdatePersonalInfo
method and invert the validation conditions so it only throws when inputs are
invalid (e.g., null/empty, wrong length or characters) rather than when they are
valid; ensure the method accepts the request.Name, request.Lastname,
request.PhoneNumber parameters and only raises exceptions on real validation
failures so UpdateDoctorCommandHandler's call succeeds.

---

Nitpick comments:
In `@src/Booking/Booking.Domain/Entities/ApplicationUser.cs`:
- Line 15: The private parameterless constructor ApplicationUser() leaves the
non-nullable properties FirstName and LastName uninitialized and triggers
nullable warnings; modify the ApplicationUser() constructor to suppress warnings
by initializing those properties with the null-forgiving operator (e.g., assign
FirstName = null! and LastName = null!) or alternatively add a scoped pragma
disable/restore for nullable warnings around the constructor, ensuring the
changes reference the ApplicationUser class and its parameterless constructor.
- Around line 27-42: The factory methods CreateDoctor and CreatePatient
currently accept any inputs; add the same input validation/invariants used by
UpdatePersonalInfo: check email, firstName and lastName are not null/empty (and
validate email format if UpdatePersonalInfo enforces it), and validate
phoneNumber if required; throw ArgumentNullException/ArgumentException on
invalid values before constructing the ApplicationUser so the factories preserve
class invariants (update ApplicationUser.CreateDoctor and
ApplicationUser.CreatePatient and add/adjust unit tests accordingly).

Comment on lines +23 to +30
var user = ApplicationUser.CreatePatient
(
firstName: request.UserName,
lastName: request.UserSurname,
email: request.UserEmail,
phoneNumber: request.PhoneNumber,
adress: request.Address
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Handle potential null values for PhoneNumber and Address.

Static analysis warns that request.PhoneNumber and request.Address may be null, but CreatePatient expects non-nullable strings. Either validate these fields are required or update the factory method to accept nullable parameters.

🛡️ Option 1: Provide fallback values
             var user = ApplicationUser.CreatePatient
             (
                 firstName: request.UserName,
                 lastName: request.UserSurname,
                 email: request.UserEmail,
-                phoneNumber: request.PhoneNumber,
-                adress: request.Address
+                phoneNumber: request.PhoneNumber ?? string.Empty,
+                adress: request.Address ?? string.Empty
             );

Alternatively, update CreatePatient to accept string? for these parameters.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var user = ApplicationUser.CreatePatient
(
firstName: request.UserName,
lastName: request.UserSurname,
email: request.UserEmail,
phoneNumber: request.PhoneNumber,
adress: request.Address
);
var user = ApplicationUser.CreatePatient
(
firstName: request.UserName,
lastName: request.UserSurname,
email: request.UserEmail,
phoneNumber: request.PhoneNumber ?? string.Empty,
adress: request.Address ?? string.Empty
);
🧰 Tools
🪛 GitHub Check: build

[warning] 29-29:
Possible null reference argument for parameter 'adress' in 'ApplicationUser ApplicationUser.CreatePatient(string firstName, string lastName, string email, string phoneNumber, string adress)'.


[warning] 28-28:
Possible null reference argument for parameter 'phoneNumber' in 'ApplicationUser ApplicationUser.CreatePatient(string firstName, string lastName, string email, string phoneNumber, string adress)'.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/Booking/Booking.Application/Identity/Commands/RegisterUser/RegisterUserCommandHandler.cs`
around lines 23 - 30, The call to ApplicationUser.CreatePatient in
RegisterUserCommandHandler passes request.PhoneNumber and request.Address which
may be null while CreatePatient requires non-nullable strings; fix by either
validating these fields in the handler (e.g., ensure PhoneNumber/Address are
present and return/throw a validation error) or pass safe fallbacks (e.g.,
coalesce to string.Empty or a default value) before calling CreatePatient;
alternatively, if null is acceptable domain-wise, update
ApplicationUser.CreatePatient signature to accept string? for phoneNumber and
address and adjust its internals to handle nulls. Ensure you update the
RegisterUserCommandHandler call or the CreatePatient signature consistently and
keep all references aligned.

Comment on lines +49 to +52
if (!string.IsNullOrEmpty(name))
throw new ArgumentException("Name cannot be empty.");
if (!string.IsNullOrEmpty(lastname))
throw new ArgumentException("Last name cannot be empty.");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical bug: Validation logic is inverted.

The conditions throw when name and lastname are not empty, which is backwards. Valid inputs will cause exceptions, while null/empty values will be accepted.

🐛 Proposed fix to correct the validation logic
         public void UpdatePersonalInfo(
         string name,
         string lastname,
         string? phoneNumber)
         {
-            if (!string.IsNullOrEmpty(name))
+            if (string.IsNullOrEmpty(name))
                 throw new ArgumentException("Name cannot be empty.");
-            if (!string.IsNullOrEmpty(lastname))
+            if (string.IsNullOrEmpty(lastname))
                 throw new ArgumentException("Last name cannot be empty.");

             FirstName = name;
             LastName = lastname;
             PhoneNumber = phoneNumber;
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!string.IsNullOrEmpty(name))
throw new ArgumentException("Name cannot be empty.");
if (!string.IsNullOrEmpty(lastname))
throw new ArgumentException("Last name cannot be empty.");
public void UpdatePersonalInfo(
string name,
string lastname,
string? phoneNumber)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentException("Name cannot be empty.");
if (string.IsNullOrEmpty(lastname))
throw new ArgumentException("Last name cannot be empty.");
FirstName = name;
LastName = lastname;
PhoneNumber = phoneNumber;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Booking/Booking.Domain/Entities/ApplicationUser.cs` around lines 49 - 52,
In ApplicationUser (ApplicationUser.cs) the validation logic is inverted: change
the conditions to throw when name or lastname are null/empty (use
string.IsNullOrEmpty(name) and string.IsNullOrEmpty(lastname)) instead of the
current negated checks, and throw ArgumentException with a clear parameter
name/message (e.g., "Name cannot be empty." and "Last name cannot be empty." or
use nameof(name)/nameof(lastname)) in the constructor or setter that currently
contains those lines.

Comment on lines +59 to +64
public static ApplicationUser CreatePatient(
string firstName,
string lastName,
string email,
string phoneNumber,
string adress)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Typo in parameter name: adress should be address.

This typo in the public API surface will propagate to all callers.

✏️ Proposed fix
         public static ApplicationUser CreatePatient(
             string firstName,
             string lastName,
             string email,
             string phoneNumber,
-            string adress)
+            string address)
         {
             return new ApplicationUser
             {
                 UserName = email,
                 Email = email,
                 FirstName = firstName,
                 LastName = lastName,
                 PhoneNumber = phoneNumber,
-                Address = adress,
+                Address = address,
                 EmailConfirmed = true
             };
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public static ApplicationUser CreatePatient(
string firstName,
string lastName,
string email,
string phoneNumber,
string adress)
public static ApplicationUser CreatePatient(
string firstName,
string lastName,
string email,
string phoneNumber,
string address)
{
return new ApplicationUser
{
UserName = email,
Email = email,
FirstName = firstName,
LastName = lastName,
PhoneNumber = phoneNumber,
Address = address,
EmailConfirmed = true
};
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Booking/Booking.Domain/Entities/ApplicationUser.cs` around lines 59 - 64,
The public factory method ApplicationUser.CreatePatient has a typo in its
parameter name "adress" — rename the parameter to "address" in the CreatePatient
signature and update all uses inside the ApplicationUser class (and any internal
parameter forwarding) to use the corrected name; then update all call sites that
pass that argument to use "address" to avoid breaking the public API surface
while keeping behavior unchanged.

@saijaku0
saijaku0 merged commit ef2bd63 into main Feb 18, 2026
4 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Feb 18, 2026
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