Skip to content

Commit 9fa1bf0

Browse files
committed
feat: implement pdf report generation
1 parent 3586fae commit 9fa1bf0

2 files changed

Lines changed: 36 additions & 11 deletions

File tree

backend/src/api.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2069,7 +2069,10 @@ pub async fn get_plan_report(
20692069
}
20702070
};
20712071

2072-
// 4. Build PDF data structs (owned, so they can cross the thread boundary)
2072+
// 4. Compute projected yield (real-time accrued yield since last ping)
2073+
let projected_yield = compute_projected_accrued_yield(&plan);
2074+
2075+
// 5. Build PDF data structs (owned, so they can cross the thread boundary)
20732076
let report_data = crate::pdf::PlanReportData {
20742077
plan_id: plan.id.to_string(),
20752078
owner_address: plan.owner_address.clone(),
@@ -2079,6 +2082,7 @@ pub async fn get_plan_report(
20792082
earn_yield: plan.earn_yield,
20802083
yield_rate_bps: plan.yield_rate_bps,
20812084
accrued_yield: plan.accrued_yield.to_string(),
2085+
projected_accrued_yield: format!("{:.7}", projected_yield),
20822086
created_at: plan.created_at.to_rfc3339(),
20832087
grace_period_seconds: plan.grace_period_seconds,
20842088
beneficiaries: beneficiary_rows
@@ -2098,7 +2102,7 @@ pub async fn get_plan_report(
20982102
.collect(),
20992103
};
21002104

2101-
// 5. Generate PDF in a blocking thread (printpdf is CPU-bound / not async)
2105+
// 6. Generate PDF in a blocking thread (printpdf is CPU-bound / not async)
21022106
let pdf_bytes =
21032107
match tokio::task::spawn_blocking(move || crate::pdf::generate(report_data)).await {
21042108
Ok(Ok(bytes)) => bytes,
@@ -2118,7 +2122,7 @@ pub async fn get_plan_report(
21182122
}
21192123
};
21202124

2121-
// 6. Return the PDF as a downloadable attachment
2125+
// 7. Return the PDF as a downloadable attachment
21222126
let filename = format!("plan-{plan_id}-report.pdf");
21232127
(
21242128
StatusCode::OK,

backend/src/pdf.rs

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub struct PlanReportData {
99
pub earn_yield: bool,
1010
pub yield_rate_bps: i32,
1111
pub accrued_yield: String,
12+
pub projected_accrued_yield: String,
1213
pub created_at: String,
1314
pub grace_period_seconds: i64,
1415
pub beneficiaries: Vec<BeneficiaryData>,
@@ -67,37 +68,57 @@ pub fn generate(data: PlanReportData) -> Result<Vec<u8>, String> {
6768
9.0,
6869
format!("Owner: {}", data.owner_address)
6970
);
71+
line!(regular, 9.0, format!("Status: {}", data.status));
7072
line!(
7173
regular,
7274
9.0,
73-
format!("Token: {}", data.token_address)
75+
format!("Grace Period (s): {}", data.grace_period_seconds)
7476
);
75-
line!(regular, 9.0, format!("Amount: {}", data.amount));
76-
line!(regular, 9.0, format!("Status: {}", data.status));
7777
line!(
7878
regular,
7979
9.0,
80-
format!("Earn Yield: {}", data.earn_yield)
80+
format!("Created At: {}", data.created_at)
81+
);
82+
y -= section_gap;
83+
84+
// Assets
85+
line!(bold, 11.0, "Assets");
86+
line!(
87+
regular,
88+
9.0,
89+
format!("Token Address: {}", data.token_address)
8190
);
91+
line!(regular, 9.0, format!("Locked Amount: {}", data.amount));
92+
y -= section_gap;
93+
94+
// Yield Details
95+
let apy_pct = data.yield_rate_bps as f32 / 100.0;
96+
line!(bold, 11.0, "Yield Details");
8297
line!(
8398
regular,
8499
9.0,
85-
format!("Yield Rate (bps): {}", data.yield_rate_bps)
100+
format!("Earn Yield: {}", data.earn_yield)
86101
);
87102
line!(
88103
regular,
89104
9.0,
90-
format!("Accrued Yield: {}", data.accrued_yield)
105+
format!(
106+
"Yield Rate: {} bps ({:.2}% APY)",
107+
data.yield_rate_bps, apy_pct
108+
)
91109
);
92110
line!(
93111
regular,
94112
9.0,
95-
format!("Grace Period (s): {}", data.grace_period_seconds)
113+
format!("Accrued Yield: {} (snapshotted)", data.accrued_yield)
96114
);
97115
line!(
98116
regular,
99117
9.0,
100-
format!("Created At: {}", data.created_at)
118+
format!(
119+
"Projected Yield: {} (real-time)",
120+
data.projected_accrued_yield
121+
)
101122
);
102123
y -= section_gap;
103124

0 commit comments

Comments
 (0)