feat: add database migrations for domains, resources, service_tokens, links

This commit is contained in:
Till Wegmueller 2026-04-03 19:22:57 +02:00
parent 8123752c9c
commit c993f4d703
No known key found for this signature in database
6 changed files with 268 additions and 11 deletions

View file

@ -1,6 +1,8 @@
[package]
name = "migration"
version = "0.1.0"
edition = "2024"
edition = "2021"
[dependencies]
sea-orm-migration = "1"
async-trait = "0.1"

View file

@ -1,14 +1,20 @@
pub fn add(left: u64, right: u64) -> u64 {
left + right
}
pub use sea_orm_migration::prelude::*;
#[cfg(test)]
mod tests {
use super::*;
mod m20260403_000001_create_domains;
mod m20260403_000002_create_resources;
mod m20260403_000003_create_service_tokens;
mod m20260403_000004_create_links;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
pub struct Migrator;
#[async_trait::async_trait]
impl MigratorTrait for Migrator {
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
vec![
Box::new(m20260403_000001_create_domains::Migration),
Box::new(m20260403_000002_create_resources::Migration),
Box::new(m20260403_000003_create_service_tokens::Migration),
Box::new(m20260403_000004_create_links::Migration),
]
}
}

View file

@ -0,0 +1,47 @@
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> {
manager
.create_table(
Table::create()
.table(Domains::Table)
.if_not_exists()
.col(ColumnDef::new(Domains::Id).string().not_null().primary_key())
.col(ColumnDef::new(Domains::Domain).string().not_null().unique_key())
.col(ColumnDef::new(Domains::OwnerTokenHash).string().not_null())
.col(ColumnDef::new(Domains::RegistrationSecret).string().not_null())
.col(ColumnDef::new(Domains::ChallengeType).string().not_null())
.col(ColumnDef::new(Domains::ChallengeToken).string().null())
.col(ColumnDef::new(Domains::Verified).boolean().not_null().default(false))
.col(ColumnDef::new(Domains::CreatedAt).date_time().not_null())
.col(ColumnDef::new(Domains::VerifiedAt).date_time().null())
.to_owned(),
)
.await
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(Domains::Table).to_owned())
.await
}
}
#[derive(DeriveIden)]
pub enum Domains {
Table,
Id,
Domain,
OwnerTokenHash,
RegistrationSecret,
ChallengeType,
ChallengeToken,
Verified,
CreatedAt,
VerifiedAt,
}

View file

@ -0,0 +1,52 @@
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> {
manager
.create_table(
Table::create()
.table(Resources::Table)
.if_not_exists()
.col(ColumnDef::new(Resources::Id).string().not_null().primary_key())
.col(ColumnDef::new(Resources::DomainId).string().not_null())
.col(ColumnDef::new(Resources::ResourceUri).string().not_null().unique_key())
.col(ColumnDef::new(Resources::Aliases).string().null())
.col(ColumnDef::new(Resources::Properties).string().null())
.col(ColumnDef::new(Resources::CreatedAt).date_time().not_null())
.col(ColumnDef::new(Resources::UpdatedAt).date_time().not_null())
.foreign_key(
ForeignKey::create()
.from(Resources::Table, Resources::DomainId)
.to(
super::m20260403_000001_create_domains::Domains::Table,
super::m20260403_000001_create_domains::Domains::Id,
)
.on_delete(ForeignKeyAction::Cascade),
)
.to_owned(),
)
.await
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(Resources::Table).to_owned())
.await
}
}
#[derive(DeriveIden)]
pub enum Resources {
Table,
Id,
DomainId,
ResourceUri,
Aliases,
Properties,
CreatedAt,
UpdatedAt,
}

View file

@ -0,0 +1,54 @@
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> {
manager
.create_table(
Table::create()
.table(ServiceTokens::Table)
.if_not_exists()
.col(ColumnDef::new(ServiceTokens::Id).string().not_null().primary_key())
.col(ColumnDef::new(ServiceTokens::DomainId).string().not_null())
.col(ColumnDef::new(ServiceTokens::Name).string().not_null())
.col(ColumnDef::new(ServiceTokens::TokenHash).string().not_null())
.col(ColumnDef::new(ServiceTokens::AllowedRels).string().not_null())
.col(ColumnDef::new(ServiceTokens::ResourcePattern).string().not_null())
.col(ColumnDef::new(ServiceTokens::CreatedAt).date_time().not_null())
.col(ColumnDef::new(ServiceTokens::RevokedAt).date_time().null())
.foreign_key(
ForeignKey::create()
.from(ServiceTokens::Table, ServiceTokens::DomainId)
.to(
super::m20260403_000001_create_domains::Domains::Table,
super::m20260403_000001_create_domains::Domains::Id,
)
.on_delete(ForeignKeyAction::Cascade),
)
.to_owned(),
)
.await
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(ServiceTokens::Table).to_owned())
.await
}
}
#[derive(DeriveIden)]
pub enum ServiceTokens {
Table,
Id,
DomainId,
Name,
TokenHash,
AllowedRels,
ResourcePattern,
CreatedAt,
RevokedAt,
}

View file

@ -0,0 +1,96 @@
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> {
manager
.create_table(
Table::create()
.table(Links::Table)
.if_not_exists()
.col(ColumnDef::new(Links::Id).string().not_null().primary_key())
.col(ColumnDef::new(Links::ResourceId).string().not_null())
.col(ColumnDef::new(Links::ServiceTokenId).string().not_null())
.col(ColumnDef::new(Links::DomainId).string().not_null())
.col(ColumnDef::new(Links::Rel).string().not_null())
.col(ColumnDef::new(Links::Href).string().null())
.col(ColumnDef::new(Links::Type).string().null())
.col(ColumnDef::new(Links::Titles).string().null())
.col(ColumnDef::new(Links::Properties).string().null())
.col(ColumnDef::new(Links::Template).string().null())
.col(ColumnDef::new(Links::TtlSeconds).integer().null())
.col(ColumnDef::new(Links::CreatedAt).date_time().not_null())
.col(ColumnDef::new(Links::ExpiresAt).date_time().null())
.foreign_key(
ForeignKey::create()
.from(Links::Table, Links::ResourceId)
.to(
super::m20260403_000002_create_resources::Resources::Table,
super::m20260403_000002_create_resources::Resources::Id,
)
.on_delete(ForeignKeyAction::Cascade),
)
.foreign_key(
ForeignKey::create()
.from(Links::Table, Links::ServiceTokenId)
.to(
super::m20260403_000003_create_service_tokens::ServiceTokens::Table,
super::m20260403_000003_create_service_tokens::ServiceTokens::Id,
)
.on_delete(ForeignKeyAction::Cascade),
)
.foreign_key(
ForeignKey::create()
.from(Links::Table, Links::DomainId)
.to(
super::m20260403_000001_create_domains::Domains::Table,
super::m20260403_000001_create_domains::Domains::Id,
)
.on_delete(ForeignKeyAction::Cascade),
)
.to_owned(),
)
.await?;
// Unique constraint for upsert behavior
manager
.create_index(
Index::create()
.name("idx_links_resource_rel_href")
.table(Links::Table)
.col(Links::ResourceId)
.col(Links::Rel)
.col(Links::Href)
.unique()
.to_owned(),
)
.await
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(Links::Table).to_owned())
.await
}
}
#[derive(DeriveIden)]
pub enum Links {
Table,
Id,
ResourceId,
ServiceTokenId,
DomainId,
Rel,
Href,
Type,
Titles,
Properties,
Template,
TtlSeconds,
CreatedAt,
ExpiresAt,
}