feat: auto-approve dummy company accounts

This commit is contained in:
Ashwin Kumar Sivakumar 2026-06-12 06:02:20 +05:30
parent b2c93f4e33
commit 418da25d37
4 changed files with 46 additions and 7 deletions

View file

@ -186,12 +186,12 @@ async fn approve_company(
State(state): State<AppState>,
Path(id): Path<Uuid>,
) -> Result<impl IntoResponse, (StatusCode, String)> {
sqlx::query("UPDATE company_profiles SET status = 'ACTIVE', updated_at = NOW() WHERE id = $1")
sqlx::query("UPDATE company_profiles SET status = 'APPROVED', updated_at = NOW() WHERE id = $1")
.bind(id)
.execute(&state.pool)
.await
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("DB error: {e}")))?;
Ok(Json(serde_json::json!({ "status": "ACTIVE" })))
Ok(Json(serde_json::json!({ "status": "APPROVED" })))
}
async fn reject_company(

View file

@ -165,6 +165,13 @@ fn resolve_signup_role_candidates(intent: Option<&str>, profession: Option<&str>
vec![]
}
fn is_dummy_account_email(email: &str) -> bool {
email.ends_with("@demo.com")
|| email == "paymentgateway@demo.com"
|| email.contains("+dummy@")
|| email.starts_with("dummy+")
}
fn role_display_name_from_code(code: &str) -> String {
code
.split('_')
@ -297,7 +304,7 @@ async fn register(
})?;
// Check if this is a demo account (payment gateway integration)
let is_demo_account = email.ends_with("@demo.com") || email == "paymentgateway@demo.com";
let is_demo_account = is_dummy_account_email(&email);
// Assign signup role immediately (intent-driven). Email verification is still required for login.
let role_candidates = resolve_signup_role_candidates(
@ -334,6 +341,7 @@ async fn register(
.bind(user.id)
.bind(role_id)
.bind(status)
.execute(&state.pool)
.await;
break;
}
@ -416,7 +424,7 @@ async fn login(
}
// Allow demo accounts to login without email verification
let is_demo_account = email.ends_with("@demo.com") || email == "paymentgateway@demo.com";
let is_demo_account = is_dummy_account_email(&email);
if !user.email_verified && !is_demo_account {
return Err(err(StatusCode::UNAUTHORIZED, "Email not verified. Check your inbox.", "EMAIL_NOT_VERIFIED"));
}

View file

@ -69,6 +69,13 @@ fn role_to_table(role_key: &str) -> Option<&'static str> {
}
}
fn is_dummy_account_email(email: &str) -> bool {
email.ends_with("@demo.com")
|| email == "paymentgateway@demo.com"
|| email.contains("+dummy@")
|| email.starts_with("dummy+")
}
fn extract_documents(profile_data: &serde_json::Value) -> serde_json::Value {
let doc_keys = [
"aadhar_doc",
@ -310,7 +317,7 @@ async fn submit_for_verification(
.bind(auth.user_id)
.fetch_one(&state.pool)
.await
.map(|email| email.ends_with("@demo.com") || email == "paymentgateway@demo.com")
.map(|email| is_dummy_account_email(&email))
.unwrap_or(false);
// For demo accounts: auto-approve verification

View file

@ -52,6 +52,20 @@ pub struct UpsertCompanyProfilePayload {
pub struct CompanyRepository;
impl CompanyRepository {
async fn is_dummy_account(pool: &PgPool, user_id: Uuid) -> Result<bool, sqlx::Error> {
let email = sqlx::query_scalar::<_, String>("SELECT email FROM users WHERE id = $1")
.bind(user_id)
.fetch_one(pool)
.await?;
Ok(
email.ends_with("@demo.com")
|| email == "paymentgateway@demo.com"
|| email.contains("+dummy@")
|| email.starts_with("dummy+"),
)
}
pub async fn get_by_user_id(
pool: &PgPool,
user_id: Uuid,
@ -81,6 +95,9 @@ impl CompanyRepository {
user_id: Uuid,
payload: UpsertCompanyProfilePayload,
) -> Result<CompanyProfile, sqlx::Error> {
let is_dummy_account = Self::is_dummy_account(pool, user_id).await?;
let default_status = if is_dummy_account { "APPROVED" } else { "PENDING" };
let profile = sqlx::query_as::<_, CompanyProfile>(
r#"
INSERT INTO company_profiles (
@ -88,7 +105,7 @@ impl CompanyRepository {
employee_count, business_type, gst_number, contact_name,
contact_email, contact_phone, address_line1, city, state, postal_code, status
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, 'PENDING')
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
ON CONFLICT (user_id) DO UPDATE SET
company_name = EXCLUDED.company_name,
registration_number = EXCLUDED.registration_number,
@ -105,6 +122,7 @@ impl CompanyRepository {
state = EXCLUDED.state,
postal_code = EXCLUDED.postal_code,
status = CASE
WHEN $17 THEN 'APPROVED'
WHEN company_profiles.status = 'APPROVED' THEN 'APPROVED'
ELSE 'PENDING'
END,
@ -133,6 +151,8 @@ impl CompanyRepository {
.bind(payload.city)
.bind(payload.state)
.bind(payload.postal_code)
.bind(default_status)
.bind(is_dummy_account)
.fetch_one(pool)
.await?;
@ -143,10 +163,13 @@ impl CompanyRepository {
pool: &PgPool,
user_id: Uuid,
) -> Result<CompanyProfile, sqlx::Error> {
let is_dummy_account = Self::is_dummy_account(pool, user_id).await?;
let next_status = if is_dummy_account { "APPROVED" } else { "PENDING_REVIEW" };
let profile = sqlx::query_as::<_, CompanyProfile>(
r#"
UPDATE company_profiles
SET status = 'PENDING_REVIEW', updated_at = NOW()
SET status = $2, updated_at = NOW()
WHERE user_id = $1
RETURNING
id, user_id, company_name, registration_number, industry,
@ -158,6 +181,7 @@ impl CompanyRepository {
"#,
)
.bind(user_id)
.bind(next_status)
.fetch_one(pool)
.await?;