Skip to content

feat(people): add fee renewal and signed receipts - #100

Merged
lorenzocorallo merged 62 commits into
mainfrom
claude/vigilant-euler-gkle0o
Oct 22, 2026
Merged

lorenzocorallo merged 62 commits into
mainfrom
claude/vigilant-euler-gkle0o

Conversation

@viganogabriele

@viganogabriele viganogabriele commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Builds membership fee renewal and receipts on #97. Members upload bank-transfer receipts in My area; fee administrators review payments, remind members, retry delivery and void receipts; the assigned President/Vice-president signs.

  • Receipt previews use eSign's PDF viewer and cancellation cleanup; the duplicate PdfPages implementation is removed.
  • CIE signing uses the existing SignWithCie popup, job states and notifications. Manual ZIP download/signed-file upload remain available. Officers see only their signing actions; fee administrators and register readers get their own controls.
  • Receipt requests in Signatures carry validated peopleReceipt provenance and link to the filtered receipt queue. Their placement is fixed, generic cancel/delete controls are hidden, and receipt signing still requires the dedicated permission.
  • Unsigned mobile receipts name the expected signer. Copy and payment actions follow the fee state; a loaded transfer is reviewed rather than manually marked paid.

The People backend/receipt bridge is implemented in PoliNetworkOrg/backend#83 and must be merged and deployed first. people.receipts.prepareSignatures must return exactly the selected receipts with distinct durable request IDs. The backend owns officer/version checks, receipt/request association, both completion paths, retention and exactly-once email delivery without a browser callback. The matching contracts are in docs/people/contract.md and docs/esign/contracts.md; peopleReceipt is optional for deployed non-People eSign responses.

Permission matrix · Actual browser verification and limitations.

Validation: pnpm check, pnpm typecheck, pnpm test (90 passed, 3 optional integrations skipped) and pnpm build; 26 existing lint warnings. Browser checks cover the permission profiles at 320px and 1440px, the shared PDF preview, one fake fee approval, officer assignment, manual ZIP/options and the CIE backend-dependency error. Real CIE hardware, backend completion/delivery/concurrency and a real signed-in OIDC session were not verified. Signatures provenance was tested through its parser, not against a real eSign backend.

Merge audit, 22 October 2026

Inherited the latest #97 census follow-up. Backend #83 implements the People/receipt bridge and must be merged and deployed first. A receipt delivery retry now reports that delivery was retried and asks the user to check its status; it no longer claims successful email delivery when SMTP may have failed.

Validation: pnpm check, typecheck, test and build pass; 204 tests passed, 3 optional integrations skipped. Browser checks covered People pages at 1440px and 320px. Backend #83 PostgreSQL tests cover durable receipt completion and both signing paths. Real SMTP, Microsoft 365 and physical CIE hardware were not exercised.

The final backend contract includes PoliNetworkOrg/backend#94, which aligns the dedicated admin-removal kind with the concurrent dashboard update and preserves pending-state privacy. Both independent follow-up reviews approved the final alignment.

claude and others added 26 commits October 14, 2026 12:11
Brief, settled decisions, backend contract and phased plan for the People area,
plus the prototype source as a structure and copy reference. The prototype is
excluded from format and lint checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
- New permissions: people:self, people:read, people:write, people:members:read,
  people:members:write, people:appoint.
- people:self alone admits a user to the dashboard; adminMiddleware now requires
  admin:access explicitly so existing reads stay closed to them.
- People middlewares for each scope, and dev-only AGENT_PERMISSIONS and
  AGENT_PERSON to preview restricted roles in agent mode.
- Typed people.* contract (zod) and the agent-mode sample data ported from the
  prototype.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
- People service (Overview, Member register, Admins, Teams, Census, Linking),
  Telegram › Capo Admin and Account › My area / Sign-in & security.
- Sections open by permission, admin:access, or a role on the person's own
  record (Capo Admin, Team Lead); /dashboard redirects pages a user can't open.
- PeopleApi with an agent-mode implementation over the sample data and a
  backend adapter that parses every response with the contract.
- Placeholder routes for every People page; pages land in the next phases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Overview table with role, team, campus, account and census filters, and the
person record with its cards and activity. Adds Add person / Edit profile,
invite, revoke and unlink confirmations, Link account, HR notes and census
answers dialogs. On mobile the Overview cards show a labelled line of role
chips and the account status instead of bare column values.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Status segments, fee filter, search and sort by number, name or admission
date. Add member, Change status and Change member number dialogs, and an
export that confirms before downloading the CSV. The person record gets the
Member card menu, and its "declared member" alert opens Add member in the
register with the person preselected. People dialogs now reload the page
before closing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Admins table with Active / Former scope, campus and year filters and four
quick filters, columns that appear as the table widens and an Open in
Telegram row action. End admin role asks for a reason, and the Direttivo can
appoint, change or end a Capo Admin and set an admin's Capo Admin of
reference, from the list or the record's Admin card. FormDialog gains a
danger submit tone for destructive forms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Teams index with one card per team and every active member in one table;
team pages with Active / Former, columns for the team's own fields and
contacts for readers and the team's Lead. Add to team, Edit team fields
and End membership from the lists and the person record, which also gets an
"Add role" menu. A Team Lead without people:read lands on their own team.
Adds the people.teams.candidates query so Leads can pick a person without
reading every record.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Census list with a progress meter per campaign, and a campaign page with the
answer breakdown, segments and role filter, per-person and bulk reminders,
View answers and Close campaign. Import responses uploads the Forms export
and walks through Review, Duplicates, Telegram and Confirm, skipping steps
with nothing to settle; nothing is saved before the last step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
People › Linking lists the sign-ins the backend couldn't link (Dismiss, or
Resolve with the resolutions that fit each kind and a required reason) and
the pending invites with Resend and Revoke. The Needs review count streams
into the section panel like the open reports count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Telegram › Capo Admin shows the groups of the signed-in Capo Admin's
course with the ones that have no admins flagged, the requests to join
them with Approve and Decline, and the admins of those groups with their
phone and Telegram and links to message them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Account › My area shows the signed-in person's census (pre-filled from last
year, with Confirm and I'm leaving), roles, people to contact, profile with
Request a correction, consents with Revoke and their team roster. A first
sign-in asks "Is this you?" with the matched record; a sign-in with no record
can ask to be added. The Sign-in & security page now uses its section title.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Adds People page notes to docs/design.md, a People paragraph to the README
and the People architecture line to the agent instructions, removes the
page placeholder now that every route is built, and records what is still
unverified in docs/people/plan.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Resolves the section pills conflict in panel.tsx: keeps main's scroll
observer for the current pill and this branch's Needs review count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Constrain table chips, use custom date pickers on every viewport and restore
calendar keyboard focus. Resolve the academic year centrally and read census
deadlines from campaign data.

Support all led teams and active rosters with scoped deep links. Gate People
behind explicit backend readiness, validate real calendar dates and stop
closed sample campaigns from accepting answers. Update the backend contract
and rollout documentation, add regression coverage and clear lint warnings.
Restore the original server configuration, authorization, route loaders and
People contract/data behavior, as requested. Keep custom date fields, table
chip constraints and calendar keyboard focus.

Fit the calendar to narrow screens and retain readable mobile navigation
labels. Reserve the device safe area below the bottom bar. Limit added tests
to calendar values used by the UI picker.
- Capo Admin approve/decline only reach requests in the caller's own scope.
- An unconfirmed or rejected match acts as a person with no record; confirmMatch
  refuses after a rejection.
- The member export neutralizes cells that spreadsheets would run as formulas.
- Ending a lead's team membership needs people:appoint, and the menus hide it.
- People procedures outside self-service need admin:access in the dashboard too.
- Input schemas bound team fields, import decisions, census lists, correction
  fields and Telegram usernames; the forms validate usernames the same way.
- docs/people/contract.md lists these as backend rules, plus content checks for
  the census import.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Runs the agent-mode People API under Node and checks the rules bd21599 added:
only the group's Capo Admin reaches a join request, an unconfirmed match gets
none of the record's powers, ending a Lead role needs people:appoint, and the
member export keeps every cell as text. Each test fails on the code before
bd21599. endTeamMembership's comment now states the people:appoint rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Without people:members:read, people rows and records carry member: null and
only the new isMember flag; the viewer's own record keeps its details. The
person page shows a plain Member card in that case, Overview shows "Yes" in
place of the number, and the contract documents the rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Below the shell breakpoint RecordHeader actions and InlineAlert actions take
their own line, so a 320px screen no longer squeezes the title, meta or
message into a narrow column. Team cards put the missing census answers on
their own line instead of wrapping mid-phrase.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Below the shell breakpoint only the current step shows its label, so the five
steps no longer wrap onto a second line that starts with a connector.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
- KeyValueList puts each key above its value in containers narrower than
  352px, so emails and course names get the full card width on phones.
- SectionCard wraps its header action under the title instead of squeezing
  the title onto two lines.
- People rows move their badges and buttons under the text when both don't
  fit, so titles like "Photo and video" no longer break word by word.
- The My area team roster marks the viewer with a muted "(you)" that stays
  out of the avatar initials.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Below the shell breakpoint the five member statuses become a Status menu
beside the fee filter, like the census Answer filter, instead of a segmented
control clipped mid-word. Admin cards say "No groups" rather than "0 groups".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
The name and date keep at least 160px, so on narrow cards Decline and Approve
move to their own line instead of breaking the date over two lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Member emails now need people:members:read, so a Team Lead saw their own
Microsoft 365 address but the course for everyone else. Team tables show the
course for every row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Below the shell breakpoint Confirm, I'm leaving and Cancel stack full width
with Confirm on top, like dialog footers, instead of leaving Confirm alone on
a second line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 45 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 20bba25d-7492-48d9-a332-d43ea80b3a90
📥 Commits

Reviewing files that changed from the base of the PR and between 99c2e8e and 8ea06aa.

📒 Files selected for processing: 49
  • AGENTS.md
  • README.md
  • docs/design.md
  • docs/esign/contracts.md
  • docs/people/README.md
  • docs/people/contract.md
  • docs/people/decisions.md
  • docs/people/fees.md
  • docs/people/plan.md
  • docs/people/verification.md
  • src/components/shell/mobile-nav.tsx
  • src/components/shell/nav.ts
  • src/features/esign/batch-page.tsx
  • src/features/esign/esign.functions.ts
  • src/features/esign/pdf-viewer.tsx
  • src/features/esign/receipt-request-link.tsx
  • src/features/esign/receipt-source.ts
  • src/features/esign/request-page.tsx
  • src/features/esign/requests-page.tsx
  • src/features/people/fee-dialogs.tsx
  • src/features/people/member-dialogs.tsx
  • src/features/people/members-page.tsx
  • src/features/people/my-area-page.tsx
  • src/features/people/my-fee-card.tsx
  • src/features/people/people-fees.functions.ts
  • src/features/people/people-fees.ts
  • src/features/people/people-files.ts
  • src/features/people/people-format.ts
  • src/features/people/people-hooks.ts
  • src/features/people/people-receipts.functions.ts
  • src/features/people/people-self.functions.ts
  • src/features/people/people.api.server.ts
  • src/features/people/people.contract.ts
  • src/features/people/people.fake.server.ts
  • src/features/people/people.fixtures.server.ts
  • src/features/people/person-page.tsx
  • src/features/people/receipt-dialogs.tsx
  • src/features/people/receipt-files.server.ts
  • src/features/people/receipts-page.tsx
  • src/lib/api/types.ts
  • src/routeTree.gen.ts
  • src/routes/dashboard.tsx
  • src/routes/dashboard/people/receipts.tsx
  • src/server/auth.middleware.ts
  • src/server/permissions.ts
  • tests/esign-pdf-lifecycle.test.mjs
  • tests/people-esign.test.mjs
  • tests/people-fees.test.mjs
  • tests/server-security.test.mjs

Walkthrough

The PR adds People fee and receipt workflows, including member uploads, fee review and payment actions, receipt issuance, and officer signing tools. It adds contracts, server functions, a receipts route, agent-mode data, and shared UI controls. The production People backend bridge for receipt signing remains pending.

Changes

People fees and receipts

Layer / File(s) Summary
Fee and receipt contracts and backend workflows
src/features/people/people.contract.ts, src/features/people/people.api.server.ts, src/features/people/people.fake.server.ts, src/features/people/people.fixtures.server.ts, src/server/*, docs/people/*, tests/people-fees.test.mjs
The People data contract and server APIs now cover fees, receipts, permissions, member uploads, payment actions, and receipt handling. The fake API and fixtures implement and seed the workflows. Documentation describes the contract and marks the production signing bridge as pending.
Member fees and fee review
src/features/people/members-page.tsx, src/features/people/person-page.tsx, src/features/people/my-fee-card.tsx, src/features/people/fee-dialogs.tsx, src/features/people/people-self.functions.ts
Member and person views now show fee data and expose receipt upload, fee review, payment, reminders, and receipt download actions. The dialogs handle receipt preview, approval or rejection, and manual payment.
Receipt queue and signing
src/features/people/receipts-page.tsx, src/features/people/receipt-dialogs.tsx, src/routes/dashboard/people/receipts.tsx, src/components/shell/nav.ts, src/routes/dashboard.tsx, src/features/people/people-receipts.functions.ts, docs/esign/contracts.md, tests/people-esign.test.mjs
The Receipts route adds filtering, signing preparation, download and upload options, email retry, and void actions. Navigation shows the officer’s pending receipt count. Signing preparation calls the People API; the production backend bridge remains pending.
Shared UI controls and People page updates
src/components/primitives/*, src/features/people/*, src/features/guides/guide-dialogs.tsx, src/features/azure/members-page.tsx, src/lib/date-only.ts, docs/design.md, tests/date-only.test.mjs
Shared controls now include date, file, filter, select, and radio-card components. People pages use shared loading, dialog, and action-menu patterns; academic-year labels now derive from the date. The design guidance and tests reflect these changes.

Sequence Diagram(s)

sequenceDiagram
  participant Member
  participant MyFeeCard
  participant uploadMyTransferReceipt
  participant PeopleApi
  participant PeopleBackend
  Member->>MyFeeCard: select transfer receipt, date, and amount
  MyFeeCard->>uploadMyTransferReceipt: submit transfer details and file
  uploadMyTransferReceipt->>PeopleApi: upload file and parsed transfer data
  PeopleApi->>PeopleBackend: forward transfer receipt request
  PeopleBackend-->>PeopleApi: upload result
  PeopleApi-->>uploadMyTransferReceipt: upload result
  uploadMyTransferReceipt-->>MyFeeCard: completion response
  MyFeeCard-->>Member: refresh fee view
Loading

Priority: ➖ Normal

Change: Feature

Merge Risk: 🔵 Low · up to 99c2e

The fee and receipt workflow is mergeable with small follow-ups. On mobile, a receipt still waiting for the other officer reads as already signed. Closing a PDF preview quickly can leave a background PDF worker running until the page reloads. Neither blocks the workflow.

Pre-merge checks: Passed 3 · Inconclusive 1

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
Docstring Coverage Inconclusive Docstring coverage is 55.14% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 185 functions across 50 files. (15 skippe… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 3 passed
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Title check Passed The title clearly summarizes the main changes: adding People fee renewal and signed-receipt workflows.
Full details: Docstring Coverage

Explanation

Docstring coverage is 55.14% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 185 functions across 50 files. (15 skipped: 9 unsupported, 6 over the file limit.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Diubii

Diubii commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Ho fatto una passata su tutta l'area People (#97 + questa PR) seguendo le tue note: bug, ripetizioni, menu strani e controlli nativi del browser. Tutto in e289666; backend e auth non li ho toccati.

Bug

  • "Add role" nella scheda persona poteva aprire un menu vuoto (solo people:members:write su una persona già socia). Ora con un solo ruolo disponibile è un pulsante semplice.
  • Menu vuoti/strani nelle righe: nei Teams un Team Lead senza people:appoint apriva un ⋮ vuoto; nel registro soci il menu poteva iniziare con un separatore; "Review receipt" compariva per gli ex soci come icona ma non nel menu.
  • todayIso() usava la data UTC: dopo mezzanotte le date di default (pagamento, bonifico, isExpired) erano del giorno prima. Ora usa la data locale (dateOnlyValue).
  • Anno corrente scritto a mano (CURRENT_YEAR = "2026/27", "Open until 31 Oct 2026"): ora si calcola dalla data con currentYear(), con l'anno accademico che parte il 1° settembre. Se la regola è un'altra si cambia in un punto solo (academicYear in src/lib/date-only.ts, con test).
  • Upload signed: il pulsante diceva "Add other files" ma sostituiva la lista → "Choose other files".
  • My area mostrava "Signed " senza data; "Use @username" si poteva cliccare due volte; il fake salvava l'email personale vuota come "" invece di null.

Menu e controlli nativi

  • Radio nativi (<input type="radio"> in 7 punti) → nuovi RadioCardGroup/RadioCard su Base UI, con nome accessibile e frecce.
  • Anteprima PDF in Review receipt: niente più <iframe> (su Android non mostra nulla, su iOS solo la prima pagina). Le pagine sono disegnate con pdf.js (pdfjs-dist, caricato solo all'apertura del dialog).
  • title= nativo → Hint; <input type="file"> scritto a mano → FilePickerButton (estratto da FileButton).
  • Date picker: l'anno andava dal 1900 (137 voci) → ultimi 10 anni + il prossimo. DateField è ora un primitive e lo usa anche il dialog delle guide, che aveva una <select> nativa nascosta.
  • Azioni di riga (ActionMenu): nessuna azione → slot vuoto, una sola → icona, due o più → ⋮ con le distruttive in fondo. Tolto "Open record" dai menu, perché la riga è già un link.
  • Header: Export register è un'icona fissa accanto ad Add member (non più un ⋮ con una sola voce); il censimento ha Close campaign come icona.

Ripetizioni / TS

  • errorMessage in people-hooks ora si appoggia a @/lib/errors e accetta qualsiasi errore: spariti ~33 caught instanceof Error ? … : …. I messaggi seguono "Couldn't {verb} {object}".
  • useDialog/useDialogState + useOpenGeneration al posto dei 23 contatori setXKey(v => v + 1); useLoaded sostituisce 6 useEffect di caricamento identici; useFileDownload 3 handler di download; saveBlob sostituisce il download() dell'export (che revocava l'URL subito).
  • SelectField, FilterMenu, ToggleFilter spostati nei primitive (il toggle era copiato da Microsoft 365 › Members, che ora lo usa).
  • Stati del consenso foto in una tabella PHOTO_CONSENT invece di ternari ripetuti; plurali con pluralize.

Lasciato com'è

  • PeopleApi resta definito tre volte (tipo, client, fake) su un client tRPC non tipizzato: va rifatto comunque quando il backend esporrà people.* nel router.

Docs aggiornate (docs/design.md, docs/people/*). pnpm check, typecheck, test (60/60) e build passano; provato in agent mode su desktop e mobile.

🤖 Generated with Claude Code

@Diubii
Diubii added this pull request to stack #101 October 17, 2026 00:40
@viganogabriele
viganogabriele force-pushed the claude/vigilant-euler-gkle0o branch from 9d0c60b to 287f5ff Compare October 18, 2026 13:11
claude and others added 17 commits October 18, 2026 13:25
…er members

- The fake resolves the invited record from the token, checks it is pending and
  unexpired, and refuses a caller who already has a linked record. Links survive
  a dev server restart and are printed when an invite is sent, so the invite flow
  can be previewed with AGENT_PERSON=none.
- A former member who declares membership in the census gets "Change status"
  instead of "Add member", which the register refuses.
- Drop the Receipts check from the PR #97 verification notes: Receipts are not in
  this PR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
- A Lead without people:read gets contacts only for the team's current
  members in people.teams.list; documented under Backend rules, with a test.
- The contract's procedure table uses PersonRow, as the code does, and lists
  people.me.roles.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
…claude/eager-mayer-bsom7v

# Conflicts:
#	docs/people/contract.md
#	src/features/people/people.fake.server.ts
Keep the updated People contract and access rules from #97 while preserving #100 fee and receipt workflows. Require CIE preparation responses to match the selected receipt IDs and order exactly.
…claude/vigilant-euler-gkle0o

# Conflicts:
#	docs/design.md
#	src/features/esign/batch-page.tsx
#	src/features/esign/esign.functions.ts
#	src/features/esign/pdf-viewer.tsx
#	src/features/esign/request-page.tsx
#	src/features/esign/requests-page.tsx
@lorenzocorallo lorenzocorallo changed the title feat(people): add fee renewals and signed receipts feat(people): add fee renewal and signed receipts Oct 22, 2026
claude and others added 5 commits October 22, 2026 20:11
…cy kind

Pending census group removals used the needs-review kind, so the person page
offered "Open Linking" for them, and My area recognised them by matching the
message text. They are now `admin-removal`, which has no Linking action and is
checked by kind. A test covers it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ti91VKqKpduLAF376TunMn
Base automatically changed from claude/eager-mayer-bsom7v to main October 22, 2026 20:20

@lorenzocorallo lorenzocorallo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technical review completed across Standards and Spec with independent review rounds. No outstanding actionable findings. Verified fee permissions, officer selection, receipt/eSign provenance and the shared signing flow against backend #83. Receipt retry now reports an attempt without claiming SMTP success. Inherits the final #97 census/privacy fixes. Validation: check, typecheck, 204 tests and production build pass; 3 optional integrations skipped. Backend PostgreSQL tests cover durable signature completion and manual/CIE paths. Live Microsoft 365, production SMTP and physical CIE hardware were outside this local validation. Administrative bypass of human approval is explicitly requested by the user.

@lorenzocorallo
lorenzocorallo merged commit b65949d into main Oct 22, 2026
2 checks passed
@lorenzocorallo
lorenzocorallo deleted the claude/vigilant-euler-gkle0o branch October 22, 2026 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants