fix(verification): align document keys and dedupe role maps across handlers
All checks were successful
build-and-release / build (cron) (push) Successful in 16s
build-and-release / build (social-media-managers) (push) Successful in 3s
build-and-release / build (developers) (push) Successful in 15s
build-and-release / build (ugc-content-creators) (push) Successful in 4s
build-and-release / build (tutors) (push) Successful in 6s
build-and-release / build (video-editors) (push) Successful in 5s
build-and-release / build (job-seekers) (push) Successful in 4s
build-and-release / build (customers) (push) Successful in 7s
build-and-release / build (jobs) (push) Successful in 4s
build-and-release / build (catering-services) (push) Successful in 10s
build-and-release / build (makeup-artists) (push) Successful in 4s
build-and-release / build (leads) (push) Successful in 6s
build-and-release / build (payments) (push) Successful in 4s
build-and-release / build (fitness-trainers) (push) Successful in 3s
build-and-release / build (photographers) (push) Successful in 5s
build-and-release / build (gateway) (push) Successful in 3s
build-and-release / build (users) (push) Successful in 8m30s
build-and-release / build (employees) (push) Successful in 13s
build-and-release / build (companies) (push) Successful in 16s
build-and-release / build (graphic-designers) (push) Successful in 3s
All checks were successful
build-and-release / build (cron) (push) Successful in 16s
build-and-release / build (social-media-managers) (push) Successful in 3s
build-and-release / build (developers) (push) Successful in 15s
build-and-release / build (ugc-content-creators) (push) Successful in 4s
build-and-release / build (tutors) (push) Successful in 6s
build-and-release / build (video-editors) (push) Successful in 5s
build-and-release / build (job-seekers) (push) Successful in 4s
build-and-release / build (customers) (push) Successful in 7s
build-and-release / build (jobs) (push) Successful in 4s
build-and-release / build (catering-services) (push) Successful in 10s
build-and-release / build (makeup-artists) (push) Successful in 4s
build-and-release / build (leads) (push) Successful in 6s
build-and-release / build (payments) (push) Successful in 4s
build-and-release / build (fitness-trainers) (push) Successful in 3s
build-and-release / build (photographers) (push) Successful in 5s
build-and-release / build (gateway) (push) Successful in 3s
build-and-release / build (users) (push) Successful in 8m30s
build-and-release / build (employees) (push) Successful in 13s
build-and-release / build (companies) (push) Successful in 16s
build-and-release / build (graphic-designers) (push) Successful in 3s
extract_documents() recognized a stale set of document keys that no longer matched what the frontend actually uploads (portfolio_ownership_proof, professional_certifications, qualification_proof, tax_document), so every non-COMPANY role's verification case was created with an empty documents array. Also extracts role_key_to_display/role_to_table into a shared role_meta module — verifications.rs and approvals.rs were each missing UGC_CONTENT_CREATOR from their inline copies, so that role's rejections and final approvals were silently no-ops. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
b9133018a5
commit
308daf4959
5 changed files with 66 additions and 101 deletions
|
|
@ -17,6 +17,8 @@ use db::models::verification::VerificationRepository;
|
|||
use serde::Deserialize;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::role_meta::{role_key_to_display, role_to_table};
|
||||
|
||||
pub fn router() -> Router<AppState> {
|
||||
Router::new()
|
||||
.route("/", get(list_pending))
|
||||
|
|
@ -165,44 +167,15 @@ async fn list_pending(
|
|||
.into_response()
|
||||
}
|
||||
|
||||
fn role_key_to_display(role_key: &str) -> String {
|
||||
match role_key.to_uppercase().as_str() {
|
||||
"COMPANY" => "Company".to_string(),
|
||||
"CUSTOMER" => "Customer".to_string(),
|
||||
"JOB_SEEKER" | "JOBSEEKER" => "Job Seeker".to_string(),
|
||||
"PHOTOGRAPHER" => "Photographer".to_string(),
|
||||
"MAKEUP_ARTIST" => "Makeup Artist".to_string(),
|
||||
"TUTOR" => "Tutor".to_string(),
|
||||
"DEVELOPER" => "Developer".to_string(),
|
||||
"VIDEO_EDITOR" => "Video Editor".to_string(),
|
||||
"GRAPHIC_DESIGNER" => "Graphic Designer".to_string(),
|
||||
"SOCIAL_MEDIA_MANAGER" => "Social Media Manager".to_string(),
|
||||
"FITNESS_TRAINER" => "Fitness Trainer".to_string(),
|
||||
"CATERING_SERVICES" => "Catering Services".to_string(),
|
||||
_ => role_key.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn activate_profile_after_final_approval(
|
||||
state: &AppState,
|
||||
user_id: Uuid,
|
||||
role_key: &str,
|
||||
) -> Result<(), sqlx::Error> {
|
||||
let role_key = role_key.to_uppercase();
|
||||
let table = match role_key.as_str() {
|
||||
"COMPANY" => "company_profiles",
|
||||
"CUSTOMER" => "customer_profiles",
|
||||
"JOB_SEEKER" | "JOBSEEKER" => "job_seeker_profiles",
|
||||
"PHOTOGRAPHER" => "photographer_profiles",
|
||||
"MAKEUP_ARTIST" => "makeup_artist_profiles",
|
||||
"TUTOR" => "tutor_profiles",
|
||||
"DEVELOPER" => "developer_profiles",
|
||||
"VIDEO_EDITOR" => "video_editor_profiles",
|
||||
"GRAPHIC_DESIGNER" => "graphic_designer_profiles",
|
||||
"SOCIAL_MEDIA_MANAGER" => "social_media_manager_profiles",
|
||||
"FITNESS_TRAINER" => "fitness_trainer_profiles",
|
||||
"CATERING_SERVICES" => "catering_service_profiles",
|
||||
_ => return Ok(()),
|
||||
let table = match role_to_table(&role_key) {
|
||||
Some(t) => t,
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
let user_role_profile_id = match sqlx::query_scalar::<_, Uuid>(
|
||||
|
|
@ -276,20 +249,9 @@ async fn reject_profile_after_final_approval(
|
|||
reason: Option<&str>,
|
||||
) -> Result<(), sqlx::Error> {
|
||||
let role_key = role_key.to_uppercase();
|
||||
let table = match role_key.as_str() {
|
||||
"COMPANY" => "company_profiles",
|
||||
"CUSTOMER" => "customer_profiles",
|
||||
"JOB_SEEKER" | "JOBSEEKER" => "job_seeker_profiles",
|
||||
"PHOTOGRAPHER" => "photographer_profiles",
|
||||
"MAKEUP_ARTIST" => "makeup_artist_profiles",
|
||||
"TUTOR" => "tutor_profiles",
|
||||
"DEVELOPER" => "developer_profiles",
|
||||
"VIDEO_EDITOR" => "video_editor_profiles",
|
||||
"GRAPHIC_DESIGNER" => "graphic_designer_profiles",
|
||||
"SOCIAL_MEDIA_MANAGER" => "social_media_manager_profiles",
|
||||
"FITNESS_TRAINER" => "fitness_trainer_profiles",
|
||||
"CATERING_SERVICES" => "catering_service_profiles",
|
||||
_ => return Ok(()),
|
||||
let table = match role_to_table(&role_key) {
|
||||
Some(t) => t,
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
let user_role_profile_id = match sqlx::query_scalar::<_, Uuid>(
|
||||
|
|
|
|||
|
|
@ -26,4 +26,5 @@ pub mod user_roles;
|
|||
pub mod external_roles;
|
||||
pub mod verifications;
|
||||
pub mod profile;
|
||||
pub mod role_meta;
|
||||
pub mod settings;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ use db::models::{role::RoleRepository, user::UserRepository, verification::Verif
|
|||
use serde::Deserialize;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::role_meta::role_to_table;
|
||||
|
||||
// ── Routers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
pub fn router() -> Router<AppState> {
|
||||
|
|
@ -52,24 +54,6 @@ pub struct SubmitInput {
|
|||
|
||||
// ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
fn role_to_table(role_key: &str) -> Option<&'static str> {
|
||||
match role_key.to_uppercase().as_str() {
|
||||
"PHOTOGRAPHER" => Some("photographer_profiles"),
|
||||
"MAKEUP_ARTIST" => Some("makeup_artist_profiles"),
|
||||
"TUTOR" => Some("tutor_profiles"),
|
||||
"DEVELOPER" => Some("developer_profiles"),
|
||||
"VIDEO_EDITOR" => Some("video_editor_profiles"),
|
||||
"GRAPHIC_DESIGNER" => Some("graphic_designer_profiles"),
|
||||
"SOCIAL_MEDIA_MANAGER" => Some("social_media_manager_profiles"),
|
||||
"FITNESS_TRAINER" => Some("fitness_trainer_profiles"),
|
||||
"CATERING_SERVICES" => Some("catering_service_profiles"),
|
||||
"UGC_CONTENT_CREATOR" => Some("ugc_content_creator_profiles"),
|
||||
"JOB_SEEKER" | "JOBSEEKER" => Some("job_seeker_profiles"),
|
||||
"CUSTOMER" => Some("customer_profiles"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_dummy_account_email(email: &str) -> bool {
|
||||
email.ends_with("@demo.com")
|
||||
|| email == "paymentgateway@demo.com"
|
||||
|
|
@ -78,17 +62,19 @@ fn is_dummy_account_email(email: &str) -> bool {
|
|||
}
|
||||
|
||||
fn extract_documents(profile_data: &serde_json::Value) -> serde_json::Value {
|
||||
// Keep in sync with DOC_FIELDS in nxtgauge-frontend-solid/src/lib/profile-fields-config.ts —
|
||||
// each entry there is the source of truth for the document key a role's upload writes.
|
||||
let doc_keys = [
|
||||
"aadhar_doc",
|
||||
"registration_doc",
|
||||
"gst_doc",
|
||||
"sample_work",
|
||||
"degree_certificate",
|
||||
"address_proof",
|
||||
"portfolio_ownership_proof",
|
||||
"professional_certifications",
|
||||
"qualification_proof",
|
||||
"certification_doc",
|
||||
"fssai_license",
|
||||
"identity_proof",
|
||||
"address_proof",
|
||||
"portfolio_proof",
|
||||
"tax_document",
|
||||
];
|
||||
let mut docs = vec![];
|
||||
for key in &doc_keys {
|
||||
|
|
|
|||
43
apps/users/src/handlers/role_meta.rs
Normal file
43
apps/users/src/handlers/role_meta.rs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
//! Single source of truth for role_key <-> display name / profile table mappings,
|
||||
//! shared by profile.rs, verifications.rs and approvals.rs so a role added to one
|
||||
//! consumer can't silently be missing from another.
|
||||
|
||||
pub fn role_key_to_display(role_key: &str) -> String {
|
||||
match role_key.to_uppercase().as_str() {
|
||||
"COMPANY" => "Company".to_string(),
|
||||
"CUSTOMER" => "Customer".to_string(),
|
||||
"JOB_SEEKER" | "JOBSEEKER" => "Job Seeker".to_string(),
|
||||
"PHOTOGRAPHER" => "Photographer".to_string(),
|
||||
"MAKEUP_ARTIST" => "Makeup Artist".to_string(),
|
||||
"TUTOR" => "Tutor".to_string(),
|
||||
"DEVELOPER" => "Developer".to_string(),
|
||||
"VIDEO_EDITOR" => "Video Editor".to_string(),
|
||||
"GRAPHIC_DESIGNER" => "Graphic Designer".to_string(),
|
||||
"SOCIAL_MEDIA_MANAGER" => "Social Media Manager".to_string(),
|
||||
"FITNESS_TRAINER" => "Fitness Trainer".to_string(),
|
||||
"CATERING_SERVICES" => "Catering Services".to_string(),
|
||||
"UGC_CONTENT_CREATOR" => "UGC Content Creator".to_string(),
|
||||
_ => role_key.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the profile table for a role, or None for roles with no dedicated
|
||||
/// profile table under this pipeline (e.g. COMPANY, which is handled separately).
|
||||
pub fn role_to_table(role_key: &str) -> Option<&'static str> {
|
||||
match role_key.to_uppercase().as_str() {
|
||||
"PHOTOGRAPHER" => Some("photographer_profiles"),
|
||||
"MAKEUP_ARTIST" => Some("makeup_artist_profiles"),
|
||||
"TUTOR" => Some("tutor_profiles"),
|
||||
"DEVELOPER" => Some("developer_profiles"),
|
||||
"VIDEO_EDITOR" => Some("video_editor_profiles"),
|
||||
"GRAPHIC_DESIGNER" => Some("graphic_designer_profiles"),
|
||||
"SOCIAL_MEDIA_MANAGER" => Some("social_media_manager_profiles"),
|
||||
"FITNESS_TRAINER" => Some("fitness_trainer_profiles"),
|
||||
"CATERING_SERVICES" => Some("catering_service_profiles"),
|
||||
"UGC_CONTENT_CREATOR" => Some("ugc_content_creator_profiles"),
|
||||
"JOB_SEEKER" | "JOBSEEKER" => Some("job_seeker_profiles"),
|
||||
"CUSTOMER" => Some("customer_profiles"),
|
||||
"COMPANY" => Some("company_profiles"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,8 @@ use db::models::verification::{VerificationRepository};
|
|||
use serde::Deserialize;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::role_meta::{role_key_to_display, role_to_table};
|
||||
|
||||
/// Creates an entry in approval_requests after verification is approved.
|
||||
/// This is the bridge between Verification Management and Approval Management.
|
||||
async fn create_approval_request_from_verification(
|
||||
|
|
@ -128,24 +130,6 @@ pub struct ActionPayload {
|
|||
pub reason: Option<String>,
|
||||
}
|
||||
|
||||
fn role_key_to_display(role_key: &str) -> String {
|
||||
match role_key.to_uppercase().as_str() {
|
||||
"COMPANY" => "Company".to_string(),
|
||||
"CUSTOMER" => "Customer".to_string(),
|
||||
"JOB_SEEKER" | "JOBSEEKER" => "Job Seeker".to_string(),
|
||||
"PHOTOGRAPHER" => "Photographer".to_string(),
|
||||
"MAKEUP_ARTIST" => "Makeup Artist".to_string(),
|
||||
"TUTOR" => "Tutor".to_string(),
|
||||
"DEVELOPER" => "Developer".to_string(),
|
||||
"VIDEO_EDITOR" => "Video Editor".to_string(),
|
||||
"GRAPHIC_DESIGNER" => "Graphic Designer".to_string(),
|
||||
"SOCIAL_MEDIA_MANAGER" => "Social Media Manager".to_string(),
|
||||
"FITNESS_TRAINER" => "Fitness Trainer".to_string(),
|
||||
"CATERING_SERVICES" => "Catering Services".to_string(),
|
||||
_ => role_key.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn trigger_rejection(
|
||||
state: &AppState,
|
||||
user_id: Uuid,
|
||||
|
|
@ -157,20 +141,9 @@ async fn trigger_rejection(
|
|||
let reason_str = reason.unwrap_or("Verification rejected");
|
||||
|
||||
if case_type == "PROFILE_VERIFICATION" {
|
||||
let table = match role_key.as_str() {
|
||||
"COMPANY" => "company_profiles",
|
||||
"CUSTOMER" => "customer_profiles",
|
||||
"JOB_SEEKER" | "JOBSEEKER" => "job_seeker_profiles",
|
||||
"PHOTOGRAPHER" => "photographer_profiles",
|
||||
"MAKEUP_ARTIST" => "makeup_artist_profiles",
|
||||
"TUTOR" => "tutor_profiles",
|
||||
"DEVELOPER" => "developer_profiles",
|
||||
"VIDEO_EDITOR" => "video_editor_profiles",
|
||||
"GRAPHIC_DESIGNER" => "graphic_designer_profiles",
|
||||
"SOCIAL_MEDIA_MANAGER" => "social_media_manager_profiles",
|
||||
"FITNESS_TRAINER" => "fitness_trainer_profiles",
|
||||
"CATERING_SERVICES" => "catering_service_profiles",
|
||||
_ => return Ok(()),
|
||||
let table = match role_to_table(&role_key) {
|
||||
Some(t) => t,
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
let user_role_profile_id = match sqlx::query_scalar::<_, Uuid>(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue