eletrotupi / tcc/ commit / 8091581

frontend: map types and new API changes

Pedro Lucas Porcellis porcellis@eletrotupi.com 1 month ago 80915813b37430b398e2f0437b36129477f1c162
Parents: ce66d00
3 file(s) changed
  • frontend/lib/api/client.ts +87 -0
  • frontend/lib/api/index.ts +16 -0
  • frontend/lib/api/types.ts +136 -0
frontend/lib/api/client.ts
1 1
import * as SecureStore from "expo-secure-store";
2 2
import {
3 3
  User,
4 4
  AuthResponse,
5 5
  VerifyTokenResponse,
▸ 16 unchanged lines
22 22
  PaginatedResponse,
23 23
  InsightType,
24 24
  InsightPeriod,
25 25
  InsightMetadata,
26 26
  Insight,
27 +
  MedicineRegimen,
28 +
  MedicineRegimenResponse,
29 +
  CreateMedicineRegimenPayload,
30 +
  UpdateMedicineRegimenPayload,
31 +
  CareAction,
32 +
  CareActionType,
33 +
  CareActionResponse,
34 +
  CreateCareActionPayload,
35 +
  TriggerMoodLink,
36 +
  LinkMoodPayload,
27 37
} from "@/lib/api/types";
28 38

29 39
const API_BASE_URL = process.env.EXPO_PUBLIC_API_BASE_URL;
30 40
const TOKEN_KEY = process.env.EXPO_PUBLIC_TOKEN_KEY;
31 41

▸ 283 unchanged lines
315 325
    if (filters?.period) query.set("period", filters.period);
316 326
    if (filters?.limit) query.set("limit", String(filters.limit));
317 327

318 328
    const qs = query.toString();
319 329
    return this.request(`/insights${qs ? `?${qs}` : ""}`);
330 +
  }
331 +

332 +
  // Medicine Regimens
333 +
  async getMedicineRegimens(): Promise<{ regimens: MedicineRegimen[] }> {
334 +
    return this.request('/medicine-regimens');
335 +
  }
336 +

337 +
  async createMedicineRegimen(
338 +
    regimen: CreateMedicineRegimenPayload
339 +
  ): Promise<MedicineRegimenResponse> {
340 +
    return this.request('/medicine-regimens', {
341 +
      method: 'POST',
342 +
      body: JSON.stringify({ regimen })
343 +
    });
344 +
  }
345 +

346 +
  async updateMedicineRegimen(
347 +
    id: string,
348 +
    regimen: UpdateMedicineRegimenPayload
349 +
  ): Promise<MedicineRegimenResponse> {
350 +
    return this.request(`/medicine-regimens/${id}`, {
351 +
      method: 'PATCH',
352 +
      body: JSON.stringify({ regimen })
353 +
    });
354 +
  }
355 +

356 +
  async deleteMedicineRegimen(id: string): Promise<void> {
357 +
    return this.request(`/medicine-regimens/${id}`, { method: 'DELETE' });
358 +
  }
359 +

360 +
  // Care Actions
361 +
  async getCareActions(
362 +
    params?: {
363 +
      type?: CareActionType;
364 +
      from?: string;
365 +
      to?: string;
366 +
      page?: number;
367 +
      limit?: number
368 +
    }): Promise<PaginatedResponse<CareAction>> {
369 +
    const query = new URLSearchParams();
370 +
    if (params?.type) query.set('type', params.type);
371 +
    if (params?.from) query.set('from', params.from);
372 +
    if (params?.to) query.set('to', params.to);
373 +
    if (params?.page) query.set('page', String(params.page));
374 +
    if (params?.limit) query.set('limit', String(params.limit));
375 +

376 +
    const qs = query.toString();
377 +

378 +
    return this.request(`/care-actions${qs ? `?${qs}` : ''}`);
379 +
  }
380 +

381 +
  async getCareAction(id: string): Promise<CareAction> {
382 +
    return this.request(`/care-actions/${id}`);
383 +
  }
384 +

385 +
  async createCareAction(payload: CreateCareActionPayload): Promise<CareActionResponse> {
386 +
    return this.request('/care-actions', {
387 +
      method: 'POST', body: JSON.stringify({ careAction: payload })
388 +
    });
389 +
  }
390 +

391 +
  async deleteCareAction(id: string): Promise<void> {
392 +
    return this.request(`/care-actions/${id}`, { method: 'DELETE' });
393 +
  }
394 +

395 +
  // Trigger to Mood linking
396 +
  async linkMoodToTrigger(
397 +
    triggerId: string, payload: LinkMoodPayload
398 +
  ): Promise<{ link: TriggerMoodLink }> {
399 +
    return this.request(`/triggers/${triggerId}/link-mood`, {
400 +
      method: 'POST',
401 +
      body: JSON.stringify(payload)
402 +
    });
403 +
  }
404 +

405 +
  async unlinkMoodFromTrigger(triggerId: string, moodId: string): Promise<void> {
406 +
    return this.request(`/triggers/${triggerId}/link-mood/${moodId}`, { method: 'DELETE' });
320 407
  }
321 408
}
322 409

323 410
export const apiClient = new ApiClient();
frontend/lib/api/index.ts
1 1
export { apiClient } from "@/lib/api/client";
2 2

3 3
export type {
4 4
  User,
5 5
  AuthResponse,
▸ 12 unchanged lines
18 18
  CreateTriggerPayload,
19 19
  // Insights
20 20
  Insight,
21 21
  InsightType,
22 22
  InsightPeriod,
23 +
  // Care Actions
24 +
  CareAction,
25 +
  CareActionType,
26 +
  CareActionResponse,
27 +
  CreateCareActionPayload,
28 +
  CreateCareActionMedicinePayload,
29 +
  CreateCareActionAppointmentPayload,
30 +
  CreateCareActionActivityPayload,
31 +
  // Medicine Regimens
32 +
  MedicineRegimen,
33 +
  MedicineRegimenResponse,
34 +
  CreateMedicineRegimenPayload,
35 +
  UpdateMedicineRegimenPayload,
36 +
  // Trigger-Mood linking
37 +
  TriggerMoodLink,
38 +
  LinkMoodPayload,
23 39
} from "@/lib/api/types";
frontend/lib/api/types.ts
1 1
export interface User {
2 2
  id: number;
3 3
  email: string;
4 4
  firstName: string;
5 5
  lastName?: string;
▸ 200 unchanged lines
206 206
}
207 207

208 208
export interface TriggerResponse {
209 209
  trigger: Trigger;
210 210
}
211 +

212 +
// Care Actions
213 +
export type CareActionType = 'MEDICINE' | 'APPOINTMENT' | 'ACTIVITY';
214 +
export type AppointmentType =
215 +
  | 'ANALYST'
216 +
  | 'PSYCHIATRIST'
217 +
  | 'GP'
218 +
  | 'NUTRITIONIST'
219 +
  | 'PHYSIOTHERAPIST'
220 +
  | 'OTHER';
221 +

222 +
export type ActivityType =
223 +
  | 'WALK'
224 +
  | 'YOGA'
225 +
  | 'GYM'
226 +
  | 'MEDITATION'
227 +
  | 'SOCIAL'
228 +
  | 'CREATIVE'
229 +
  | 'OTHER';
230 +

231 +
  export type MedicinePeriodicity =
232 +
  | 'ONCE'
233 +
  | 'DAILY'
234 +
  | 'TWICE_DAILY'
235 +
  | 'THREE_TIMES_DAILY'
236 +
  | 'WEEKLY'
237 +
  | 'BIWEEKLY'
238 +
  | 'MONTHLY';
239 +

240 +
export interface MedicineRegimen {
241 +
  id: number;
242 +
  name: string;
243 +
  dosage: string;
244 +
  periodicity: MedicinePeriodicity;
245 +
  scheduledAt?: string;
246 +
  active: boolean;
247 +
  userId: number;
248 +
  createdAt: Date;
249 +
  updatedAt: Date;
250 +
}
251 +

252 +
export interface MedicineLog {
253 +
  id: number;
254 +
  regimenId?: number;
255 +
  careActionId: number;
256 +
  takenAt: Date;
257 +
}
258 +

259 +
export interface AppointmentDetail {
260 +
  id: number;
261 +
  careActionId: number;
262 +
  type: AppointmentType;
263 +
  duration: number;
264 +
  note?: string;
265 +
}
266 +

267 +
export interface ActivityDetail {
268 +
  id: number;
269 +
  careActionId: number;
270 +
  type: ActivityType;
271 +
  duration?: number;
272 +
}
273 +

274 +
export interface CareAction {
275 +
  id: number;
276 +
  type: CareActionType;
277 +
  moment: Date;
278 +
  userId: number;
279 +
  triggerId?: number;
280 +
  moodId?: number;
281 +
  medicineLog?: MedicineLog;
282 +
  appointment?: AppointmentDetail;
283 +
  activity?: ActivityDetail;
284 +
  createdAt: Date;
285 +
  updatedAt: Date;
286 +
}
287 +

288 +
export interface TriggerMoodLink {
289 +
  id: number;
290 +
  triggerId: number;
291 +
  moodId: number;
292 +
  perceivedImpact: number;
293 +
  linkedAt: Date;
294 +
}
295 +

296 +
// Payloads
297 +
export interface CreateMedicineRegimenPayload {
298 +
  name: string;
299 +
  dosage: string;
300 +
  periodicity: MedicinePeriodicity;
301 +
  scheduledAt?: string;
302 +
}
303 +

304 +
export interface UpdateMedicineRegimenPayload extends Partial<CreateMedicineRegimenPayload> {
305 +
  active?: boolean;
306 +
}
307 +

308 +
export interface CreateCareActionMedicinePayload {
309 +
  type: 'MEDICINE';
310 +
  moment: Date;
311 +
  regimenId?: number;
312 +
  medicine?: {
313 +
    name: string;
314 +
    dosage: string;
315 +
    periodicity: MedicinePeriodicity;
316 +
    scheduledAt?: string
317 +
  };
318 +
  triggerId?: number;
319 +
  moodId?: number;
320 +
}
321 +

322 +
export interface CreateCareActionAppointmentPayload {
323 +
  type: 'APPOINTMENT';
324 +
  moment: Date;
325 +
  appointment: { type: AppointmentType; duration: number; note?: string };
326 +
  triggerId?: number;
327 +
  moodId?: number;
328 +
}
329 +

330 +
export interface CreateCareActionActivityPayload {
331 +
  type: 'ACTIVITY';
332 +
  moment: Date;
333 +
  activity: { type: ActivityType; duration?: number };
334 +
  triggerId?: number;
335 +
  moodId?: number;
336 +
}
337 +

338 +
export type CreateCareActionPayload =
339 +
  | CreateCareActionMedicinePayload
340 +
  | CreateCareActionAppointmentPayload
341 +
  | CreateCareActionActivityPayload;
342 +

343 +
export interface CareActionResponse { careAction: CareAction; }
344 +
export interface MedicineRegimenResponse { regimen: MedicineRegimen; }
345 +

346 +
export interface LinkMoodPayload { moodId: number; perceivedImpact: number; }