robson-core 0.1.0

Rust async agent orchestrator for automated development workflows
Documentation
use sea_orm_migration::{prelude::*, schema::*};

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        // --- conversations table ---
        manager
            .create_table(
                Table::create()
                    .table(Conversations::Table)
                    .if_not_exists()
                    .col(pk_auto(Conversations::Id))
                    .col(string(Conversations::ChannelId))
                    .col(string(Conversations::ThreadTs))
                    .col(string(Conversations::UserId))
                    .col(
                        string(Conversations::Role)
                            .check(Expr::cust("role IN ('user', 'assistant', 'system')")),
                    )
                    .col(string(Conversations::Content))
                    .col(string(Conversations::CreatedAt))
                    .to_owned(),
            )
            .await?;

        manager
            .create_index(
                Index::create()
                    .name("idx_conversations_channel_thread")
                    .table(Conversations::Table)
                    .col(Conversations::ChannelId)
                    .col(Conversations::ThreadTs)
                    .to_owned(),
            )
            .await?;

        // --- allowed_channels table ---
        manager
            .create_table(
                Table::create()
                    .table(AllowedChannels::Table)
                    .if_not_exists()
                    .col(pk_auto(AllowedChannels::Id))
                    .col(string_uniq(AllowedChannels::ChannelId))
                    .col(string(AllowedChannels::ChannelName))
                    .col(string(AllowedChannels::CreatedAt))
                    .to_owned(),
            )
            .await?;

        // --- rate_limits table ---
        manager
            .create_table(
                Table::create()
                    .table(RateLimits::Table)
                    .if_not_exists()
                    .col(pk_auto(RateLimits::Id))
                    .col(
                        string(RateLimits::ScopeType)
                            .check(Expr::cust("scope_type IN ('user', 'channel')")),
                    )
                    .col(string(RateLimits::ScopeId))
                    .col(string(RateLimits::WindowStart))
                    .col(integer(RateLimits::RequestCount).default(1))
                    .to_owned(),
            )
            .await?;

        manager
            .create_index(
                Index::create()
                    .name("idx_rate_limits_scope_unique")
                    .table(RateLimits::Table)
                    .col(RateLimits::ScopeType)
                    .col(RateLimits::ScopeId)
                    .unique()
                    .to_owned(),
            )
            .await?;

        Ok(())
    }

    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        manager
            .drop_table(Table::drop().table(RateLimits::Table).to_owned())
            .await?;
        manager
            .drop_table(Table::drop().table(AllowedChannels::Table).to_owned())
            .await?;
        manager
            .drop_table(Table::drop().table(Conversations::Table).to_owned())
            .await?;
        Ok(())
    }
}

#[derive(DeriveIden)]
enum Conversations {
    Table,
    Id,
    ChannelId,
    ThreadTs,
    UserId,
    Role,
    Content,
    CreatedAt,
}

#[derive(DeriveIden)]
enum AllowedChannels {
    Table,
    Id,
    ChannelId,
    ChannelName,
    CreatedAt,
}

#[derive(DeriveIden)]
enum RateLimits {
    Table,
    Id,
    ScopeType,
    ScopeId,
    WindowStart,
    RequestCount,
}