Repository navigation
Commit 134c20a
committed
The records a rental business is asked for when something goes wrong
Most of the nine sections asked for were already here -- payment history with
proofs, deposit collection and refund with deductions, pickup and return
readings, extra-KM maths, a seven-stage lifecycle. What was missing was the
evidence: the licence that was checked, the state the car left in, what came
back damaged, and what was charged for it. Those are what a dispute turns on,
and they were on somebody's phone or nowhere.
--- the customer
A WhatsApp number, because the one that answers a call is often not the one
that answers a message and WhatsApp is how this business talks. A licence
expiry, because a licence that runs out mid-hire is the owner's liability and
worth knowing before the keys move. An ID number. A customer type -- new,
returning, corporate. An estimated KM, which is useful before a hire for
quoting and after it for knowing whose estimates to trust.
--- documents
Driving licence, Aadhaar or ID, passport, and anything else. PDF as well as
photographs, because a licence usually arrives as a PDF -- and a PDF is
recognised by its first five bytes rather than by what the file was called, for
the same reason the images are.
Against the customer rather than the booking. A returning customer's licence is
the same licence, and asking for it again every hire is how a file ends up
attached to three bookings and missing from the fourth. Uploading a licence
replaces the one on file rather than stacking a fourth copy nobody can pick
between; "other" is the exception, being where everything else goes.
An expiry that has passed is marked, in red, on the booking.
These are the most private things the system holds -- a licence carries a name,
an address, a date of birth and a photograph -- so the reader requires a
signed-in user, sends no-store, and the file names carry nothing. Signed out it
answers 302 and zero bytes; a traversal, a .php and a .pdf.php all answer 404.
--- the handover check
Thirteen items on both legs: exterior, interior, tyres, spare, tools, papers in
the car, AC, lights, indicators, horn, mirrors, wipers, toolkit. Stored as JSON
on the reading rather than as thirteen columns, because the list changes -- a
business that starts hiring bikes wants a different one -- and a schema change
per item is how a checklist stops being maintained.
Unticked is stored as false rather than left out. "Not checked" and "checked
and wrong" are different things and only the first is what a blank should mean.
--- charges at return
Cleaning, fuel, late return, other -- each its own line with its own amount and
note, and each feeding the booking's total. Itemised rather than folded into
other_charges, because "₹1,150 of other charges" is not something a customer
accepts and not something anyone can explain a month later. An "other" charge
with no note is refused, and refusing it does not take the fuel charge down
with it.
Raised after the reading is saved, not with it, so a rejected charge never
costs someone the reading they just took.
--- damage
What was damaged, what it is thought to cost, which leg it was noticed at,
notes and photographs. Deliberately not money in itself: an estimate is not a
charge. Some damage is billed, some is held back from the deposit, some is
absorbed -- and a record that assumed the first would make the other two wrong.
A tick on the return form raises the charge; leaving it unticked records the
damage and bills nothing.
--- the lifecycle
Not changed, and this is the one place I did not do as asked. The statuses
already run Enquiry, Confirmed, Ready, Active, Returned, Completed, Cancelled.
The extra ones wanted -- Advance Paid, Payment Pending, Deposit Pending -- are
not stages a booking is moved through: they are facts about the money, true or
false on their own, and the panel already derives and shows them. Making them
statuses would mean somebody remembering to move a booking to "Payment
Pending", and a status nobody remembers to set is worse than none.
Checked: twenty-nine browser assertions over the new fields, the checklist
round trip, the charges going up line by line, the refusal that spares the
rest, and what the detail screen shows; the document validator against a real
multipart upload, where a PHP script renamed .pdf is refused and a genuine PDF
is not; the reader's session guard; and the earlier suites still passing -- 35
money tests, 15 commission-split tests, 19 feature tests.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0128YzbhrfGdegUSc9RrARRf1 parent 071a638 commit 134c20a
14 files changed
Lines changed: 1248 additions & 28 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
583 | 583 | | |
584 | 584 | | |
585 | 585 | | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
586 | 616 | | |
587 | 617 | | |
588 | 618 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1180 | 1180 | | |
1181 | 1181 | | |
1182 | 1182 | | |
| 1183 | + | |
| 1184 | + | |
| 1185 | + | |
| 1186 | + | |
| 1187 | + | |
1183 | 1188 | | |
1184 | 1189 | | |
1185 | 1190 | | |
| |||
1248 | 1253 | | |
1249 | 1254 | | |
1250 | 1255 | | |
| 1256 | + | |
| 1257 | + | |
| 1258 | + | |
| 1259 | + | |
| 1260 | + | |
1251 | 1261 | | |
1252 | 1262 | | |
1253 | 1263 | | |
| |||
1420 | 1430 | | |
1421 | 1431 | | |
1422 | 1432 | | |
| 1433 | + | |
| 1434 | + | |
1423 | 1435 | | |
1424 | 1436 | | |
1425 | 1437 | | |
| |||
1486 | 1498 | | |
1487 | 1499 | | |
1488 | 1500 | | |
| 1501 | + | |
1489 | 1502 | | |
1490 | 1503 | | |
1491 | 1504 | | |
| |||
1510 | 1523 | | |
1511 | 1524 | | |
1512 | 1525 | | |
| 1526 | + | |
1513 | 1527 | | |
1514 | 1528 | | |
1515 | 1529 | | |
1516 | 1530 | | |
1517 | 1531 | | |
| 1532 | + | |
| 1533 | + | |
| 1534 | + | |
| 1535 | + | |
| 1536 | + | |
| 1537 | + | |
| 1538 | + | |
| 1539 | + | |
| 1540 | + | |
| 1541 | + | |
| 1542 | + | |
| 1543 | + | |
| 1544 | + | |
| 1545 | + | |
| 1546 | + | |
| 1547 | + | |
| 1548 | + | |
| 1549 | + | |
| 1550 | + | |
| 1551 | + | |
| 1552 | + | |
| 1553 | + | |
1518 | 1554 | | |
1519 | 1555 | | |
1520 | 1556 | | |
| |||
1553 | 1589 | | |
1554 | 1590 | | |
1555 | 1591 | | |
| 1592 | + | |
| 1593 | + | |
| 1594 | + | |
| 1595 | + | |
| 1596 | + | |
| 1597 | + | |
| 1598 | + | |
| 1599 | + | |
| 1600 | + | |
| 1601 | + | |
| 1602 | + | |
| 1603 | + | |
| 1604 | + | |
| 1605 | + | |
| 1606 | + | |
| 1607 | + | |
| 1608 | + | |
| 1609 | + | |
| 1610 | + | |
| 1611 | + | |
| 1612 | + | |
| 1613 | + | |
| 1614 | + | |
| 1615 | + | |
| 1616 | + | |
| 1617 | + | |
| 1618 | + | |
| 1619 | + | |
| 1620 | + | |
| 1621 | + | |
| 1622 | + | |
| 1623 | + | |
| 1624 | + | |
| 1625 | + | |
| 1626 | + | |
| 1627 | + | |
| 1628 | + | |
| 1629 | + | |
| 1630 | + | |
| 1631 | + | |
| 1632 | + | |
| 1633 | + | |
| 1634 | + | |
| 1635 | + | |
| 1636 | + | |
| 1637 | + | |
| 1638 | + | |
| 1639 | + | |
| 1640 | + | |
| 1641 | + | |
| 1642 | + | |
1556 | 1643 | | |
1557 | 1644 | | |
1558 | 1645 | | |
| |||
1623 | 1710 | | |
1624 | 1711 | | |
1625 | 1712 | | |
| 1713 | + | |
| 1714 | + | |
| 1715 | + | |
| 1716 | + | |
| 1717 | + | |
| 1718 | + | |
| 1719 | + | |
| 1720 | + | |
| 1721 | + | |
| 1722 | + | |
| 1723 | + | |
| 1724 | + | |
| 1725 | + | |
| 1726 | + | |
| 1727 | + | |
| 1728 | + | |
| 1729 | + | |
| 1730 | + | |
| 1731 | + | |
| 1732 | + | |
| 1733 | + | |
| 1734 | + | |
| 1735 | + | |
| 1736 | + | |
| 1737 | + | |
| 1738 | + | |
| 1739 | + | |
| 1740 | + | |
| 1741 | + | |
| 1742 | + | |
| 1743 | + | |
| 1744 | + | |
| 1745 | + | |
| 1746 | + | |
| 1747 | + | |
| 1748 | + | |
| 1749 | + | |
| 1750 | + | |
| 1751 | + | |
| 1752 | + | |
| 1753 | + | |
| 1754 | + | |
| 1755 | + | |
| 1756 | + | |
| 1757 | + | |
| 1758 | + | |
| 1759 | + | |
| 1760 | + | |
| 1761 | + | |
| 1762 | + | |
| 1763 | + | |
| 1764 | + | |
| 1765 | + | |
| 1766 | + | |
| 1767 | + | |
| 1768 | + | |
| 1769 | + | |
| 1770 | + | |
| 1771 | + | |
| 1772 | + | |
| 1773 | + | |
| 1774 | + | |
| 1775 | + | |
| 1776 | + | |
| 1777 | + | |
| 1778 | + | |
| 1779 | + | |
| 1780 | + | |
| 1781 | + | |
| 1782 | + | |
| 1783 | + | |
| 1784 | + | |
| 1785 | + | |
| 1786 | + | |
| 1787 | + | |
| 1788 | + | |
| 1789 | + | |
| 1790 | + | |
| 1791 | + | |
| 1792 | + | |
| 1793 | + | |
| 1794 | + | |
1626 | 1795 | | |
1627 | 1796 | | |
1628 | 1797 | | |
| |||
1855 | 2024 | | |
1856 | 2025 | | |
1857 | 2026 | | |
| 2027 | + | |
1858 | 2028 | | |
1859 | 2029 | | |
1860 | 2030 | | |
| |||
1878 | 2048 | | |
1879 | 2049 | | |
1880 | 2050 | | |
| 2051 | + | |
1881 | 2052 | | |
1882 | 2053 | | |
1883 | 2054 | | |
| |||
1904 | 2075 | | |
1905 | 2076 | | |
1906 | 2077 | | |
| 2078 | + | |
1907 | 2079 | | |
1908 | 2080 | | |
1909 | 2081 | | |
| |||
1931 | 2103 | | |
1932 | 2104 | | |
1933 | 2105 | | |
| 2106 | + | |
1934 | 2107 | | |
| 2108 | + | |
| 2109 | + | |
| 2110 | + | |
| 2111 | + | |
| 2112 | + | |
1935 | 2113 | | |
1936 | 2114 | | |
1937 | 2115 | | |
1938 | 2116 | | |
1939 | 2117 | | |
1940 | 2118 | | |
| 2119 | + | |
| 2120 | + | |
| 2121 | + | |
| 2122 | + | |
| 2123 | + | |
| 2124 | + | |
| 2125 | + | |
| 2126 | + | |
| 2127 | + | |
| 2128 | + | |
| 2129 | + | |
| 2130 | + | |
| 2131 | + | |
| 2132 | + | |
| 2133 | + | |
| 2134 | + | |
| 2135 | + | |
| 2136 | + | |
| 2137 | + | |
| 2138 | + | |
| 2139 | + | |
| 2140 | + | |
| 2141 | + | |
| 2142 | + | |
| 2143 | + | |
| 2144 | + | |
| 2145 | + | |
| 2146 | + | |
| 2147 | + | |
| 2148 | + | |
| 2149 | + | |
| 2150 | + | |
| 2151 | + | |
| 2152 | + | |
| 2153 | + | |
| 2154 | + | |
| 2155 | + | |
| 2156 | + | |
| 2157 | + | |
| 2158 | + | |
| 2159 | + | |
| 2160 | + | |
| 2161 | + | |
| 2162 | + | |
| 2163 | + | |
| 2164 | + | |
| 2165 | + | |
| 2166 | + | |
| 2167 | + | |
| 2168 | + | |
| 2169 | + | |
| 2170 | + | |
| 2171 | + | |
1941 | 2172 | | |
1942 | 2173 | | |
1943 | 2174 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
156 | 156 | | |
157 | 157 | | |
158 | 158 | | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
159 | 188 | | |
160 | 189 | | |
161 | 190 | | |
| |||
0 commit comments