actual state

This commit is contained in:
2026-07-29 14:50:11 -05:00
parent c9202d0b80
commit 96a37a495e
10 changed files with 561 additions and 117 deletions

View File

@@ -201,6 +201,7 @@ directory aborts the scan with an error naming the path.
| POST | /api/nda-inbox/import | import one request into buyer/contact/nda(/deal) | yes |
| POST | /api/nda-inbox/sync | background: re-check pending NDAs + stale mirror rows | yes |
| POST | /api/nda-inbox/backfill-fields | retrofit form fields onto signed rounds | yes |
| DELETE | /api/deals/:id | delete a deal; notes/todos cascade | yes |
| GET | /api/ndas/:id/file | stream the filed NDA PDF (Range + ETag) | yes |
Everything except health, staff (GET+POST) and login requires the session
@@ -307,6 +308,28 @@ it is never committed and never logged.
Only requests whose title starts with **`Buyer Forms - NDA`** are considered.
**The template was renamed around 2026-06-29.** Requests created before that
are titled `Buyer Forms -<Name> - <Business>`, without the ` - NDA`. The
refresh therefore runs **two legs**:
| leg | query | when |
| --- | --- | --- |
| current | `title:"Buyer Forms - NDA" AND created:{<cutoff> TO *}` | always |
| pre-rename | `title:"Buyer Forms" AND created:{<cutoff> TO 2026-06-30}` | only when the window starts before `RENAME_DATE` |
Both feed the same upsert, so the inbox needs no notion of the two formats —
rows are rows. An incremental refresh never pays for the second leg: its
cutoff is days old, well past the rename.
The legacy query is deliberately **`Buyer Forms`, not `Buyer Forms -`**. The
API does not treat the trailing punctuation as part of the phrase: with the
hyphen it returns 70 requests for May/June, without it 535, and ~87% of the
wider set are genuine pre-rename NDAs. Precision comes from the code-side
safety net instead — `/^Buyer Forms -(?!.*NDA)/` plus a signer — which is why
the loose phrase is safe here. Unbounded it would not be: `title:"Buyer Forms"`
matches 11,877 of the account's 13,264 requests, so the date bound is what
makes it selective.
**The inbox is DB-backed.** Proxying the list endpoint on every view mount did
not survive contact with the real account: 700+ requests in a 90-day window
means 78 paged calls, ~74s of latency, throttling (Dropbox answers `409` as
@@ -317,7 +340,17 @@ are mirrored into `ds_request` by a background task, and
unaffected by tab switches. It returns the same per-request shape as before
(status, signer, `imported`, `known_buyer` by exact normalised e-mail, up to
five `business_suggestions` by word overlap with the title remainder) plus
`last_refresh_at` and `refresh_state`.
`last_refresh_at`, `refresh_state` and `covers_from`.
* Filtering is **DB-side**: `?status=pending|signed|declined` and `?q=` over
signer name and e-mail. The per-status counts describe the whole matching
set (search applied, status not), so the chips stay meaningful while one is
active — the same rule the business and buyer lists follow.
* `covers_from` is how far back the mirror actually reaches. A walk stopped by
the `MAX_PAGES` cap covers less than it was asked for, so it records the
oldest date it got to and the inbox says "showing data from …" instead of
presenting a short list as complete. Coverage only ever widens: an
incremental walk reaching back two days does not un-mirror what a full reload
fetched last week.
* `POST /api/nda-inbox/refresh` starts the walk and returns `202` immediately,
or `409` when one is already running — the slot is claimed with a conditional
upsert on `app_meta`, so two clicks cannot start two walks. A `running` state