P-09b · Staff: the Client approval Work page (stage-first layout)
SOP:
Payroll_Processing.md§6 / Step 6.0 (client approval). This page describes how staff work Gate 2 on the console; the SOP is unchanged. Sending, the client's decision and its rules are in P-09 and P-10. Actors: Payroll Executive, Payroll Lead (and Admin / Platform admin). Pre-state: a payroll month inCLIENT_REVIEW,CLIENT_QUERY_OPENorREVISION_REQUESTED. Post-state: the client approved on their payroll link, or a Payroll Lead approved without them (APPROVED); today's page takes over for the final approval.
Since 31 Oct 2026 (branch feat/work-page-stage-first) a month at Client approval opens on the same stage-first frame as Collecting inputs (P-02b) and Validation (P-04b). The final approval (APPROVED) and every later stage still open today's page. Add ?layout=classic to the URL to see today's page for any month.
Nothing changed on the server. The page reads what today's page reads (approvalDraft, revisionReply, clientQuery, approvalRequestBlockers, the issue list) and calls the same routes.
What the page shows, top to bottom
- Header. Company · month, the "Client approval" pill, assignee, pay-by date, when the month reached Client approval.
- This stage's job. "Get the client's yes on October's figures." How this stage ends: the client approves on their link, or a Payroll Lead records why the month goes ahead without them; a chat reply is never an approval.
- Where the request stands, one sentence, coloured by urgency:
- Drafted, not sent. Nothing reaches Priya Menon until you send it.
- Drafted, but it cannot go to the client yet plus the server's reasons (an undecided change, a due increment, an open blocking issue) and an approver whose send was refused for having no email.
- Sending to … · The send to Tanya Rao failed: they have not received the request. (red)
- Sent to … on 29 Oct, delivered · 2 days waiting. (amber from day 3, the first reminder day)
- No live request: the last one was withdrawn, or replaced when the figures changed. (re-issue)
- What the client said: Nadia Salleh asked for changes on 24 Oct. / Owen Lau asked a question on 24 Oct. with whether the reply is drafted, sent or answered.
- The request card (today's): the message, what the client receives, the approver, Send / Resend / Withdraw, and Approve without the client… for a Payroll Lead. When the client asked for changes or a question, their card comes instead (their words, the drafted reply, Changes applied: re-validate, or the answer box).
- Open now tiles, only for what is open besides the request: a change to decide that arrived after the sign-off, something for a Lead, a final pay held until IRAS clears it, month-wide items.
- Employee list. Opens on Pay result: the figures the request was built from ("What the client is approving: the request sent on 29 Oct was built from these figures."). It opens on the Work view instead when a change arrived after the sign-off; that person's row says stops the request · decide the change. The leaver's withheld final pay and its clearance actions are on their row, as at Validation. The "Accept at sign-off" tab is gone: the sign-off is done.
- Needs attention. Month-wide issues (the approval aging warnings, an undeliverable approver, client messages). Hidden when empty.
- Documents, folded, as at Validation.
- Background, folded: Ask the client for something on their payroll link (also at Validation), settled attendance with Reopen, Back to checking (only while no request is out), closed warnings, Cancel this month, the full cycle page.
- Bottom bar: the state in a few words and one action for it: Review and send… (draft; Go to the request… when it cannot go), Resend (send failed), Re-issue approval request (no live request; disabled with the reason while something blocks it), Review and send the reply… (changes asked), Resolve query (a question; always offered, with "answer the client in the card above first" until a reply has gone out, since a reply is recorded only once the worker delivers it). While the client is deciding there is no button: nothing to do until they decide.
A Payroll Lead moves the month on without the client
Approve without the client… sits in the request card, for a Payroll Lead only, with a reason (and what the client said or sent, if anything). It is offered:
- on a sent request (delivered, still sending, or failed): the rule since 24 Oct 2026;
- since 31 Oct 2026 (Kabeer), also on a request that was never sent, for when it cannot go (an approver with no email and nobody else to ask). The Lead must then also say how the client had the figures (at least 10 characters, e.g. "went through the summary with the director by phone on 30 Oct"). Only the sending is waived: while Gate 2's own checks are open (an undecided change, a due increment, an open blocking issue) the option is not offered and the server refuses it. The record reads "Approved by the Payroll Lead without the client's approval: ‹reason› (the request was never sent; the client had the figures: ‹statement›)".
Not offered once the client asked for changes or a question: they answered, so the month goes back through validation. Everything else is as before: Payroll Lead only, the contact-editor rule, the client told at once, and another person gives the final approval when there is one.
Added on 1 Nov 2026 (gap review)
- Approve without the client follows the same independence rule as every other gate (new gate
APPROVE_WITHOUT_CLIENT, Payroll Lead only): a Lead who prepared the month is refused while another Lead can, and the page greys the button with who can. When every Lead prepared it, a preparer may. - Dates line, deadline-at-risk tile and the preparers note as on the inputs page.
Not on this page by design
- The rule results of the last validation run: they were signed at Confirm review; the rail's Who did what keeps the sign-off with its reason.
- Reminder scheduling at this stage: the server's approval reminders and their failures arrive as issues in Needs attention.
- The Payroll Lead's final approval (
APPROVED): next piece, still today's page.
Manual test (seeded stage companies, built app)
Sign in as executive@spade.local / lead@spade.local. Each month below shows one state:
| Company | State |
|---|---|
| Dev Exception 28 Approver Without Email | Draft that cannot go: the approver has no email |
| Dev Exception 07 Foreign Leaver Held | Send failed; final pay held on Chen Xin Yi's row |
| Dev Exception 01 Client Asked For Change | The client asked for changes; reply drafted |
| Dev Exception 02 Client Asked A Question | The client asked a question, not answered |
| Dev Exception 11 Letter After Approval | Round 2 drafted, blocked by Jia Hui's late change under To decide |
| Dev Exception 03 Raise Above Limit | Sent from this page on 31 Oct (sending until the worker runs) |