adding weight edits
This commit is contained in:
@@ -64,6 +64,7 @@ import {
|
||||
updateBird,
|
||||
updateMemorialReminderPreference,
|
||||
updateMedicationForBird,
|
||||
updateWeightForBird,
|
||||
upsertMedicationAdministrationForBird,
|
||||
updateVetVisitForBird,
|
||||
} from './repositories/birdRepository.js';
|
||||
@@ -4150,6 +4151,61 @@ app.post('/api/birds/:birdId/weights', requireAuth, requireWriteAccess, requireW
|
||||
}
|
||||
});
|
||||
|
||||
app.put(
|
||||
'/api/birds/:birdId/weights/:weightId',
|
||||
requireAuth,
|
||||
requireWriteAccess,
|
||||
requireWorkspaceRole(['owner', 'assistant', 'caregiver']),
|
||||
async (req: Request, res: Response, next: NextFunction) => {
|
||||
const parsed = weightSchema.safeParse(req.body);
|
||||
|
||||
if (!parsed.success) {
|
||||
res.status(400).json({ error: 'Invalid weight payload', details: parsed.error.flatten() });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const bird = await getBirdById(req.params.birdId, req.auth!.workspace.id);
|
||||
|
||||
if (!bird) {
|
||||
res.status(404).json({ error: 'Bird not found.' });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ensureBirdWritable(bird, res)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const weight = await updateWeightForBird(
|
||||
req.params.weightId,
|
||||
req.params.birdId,
|
||||
parsed.data.weightGrams,
|
||||
parsed.data.recordedOn,
|
||||
emptyToNull(parsed.data.notes),
|
||||
);
|
||||
|
||||
if (!weight) {
|
||||
res.status(404).json({ error: 'Weight entry not found.' });
|
||||
return;
|
||||
}
|
||||
|
||||
await writeAuditLog(req.auth!, 'weight.updated', 'weight', weight.id, bird.name, {
|
||||
birdId: bird.id,
|
||||
weightGrams: parsed.data.weightGrams,
|
||||
recordedOn: parsed.data.recordedOn,
|
||||
});
|
||||
res.json({ weight: normalizeWeight(weight) });
|
||||
} catch (error) {
|
||||
if (typeof error === 'object' && error && 'code' in error && error.code === '23505') {
|
||||
res.status(409).json({ error: 'A weight entry already exists for that bird on that date.' });
|
||||
return;
|
||||
}
|
||||
|
||||
next(error);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
app.get('/api/birds/:birdId/vet-visits', requireAuth, async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const vetVisits = await listVetVisitsForBird(req.params.birdId, req.auth!.workspace.id);
|
||||
|
||||
@@ -895,6 +895,27 @@ export const createWeightForBird = async (birdId: string, weightGrams: number, r
|
||||
return result.rows[0] ?? null;
|
||||
};
|
||||
|
||||
export const updateWeightForBird = async (
|
||||
weightId: string,
|
||||
birdId: string,
|
||||
weightGrams: number,
|
||||
recordedOn: string,
|
||||
notes: string | null,
|
||||
) => {
|
||||
const result = await db.query<WeightRow>(
|
||||
`UPDATE weight_records
|
||||
SET weight_grams = $3,
|
||||
recorded_on = $4,
|
||||
notes = $5
|
||||
WHERE id = $1
|
||||
AND bird_id = $2
|
||||
RETURNING id, bird_id, weight_grams, recorded_on::text, notes`,
|
||||
[weightId, birdId, weightGrams, recordedOn, notes],
|
||||
);
|
||||
|
||||
return result.rows[0] ?? null;
|
||||
};
|
||||
|
||||
export const listVetVisitsForBird = async (birdId: string, workspaceId: number) => {
|
||||
const result = await db.query<VetVisitRow>(
|
||||
`SELECT id, bird_id, visited_on::text, clinic_name, reason, notes
|
||||
|
||||
Reference in New Issue
Block a user