Реализованы задачи бэклога 1-5 (1я не до конца)

This commit is contained in:
mi
2026-07-21 12:50:46 +03:00
parent 3b71caf7b3
commit 0d7f7a819f
105 changed files with 7185 additions and 38 deletions
+1
View File
@@ -103,6 +103,7 @@ class UxSession(Common, Base):
platform: Mapped[str] = mapped_column(String(32))
app_version: Mapped[str] = mapped_column(String(64))
device_id_hash: Mapped[str | None] = mapped_column(String(64))
device_id: Mapped[str | None] = mapped_column(String(255))
started_at: Mapped[datetime] = mapped_column(DateTime(timezone=True))
+2 -1
View File
@@ -415,7 +415,7 @@ async def ready(request: Request, db: Session):
try:
await db.execute(text("SELECT 1"))
revision = await db.scalar(text("SELECT version_num FROM han_app.alembic_version LIMIT 1"))
if revision != "0003_consent_audit":
if revision != "0004_device_otp":
raise RuntimeError("unexpected database revision")
await load_settings(db)
components["postgres"] = "ok"
@@ -979,6 +979,7 @@ async def otp_settings(
return JSONResponse({
"max_send_attempts_per_24h": settings.integer("otp.phone.max_send_attempts_per_24h"),
"min_seconds_between_attempts": settings.integer("otp.phone.min_seconds_between_attempts"),
"max_verify_attempts": settings.integer("otp.phone.max_verify_attempts"),
"version": settings.version,
"cache_ttl_seconds": 60,
}, headers=headers)
+5 -6
View File
@@ -63,6 +63,7 @@ REQUIRED_SETTINGS = {
"auth.password.enabled",
"otp.phone.max_send_attempts_per_24h",
"otp.phone.min_seconds_between_attempts",
"otp.phone.max_verify_attempts",
"operator.call.phone",
"consent.personal_data.required",
"consent.personal_data.document_url",
@@ -182,9 +183,7 @@ def device_snapshot(device: Any) -> dict[str, str | None]:
return {
"platform": device.platform,
"app_version": device.app_version,
"device_id_hash": (
hashlib.sha256(device.device_id.encode()).hexdigest() if device.device_id else None
),
"device_id": device.device_id,
}
@@ -235,7 +234,7 @@ async def bootstrap(
user_id = (await session.execute(statement)).scalar_one()
await session.execute(
insert(ClientProfile)
.values(id=uuid.uuid4(), user_id=user_id)
.values(id=uuid.uuid4(), user_id=user_id, russian_phone=principal.phone_number)
.on_conflict_do_nothing(index_elements=[ClientProfile.user_id])
)
for consent_type in ("personal_data", "user_agreement", "marketing"):
@@ -300,7 +299,7 @@ async def record_consents(
device = {
"platform": ux_session.platform,
"app_version": ux_session.app_version,
"device_id_hash": ux_session.device_id_hash,
"device_id": ux_session.device_id,
}
now = datetime.now(UTC)
versions: dict[str, str] = {}
@@ -366,7 +365,7 @@ async def start_session(
start_reason=body.start_reason,
platform=body.device.platform,
app_version=body.device.app_version,
device_id_hash=device["device_id_hash"],
device_id=device["device_id"],
started_at=now,
)
)