Skip to content

feat(referral): template the real email#2147

Merged
seanaye merged 2 commits intomainfrom
seanaye/feat/referral-email-template
Mar 24, 2026
Merged

feat(referral): template the real email#2147
seanaye merged 2 commits intomainfrom
seanaye/feat/referral-email-template

Conversation

@seanaye
Copy link
Copy Markdown
Contributor

@seanaye seanaye commented Mar 24, 2026

Replace the placeholder with the real email template

  • use the referral code in the email
  • add tests

@seanaye seanaye requested a review from a team as a code owner March 24, 2026 16:51
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 24, 2026

Walkthrough

This change adds Askama (workspace dependency) and converts the referral_invitation crate to use Askama templates. InviteToMacro now derives Askama Template and includes a template path; URL construction logic was added to produce environment-aware referral links (/app/signup with referral_code). The email rendering uses the template output. New tests validate URL generation, email formatting, rate-limit helpers, and serde roundtrips. The invite HTML template now uses the generated referral URL.

Poem

🐇 I nibble lines of Rust tonight,
Templates stitched with Askama light,
Hosts shift by env, links hop through,
Tests thump paws to check what's true,
A tiny rabbit, code and delight.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: implementing a real email template for referral invitations with dynamic content.
Description check ✅ Passed The description is related to the changeset, mentioning using the referral code in the email and adding tests, which aligns with the changes shown.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch seanaye/feat/referral-email-template

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
rust/cloud-storage/referral_invitation/templates/invite.html (1)

124-124: 🧹 Nitpick | 🔵 Trivial

Static "User" placeholder may need dynamic replacement.

Lines 124 and 142 display "User has invited you..." but this appears to be a static placeholder. Consider whether the inviter's name should be templated here for personalization (e.g., {{ inviter_name }}).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rust/cloud-storage/referral_invitation/templates/invite.html` at line 124,
The static text "User has invited you to Macro" in the invite.html template
should be replaced with a templated inviter name to personalize the message;
update the template to use a variable like {{ inviter_name }} (or the project's
existing context key) in both occurrences, ensure the rendering code that calls
the invite.html template (the function or controller responsible for creating
referral invitations) supplies inviter_name in the template context, and add a
fallback (e.g., "Someone") if inviter_name is missing to avoid blank output.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@rust/cloud-storage/Cargo.toml`:
- Line 136: Update the askama dependency from "0.14" to the newer version (e.g.,
"0.15.5") in Cargo.toml by changing the askama = "0.14" line to askama =
"0.15.5"; after updating run cargo update and cargo check/cargo build (and cargo
test) to catch any breakages, and address any API changes in code that
references Askama types/macros (search for usages of askama::Template,
#[derive(Template)], and related template macros) and adjust imports or template
attributes as needed.

In `@rust/cloud-storage/referral_invitation/src/lib.rs`:
- Line 67: Replace the terse expect message on the self.render() call with a
more descriptive context that names the Askama template/struct and the enclosing
function so failures are easier to debug; locate the expression setting body:
self.render().expect("This cant fail, it is tested") and update the expect text
to mention the template type (e.g., the invitation template) and the
function/operation that attempted the render so the panic message clearly
identifies what failed.

In `@rust/cloud-storage/referral_invitation/src/test.rs`:
- Around line 16-28: The test get_url_all_environments currently checks path and
query but not that host differs by Environment; update the test to assert
expected host values for each Environment (Environment::Production,
Environment::Develop, Environment::Local) when calling get_url(&code) for
ReferralCode("CODE"), e.g. check url.host_str() or url.as_str() contains the
expected host for each variant alongside the existing assertions so the test
verifies environment-specific hosts in get_url.
- Around line 30-36: The test format_email_does_not_panic currently only checks
that subject and body are non-empty; update it to also assert that the rendered
email body contains the referral link so template regressions are caught. Locate
the test using make_invite() and invite.format_email(), then add an assertion
that email.body contains the invite's referral URL (or the specific field on the
Invite struct, e.g., invite.url or invite.referral_code formatted into the
expected URL) so the test will fail if the link is omitted from the template.

---

Outside diff comments:
In `@rust/cloud-storage/referral_invitation/templates/invite.html`:
- Line 124: The static text "User has invited you to Macro" in the invite.html
template should be replaced with a templated inviter name to personalize the
message; update the template to use a variable like {{ inviter_name }} (or the
project's existing context key) in both occurrences, ensure the rendering code
that calls the invite.html template (the function or controller responsible for
creating referral invitations) supplies inviter_name in the template context,
and add a fallback (e.g., "Someone") if inviter_name is missing to avoid blank
output.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2d2213fd-0a92-4c5b-a239-81c10368ad93

📥 Commits

Reviewing files that changed from the base of the PR and between cc8467c and 6846da2.

⛔ Files ignored due to path filters (1)
  • rust/cloud-storage/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • rust/cloud-storage/Cargo.toml
  • rust/cloud-storage/email_formatting/Cargo.toml
  • rust/cloud-storage/referral_invitation/Cargo.toml
  • rust/cloud-storage/referral_invitation/src/lib.rs
  • rust/cloud-storage/referral_invitation/src/test.rs
  • rust/cloud-storage/referral_invitation/templates/invite.html


[workspace.dependencies]
anyhow = "1.0.93"
askama = "0.14"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

🧩 Analysis chain

🌐 Web query:

askama crate latest version 2025

💡 Result:

In 2025, the latest askama crate release was v0.15.0, published on December 22, 2025. [1]

Earlier in 2025, v0.14.0 was released on April 23, 2025. [2]

(For reference, as of March 24, 2026, docs.rs shows the latest askama version as 0.15.5.) [3]

Sources:
[1] [GitHub releases: askama-rs/askama (v0.15.0, Dec 22)] (github.com)
[2] [GitHub releases: askama-rs/askama (v0.14.0, Apr 23)] (github.com)
[3] [docs.rs: askama 0.15.5] (docs.rs)

Citations:


Consider updating askama to the latest version.

Askama v0.14.0 is valid (released April 23, 2025), but as of March 2026, the latest version is 0.15.5. Consider updating to benefit from recent improvements and security patches.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rust/cloud-storage/Cargo.toml` at line 136, Update the askama dependency from
"0.14" to the newer version (e.g., "0.15.5") in Cargo.toml by changing the
askama = "0.14" line to askama = "0.15.5"; after updating run cargo update and
cargo check/cargo build (and cargo test) to catch any breakages, and address any
API changes in code that references Askama types/macros (search for usages of
askama::Template, #[derive(Template)], and related template macros) and adjust
imports or template attributes as needed.

@seanaye seanaye force-pushed the seanaye/feat/referral-email-template branch from 6846da2 to 1f67a7a Compare March 24, 2026 17:06
@seanaye seanaye force-pushed the seanaye/feat/referral-email-template branch from 1f67a7a to 33cc78c Compare March 24, 2026 17:07
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@rust/cloud-storage/referral_invitation/src/lib.rs`:
- Around line 48-61: The get_url function is private but your tests need to call
it directly; make it test-accessible by changing its visibility to pub(crate)
(i.e., pub(crate) fn get_url(env: Environment, code: &ReferralCode) -> Url) so
tests in the crate can import and exercise it, leaving the function body and
types (Environment, ReferralCode, Url) unchanged; update any references that
rely on the old private visibility if necessary.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f4cefcdc-096a-4c1b-bb03-f9e186c4ee10

📥 Commits

Reviewing files that changed from the base of the PR and between 6846da2 and 33cc78c.

⛔ Files ignored due to path filters (1)
  • rust/cloud-storage/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • rust/cloud-storage/Cargo.toml
  • rust/cloud-storage/email_formatting/Cargo.toml
  • rust/cloud-storage/referral_invitation/Cargo.toml
  • rust/cloud-storage/referral_invitation/src/lib.rs
  • rust/cloud-storage/referral_invitation/src/test.rs
  • rust/cloud-storage/referral_invitation/templates/invite.html

Comment on lines +48 to +61
fn get_url(env: Environment, code: &ReferralCode) -> Url {
let host = match env {
Environment::Production => "https://macro.com",
Environment::Develop => "https://dev.macro.com",
Environment::Local => "http://localhost:3000",
};
let mut url = Url::parse(host).expect("all the inputs are static, valid values");
url.set_path("/app/signup");
url.query_pairs_mut()
.clear()
.append_pair("referral_code", &code.0)
.finish();
url
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider making get_url testable.

The get_url function is private but is directly called in tests. See the related comment on test.rs regarding the use super::* import not bringing private items into scope.

If you want to keep this function tested directly, consider making it pub(crate):

Suggested change
-fn get_url(env: Environment, code: &ReferralCode) -> Url {
+pub(crate) fn get_url(env: Environment, code: &ReferralCode) -> Url {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fn get_url(env: Environment, code: &ReferralCode) -> Url {
let host = match env {
Environment::Production => "https://macro.com",
Environment::Develop => "https://dev.macro.com",
Environment::Local => "http://localhost:3000",
};
let mut url = Url::parse(host).expect("all the inputs are static, valid values");
url.set_path("/app/signup");
url.query_pairs_mut()
.clear()
.append_pair("referral_code", &code.0)
.finish();
url
}
pub(crate) fn get_url(env: Environment, code: &ReferralCode) -> Url {
let host = match env {
Environment::Production => "https://macro.com",
Environment::Develop => "https://dev.macro.com",
Environment::Local => "http://localhost:3000",
};
let mut url = Url::parse(host).expect("all the inputs are static, valid values");
url.set_path("/app/signup");
url.query_pairs_mut()
.clear()
.append_pair("referral_code", &code.0)
.finish();
url
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rust/cloud-storage/referral_invitation/src/lib.rs` around lines 48 - 61, The
get_url function is private but your tests need to call it directly; make it
test-accessible by changing its visibility to pub(crate) (i.e., pub(crate) fn
get_url(env: Environment, code: &ReferralCode) -> Url) so tests in the crate can
import and exercise it, leaving the function body and types (Environment,
ReferralCode, Url) unchanged; update any references that rely on the old private
visibility if necessary.

@seanaye seanaye merged commit 01efe78 into main Mar 24, 2026
43 checks passed
@seanaye seanaye deleted the seanaye/feat/referral-email-template branch March 24, 2026 17:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant