TG almost works

This commit is contained in:
AB from home.homenet
2025-10-19 04:13:36 +03:00
parent 42c8016d9c
commit d972f10f83
31 changed files with 3302 additions and 427 deletions

View File

@@ -0,0 +1,193 @@
use sea_orm_migration::prelude::*;
#[derive(DeriveMigrationName)]
pub struct Migration;
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
// Create user_requests table
manager
.create_table(
Table::create()
.table(UserRequests::Table)
.if_not_exists()
.col(
ColumnDef::new(UserRequests::Id)
.uuid()
.not_null()
.primary_key()
.default(Expr::cust("gen_random_uuid()")),
)
.col(
ColumnDef::new(UserRequests::UserId)
.uuid()
.null(), // Can be null if user doesn't exist yet
)
.col(
ColumnDef::new(UserRequests::TelegramId)
.big_integer()
.not_null()
.unique_key(),
)
.col(
ColumnDef::new(UserRequests::TelegramUsername)
.string()
.null(),
)
.col(
ColumnDef::new(UserRequests::TelegramFirstName)
.string()
.null(),
)
.col(
ColumnDef::new(UserRequests::TelegramLastName)
.string()
.null(),
)
.col(
ColumnDef::new(UserRequests::Status)
.string()
.not_null()
.default("pending"), // pending, approved, declined
)
.col(
ColumnDef::new(UserRequests::RequestMessage)
.text()
.null(),
)
.col(
ColumnDef::new(UserRequests::ResponseMessage)
.text()
.null(),
)
.col(
ColumnDef::new(UserRequests::ProcessedByUserId)
.uuid()
.null(),
)
.col(
ColumnDef::new(UserRequests::ProcessedAt)
.timestamp_with_time_zone()
.null(),
)
.col(
ColumnDef::new(UserRequests::CreatedAt)
.timestamp_with_time_zone()
.not_null()
.default(Expr::current_timestamp()),
)
.col(
ColumnDef::new(UserRequests::UpdatedAt)
.timestamp_with_time_zone()
.not_null()
.default(Expr::current_timestamp()),
)
.foreign_key(
ForeignKey::create()
.name("fk_user_requests_user")
.from(UserRequests::Table, UserRequests::UserId)
.to(Users::Table, Users::Id)
.on_delete(ForeignKeyAction::SetNull)
.on_update(ForeignKeyAction::Cascade),
)
.foreign_key(
ForeignKey::create()
.name("fk_user_requests_processed_by")
.from(UserRequests::Table, UserRequests::ProcessedByUserId)
.to(Users::Table, Users::Id)
.on_delete(ForeignKeyAction::SetNull)
.on_update(ForeignKeyAction::Cascade),
)
.to_owned(),
)
.await?;
// Create index on telegram_id for faster lookups
manager
.create_index(
Index::create()
.name("idx_user_requests_telegram_id")
.table(UserRequests::Table)
.col(UserRequests::TelegramId)
.to_owned(),
)
.await?;
// Create index on status for filtering
manager
.create_index(
Index::create()
.name("idx_user_requests_status")
.table(UserRequests::Table)
.col(UserRequests::Status)
.to_owned(),
)
.await?;
// Create trigger to update updated_at timestamp
manager
.get_connection()
.execute_unprepared(
r#"
CREATE OR REPLACE FUNCTION update_user_requests_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER user_requests_updated_at
BEFORE UPDATE ON user_requests
FOR EACH ROW
EXECUTE FUNCTION update_user_requests_updated_at();
"#,
)
.await?;
Ok(())
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
// Drop trigger and function
manager
.get_connection()
.execute_unprepared(
r#"
DROP TRIGGER IF EXISTS user_requests_updated_at ON user_requests;
DROP FUNCTION IF EXISTS update_user_requests_updated_at();
"#,
)
.await?;
// Drop table
manager
.drop_table(Table::drop().table(UserRequests::Table).to_owned())
.await
}
}
#[derive(Iden)]
enum UserRequests {
Table,
Id,
UserId,
TelegramId,
TelegramUsername,
TelegramFirstName,
TelegramLastName,
Status,
RequestMessage,
ResponseMessage,
ProcessedByUserId,
ProcessedAt,
CreatedAt,
UpdatedAt,
}
#[derive(Iden)]
enum Users {
Table,
Id,
}

View File

@@ -0,0 +1,38 @@
use sea_orm_migration::prelude::*;
#[derive(DeriveMigrationName)]
pub struct Migration;
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
// Drop the unique constraint on telegram_id
// This allows users to have multiple requests (e.g., if one was declined)
manager
.get_connection()
.execute_unprepared(
r#"
ALTER TABLE user_requests
DROP CONSTRAINT IF EXISTS user_requests_telegram_id_key;
"#,
)
.await?;
Ok(())
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
// Re-add the unique constraint
manager
.get_connection()
.execute_unprepared(
r#"
ALTER TABLE user_requests
ADD CONSTRAINT user_requests_telegram_id_key UNIQUE (telegram_id);
"#,
)
.await?;
Ok(())
}
}

View File

@@ -0,0 +1,41 @@
use sea_orm_migration::prelude::*;
#[derive(DeriveMigrationName)]
pub struct Migration;
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
// Add language column to user_requests table
manager
.alter_table(
Table::alter()
.table(UserRequests::Table)
.add_column(
ColumnDef::new(UserRequests::Language)
.string()
.default("en") // Default to English
)
.to_owned(),
)
.await
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
// Remove language column from user_requests table
manager
.alter_table(
Table::alter()
.table(UserRequests::Table)
.drop_column(UserRequests::Language)
.to_owned(),
)
.await
}
}
#[derive(Iden)]
enum UserRequests {
Table,
Language,
}

View File

@@ -12,6 +12,9 @@ mod m20250922_000001_add_grpc_hostname_to_servers;
mod m20250923_000001_create_dns_providers_table;
mod m20250929_000001_create_telegram_config_table;
mod m20250929_000002_add_telegram_admin_to_users;
mod m20251018_000001_create_user_requests_table;
mod m20251018_000002_remove_unique_telegram_id;
mod m20251018_000003_add_language_to_user_requests;
pub struct Migrator;
@@ -31,6 +34,9 @@ impl MigratorTrait for Migrator {
Box::new(m20250923_000001_create_dns_providers_table::Migration),
Box::new(m20250929_000001_create_telegram_config_table::Migration),
Box::new(m20250929_000002_add_telegram_admin_to_users::Migration),
Box::new(m20251018_000001_create_user_requests_table::Migration),
Box::new(m20251018_000002_remove_unique_telegram_id::Migration),
Box::new(m20251018_000003_add_language_to_user_requests::Migration),
]
}
}