Skip to content
29 linesCodeBlameRaw
1/**
2 * Access requests' limit: a person asks for a folio at most once a day,
3 * however many times they press the button. One row per person and folio
4 * (`folio_access_requests`) holds when they last asked.
5 */
6
7/** How long a person waits before asking for the same folio again. */
8export const REQUEST_EVERY_MS = 24 * 60 * 60 * 1000;
9/** The most people one request goes to: the owner and people with full access. */
10export const REQUEST_RECIPIENTS = 20;
11
12/**
13 * Records a request when the person may ask now, in one statement so two
14 * presses at once send one request. True: send it. False: they asked for
15 * this folio within the last day.
16 */
17export async function claimAccessRequest(db: D1Database, folioId: string, userId: string, at = new Date()): Promise<boolean> {
18 const when = at.toISOString();
19 const since = new Date(at.getTime() - REQUEST_EVERY_MS).toISOString();
20 const row = await db
21 .prepare(
22 `INSERT INTO folio_access_requests (folio_id, user_id, requested_at) VALUES (?, ?, ?)
23 ON CONFLICT (folio_id, user_id) DO UPDATE SET requested_at = excluded.requested_at WHERE folio_access_requests.requested_at <= ?
24 RETURNING requested_at`,
25 )
26 .bind(folioId, userId, when, since)
27 .first<{ requested_at: string }>();
28 return row !== null;
29}