kasl-server 0.9.0

Team server for kasl: collects work-time data from employees' kasl agents and turns it into dashboards, reports, and personal pages
Documentation
[package]
name = "kasl-server"
version = "0.9.0"
edition = "2024"
rust-version = "1.94"
description = "Team server for kasl: collects work-time data from employees' kasl agents and turns it into dashboards, reports, and personal pages"
license = "MIT"
repository = "https://github.com/lacodda/kasl-server"
homepage = "https://github.com/lacodda/kasl-server"
readme = "README.md"
keywords = ["time-tracking", "server", "team", "dashboard", "kasl"]
categories = ["web-programming::http-server"]
authors = ["Kirill Lakhtachev <lahtachev@gmail.com>"]
exclude = ["docs/", ".github/", "frontend/", "cliff.toml", "rustfmt.toml"]

[dependencies]
anyhow = "1.0.104"
# Passwords, unlike the agents' random tokens, are human-chosen and worth
# guessing at scale - so they get a memory-hard hash rather than SHA-256.
argon2 = { version = "0.5.3", features = ["std"] }
axum = "0.8.9"
chrono = { version = "0.4.45", default-features = false, features = ["clock", "serde"] }
clap = { version = "4.6.6", features = ["derive"] }
# Session tokens come from the OS entropy source, not from a counter.
rand = "0.10.2"
# Reads an agent's own database during import. Bundled rather than linked
# against a system SQLite: the file is the employee's history, and the version
# that reads it should not depend on what the host happens to ship.
rusqlite = { version = "0.38.0", features = ["bundled", "chrono"] }
serde = { version = "1.0.229", features = ["derive"] }
serde_json = "1.0.151"
sha2 = "0.11.0"
sqlx = { version = "0.9", features = ["runtime-tokio", "tls-rustls", "postgres", "migrate", "chrono", "uuid"] }
tokio = { version = "1.53.1", features = ["full"] }
tower-http = { version = "0.7.0", features = ["trace"] }
tracing = "0.1.44"
tracing-subscriber = { version = "0.3.23", features = ["env-filter"] }
uuid = { version = "1.24.1", features = ["v4", "serde"] }

[dev-dependencies]
http-body-util = "0.1.5"
tower = { version = "0.5.3", features = ["util"] }
# Integration tests are their own crates: the binary's dependencies do not
# reach them, so the schema tests declare what they touch directly.
chrono = { version = "0.4.45", default-features = false, features = ["clock"] }
uuid = { version = "1.24.1", features = ["v4"] }
# The import tests build a fixture in the agent's own schema.
rusqlite = { version = "0.38.0", features = ["bundled"] }