refactor: split backend domains and add API behavior coverage

This commit is contained in:
3252a8
2026-05-13 18:38:10 +03:00
parent a96007d48a
commit 7401649841
103 changed files with 10558 additions and 9832 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ async def create_campaign(
await session.flush()
await session.refresh(campaign)
logging.info(
f"AdCampaign created id={campaign.ad_campaign_id}, source={source}, start={start_param}, cost={cost}"
f"AdCampaign created id={campaign.ad_campaign_id}, source={source}, start={start_param}, cost={cost}" # noqa: E501
)
return campaign
+2 -2
View File
@@ -75,7 +75,7 @@ async def create_message_log_no_commit(session: AsyncSession, log_data: dict) ->
target_user = await get_user_by_id(session, log_data["target_user_id"])
if not target_user:
logging.warning(
f"Target user {log_data['target_user_id']} not found for message log. Setting to NULL."
f"Target user {log_data['target_user_id']} not found for message log. Setting to NULL." # noqa: E501
)
log_data["target_user_id"] = None
@@ -83,6 +83,6 @@ async def create_message_log_no_commit(session: AsyncSession, log_data: dict) ->
session.add(new_log)
logging.debug(
f"Message log added to session: user {log_data.get('user_id')}, event {log_data.get('event_type')}"
f"Message log added to session: user {log_data.get('user_id')}, event {log_data.get('event_type')}" # noqa: E501
)
return new_log
+1 -1
View File
@@ -165,7 +165,7 @@ async def update_provider_payment_and_status(
await session.flush()
await session.refresh(payment)
logging.info(
f"Payment record {payment.payment_id} updated with provider id {provider_payment_id} and status {new_status}."
f"Payment record {payment.payment_id} updated with provider id {provider_payment_id} and status {new_status}." # noqa: E501
)
else:
logging.warning(f"Payment record with DB ID {payment_db_id} not found for provider update.")
+2 -2
View File
@@ -170,7 +170,7 @@ async def record_promo_activation(
existing_activation = await get_user_activation_for_promo(session, promo_code_id, user_id)
if existing_activation:
logging.info(
f"User {user_id} has already activated promo code {promo_code_id}. Activation ID: {existing_activation.activation_id}"
f"User {user_id} has already activated promo code {promo_code_id}. Activation ID: {existing_activation.activation_id}" # noqa: E501
)
return existing_activation
@@ -203,6 +203,6 @@ async def record_promo_activation(
await session.flush()
await session.refresh(new_activation)
logging.info(
f"Promo code {promo_code_id} activated by user {user_id}. Activation ID: {new_activation.activation_id}"
f"Promo code {promo_code_id} activated by user {user_id}. Activation ID: {new_activation.activation_id}" # noqa: E501
)
return new_activation
+4 -4
View File
@@ -99,7 +99,7 @@ async def upsert_subscription(session: AsyncSession, sub_payload: Dict[str, Any]
if existing_sub:
logging.info(
f"Updating existing subscription {existing_sub.subscription_id} by panel_sub_uuid {panel_sub_uuid}"
f"Updating existing subscription {existing_sub.subscription_id} by panel_sub_uuid {panel_sub_uuid}" # noqa: E501
)
for key, value in sub_payload.items():
if hasattr(existing_sub, key):
@@ -120,7 +120,7 @@ async def upsert_subscription(session: AsyncSession, sub_payload: Dict[str, Any]
user = await get_user_by_id(session, sub_payload["user_id"])
if not user:
raise ValueError(
f"User {sub_payload['user_id']} not found for new subscription with panel_uuid {panel_sub_uuid}."
f"User {sub_payload['user_id']} not found for new subscription with panel_uuid {panel_sub_uuid}." # noqa: E501
)
new_sub = Subscription(**sub_payload)
@@ -147,7 +147,7 @@ async def deactivate_other_active_subscriptions(
result = await session.execute(stmt)
if result.rowcount > 0:
logging.info(
f"Deactivated {result.rowcount} other active subscriptions for panel_user_uuid {panel_user_uuid}."
f"Deactivated {result.rowcount} other active subscriptions for panel_user_uuid {panel_user_uuid}." # noqa: E501
)
@@ -160,7 +160,7 @@ async def deactivate_all_user_subscriptions(session: AsyncSession, user_id: int)
result = await session.execute(stmt)
if result.rowcount > 0:
logging.info(
f"Deactivated {result.rowcount} subscriptions for user {user_id} due to missing panel user."
f"Deactivated {result.rowcount} subscriptions for user {user_id} due to missing panel user." # noqa: E501
)
return result.rowcount
+1 -1
View File
@@ -169,7 +169,7 @@ async def delete_user_payment_method_by_provider_id(
"""Delete a saved payment method by its provider payment_method.id for a specific user.
Useful when callbacks pass the provider id (e.g., YooKassa pm_...) instead of our internal method_id.
"""
""" # noqa: E501
stmt = select(UserPaymentMethod).where(
UserPaymentMethod.user_id == user_id,
UserPaymentMethod.provider_payment_method_id == provider_payment_method_id,
+2 -2
View File
@@ -65,7 +65,7 @@ async def init_db(settings: Settings, session_factory: sessionmaker):
logging.warning("init_db: async_engine was None, re-initializing via init_db_connection.")
raise RuntimeError(
"async_engine is not initialized. Call init_db_connection and get session_factory first."
"async_engine is not initialized. Call init_db_connection and get session_factory first." # noqa: E501
)
async with async_engine.begin() as conn:
@@ -136,7 +136,7 @@ async def init_db(settings: Settings, session_factory: sessionmaker):
)
WHERE s.is_active = TRUE
AND s.tariff_key IS NULL
"""
""" # noqa: E501
),
{
"tariff_key": default_tariff.key,
+25 -25
View File
@@ -244,7 +244,7 @@ def _migration_0008_add_email_verification_code_status(connection: Connection) -
if "status" not in columns:
connection.execute(
text(
"ALTER TABLE email_verification_codes ADD COLUMN status VARCHAR NOT NULL DEFAULT 'active'"
"ALTER TABLE email_verification_codes ADD COLUMN status VARCHAR NOT NULL DEFAULT 'active'" # noqa: E501
)
)
else:
@@ -331,11 +331,11 @@ def _migration_0012_add_tariffs_schema(connection: Connection) -> None:
)
if "premium_topup_balance_bytes" not in sub_columns:
sub_statements.append(
"ALTER TABLE subscriptions ADD COLUMN premium_topup_balance_bytes BIGINT NOT NULL DEFAULT 0"
"ALTER TABLE subscriptions ADD COLUMN premium_topup_balance_bytes BIGINT NOT NULL DEFAULT 0" # noqa: E501
)
if "premium_topup_used_bytes" not in sub_columns:
sub_statements.append(
"ALTER TABLE subscriptions ADD COLUMN premium_topup_used_bytes BIGINT NOT NULL DEFAULT 0"
"ALTER TABLE subscriptions ADD COLUMN premium_topup_used_bytes BIGINT NOT NULL DEFAULT 0" # noqa: E501
)
if "premium_used_bytes" not in sub_columns:
sub_statements.append(
@@ -407,7 +407,7 @@ def _migration_0012_add_tariffs_schema(connection: Connection) -> None:
sent_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT uq_traffic_warning_period_level UNIQUE (subscription_id, period_start_at, level)
)
"""
""" # noqa: E501
)
)
connection.execute(
@@ -446,16 +446,16 @@ def _migration_0012_add_tariffs_schema(connection: Connection) -> None:
for stmt in [
"CREATE INDEX IF NOT EXISTS ix_subscriptions_tariff_key ON subscriptions (tariff_key)",
"CREATE INDEX IF NOT EXISTS ix_subscriptions_is_throttled ON subscriptions (is_throttled)",
"CREATE INDEX IF NOT EXISTS ix_subscriptions_premium_is_limited ON subscriptions (premium_is_limited)",
"CREATE INDEX IF NOT EXISTS ix_subscriptions_premium_is_limited ON subscriptions (premium_is_limited)", # noqa: E501
"CREATE INDEX IF NOT EXISTS ix_payments_sale_mode ON payments (sale_mode)",
"CREATE INDEX IF NOT EXISTS ix_payments_tariff_key ON payments (tariff_key)",
"CREATE INDEX IF NOT EXISTS ix_traffic_topups_subscription_id ON traffic_topups (subscription_id)",
"CREATE INDEX IF NOT EXISTS ix_traffic_topups_subscription_id ON traffic_topups (subscription_id)", # noqa: E501
"CREATE INDEX IF NOT EXISTS ix_traffic_topups_payment_id ON traffic_topups (payment_id)",
"CREATE INDEX IF NOT EXISTS ix_traffic_topups_kind ON traffic_topups (kind)",
"CREATE INDEX IF NOT EXISTS ix_traffic_warnings_subscription_id ON traffic_warnings (subscription_id)",
"CREATE INDEX IF NOT EXISTS ix_tariff_changes_subscription_id ON tariff_changes (subscription_id)",
"CREATE INDEX IF NOT EXISTS ix_hwid_device_purchases_subscription_id ON hwid_device_purchases (subscription_id)",
"CREATE INDEX IF NOT EXISTS ix_hwid_device_purchases_payment_id ON hwid_device_purchases (payment_id)",
"CREATE INDEX IF NOT EXISTS ix_traffic_warnings_subscription_id ON traffic_warnings (subscription_id)", # noqa: E501
"CREATE INDEX IF NOT EXISTS ix_tariff_changes_subscription_id ON tariff_changes (subscription_id)", # noqa: E501
"CREATE INDEX IF NOT EXISTS ix_hwid_device_purchases_subscription_id ON hwid_device_purchases (subscription_id)", # noqa: E501
"CREATE INDEX IF NOT EXISTS ix_hwid_device_purchases_payment_id ON hwid_device_purchases (payment_id)", # noqa: E501
]:
connection.execute(text(stmt))
@@ -497,11 +497,11 @@ def _migration_0014_add_premium_squad_traffic_fields(connection: Connection) ->
)
if "premium_topup_balance_bytes" not in sub_columns:
statements.append(
"ALTER TABLE subscriptions ADD COLUMN premium_topup_balance_bytes BIGINT NOT NULL DEFAULT 0"
"ALTER TABLE subscriptions ADD COLUMN premium_topup_balance_bytes BIGINT NOT NULL DEFAULT 0" # noqa: E501
)
if "premium_topup_used_bytes" not in sub_columns:
statements.append(
"ALTER TABLE subscriptions ADD COLUMN premium_topup_used_bytes BIGINT NOT NULL DEFAULT 0"
"ALTER TABLE subscriptions ADD COLUMN premium_topup_used_bytes BIGINT NOT NULL DEFAULT 0" # noqa: E501
)
if "premium_used_bytes" not in sub_columns:
statements.append(
@@ -519,7 +519,7 @@ def _migration_0014_add_premium_squad_traffic_fields(connection: Connection) ->
connection.execute(text(stmt))
connection.execute(
text(
"CREATE INDEX IF NOT EXISTS ix_subscriptions_premium_is_limited ON subscriptions (premium_is_limited)"
"CREATE INDEX IF NOT EXISTS ix_subscriptions_premium_is_limited ON subscriptions (premium_is_limited)" # noqa: E501
)
)
@@ -530,7 +530,7 @@ def _migration_0015_add_premium_topup_carryover_fields(connection: Connection) -
statements: List[str] = []
if "premium_topup_used_bytes" not in sub_columns:
statements.append(
"ALTER TABLE subscriptions ADD COLUMN premium_topup_used_bytes BIGINT NOT NULL DEFAULT 0"
"ALTER TABLE subscriptions ADD COLUMN premium_topup_used_bytes BIGINT NOT NULL DEFAULT 0" # noqa: E501
)
if "premium_period_start_at" not in sub_columns:
statements.append(
@@ -559,7 +559,7 @@ def _migration_0016_add_message_logs_admin_fields(connection: Connection) -> Non
connection.execute(
text(
"CREATE INDEX IF NOT EXISTS ix_message_logs_target_user_id ON message_logs (target_user_id)"
"CREATE INDEX IF NOT EXISTS ix_message_logs_target_user_id ON message_logs (target_user_id)" # noqa: E501
)
)
@@ -571,7 +571,7 @@ def _migration_0018_add_premium_admin_overrides(connection: Connection) -> None:
statements: List[str] = []
if "premium_unlimited_override" not in sub_columns:
statements.append(
"ALTER TABLE subscriptions ADD COLUMN premium_unlimited_override BOOLEAN NOT NULL DEFAULT FALSE"
"ALTER TABLE subscriptions ADD COLUMN premium_unlimited_override BOOLEAN NOT NULL DEFAULT FALSE" # noqa: E501
)
if "premium_bonus_bytes" not in sub_columns:
statements.append(
@@ -593,7 +593,7 @@ def _migration_0021_add_regular_unlimited_override(connection: Connection) -> No
if "regular_unlimited_override" not in sub_columns:
connection.execute(
text(
"ALTER TABLE subscriptions ADD COLUMN regular_unlimited_override BOOLEAN NOT NULL DEFAULT FALSE"
"ALTER TABLE subscriptions ADD COLUMN regular_unlimited_override BOOLEAN NOT NULL DEFAULT FALSE" # noqa: E501
)
)
connection.execute(
@@ -670,15 +670,15 @@ def _migration_0017_reconcile_legacy_admin_api_schema(connection: Connection) ->
)
if "premium_baseline_bytes" not in sub_columns:
sub_statements.append(
"ALTER TABLE subscriptions ADD COLUMN premium_baseline_bytes BIGINT NOT NULL DEFAULT 0"
"ALTER TABLE subscriptions ADD COLUMN premium_baseline_bytes BIGINT NOT NULL DEFAULT 0" # noqa: E501
)
if "premium_topup_balance_bytes" not in sub_columns:
sub_statements.append(
"ALTER TABLE subscriptions ADD COLUMN premium_topup_balance_bytes BIGINT NOT NULL DEFAULT 0"
"ALTER TABLE subscriptions ADD COLUMN premium_topup_balance_bytes BIGINT NOT NULL DEFAULT 0" # noqa: E501
)
if "premium_topup_used_bytes" not in sub_columns:
sub_statements.append(
"ALTER TABLE subscriptions ADD COLUMN premium_topup_used_bytes BIGINT NOT NULL DEFAULT 0"
"ALTER TABLE subscriptions ADD COLUMN premium_topup_used_bytes BIGINT NOT NULL DEFAULT 0" # noqa: E501
)
if "premium_used_bytes" not in sub_columns:
sub_statements.append(
@@ -686,7 +686,7 @@ def _migration_0017_reconcile_legacy_admin_api_schema(connection: Connection) ->
)
if "premium_is_limited" not in sub_columns:
sub_statements.append(
"ALTER TABLE subscriptions ADD COLUMN premium_is_limited BOOLEAN NOT NULL DEFAULT FALSE"
"ALTER TABLE subscriptions ADD COLUMN premium_is_limited BOOLEAN NOT NULL DEFAULT FALSE" # noqa: E501
)
if "is_throttled" not in sub_columns:
sub_statements.append(
@@ -718,13 +718,13 @@ def _migration_0017_reconcile_legacy_admin_api_schema(connection: Connection) ->
)
if "target_user_id" not in msg_columns:
msg_statements.append(
"ALTER TABLE message_logs ADD COLUMN target_user_id BIGINT REFERENCES users(user_id)"
"ALTER TABLE message_logs ADD COLUMN target_user_id BIGINT REFERENCES users(user_id)" # noqa: E501
)
for stmt in msg_statements:
connection.execute(text(stmt))
connection.execute(
text(
"CREATE INDEX IF NOT EXISTS ix_message_logs_target_user_id ON message_logs (target_user_id)"
"CREATE INDEX IF NOT EXISTS ix_message_logs_target_user_id ON message_logs (target_user_id)" # noqa: E501
)
)
@@ -828,12 +828,12 @@ MIGRATIONS: List[Migration] = [
),
Migration(
id="0018_add_premium_admin_overrides",
description="Per-subscription admin overrides for premium traffic (unlimited toggle + bonus bytes)",
description="Per-subscription admin overrides for premium traffic (unlimited toggle + bonus bytes)", # noqa: E501
upgrade=_migration_0018_add_premium_admin_overrides,
),
Migration(
id="0019_clear_subscription_months_for_non_subscription_payments",
description="Backfill: null out subscription_duration_months for legacy traffic/topup/hwid payments",
description="Backfill: null out subscription_duration_months for legacy traffic/topup/hwid payments", # noqa: E501
upgrade=_migration_0019_clear_subscription_months_for_non_subscription_payments,
),
Migration(
+2 -2
View File
@@ -136,7 +136,7 @@ class Subscription(Base):
user = relationship("User", back_populates="subscriptions")
def __repr__(self):
return f"<Subscription(id={self.subscription_id}, user_id={self.user_id}, panel_uuid='{self.panel_user_uuid}', ends='{self.end_date}')>"
return f"<Subscription(id={self.subscription_id}, user_id={self.user_id}, panel_uuid='{self.panel_user_uuid}', ends='{self.end_date}')>" # noqa: E501
class EmailVerificationCode(Base):
@@ -402,7 +402,7 @@ class AdCampaign(Base):
)
def __repr__(self):
return f"<AdCampaign(id={self.ad_campaign_id}, source='{self.source}', start_param='{self.start_param}', cost={self.cost})>"
return f"<AdCampaign(id={self.ad_campaign_id}, source='{self.source}', start_param='{self.start_param}', cost={self.cost})>" # noqa: E501
class AdAttribution(Base):