Conversation
This commit adds the SurrealDB schema files and dependencies to support database migrations and management. It also includes: - Dependencies: axum-macros, include_dir - Files: .surrealdb, Cargo.lock and Cargo.toml changes. - Code: Implement confirm subscription
WalkthroughAdds SurrealDB config file, updates dependencies (adds include_dir, axum macros), boxes SurrealDB errors, refactors health check error mapping, expands subscribe handler to use AppState and delegate confirmation to ModelManager, introduces ModelManager::confirm_subscriber, embeds and runs migrations at startup, and changes main to return Result instead of exiting. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Router as Axum Router
participant SubH as subscribe Handler
participant MM as ModelManager
participant EC as EmailClient
participant DB as SurrealDB
User->>Router: POST /subscriptions (form)
Router->>SubH: Extract State(mm, config, email_client) + Form
SubH->>MM: create_subscriber(form)
MM->>DB: INSERT subscription (pending)
DB-->>MM: ok / error (boxed)
alt insert ok
SubH->>EC: send_confirmation_email(get_confirmation_link(config, token))
EC-->>SubH: ok
SubH-->>Router: 200 OK
else insert/email error
SubH-->>Router: error (propagated)
end
sequenceDiagram
autonumber
actor User
participant Router as Axum Router
participant ConfH as confirm Handler
participant MM as ModelManager
participant DB as SurrealDB
User->>Router: GET /subscriptions/confirm?token=...
Router->>ConfH: Extract State(mm)
ConfH->>MM: confirm_subscriber(token)
MM->>DB: UPDATE subscriptions SET status=CONFIRMED WHERE ...
DB-->>MM: ok / error (boxed)
MM-->>ConfH: Result
ConfH-->>Router: 200 OK or error
sequenceDiagram
autonumber
participant Main as main()
participant MM as ModelManager
participant FS as Embedded Migrations
participant DB as SurrealDB
Main->>MM: connect()
MM->>DB: connect/signin (errors boxed)
MM->>FS: load migrations (include_dir)
MM->>DB: apply migrations .up()
DB-->>MM: ok / error
MM-->>Main: Result
Main-->>Main: use ? to propagate
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Poem
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
Cargo.toml (1)
27-29: Gate SurrealDB storage backends via Cargo features
kv-memis great for tests/dev but not for prod. Suggest feature flags to switch backends without touching code.[dependencies] -surrealdb = { version = "2.3.7", features = ["kv-mem"] } +surrealdb = { version = "2.3.7", default-features = false } +[features] +default = ["db-mem"] +# In-memory (dev/test) +db-mem = ["surrealdb/kv-mem"] +# Example alternative backends you can enable in prod builds: +# db-rocks = ["surrealdb/kv-rocksdb"] +# db-tikv = ["surrealdb/kv-tikv"]If you adopt this, ensure CI builds pass with at least
--features db-mem.src/errors.rs (1)
31-38: Polish log messages; keep semantics the sameMinor wording fixes for clarity; retains status behavior.
- tracing::info!("Bad request: - {self:?}"); + tracing::info!("Bad Request - {self:?}"); @@ - tracing::error!("Internal Server: - {self:?}"); + tracing::error!("Internal Server Error - {self:?}");src/model.rs (3)
86-93: Avoid string interpolation for credentials in DDLInterpolating username/password directly into
DEFINE USERis fragile (quoting) and risky if config ever becomes untrusted. Prefer parameters if Surreal supports them for DDL, or at least ensure strict validation/sanitization ofusername.If params aren’t supported in DDL, validate
config.usernameagainst^[A-Za-z0-9_]+$before executing.
107-113: Add migration locking to prevent concurrent runnersIf this service can start multiple instances, guard migrations with a lock key to avoid race conditions. Many migration runners expose a lock key API.
109-113: Stabilize migrations dir reference and correct path
Verified the migrations folder is namedsurrealdb/(no leading dot). Define a'staticDirand reference it to avoid holding a temporary reference across.up().await:-use include_dir::include_dir; +use include_dir::{include_dir, Dir}; + +static MIGRATIONS_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/surrealdb"); @@ - .load_files(&include_dir!("$CARGO_MANIFEST_DIR/surrealdb")) + .load_files(&MIGRATIONS_DIR)src/handlers/subscription.rs (1)
31-35: Minor observability tweakConsider logging a compact event after DB write and after email send (without PII/token). Helps diagnose issues without leaking secrets.
Also applies to: 62-85
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (8)
.surrealdb(1 hunks)Cargo.toml(2 hunks)src/domain/subscriber/mod.rs(1 hunks)src/errors.rs(1 hunks)src/handlers/health_check.rs(1 hunks)src/handlers/subscription.rs(4 hunks)src/main.rs(2 hunks)src/model.rs(5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-28T13:50:40.460Z
Learnt from: TN19N
PR: TN19N/subscriptions#9
File: src/domain/subscriber/email.rs:18-19
Timestamp: 2025-08-28T13:50:40.460Z
Learning: For the SubscriberEmail validation in src/domain/subscriber/email.rs, the user TN19N prefers to include the actual email value in ValidationError messages for debugging purposes, accepting the PII exposure trade-off in favor of detailed error information returned with 400 HTTP status.
Applied to files:
src/domain/subscriber/mod.rs
🧬 Code graph analysis (5)
src/domain/subscriber/mod.rs (2)
src/email_client.rs (1)
src/domain/subscriber/email.rs (4)
SubscriberEmail(6-6)tests(27-65)AsRef(8-12)as_ref(9-11)
src/handlers/health_check.rs (3)
src/state.rs (4)
new(17-23)AppState(10-14)FromRef(26-30)FromRef(32-36)tests/api/health_check.rs (1)
health_works(4-16)src/startup.rs (1)
init(20-43)
src/handlers/subscription.rs (2)
src/email_client.rs (2)
email_client(207-215)EmailClient(25-62)src/state.rs (1)
AppState(10-14)
src/main.rs (3)
src/config.rs (1)
load(36-41)src/startup.rs (1)
init(20-43)src/state.rs (1)
AppState(16-24)
src/model.rs (4)
src/state.rs (1)
new(17-23)tests/api/helpers.rs (1)
new(24-51)tests/api/subscriptions_confirm.rs (2)
QueryResult(52-56)confirmation_works(24-75)tests/api/subscriptions.rs (2)
subscribe_works(10-48)subscribe_returns_a_200_for_valid_form_data(150-191)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: check
🔇 Additional comments (10)
src/domain/subscriber/mod.rs (1)
5-5: LGTM: Re-export reorder is non-breaking.Public API unchanged; moving
pub use email::SubscriberEmail;below the import is fine.Cargo.toml (3)
17-17: Enabling axum macros is correct for #[axum::debug_handler]This aligns with the handler attribute usage. LGTM.
20-23: No functional change in reqwest featuresPurely formatting; nothing to flag.
40-40: include_dir addition: OKMatches the embedded migrations approach.
src/handlers/health_check.rs (1)
7-7: Good use of #[axum::debug_handler] with AppStateThis helps catch extractor/state issues at compile time. LGTM.
src/main.rs (1)
6-6: main returning Result is a solid improvementError propagation via
?keeps startup code clean. LGTM.src/model.rs (2)
48-50: Good: transaction + .check() ensures write errors surfaceThe transaction around token + subscription creation plus
.check()is solid. This should fail fast on constraint errors once you add schema.
81-84: Consistent boxed error mapping looks goodUniform
.map_err(Box::new)?across connect, mem-setup, and signin keeps error typing consistent with your crate’sResult.Also applies to: 94-96, 104-106
src/handlers/subscription.rs (2)
87-92: Confirmation link builder looks correct
Url::join+set_queryavoids manual string concat and handles base URL slashes.
55-57: No changes needed:rand::rng()andrand::distr::Alphanumericare correct for rand 0.9.2
Your Cargo.toml pins rand at 0.9.2, where top-levelthread_rng()was renamed torng()(withthread_rng()kept as a deprecated alias) and thedistributionsmodule was renamed todistr(docs.rs)
This commit adds the SurrealDB schema files and dependencies to support database migrations and management.
It also includes: - Dependencies: axum-macros, include_dir - Files: .surrealdb, Cargo.lock and Cargo.toml changes. - Code: Implement confirm subscription
Summary by CodeRabbit
New Features
Improvements
Chores