Found in PR #79 (fix/70-project-access-email-case)
Severity: Minor
PR #79 introduced normalizeSharedWith() as a reusable helper for lowercasing + deduping emails. The POST /projects route correctly uses it:
shared_with: normalizeSharedWith(shared_with ?? []),
But PATCH /:projectId inlines the same logic manually (lines 246–258):
if (Array.isArray(req.body.shared_with)) {
// Normalise: lowercase + dedupe + drop empties.
const seen = new Set<string>();
const cleaned: string[] = [];
for (const raw of req.body.shared_with) {
if (typeof raw !== "string") continue;
const e = raw.trim().toLowerCase();
if (!e || seen.has(e)) continue;
seen.add(e);
cleaned.push(e);
}
updates.shared_with = cleaned;
}
This is a DRY violation — the same logic now lives in two places. Any future change to normalization rules (e.g. strip subaddress, normalize unicode) would need to be updated in both.
Fix: Replace the inlined loop with normalizeSharedWith:
if (Array.isArray(req.body.shared_with)) {
updates.shared_with = normalizeSharedWith(req.body.shared_with);
}
Found in PR #79 (fix/70-project-access-email-case)
Severity: Minor
PR #79 introduced
normalizeSharedWith()as a reusable helper for lowercasing + deduping emails. ThePOST /projectsroute correctly uses it:But
PATCH /:projectIdinlines the same logic manually (lines 246–258):This is a DRY violation — the same logic now lives in two places. Any future change to normalization rules (e.g. strip subaddress, normalize unicode) would need to be updated in both.
Fix: Replace the inlined loop with
normalizeSharedWith: