mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-14 00:01:03 +00:00
29816f81a9
- The upload posted its FormData through the client's JSON default, so the form went as JSON and the server saw no file (400). It goes through postMultipart now, like every other upload. - reservation-origin.ts becomes reservation-origin.contract.ts: the booking import sets an origin, and a contract is what another domain may import. - CI: the client's strict type check holds the whole program with strict checks and outgrew the default ~4 GB heap; it gets 8 GB like the server's.
50 lines
2.8 KiB
TypeScript
50 lines
2.8 KiB
TypeScript
import apiClient, { postMultipart } from './client';
|
|
|
|
/**
|
|
* The booking mail import (server nest/mail-ingest): the person's settings and
|
|
* forwarding address, the inbox of bookings read from forwarded mails, and the
|
|
* actions on them. Answers come back unparsed; store/mailIngestStore.ts checks
|
|
* them against the shared contracts. apiClient puts an idempotency key on every
|
|
* write, so a request sent again on a flaky connection acts once.
|
|
*/
|
|
const data = (response: { data: unknown }) => response.data;
|
|
|
|
export type MailIngestAction = 'apply' | 'move' | 'file' | 'undo' | 'discard';
|
|
|
|
export const mailIngestApi = {
|
|
// The admin's view: how the import runs, in counts only, and whether the transport reaches its mail now.
|
|
adminStatus: (): Promise<unknown> => apiClient.get('/admin/mail-ingest/status').then(data),
|
|
adminTest: (): Promise<unknown> => apiClient.post('/admin/mail-ingest/test', {}).then(data),
|
|
/** The stored transport fields, passwords masked, from the admin's app settings. */
|
|
adminSettings: (): Promise<unknown> => apiClient.get('/auth/app-settings').then(data),
|
|
saveAdminSettings: (patch: Record<string, string | boolean>): Promise<unknown> =>
|
|
apiClient.put('/auth/app-settings', patch).then(data),
|
|
|
|
settings: (): Promise<unknown> => apiClient.get('/mail-ingest/settings').then(data),
|
|
updateSettings: (body: { enabled?: boolean; ai_enabled?: boolean; auto_add?: boolean }): Promise<unknown> =>
|
|
apiClient.patch('/mail-ingest/settings', body).then(data),
|
|
renewAddress: (): Promise<unknown> => apiClient.post('/mail-ingest/address/renew', {}).then(data),
|
|
|
|
tripAddress: (tripId: number): Promise<unknown> => apiClient.get(`/trips/${tripId}/mail-ingest/address`).then(data),
|
|
createTripAddress: (tripId: number): Promise<unknown> =>
|
|
apiClient.post(`/trips/${tripId}/mail-ingest/address`, {}).then(data),
|
|
|
|
inbox: (params: { status?: 'open' | 'resolved'; before?: number; limit?: number }): Promise<unknown> =>
|
|
apiClient.get('/mail-ingest/inbox', { params }).then(data),
|
|
inboxCount: (): Promise<unknown> => apiClient.get('/mail-ingest/inbox/count').then(data),
|
|
preview: (messageId: number): Promise<unknown> =>
|
|
apiClient.get(`/mail-ingest/messages/${messageId}/preview`).then(data),
|
|
prefill: (candidateId: number): Promise<unknown> =>
|
|
apiClient.get(`/mail-ingest/candidates/${candidateId}/prefill`).then(data),
|
|
|
|
act: (candidateId: number, action: MailIngestAction, body: Record<string, unknown> = {}): Promise<unknown> =>
|
|
apiClient.post(`/mail-ingest/candidates/${candidateId}/${action}`, body).then(data),
|
|
|
|
upload: (file: File): Promise<unknown> => {
|
|
const form = new FormData();
|
|
form.append('file', file);
|
|
// As multipart: under the client's default JSON content type the form went as JSON, without the file.
|
|
return postMultipart('/mail-ingest/upload', form);
|
|
},
|
|
};
|