mirror of
https://github.com/hanzoai/captable.git
synced 2026-10-16 14:21:29 +00:00
The cap table is served at /v1/captable, org-scoped from the caller's own bearer. This app kept its own Postgres copy of the same entities, so the two could disagree about who owns what — the reason to move rather than keep both. The tRPC procedures for share classes, equity plans, shares, options, SAFEs and stakeholders now call one client (src/server/captable-api.ts) whose normalizers read either spelling the surface uses and degrade to an honest empty value rather than throwing inside a render. Each procedure keeps the shape it already returned, so no component changed for the move. The bearer rides the encrypted next-auth JWT and is read server-side only; it is never put on `session`, which is served to the browser verbatim. Paperwork stays local — buckets, uploaders, e-sign, data rooms are this app's. Document.shareId/optionId/safeId/convertibleNoteId keep their columns and now hold the id Hanzo Cloud assigned, so they are no longer foreign keys. Creates answer no body, so the new row is found by the natural key each write already enforces unique: certificateId, grantId, publicId. The public REST routes for shares and stakeholders are removed. They were a second write path over the same data, they authenticate with an app-issued API key that carries no IAM principal to present upstream, and one of them declared the stakeholder path — shadowing the real stakeholder PATCH, so PATCH on a share never existed. api.hanzo.ai/v1/captable is the public cap-table API. Two surfaces are left honest rather than faked: equityPlan.update refuses, because the backend serves no update route for plans; company.getCompany stays local, because /v1/captable/company carries six fields and that read feeds a form needing fourteen.