refactor: update upsert API to handle multiple rows and adjust related service methods#119
Open
Aadil-Ahmed-27 wants to merge 1 commit into
Open
refactor: update upsert API to handle multiple rows and adjust related service methods#119Aadil-Ahmed-27 wants to merge 1 commit into
Aadil-Ahmed-27 wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the operator CRUD layer to support new employees_internal fields and adds request validation for employee upserts.
Changes:
- Added
email_hashandpassword_hashto the known column list foremployees_internal. - Modified upsert column derivation to consider keys across all provided rows and avoid updating key columns for
employees_internal. - Added handler-level validation for
employees_internalupserts to enforce presence ofemail_hash/mobile_noand requirepassword_hashwhenemail_hashis present.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/services/operator.rs | Extends employee columns, changes PK mapping for employees, and adjusts upsert column/update-set generation. |
| src/handlers/routes.rs | Adds employees_internal-specific upsert validation prior to calling the service layer. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
1471
to
1487
| // Build column list from ALL rows, excluding gtfs_id (we inject it ourselves) | ||
| // Also exclude keys whose value is JSON null — omit-null semantics so that a partial | ||
| // update (e.g. just {waybill_id, duty_date}) never triggers NOT NULL violations on | ||
| // columns the caller didn't intend to touch. | ||
| let mut cols: Vec<&str> = first_obj | ||
| .keys() | ||
| .filter(|k| k.as_str() != "gtfs_id" && !first_obj[k.as_str()].is_null()) | ||
| .map(|s| s.as_str()) | ||
| .collect(); | ||
| let mut col_set: std::collections::HashSet<&str> = std::collections::HashSet::new(); | ||
| for row in &arr { | ||
| if let Some(obj) = row.as_object() { | ||
| for (k, v) in obj.iter() { | ||
| if k.as_str() != "gtfs_id" && !v.is_null() { | ||
| col_set.insert(k.as_str()); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| let mut cols: Vec<&str> = col_set.into_iter().collect(); | ||
| cols.sort(); // Sort for consistent SQL generation | ||
| cols.push("gtfs_id"); // gtfs_id always last |
Comment on lines
+3456
to
+3494
| fn validate_employee_upsert(body: &Value) -> AppResult<()> { | ||
| let rows: Vec<&Value> = if let Some(arr) = body.as_array() { | ||
| arr.iter().collect() | ||
| } else if body.is_object() { | ||
| vec![body] | ||
| } else { | ||
| return Ok(()); | ||
| }; | ||
|
|
||
| for (i, row) in rows.iter().enumerate() { | ||
| let obj = match row.as_object() { | ||
| Some(o) => o, | ||
| None => continue, | ||
| }; | ||
|
|
||
| let has_email = obj.get("email_hash").map(|v| !v.is_null()).unwrap_or(false); | ||
| let has_mobile = obj.get("mobile_no").map(|v| !v.is_null()).unwrap_or(false); | ||
|
|
||
| if !has_email && !has_mobile { | ||
| return Err(AppError::BadRequest(format!( | ||
| "Row {}: at least one of 'email_hash' or 'mobile_no' must be present", | ||
| i | ||
| ))); | ||
| } | ||
|
|
||
| if has_email { | ||
| let has_password = obj | ||
| .get("password_hash") | ||
| .map(|v| !v.is_null()) | ||
| .unwrap_or(false); | ||
| if !has_password { | ||
| return Err(AppError::BadRequest(format!( | ||
| "Row {}: 'password_hash' is required when 'email_hash' is provided", | ||
| i | ||
| ))); | ||
| } | ||
| } | ||
| } | ||
|
|
Collaborator
There was a problem hiding this comment.
can be moved to domain
Comment on lines
+3533
to
+3537
| // Validate employees_internal specific rules | ||
| if table == "employees_internal" { | ||
| validate_employee_upsert(&body_value)?; | ||
| } | ||
|
|
Collaborator
There was a problem hiding this comment.
move to domain
| "employees_internal" => vec!["gtfs_id", "token_no"], | ||
| _ => vec![], | ||
| }; | ||
|
|
Collaborator
There was a problem hiding this comment.
should be handled by table_pk ig
Aadil-Ahmed-27
force-pushed
the
Upsert-API-update
branch
2 times, most recently
from
June 3, 2026 08:46
0468d47 to
046ebe3
Compare
Aadil-Ahmed-27
force-pushed
the
Upsert-API-update
branch
2 times, most recently
from
June 8, 2026 12:13
c6fc1cd to
ac86108
Compare
Jayanth-Parthsarathy
approved these changes
Jun 8, 2026
Jayanth-Parthsarathy
approved these changes
Jun 22, 2026
Aadil-Ahmed-27
force-pushed
the
Upsert-API-update
branch
from
June 22, 2026 12:01
d258e4f to
871136f
Compare
…d service methods
Aadil-Ahmed-27
force-pushed
the
Upsert-API-update
branch
from
July 17, 2026 07:10
871136f to
e71e1c2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
…ructure