[package]
name = "dwctl"
version = "8.33.4"
edition = "2024"
description = "The Doubleword Control Layer - A self-hostable observability and analytics platform for LLM applications"
license = "MIT OR Apache-2.0"

[lib]
name = "dwctl"
path = "src/lib.rs"

[[bin]]
name = "dwctl"
path = "src/main.rs"

[features]
default = ["embedded-db"]
embedded-db = ["dep:postgresql_embedded"]

[dependencies]
axum = { version = "0.8", features = ["multipart"] }
fusillade = { version = "14.2.2" }
tokio = { version = "1.0", features = ["full"] }
tokio-stream = { version = "0.1", features = ["sync"] }
tokio-util = "0.7"
notify = "8.2.0"
sqlx = { version = "0.8", features = [
  "runtime-tokio-rustls",
  "postgres",
  "uuid",
  "chrono",
  "migrate",
  "rust_decimal",
] }
scopeguard = "1"
underway = "0.2"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
uuid = { version = "1.0", features = ["v4", "serde"] }
chrono = { version = "0.4", features = ["serde"] }
anyhow = "1.0"
arc-swap = "1.7"
log = "0.4"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
# OpenTelemetry
opentelemetry = "0.31.0"
opentelemetry_sdk = { version = "0.31", features = ["rt-tokio"] }
opentelemetry-otlp = { version = "0.31", default-features = false, features = [
  "http-proto",
  "reqwest-blocking-client",
  "reqwest-rustls",
] }
tracing-opentelemetry = "0.32.1"
tower = "0.5"
tower-http = { version = "0.6", features = ["cors", "fs", "trace"] }
async-trait = "0.1"
url = { version = "2.4", features = ["serde"] }
clap = { version = "4.4", features = ["derive", "env"] }
reqwest = { version = "0.13", default-features = false, features = [
  "json",
  "rustls-no-provider",
  "http2",
  "charset",
] }
humantime = "2.2.0"
humantime-serde = "1.1"
utoipa = { version = "5.0", features = [
  "axum_extras",
  "chrono",
  "uuid",
  "macros",
] }
utoipa-scalar = { version = "0.3", features = ["axum"] }
figment = { version = "0.10", features = ["yaml", "env", "test"] }
rand = "0.10"
# Authentication
jsonwebtoken = "9.0"
argon2 = "0.5"
base64 = "0.22"
bytes = "1.5"
onwards = "0.22.1"
thiserror = "2.0.14"
axum-prometheus = "0.10"
# Metrics facade and exporter (same versions as axum-prometheus uses)
metrics = "0.24"
metrics-exporter-prometheus = "0.18"
outlet = "0.8.0"
outlet-postgres = "0.5.1"
async-openai = { version = "0.33.0", default-features = false, features = [
  "chat-completion-types",
  "completion-types",
  "embedding-types",
  "response-types",
] }
brotli = "8.0"
lettre = { version = "0.11", features = [
  "smtp-transport",
  "file-transport",
  "tokio1-rustls-tls",
  "builder",
], default-features = false }
aes-gcm = "0.10.3"
paste = "1.0"
serde_with = "3.14.1"
rust_decimal = { version = "1.38.0", features = ["serde"] }
bon = "3.3"
once_cell = "1.20"
# Prometheus for GenAI metrics (via axum-prometheus)
prometheus = "0.14"
# Embedded database support
postgresql_embedded = { version = "0.20", optional = true, features = [
  "bundled",
] }
# Embedded static assets
rust-embed = { version = "8.5", features = ["debug-embed"] }
mime_guess = "2.0"
futures = "0.3.31"
dashmap = { version = "6.1.0", features = ["serde"] }
moka = { version = "0.12", features = ["future"] }
# Stripe payment processing - Fixed at rc0 currently as this is the only semi-stable version supporting a modern stripe API
async-stripe = { version = "1.0.0-rc.0", default-features = false, features = [
  "rustls-tls-webpki-roots",
  "rustls-aws-lc-rs",
] }
async-stripe-checkout = { version = "1.0.0-rc.0", features = [
  "checkout_session",
] }
async-stripe-webhook = { version = "1.0.0-rc.0", features = [
  "async-stripe-checkout",
  "deserialize",
] }
async-stripe-types = { version = "1.0.0-rc.0" }
async-stripe-core = { version = "1.0.0-rc.0", features = [
  "payment_intent",
  "customer",
] }
async-stripe-misc = { version = "1.0.0-rc.0", features = ["tax_calculation"] }
rustls = { version = "0.23", features = ["aws-lc-rs"] }
async-stripe-billing = { version = "1.0.0-rc.0", features = [
  "billing_portal_session",
] }
sqlx-pool-router = "0.2.0"
minijinja = "2.15.1"
multer = "3.1.0"
ctor = "0.6"
hmac = "0.12.1"
sha2 = "0.10.9"

[dev-dependencies]
axum-test = { version = "18.4.1" }
sqlx = { version = "0.8", features = [
  "postgres",
  "runtime-tokio-rustls",
  "uuid",
  "chrono",
  "migrate",
] }
tokio-test = "0.4"
serial_test = "3.0"
test-log = { version = "0.2", features = ["trace"] }
criterion = { version = "0.8", features = ["async_tokio"] }
tempfile = "3.0"
wiremock = "0.6"
serde_urlencoded = "0.7"
