feat(db): connection factory + env config + feature flags (Phase 2)#187
Merged
Conversation
…167) - Add factory in trapfall-db that detects URL scheme ( → SqliteBackend, → PostgresBackend stub) - Add helper: bare paths auto-prefixed with - Add Cargo feature flags: , optional - Gate module behind - Read env var via clap NVM_INC=/Users/ajianaz/.nvm/versions/node/v24.16.0/include/node MANPATH=/Users/ajianaz/.nvm/versions/node/v24.16.0/share/man::/usr/share/man:/usr/local/share/man:/Applications/Ghostty.app/Contents/Resources/ghostty/../man: GHOSTTY_RESOURCES_DIR=/Applications/Ghostty.app/Contents/Resources/ghostty ZLE_RPROMPT_INDENT=0 TERM_PROGRAM=ghostty NVM_CD_FLAGS=-q POSH_SHELL=zsh SHELL=/bin/zsh TERM=xterm-256color HOMEBREW_REPOSITORY=/opt/homebrew TMPDIR=/var/folders/2p/cq1s63ns5ws25clfnxx1mv240000gn/T/ CONDA_PROMPT_MODIFIER=false TERM_PROGRAM_VERSION=1.3.1 FPATH=/opt/homebrew/share/zsh/site-functions:/usr/local/share/zsh/site-functions:/usr/share/zsh/site-functions:/usr/share/zsh/5.9/functions:/Users/ajianaz/.orbstack/shell/completions/zsh PI_CODING_AGENT=true POWERLINE_COMMAND=oh-my-posh ZAI_API_KEY=7bcf7223da584f608232b592bf493de1.k0ooxDcGZTWoHGX7 NVM_DIR=/Users/ajianaz/.nvm POSH_SESSION_ID=6ac4ee50-10d7-4c1b-8b1c-e3f79bf41ccf USER=ajianaz COMMAND_MODE=unix2003 CHROME_EXECUTABLE=/Applications/Brave Browser.app/Contents/MacOS/Brave Browser SSH_AUTH_SOCK=/var/run/com.apple.launchd.rxcSj5frzD/Listeners PYENV_VIRTUALENV_DISABLE_PROMPT=1 __CF_USER_TEXT_ENCODING=0x1F5:0x0:0x0 VIRTUAL_ENV_DISABLE_PROMPT=1 PATH=/Users/ajianaz/.pi/agent/bin:/Users/ajianaz/bin:/Users/ajianaz/.local/bin:/Users/ajianaz/.antigravity/antigravity/bin:/Users/ajianaz/.bun/bin:/Users/ajianaz/.nvm/versions/node/v24.16.0/bin:/opt/homebrew/opt/python@3.12/libexec/bin:/opt/homebrew/bin:/Users/ajianaz/.pub-cache/bin:/Users/ajianaz/.npm-global/bin:/opt/homebrew/opt/openjdk@17/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/pkg/env/global/bin:/usr/local/co.palokaj.battery:/Library/Apple/usr/bin:/usr/local/go/bin:/Users/ajianaz/.cargo/bin:/Applications/Ghostty.app/Contents/MacOS:/Users/ajianaz/.orbstack/bin:/Users/ajianaz/Ngoding/flutter/bin:/usr/local/mysql/bin/mysql:/usr/local/bin:/usr/local/go/bin:/opt/homebrew/share/android-platform-tools _=/usr/bin/env LaunchInstanceID=39327689-4F43-4DB9-9891-BE35FF3D4A24 GHOSTTY_SHELL_FEATURES=cursor:blink,path,title __CFBundleIdentifier=com.mitchellh.ghostty PWD=/Users/ajianaz/Ngoding/project-latest/trapfall JAVA_HOME=/opt/homebrew/opt/openjdk@17 FIRECRAWL_API_KEY=test POSH_SHELL_VERSION=5.9 LANG=en_US.UTF-8 XPC_FLAGS=0x0 FIRECRAWL_API_URL=https://firecrawl.ajianaz.dev XPC_SERVICE_NAME=0 HOME=/Users/ajianaz SHLVL=2 OSTYPE=darwin25.0 TERMINFO=/Applications/Ghostty.app/Contents/Resources/terminfo HOMEBREW_PREFIX=/opt/homebrew PYTHONPATH=/Users/ajianaz/Ngoding/project-latest/Auto-Claude: LOGNAME=ajianaz XDG_DATA_DIRS=/usr/local/share:/usr/share:/Applications/Ghostty.app/Contents/Resources/ghostty/.. GHOSTTY_BIN_DIR=/Applications/Ghostty.app/Contents/MacOS BUN_INSTALL=/Users/ajianaz/.bun NVM_BIN=/Users/ajianaz/.nvm/versions/node/v24.16.0/bin INFOPATH=/opt/homebrew/share/info: HOMEBREW_CELLAR=/opt/homebrew/Cellar OSLogRateLimit=64 SECURITYSESSIONID=186b7 COLORTERM=truecolor (falls back to ) - Change from PathBuf to String (accepts URLs) - Docker: support env var in docker-compose - Dockerfile: cache trapfall-db Cargo.toml in dependency stage - Root sqlx dep trimmed to only; crates opt-in backends - Add clap NVM_INC=/Users/ajianaz/.nvm/versions/node/v24.16.0/include/node MANPATH=/Users/ajianaz/.nvm/versions/node/v24.16.0/share/man::/usr/share/man:/usr/local/share/man:/Applications/Ghostty.app/Contents/Resources/ghostty/../man: GHOSTTY_RESOURCES_DIR=/Applications/Ghostty.app/Contents/Resources/ghostty ZLE_RPROMPT_INDENT=0 TERM_PROGRAM=ghostty NVM_CD_FLAGS=-q POSH_SHELL=zsh SHELL=/bin/zsh TERM=xterm-256color HOMEBREW_REPOSITORY=/opt/homebrew TMPDIR=/var/folders/2p/cq1s63ns5ws25clfnxx1mv240000gn/T/ CONDA_PROMPT_MODIFIER=false TERM_PROGRAM_VERSION=1.3.1 FPATH=/opt/homebrew/share/zsh/site-functions:/usr/local/share/zsh/site-functions:/usr/share/zsh/site-functions:/usr/share/zsh/5.9/functions:/Users/ajianaz/.orbstack/shell/completions/zsh PI_CODING_AGENT=true POWERLINE_COMMAND=oh-my-posh ZAI_API_KEY=7bcf7223da584f608232b592bf493de1.k0ooxDcGZTWoHGX7 NVM_DIR=/Users/ajianaz/.nvm POSH_SESSION_ID=6ac4ee50-10d7-4c1b-8b1c-e3f79bf41ccf USER=ajianaz COMMAND_MODE=unix2003 CHROME_EXECUTABLE=/Applications/Brave Browser.app/Contents/MacOS/Brave Browser SSH_AUTH_SOCK=/var/run/com.apple.launchd.rxcSj5frzD/Listeners PYENV_VIRTUALENV_DISABLE_PROMPT=1 __CF_USER_TEXT_ENCODING=0x1F5:0x0:0x0 VIRTUAL_ENV_DISABLE_PROMPT=1 PATH=/Users/ajianaz/.pi/agent/bin:/Users/ajianaz/bin:/Users/ajianaz/.local/bin:/Users/ajianaz/.antigravity/antigravity/bin:/Users/ajianaz/.bun/bin:/Users/ajianaz/.nvm/versions/node/v24.16.0/bin:/opt/homebrew/opt/python@3.12/libexec/bin:/opt/homebrew/bin:/Users/ajianaz/.pub-cache/bin:/Users/ajianaz/.npm-global/bin:/opt/homebrew/opt/openjdk@17/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/pkg/env/global/bin:/usr/local/co.palokaj.battery:/Library/Apple/usr/bin:/usr/local/go/bin:/Users/ajianaz/.cargo/bin:/Applications/Ghostty.app/Contents/MacOS:/Users/ajianaz/.orbstack/bin:/Users/ajianaz/Ngoding/flutter/bin:/usr/local/mysql/bin/mysql:/usr/local/bin:/usr/local/go/bin:/opt/homebrew/share/android-platform-tools _=/usr/bin/env LaunchInstanceID=39327689-4F43-4DB9-9891-BE35FF3D4A24 GHOSTTY_SHELL_FEATURES=cursor:blink,path,title __CFBundleIdentifier=com.mitchellh.ghostty PWD=/Users/ajianaz/Ngoding/project-latest/trapfall JAVA_HOME=/opt/homebrew/opt/openjdk@17 FIRECRAWL_API_KEY=test POSH_SHELL_VERSION=5.9 LANG=en_US.UTF-8 XPC_FLAGS=0x0 FIRECRAWL_API_URL=https://firecrawl.ajianaz.dev XPC_SERVICE_NAME=0 HOME=/Users/ajianaz SHLVL=2 OSTYPE=darwin25.0 TERMINFO=/Applications/Ghostty.app/Contents/Resources/terminfo HOMEBREW_PREFIX=/opt/homebrew PYTHONPATH=/Users/ajianaz/Ngoding/project-latest/Auto-Claude: LOGNAME=ajianaz XDG_DATA_DIRS=/usr/local/share:/usr/share:/Applications/Ghostty.app/Contents/Resources/ghostty/.. GHOSTTY_BIN_DIR=/Applications/Ghostty.app/Contents/MacOS BUN_INSTALL=/Users/ajianaz/.bun NVM_BIN=/Users/ajianaz/.nvm/versions/node/v24.16.0/bin INFOPATH=/opt/homebrew/share/info: HOMEBREW_CELLAR=/opt/homebrew/Cellar OSLogRateLimit=64 SECURITYSESSIONID=186b7 COLORTERM=truecolor feature to workspace dependencies - Add 9 factory tests covering URL detection, feature flags, error messages - Update CHANGELOG with [Unreleased] section Acceptance criteria (#167): ✅ works (default) ✅ panics with clear message if feature not enabled ✅ (default) = SQLite only ✅ = both backends compiled ✅ Docker container starts with correct backend via env var Closes #167
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements Phase 2 of the Multi-Backend Database epic (#171).
Adds a connection factory that detects the database URL scheme and instantiates the correct backend. Users select a backend via
TRAPFALL_DATABASE_URLenv var or--dbflag.Closes #167.
Changes
trapfall_db::open_database(url)— factory function detectingsqlite:/postgres:URL schemestrapfall_db::normalise_url(url)— bare paths (e.g.trapfall.db) auto-prefixed withsqlite:default = ["sqlite"], optionalpostgressqlitemodule gated behind#[cfg(feature = "sqlite")]sqlxdep trimmed toruntime-tokio; each crate opts-in its backendTRAPFALL_DATABASE_URLenv var support via clapenvfeature--dbchanged fromPathBuftoString(accepts URLs)--dbflag →TRAPFALL_DATABASE_URLenv →trapfall.dbdefaultTRAPFALL_DATABASE_URLenv var indocker-compose.ymltrapfall-db/Cargo.tomlin dependency stageAcceptance Criteria
TRAPFALL_DATABASE_URL=sqlite:./trapfall.dbworkspostgres://...errors clearly ifpostgresfeature not enabledcargo build(default) = SQLite onlycargo build --features postgres= both backends compiledTest Plan
cargo fmt --check— cleancargo clippy --all-targets -- -D warnings— zero warningscargo test --workspace— 93 tests passed, 0 failedcargo build --release -p trapfalld— binary buildstrapfall --help— shows database URL documentationTRAPFALL_DATABASE_URL=sqlite:/tmp/test.db trapfall healthcheck— exit 0trapfall --db /tmp/test.db healthcheck— exit 0 (bare path)trapfall --db postgres://localhost/db healthcheck— clear error, exit 1Roadmap