An expense request travels through a chain of approvers. Each approver checks the amount against its own limit. An approver that can accept the request returns an approval immediately; otherwise it passes the same request to the next approver.
The provided ExpenseChain exposes this API:
ExpenseChain() creates an empty approval chain.boolean addApprover(String kind) appends "team-lead", "manager" or "director" to the chain. It returns false for an unknown kind or a kind already present.String chainOrder() returns approver names from head to tail joined by " -> ", or "EMPTY".String request(int amount, String purpose) sends a request to the head. An approval is "<Name> approved $<amount>: <purpose>". If no configured approver can accept it, return "DECLINED". A non-positive amount returns "INVALID" without entering the chain.int approverCount() returns the number of approvers in the chain.int approvedCount() returns the number of approved requests across all calls.The approvers and their inclusive limits are:
TeamLead approves up to $100.Manager approves up to $500.Director approves up to $2000.The first capable approver stops the chain. This makes insertion order observable: a director placed before a team lead approves even the smallest request.
Complete only the five Chain of Responsibility types left in the starter code:
Approver defines name, setNext, getNext and approve.BaseApprover stores the next approver and centralises forwarding. Forwarding past the tail returns "DECLINED".TeamLead, Manager and Director own their names and approval limits.The supplied ExpenseChain builds and reports the chain, validates amounts, and counts approvals. It is the only type the tests call; do not change it.
Input:
Output:
Explanation: The amount is above the team lead's limit. The manager accepts it and returns without calling the director.
Input:
Output:
Explanation: The director is first and accepts $75. Neither configured approver can accept $2500, so the second request reaches the end of the chain.
-10 <= amount <= 30001 <= purpose.length <= 803 approvers are added to one chain.100 calls in total are made across all methods.Full marks when team lead, manager and director are separate classes behind one approver contract, each object owns its limit, and `request` sends the expense to the head without comparing approval limits. Lose points heavily when the chain class chooses an approver with amount conditionals or performs approval while traversing the links.
Full marks when an approver returns immediately for an amount within its limit and forwards only an amount above its limit, so exactly one approver can approve a request. Lose points when every approver runs, a capable approver forwards, or an incapable approver declines before later approvers get a chance.
Full marks when insertion order controls the result, unknown and repeated kinds leave the chain unchanged, forwarding past the tail returns `DECLINED`, non-positive amounts return `INVALID`, and only approvals increase `approvedCount`. Lose points for printing to stdout.
Passing every test is not enough on its own. A submission is accepted only when the design also clears the bar.
| Call | Returns |
|---|---|
| new ExpenseChain() | null |
| addApprover("team-lead") | true |
| addApprover("manager") | true |
| addApprover("director") | true |
| chainOrder() | "TeamLead -> Manager -> Director" |
| request(350, "Team lunch") | "Manager approved $350: Team lunch" |
| approvedCount() | 1 |
The request is above the team lead's $100 limit, so it reaches the manager. The manager can approve $350 and stops the chain.
Run checks these cases. Submit also runs a larger hidden set.

