Commit graph

2 commits

Author SHA1 Message Date
Marcel Enguehard
6a47fc8ccd Introduce InterestRate so a rate carries its unit
A bare Decimal rate is ambiguous between the fraction 0,0341 and the percentage
3,41, and nothing in the type system separated them. from_fraction and
from_percentage force the call site to say which one it means.

Migrating the call sites showed the ambiguity was already there: several tests
passed Decimal::new(45, 2), which the old code consumed as the fraction 0,45,
that is 45 %, while it reads naturally as 0,45 %. Those tests exercise capital
and duration rather than the rate, so their outcome is unchanged, but the
reading was a coin flip before and is now explicit.

The type deliberately validates nothing. Comparing buying against investing the
same cash needs rates for expected return and inflation, where a negative value
is meaningful and a 99 % ceiling is nonsense. Range stays a LoanOffer rule,
which is where the domain knows what a plausible loan rate is.

LoanOffer::annual_nominal_rate_in_percent is replaced by InterestRate::
as_percentage, so the conversion stays in immo-core instead of immo-web having
to multiply by 100 itself. It normalises: dividing by 100 and multiplying back
does not restore the original scale, so 3,41 % round-tripped through Display as
"3.4100 %".

This fixes the fraction versus percentage axis only. InterestRate carries no
period, so proportional_monthly_interest_rate still returns a bare Decimal and
naming alone separates annual from monthly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 13:40:06 +02:00
Marcel Enguehard
85b0836d6e Add reference amortisation generator for known-answer tests
Computes the mensualité, échéancier, coût total and TAEG of a French
fixed-instalment loan in Decimal arithmetic, and emits the four anonymised
sample offers as either JSON or a Rust fixtures module.

Conventions (taux mensuel proportionnel, arrondi ROUND_HALF_UP au centime,
dernière échéance ajustée pour solder le CRD) are verified against a real
amortisation table via the `verify` subcommand, and cross-checked against the
ANIL simulator on 2026-08-03.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 18:07:23 +02:00