Add additional lint rules
This commit is contained in:
parent
02d782c3da
commit
420b18eb78
67 changed files with 3686 additions and 1415 deletions
|
|
@ -13,17 +13,17 @@ import {
|
|||
RefillListListResponseSchema,
|
||||
AddToCabinetResponseSchema,
|
||||
StoreComparisonItemSchema,
|
||||
type CreateRefillListInput,
|
||||
type UpdateRefillListInput,
|
||||
type UpdateRefillListItemInput,
|
||||
type RefillListQueryInput,
|
||||
} from '@meshitrack/shared';
|
||||
import { RefillsRepository } from './refills.repository.js';
|
||||
import { RefillsService } from './refills.service.js';
|
||||
import type { RefillListDocument } from '../../schemas/refill-list.schema.js';
|
||||
|
||||
function toIso(v: Date | string | { toISOString: () => string }): string {
|
||||
if (typeof v === 'string') return v;
|
||||
return v.toISOString();
|
||||
}
|
||||
|
||||
type AnyItem = {
|
||||
_id: string | { toString: () => string };
|
||||
interface SerializedRefillListItemResponse {
|
||||
_id: string;
|
||||
medicineId: string;
|
||||
medicineName: string;
|
||||
quantity: number;
|
||||
|
|
@ -31,57 +31,90 @@ type AnyItem = {
|
|||
estimatedPrice?: number;
|
||||
actualPrice?: number;
|
||||
checked: boolean;
|
||||
checkedAt?: Date | string;
|
||||
checkedAt?: string;
|
||||
addedToCabinet: boolean;
|
||||
storeId?: string;
|
||||
notes?: string;
|
||||
};
|
||||
}
|
||||
|
||||
type AnyRefillList = {
|
||||
_id: string | { toString: () => string };
|
||||
interface SerializedRefillListResponse {
|
||||
_id: string;
|
||||
householdId: string;
|
||||
name: string;
|
||||
items: AnyItem[];
|
||||
status: string;
|
||||
items: SerializedRefillListItemResponse[];
|
||||
status: 'active' | 'completed' | 'cancelled';
|
||||
preferredStoreId?: string;
|
||||
totalEstimatedCost?: number;
|
||||
createdBy: string;
|
||||
createdAt: Date | string | { toISOString: () => string };
|
||||
updatedAt: Date | string | { toISOString: () => string };
|
||||
};
|
||||
|
||||
function toItemResponse(rawItem: unknown) {
|
||||
const item = rawItem as AnyItem;
|
||||
return {
|
||||
_id: typeof item._id === 'string' ? item._id : item._id.toString(),
|
||||
medicineId: item.medicineId,
|
||||
medicineName: item.medicineName,
|
||||
quantity: item.quantity,
|
||||
unit: item.unit,
|
||||
...(item.estimatedPrice != null ? { estimatedPrice: item.estimatedPrice } : {}),
|
||||
...(item.actualPrice != null ? { actualPrice: item.actualPrice } : {}),
|
||||
checked: item.checked,
|
||||
...(item.checkedAt != null ? { checkedAt: toIso(item.checkedAt) } : {}),
|
||||
addedToCabinet: item.addedToCabinet,
|
||||
...(item.storeId != null ? { storeId: item.storeId } : {}),
|
||||
...(item.notes != null ? { notes: item.notes } : {}),
|
||||
};
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
function toListResponse(rawDoc: unknown) {
|
||||
const doc = rawDoc as AnyRefillList;
|
||||
return {
|
||||
_id: typeof doc._id === 'string' ? doc._id : doc._id.toString(),
|
||||
function toListResponse(doc: RefillListDocument): SerializedRefillListResponse {
|
||||
const docAny = doc as unknown as {
|
||||
preferredStoreId?: string | null;
|
||||
totalEstimatedCost?: number | null;
|
||||
createdAt?: { toISOString?: () => string } | string;
|
||||
updatedAt?: { toISOString?: () => string } | string;
|
||||
};
|
||||
|
||||
const getIsoStr = (d: { toISOString?: () => string } | string | undefined | null): string => {
|
||||
if (!d) return '';
|
||||
if (typeof d === 'string') return d;
|
||||
if (typeof d.toISOString === 'function') return d.toISOString();
|
||||
return String(d);
|
||||
};
|
||||
|
||||
const response: SerializedRefillListResponse = {
|
||||
_id: doc._id.toString(),
|
||||
householdId: doc.householdId,
|
||||
name: doc.name,
|
||||
items: doc.items.map(toItemResponse),
|
||||
status: doc.status as never,
|
||||
...(doc.preferredStoreId != null ? { preferredStoreId: doc.preferredStoreId } : {}),
|
||||
...(doc.totalEstimatedCost != null ? { totalEstimatedCost: doc.totalEstimatedCost } : {}),
|
||||
items: doc.items.map((item) => {
|
||||
const itemAny = item as unknown as {
|
||||
_id: { toString: () => string };
|
||||
estimatedPrice?: number | null;
|
||||
actualPrice?: number | null;
|
||||
checkedAt?: { toISOString?: () => string } | string | Date;
|
||||
storeId?: string | null;
|
||||
notes?: string | null;
|
||||
};
|
||||
|
||||
const itemResponse: SerializedRefillListItemResponse = {
|
||||
_id: itemAny._id.toString(),
|
||||
medicineId: item.medicineId,
|
||||
medicineName: item.medicineName,
|
||||
quantity: item.quantity,
|
||||
unit: item.unit,
|
||||
checked: item.checked,
|
||||
addedToCabinet: item.addedToCabinet,
|
||||
};
|
||||
|
||||
if (itemAny.estimatedPrice != null) itemResponse.estimatedPrice = itemAny.estimatedPrice;
|
||||
if (itemAny.actualPrice != null) itemResponse.actualPrice = itemAny.actualPrice;
|
||||
if (itemAny.checkedAt) {
|
||||
if (typeof itemAny.checkedAt === 'string') {
|
||||
itemResponse.checkedAt = itemAny.checkedAt;
|
||||
} else if (itemAny.checkedAt instanceof Date) {
|
||||
itemResponse.checkedAt = itemAny.checkedAt.toISOString();
|
||||
} else if (typeof itemAny.checkedAt.toISOString === 'function') {
|
||||
itemResponse.checkedAt = itemAny.checkedAt.toISOString();
|
||||
}
|
||||
}
|
||||
if (itemAny.storeId) itemResponse.storeId = itemAny.storeId;
|
||||
if (itemAny.notes) itemResponse.notes = itemAny.notes;
|
||||
|
||||
return itemResponse;
|
||||
}),
|
||||
status: doc.status as 'active' | 'completed' | 'cancelled',
|
||||
createdBy: doc.createdBy,
|
||||
createdAt: toIso(doc.createdAt),
|
||||
updatedAt: toIso(doc.updatedAt),
|
||||
createdAt: getIsoStr(docAny.createdAt),
|
||||
updatedAt: getIsoStr(docAny.updatedAt),
|
||||
};
|
||||
|
||||
if (docAny.preferredStoreId) response.preferredStoreId = docAny.preferredStoreId;
|
||||
if (docAny.totalEstimatedCost != null) response.totalEstimatedCost = docAny.totalEstimatedCost;
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
declare module '@fastify/awilix' {
|
||||
|
|
@ -111,19 +144,21 @@ export default fp(
|
|||
},
|
||||
handler: async (request, reply) => {
|
||||
const service = fastify.diContainer.resolve('refillsService');
|
||||
const params = request.params as { householdId: string };
|
||||
const query = request.query as { userId?: string; thresholdDays?: number };
|
||||
const alerts = await service.getAlerts(
|
||||
request.params.householdId,
|
||||
request.query.userId ?? request.user.keycloakId,
|
||||
request.query.thresholdDays,
|
||||
params.householdId,
|
||||
query.userId ?? request.user.keycloakId,
|
||||
query.thresholdDays,
|
||||
);
|
||||
return reply.send({
|
||||
data: alerts.map((a) => ({
|
||||
...a,
|
||||
lastKnownPrice: a.lastKnownPrice
|
||||
? { ...a.lastKnownPrice, date: toIso(a.lastKnownPrice.date) }
|
||||
? { ...a.lastKnownPrice, date: a.lastKnownPrice.date.toISOString() }
|
||||
: undefined,
|
||||
cheapestOption: a.cheapestOption
|
||||
? { ...a.cheapestOption, date: toIso(a.cheapestOption.date) }
|
||||
? { ...a.cheapestOption, date: a.cheapestOption.date.toISOString() }
|
||||
: undefined,
|
||||
})),
|
||||
});
|
||||
|
|
@ -140,11 +175,9 @@ export default fp(
|
|||
},
|
||||
handler: async (request, reply) => {
|
||||
const service = fastify.diContainer.resolve('refillsService');
|
||||
const list = await service.createList(
|
||||
request.body,
|
||||
request.params.householdId,
|
||||
request.user.keycloakId,
|
||||
);
|
||||
const params = request.params as { householdId: string };
|
||||
const body = request.body as CreateRefillListInput;
|
||||
const list = await service.createList(body, params.householdId, request.user.keycloakId);
|
||||
return reply.status(201).send(toListResponse(list));
|
||||
},
|
||||
});
|
||||
|
|
@ -159,7 +192,9 @@ export default fp(
|
|||
},
|
||||
handler: async (request, reply) => {
|
||||
const service = fastify.diContainer.resolve('refillsService');
|
||||
const result = await service.list(request.params.householdId, request.query);
|
||||
const params = request.params as { householdId: string };
|
||||
const query = request.query as RefillListQueryInput;
|
||||
const result = await service.list(params.householdId, query);
|
||||
return reply.send({
|
||||
data: result.data.map(toListResponse),
|
||||
pagination: result.pagination,
|
||||
|
|
@ -176,7 +211,8 @@ export default fp(
|
|||
},
|
||||
handler: async (request, reply) => {
|
||||
const service = fastify.diContainer.resolve('refillsService');
|
||||
const list = await service.getById(request.params.id, request.params.householdId);
|
||||
const params = request.params as { householdId: string; id: string };
|
||||
const list = await service.getById(params.id, params.householdId);
|
||||
return reply.send(toListResponse(list));
|
||||
},
|
||||
});
|
||||
|
|
@ -191,11 +227,9 @@ export default fp(
|
|||
},
|
||||
handler: async (request, reply) => {
|
||||
const service = fastify.diContainer.resolve('refillsService');
|
||||
const list = await service.updateList(
|
||||
request.params.id,
|
||||
request.params.householdId,
|
||||
request.body,
|
||||
);
|
||||
const params = request.params as { householdId: string; id: string };
|
||||
const body = request.body as UpdateRefillListInput;
|
||||
const list = await service.updateList(params.id, params.householdId, body);
|
||||
return reply.send(toListResponse(list));
|
||||
},
|
||||
});
|
||||
|
|
@ -210,12 +244,9 @@ export default fp(
|
|||
},
|
||||
handler: async (request, reply) => {
|
||||
const service = fastify.diContainer.resolve('refillsService');
|
||||
const list = await service.updateItem(
|
||||
request.params.id,
|
||||
request.params.householdId,
|
||||
request.params.itemId,
|
||||
request.body,
|
||||
);
|
||||
const params = request.params as { householdId: string; id: string; itemId: string };
|
||||
const body = request.body as UpdateRefillListItemInput;
|
||||
const list = await service.updateItem(params.id, params.householdId, params.itemId, body);
|
||||
return reply.send(toListResponse(list));
|
||||
},
|
||||
});
|
||||
|
|
@ -229,9 +260,10 @@ export default fp(
|
|||
},
|
||||
handler: async (request, reply) => {
|
||||
const service = fastify.diContainer.resolve('refillsService');
|
||||
const params = request.params as { householdId: string; id: string };
|
||||
const result = await service.addToCabinet(
|
||||
request.params.id,
|
||||
request.params.householdId,
|
||||
params.id,
|
||||
params.householdId,
|
||||
request.user.keycloakId,
|
||||
);
|
||||
return reply.send(result);
|
||||
|
|
@ -256,16 +288,14 @@ export default fp(
|
|||
},
|
||||
handler: async (request, reply) => {
|
||||
const service = fastify.diContainer.resolve('refillsService');
|
||||
const comparisons = await service.getStoreComparison(
|
||||
request.params.id,
|
||||
request.params.householdId,
|
||||
);
|
||||
const params = request.params as { householdId: string; id: string };
|
||||
const comparisons = await service.getStoreComparison(params.id, params.householdId);
|
||||
return reply.send({
|
||||
data: comparisons.map((c) => ({
|
||||
medicineId: c.medicineId,
|
||||
storeOptions: c.storeOptions.map((opt) => ({
|
||||
...opt,
|
||||
date: toIso(opt.date),
|
||||
date: opt.date.toISOString(),
|
||||
})),
|
||||
})),
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue