feat: auto-approve dummy company accounts
This commit is contained in:
parent
b2c93f4e33
commit
418da25d37
4 changed files with 46 additions and 7 deletions
|
|
@ -186,12 +186,12 @@ async fn approve_company(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
Path(id): Path<Uuid>,
|
Path(id): Path<Uuid>,
|
||||||
) -> Result<impl IntoResponse, (StatusCode, String)> {
|
) -> 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)
|
.bind(id)
|
||||||
.execute(&state.pool)
|
.execute(&state.pool)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("DB error: {e}")))?;
|
.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(
|
async fn reject_company(
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,13 @@ fn resolve_signup_role_candidates(intent: Option<&str>, profession: Option<&str>
|
||||||
vec![]
|
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 {
|
fn role_display_name_from_code(code: &str) -> String {
|
||||||
code
|
code
|
||||||
.split('_')
|
.split('_')
|
||||||
|
|
@ -297,7 +304,7 @@ async fn register(
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Check if this is a demo account (payment gateway integration)
|
// 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.
|
// Assign signup role immediately (intent-driven). Email verification is still required for login.
|
||||||
let role_candidates = resolve_signup_role_candidates(
|
let role_candidates = resolve_signup_role_candidates(
|
||||||
|
|
@ -334,6 +341,7 @@ async fn register(
|
||||||
.bind(user.id)
|
.bind(user.id)
|
||||||
.bind(role_id)
|
.bind(role_id)
|
||||||
.bind(status)
|
.bind(status)
|
||||||
|
.execute(&state.pool)
|
||||||
.await;
|
.await;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -416,7 +424,7 @@ async fn login(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow demo accounts to login without email verification
|
// 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 {
|
if !user.email_verified && !is_demo_account {
|
||||||
return Err(err(StatusCode::UNAUTHORIZED, "Email not verified. Check your inbox.", "EMAIL_NOT_VERIFIED"));
|
return Err(err(StatusCode::UNAUTHORIZED, "Email not verified. Check your inbox.", "EMAIL_NOT_VERIFIED"));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
fn extract_documents(profile_data: &serde_json::Value) -> serde_json::Value {
|
||||||
let doc_keys = [
|
let doc_keys = [
|
||||||
"aadhar_doc",
|
"aadhar_doc",
|
||||||
|
|
@ -310,7 +317,7 @@ async fn submit_for_verification(
|
||||||
.bind(auth.user_id)
|
.bind(auth.user_id)
|
||||||
.fetch_one(&state.pool)
|
.fetch_one(&state.pool)
|
||||||
.await
|
.await
|
||||||
.map(|email| email.ends_with("@demo.com") || email == "paymentgateway@demo.com")
|
.map(|email| is_dummy_account_email(&email))
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
|
|
||||||
// For demo accounts: auto-approve verification
|
// For demo accounts: auto-approve verification
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,20 @@ pub struct UpsertCompanyProfilePayload {
|
||||||
pub struct CompanyRepository;
|
pub struct CompanyRepository;
|
||||||
|
|
||||||
impl 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(
|
pub async fn get_by_user_id(
|
||||||
pool: &PgPool,
|
pool: &PgPool,
|
||||||
user_id: Uuid,
|
user_id: Uuid,
|
||||||
|
|
@ -81,6 +95,9 @@ impl CompanyRepository {
|
||||||
user_id: Uuid,
|
user_id: Uuid,
|
||||||
payload: UpsertCompanyProfilePayload,
|
payload: UpsertCompanyProfilePayload,
|
||||||
) -> Result<CompanyProfile, sqlx::Error> {
|
) -> 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>(
|
let profile = sqlx::query_as::<_, CompanyProfile>(
|
||||||
r#"
|
r#"
|
||||||
INSERT INTO company_profiles (
|
INSERT INTO company_profiles (
|
||||||
|
|
@ -88,7 +105,7 @@ impl CompanyRepository {
|
||||||
employee_count, business_type, gst_number, contact_name,
|
employee_count, business_type, gst_number, contact_name,
|
||||||
contact_email, contact_phone, address_line1, city, state, postal_code, status
|
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
|
ON CONFLICT (user_id) DO UPDATE SET
|
||||||
company_name = EXCLUDED.company_name,
|
company_name = EXCLUDED.company_name,
|
||||||
registration_number = EXCLUDED.registration_number,
|
registration_number = EXCLUDED.registration_number,
|
||||||
|
|
@ -105,6 +122,7 @@ impl CompanyRepository {
|
||||||
state = EXCLUDED.state,
|
state = EXCLUDED.state,
|
||||||
postal_code = EXCLUDED.postal_code,
|
postal_code = EXCLUDED.postal_code,
|
||||||
status = CASE
|
status = CASE
|
||||||
|
WHEN $17 THEN 'APPROVED'
|
||||||
WHEN company_profiles.status = 'APPROVED' THEN 'APPROVED'
|
WHEN company_profiles.status = 'APPROVED' THEN 'APPROVED'
|
||||||
ELSE 'PENDING'
|
ELSE 'PENDING'
|
||||||
END,
|
END,
|
||||||
|
|
@ -133,6 +151,8 @@ impl CompanyRepository {
|
||||||
.bind(payload.city)
|
.bind(payload.city)
|
||||||
.bind(payload.state)
|
.bind(payload.state)
|
||||||
.bind(payload.postal_code)
|
.bind(payload.postal_code)
|
||||||
|
.bind(default_status)
|
||||||
|
.bind(is_dummy_account)
|
||||||
.fetch_one(pool)
|
.fetch_one(pool)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
@ -143,10 +163,13 @@ impl CompanyRepository {
|
||||||
pool: &PgPool,
|
pool: &PgPool,
|
||||||
user_id: Uuid,
|
user_id: Uuid,
|
||||||
) -> Result<CompanyProfile, sqlx::Error> {
|
) -> 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>(
|
let profile = sqlx::query_as::<_, CompanyProfile>(
|
||||||
r#"
|
r#"
|
||||||
UPDATE company_profiles
|
UPDATE company_profiles
|
||||||
SET status = 'PENDING_REVIEW', updated_at = NOW()
|
SET status = $2, updated_at = NOW()
|
||||||
WHERE user_id = $1
|
WHERE user_id = $1
|
||||||
RETURNING
|
RETURNING
|
||||||
id, user_id, company_name, registration_number, industry,
|
id, user_id, company_name, registration_number, industry,
|
||||||
|
|
@ -158,6 +181,7 @@ impl CompanyRepository {
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.bind(user_id)
|
.bind(user_id)
|
||||||
|
.bind(next_status)
|
||||||
.fetch_one(pool)
|
.fetch_one(pool)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue