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> {
        // --- tasks table ---
        manager
            .create_table(
                Table::create()
                    .table(Tasks::Table)
                    .if_not_exists()
                    .col(pk_auto(Tasks::Id))
                    .col(string_uniq(Tasks::JiraKey))
                    .col(string(Tasks::Summary))
                    .col(string_null(Tasks::Description))
                    .col(string_null(Tasks::Assignee))
                    .col(string(Tasks::Project))
                    .col(string(Tasks::Status).default("pending"))
                    .col(string_null(Tasks::BranchName))
                    .col(string_null(Tasks::PrUrl))
                    .col(string_null(Tasks::ErrorMessage))
                    .col(string(Tasks::FetchedAt))
                    .col(string_null(Tasks::ProcessedAt))
                    .col(string(Tasks::RepoUrl).default(""))
                    .to_owned(),
            )
            .await?;

        // --- repos table ---
        manager
            .create_table(
                Table::create()
                    .table(Repos::Table)
                    .if_not_exists()
                    .col(pk_auto(Repos::Id))
                    .col(string_uniq(Repos::Slug))
                    .col(string(Repos::Provider).check(Expr::cust("provider IN ('github', 'bitbucket')")))
                    .col(string(Repos::Workspace))
                    .col(string(Repos::TargetBranch).default("develop"))
                    .col(string_null(Repos::DeveloperFocus))
                    .col(string_null(Repos::CustomPrompt))
                    .col(string(Repos::Token).default(""))
                    .col(string(Repos::CreatedAt))
                    .to_owned(),
            )
            .await?;

        // --- task_repos table ---
        manager
            .create_table(
                Table::create()
                    .table(TaskRepos::Table)
                    .if_not_exists()
                    .col(pk_auto(TaskRepos::Id))
                    .col(integer(TaskRepos::TaskId))
                    .col(integer(TaskRepos::RepoId))
                    .col(string(TaskRepos::Status).default("pending").check(Expr::cust("status IN ('pending', 'in_progress', 'done', 'failed')")))

                    .col(string_null(TaskRepos::BranchName))
                    .col(string_null(TaskRepos::PrUrl))
                    .col(string_null(TaskRepos::ErrorMessage))
                    .col(string_null(TaskRepos::StartedAt))
                    .col(string_null(TaskRepos::CompletedAt))
                    .foreign_key(
                        ForeignKey::create()
                            .name("fk_task_repos_task")
                            .from(TaskRepos::Table, TaskRepos::TaskId)
                            .to(Tasks::Table, Tasks::Id)
                            .on_delete(ForeignKeyAction::Cascade),
                    )
                    .foreign_key(
                        ForeignKey::create()
                            .name("fk_task_repos_repo")
                            .from(TaskRepos::Table, TaskRepos::RepoId)
                            .to(Repos::Table, Repos::Id)
                            .on_delete(ForeignKeyAction::Cascade),
                    )
                    .to_owned(),
            )
            .await?;

        manager
            .create_index(
                Index::create()
                    .name("idx_task_repos_unique")
                    .table(TaskRepos::Table)
                    .col(TaskRepos::TaskId)
                    .col(TaskRepos::RepoId)
                    .unique()
                    .to_owned(),
            )
            .await?;

        Ok(())
    }

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

#[derive(DeriveIden)]
enum Tasks {
    Table,
    Id,
    JiraKey,
    Summary,
    Description,
    Assignee,
    Project,
    Status,
    BranchName,
    PrUrl,
    ErrorMessage,
    FetchedAt,
    ProcessedAt,
    RepoUrl,
}

#[derive(DeriveIden)]
enum Repos {
    Table,
    Id,
    Slug,
    Provider,
    Workspace,
    TargetBranch,
    DeveloperFocus,
    CustomPrompt,
    Token,
    CreatedAt,
}

#[derive(DeriveIden)]
enum TaskRepos {
    Table,
    Id,
    TaskId,
    RepoId,
    Status,
    BranchName,
    PrUrl,
    ErrorMessage,
    StartedAt,
    CompletedAt,
}