mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-08 02:17:46 +08:00
feat(admin-users): add plan entitlement revocation flow
This commit is contained in:
@@ -999,19 +999,54 @@ ORDER BY expires_at ASC, created_at ASC
|
||||
))
|
||||
}
|
||||
|
||||
async fn revoke_user_plan_entitlement(
|
||||
&self,
|
||||
user_id: &str,
|
||||
entitlement_id: &str,
|
||||
) -> Result<AdminBillingMutationOutcome<()>, DataLayerError> {
|
||||
let result = sqlx::query(
|
||||
r#"
|
||||
UPDATE user_plan_entitlements
|
||||
SET status = 'revoked',
|
||||
expires_at = LEAST(expires_at, NOW()),
|
||||
updated_at = NOW()
|
||||
WHERE id = $1
|
||||
AND user_id = $2
|
||||
AND status = 'active'
|
||||
AND expires_at > NOW()
|
||||
"#,
|
||||
)
|
||||
.bind(entitlement_id)
|
||||
.bind(user_id)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_postgres_err()?;
|
||||
if result.rows_affected() == 0 {
|
||||
Ok(AdminBillingMutationOutcome::NotFound)
|
||||
} else {
|
||||
Ok(AdminBillingMutationOutcome::Applied(()))
|
||||
}
|
||||
}
|
||||
|
||||
async fn find_user_daily_quota_availability(
|
||||
&self,
|
||||
user_id: &str,
|
||||
) -> Result<Option<UserDailyQuotaAvailabilityRecord>, DataLayerError> {
|
||||
let rows = sqlx::query(
|
||||
r#"
|
||||
SELECT id, entitlements_snapshot
|
||||
SELECT
|
||||
user_plan_entitlements.id,
|
||||
user_plan_entitlements.entitlements_snapshot,
|
||||
billing_plans.entitlements_json AS plan_entitlements_json
|
||||
FROM user_plan_entitlements
|
||||
WHERE user_id = $1
|
||||
AND status = 'active'
|
||||
AND starts_at <= NOW()
|
||||
AND expires_at > NOW()
|
||||
ORDER BY expires_at ASC, created_at ASC, id ASC
|
||||
JOIN billing_plans ON billing_plans.id = user_plan_entitlements.plan_id
|
||||
WHERE user_plan_entitlements.user_id = $1
|
||||
AND user_plan_entitlements.status = 'active'
|
||||
AND user_plan_entitlements.starts_at <= NOW()
|
||||
AND user_plan_entitlements.expires_at > NOW()
|
||||
ORDER BY user_plan_entitlements.expires_at ASC,
|
||||
user_plan_entitlements.created_at ASC,
|
||||
user_plan_entitlements.id ASC
|
||||
"#,
|
||||
)
|
||||
.bind(user_id)
|
||||
@@ -1024,9 +1059,12 @@ ORDER BY expires_at ASC, created_at ASC, id ASC
|
||||
let entitlement_id: String = row.try_get("id").map_postgres_err()?;
|
||||
let entitlements: serde_json::Value =
|
||||
row.try_get("entitlements_snapshot").map_postgres_err()?;
|
||||
let plan_entitlements: serde_json::Value =
|
||||
row.try_get("plan_entitlements_json").map_postgres_err()?;
|
||||
grants.extend(daily_quota_grants_from_entitlement(
|
||||
&entitlement_id,
|
||||
&entitlements,
|
||||
daily_quota_wallet_overage_policy(&plan_entitlements),
|
||||
now,
|
||||
)?);
|
||||
}
|
||||
@@ -1160,6 +1198,7 @@ fn daily_quota_usage_date(
|
||||
fn daily_quota_grants_from_entitlement(
|
||||
entitlement_id: &str,
|
||||
entitlements: &serde_json::Value,
|
||||
current_allow_wallet_overage: Option<bool>,
|
||||
now: chrono::DateTime<chrono::Utc>,
|
||||
) -> Result<Vec<DailyQuotaGrant>, DataLayerError> {
|
||||
let mut grants = Vec::new();
|
||||
@@ -1185,15 +1224,27 @@ fn daily_quota_grants_from_entitlement(
|
||||
.and_then(serde_json::Value::as_str),
|
||||
now,
|
||||
)?,
|
||||
allow_wallet_overage: item
|
||||
.get("allow_wallet_overage")
|
||||
.and_then(serde_json::Value::as_bool)
|
||||
.unwrap_or(false),
|
||||
allow_wallet_overage: current_allow_wallet_overage.unwrap_or_else(|| {
|
||||
item.get("allow_wallet_overage")
|
||||
.and_then(serde_json::Value::as_bool)
|
||||
.unwrap_or(false)
|
||||
}),
|
||||
});
|
||||
}
|
||||
Ok(grants)
|
||||
}
|
||||
|
||||
fn daily_quota_wallet_overage_policy(entitlements: &serde_json::Value) -> Option<bool> {
|
||||
entitlements.as_array()?.iter().find_map(|item| {
|
||||
(item.get("type").and_then(serde_json::Value::as_str) == Some("daily_quota"))
|
||||
.then(|| {
|
||||
item.get("allow_wallet_overage")
|
||||
.and_then(serde_json::Value::as_bool)
|
||||
})
|
||||
.flatten()
|
||||
})
|
||||
}
|
||||
|
||||
fn map_payment_gateway_config_row(
|
||||
row: &sqlx::postgres::PgRow,
|
||||
) -> Result<PaymentGatewayConfigRecord, DataLayerError> {
|
||||
|
||||
Reference in New Issue
Block a user