Harden reference date reads

This commit is contained in:
karilint
2026-04-29 11:38:45 +03:00
parent 172aa16c03
commit 647773d1c9
6 changed files with 72 additions and 92 deletions
+3 -35
View File
@@ -20,6 +20,7 @@ import { logDb, nowDb } from '../utils/db'
import { validateCollectingMethodValues } from '../utils/validation/collectingMethodValues'
import { buildPersonLookupByInitials, getPersonDisplayName, getPersonFromLookup } from './utils/person'
import { getReferenceDetails } from './reference'
import { addNullExactDateToReferenceJoins, referenceWithoutExactDateSelect } from './utils/referenceDate'
const normalizeNumberField = (value: unknown) => {
if (typeof value === 'string') {
@@ -259,34 +260,7 @@ export const getLocalityDetails = async (id: number, user: User | undefined) =>
now_lr: {
include: {
ref_ref: {
select: {
rid: true,
ref_type_id: true,
journal_id: true,
title_primary: true,
date_primary: true,
volume: true,
issue: true,
start_page: true,
end_page: true,
publisher: true,
pub_place: true,
title_secondary: true,
date_secondary: true,
title_series: true,
issn_isbn: true,
ref_abstract: true,
web_url: true,
misc_1: true,
misc_2: true,
gen_notes: true,
printed_language: true,
used_morph: true,
used_now: true,
used_gene: true,
ref_authors: true,
ref_journal: true,
},
select: referenceWithoutExactDateSelect,
},
},
},
@@ -315,13 +289,7 @@ export const getLocalityDetails = async (id: number, user: User | undefined) =>
...lau,
lau_coordinator: getPersonDisplayName(coordinatorPerson, lau.lau_coordinator),
lau_authorizer: getPersonDisplayName(authorizerPerson, lau.lau_authorizer),
now_lr: lau.now_lr.map(lr => ({
...lr,
ref_ref: {
...lr.ref_ref,
exact_date: null,
},
})),
now_lr: addNullExactDateToReferenceJoins(lau.now_lr),
updates,
}
})
+3 -40
View File
@@ -4,6 +4,7 @@ import { AccessError } from '../middlewares/authorizer'
import { logDb, nowDb } from '../utils/db'
import { buildPersonLookupByInitials, getPersonDisplayName, getPersonFromLookup } from './utils/person'
import { generateOccurrenceDetailSql } from './queries/crossSearchQuery'
import { addNullExactDateToReferenceJoins, referenceWithoutExactDateSelect } from './utils/referenceDate'
const getAllowedLocalities = async (user: User) => {
const usersProjects = await nowDb.now_proj_people.findMany({
@@ -119,44 +120,6 @@ type OccurrenceUpdate = {
updates: OccurrenceLogRow[]
}
const referenceWithoutExactDateSelect = {
rid: true,
ref_type_id: true,
journal_id: true,
title_primary: true,
date_primary: true,
volume: true,
issue: true,
start_page: true,
end_page: true,
publisher: true,
pub_place: true,
title_secondary: true,
date_secondary: true,
title_series: true,
issn_isbn: true,
ref_abstract: true,
web_url: true,
misc_1: true,
misc_2: true,
gen_notes: true,
printed_language: true,
used_morph: true,
used_now: true,
used_gene: true,
ref_authors: true,
ref_journal: true,
} as const
const addNullExactDateToReferences = <T extends { ref_ref: object }>(references: T[]) =>
references.map(reference => ({
...reference,
ref_ref: {
...reference.ref_ref,
exact_date: null,
},
}))
const stringifyLogValue = (value: unknown) => {
if (value === null || value === undefined) return ''
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') return String(value)
@@ -271,7 +234,7 @@ const getOccurrenceUpdates = async (lid: number, speciesId: number) => {
update.lau_coordinator
),
occ_comment: update.lau_comment ?? '',
references: addNullExactDateToReferences(update.now_lr) as unknown as AnyReference[],
references: addNullExactDateToReferenceJoins(update.now_lr) as unknown as AnyReference[],
updates: nowLsLogs.filter(logRow => logRow.luid === update.luid),
})),
...speciesUpdates.map(update => ({
@@ -285,7 +248,7 @@ const getOccurrenceUpdates = async (lid: number, speciesId: number) => {
update.sau_coordinator
),
occ_comment: update.sau_comment ?? '',
references: addNullExactDateToReferences(update.now_sr) as unknown as AnyReference[],
references: addNullExactDateToReferenceJoins(update.now_sr) as unknown as AnyReference[],
updates: nowLsLogs.filter(logRow => logRow.suid === update.suid),
})),
])
+21 -9
View File
@@ -7,6 +7,20 @@ import {
} from './referenceValidation'
import { Role, User } from '../../../frontend/src/shared/types'
import { getIdsOfUsersProjects } from './locality'
import { referenceWithoutExactDateSelect } from './utils/referenceDate'
type RawReferenceExactDate = {
exact_date: string | null
}
const normalizeRawExactDate = (value: string | null | undefined): string | null => {
if (!value) return null
const date = value.slice(0, 10)
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(date)
if (!match) return null
if (match[2] === '00' || match[3] === '00') return null
return date
}
export const getAllReferences = async () => {
const result = await nowDb.ref_ref.findMany({
@@ -41,22 +55,20 @@ export const getAllReferences = async () => {
export const getReferenceDetails = async (id: number, _user?: User) => {
const result = await nowDb.ref_ref.findUnique({
where: { rid: id },
include: { ref_authors: true, ref_journal: true },
select: referenceWithoutExactDateSelect,
})
if (!result) {
return null
}
//changing exact_date to yyyy-mm-dd string since frontend uses that + we don't want to display ISO string in frontend
if (result && result.exact_date) {
const date = new Date(result.exact_date)
const formattedDate = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`
const exactDateRows = await nowDb.$queryRaw<RawReferenceExactDate[]>`
SELECT CAST(exact_date AS CHAR) AS exact_date
FROM ref_ref
WHERE rid = ${id}
`
return { ...result, exact_date: formattedDate }
}
return result
return { ...result, exact_date: normalizeRawExactDate(exactDateRows[0]?.exact_date) }
}
// Fetch localities that have been updated by the given reference id
+3 -4
View File
@@ -6,6 +6,7 @@ import { ValidationObject, referenceValidator } from '../../../frontend/src/shar
import { getReferenceDetails } from './reference'
import { buildPersonLookupByInitials, getPersonDisplayName, getPersonFromLookup } from './utils/person'
import { TabListQueryOptions } from './tabularQuery'
import { addNullExactDateToReferenceJoins, referenceWithoutExactDateSelect } from './utils/referenceDate'
export const getAllTimeBounds = async () => {
const result = await nowDb.now_tu_bound.findMany({
@@ -30,10 +31,7 @@ export const getTimeBoundDetails = async (id: number) => {
now_br: {
include: {
ref_ref: {
include: {
ref_authors: true,
ref_journal: true,
},
select: referenceWithoutExactDateSelect,
},
},
},
@@ -61,6 +59,7 @@ export const getTimeBoundDetails = async (id: number) => {
...bau,
bau_coordinator: getPersonDisplayName(coordinatorPerson, bau.bau_coordinator),
bau_authorizer: getPersonDisplayName(authorizerPerson, bau.bau_authorizer),
now_br: addNullExactDateToReferenceJoins(bau.now_br),
updates,
}
})
+3 -4
View File
@@ -5,6 +5,7 @@ import { validateTimeUnit } from '../../../frontend/src/shared/validators/timeUn
import { getReferenceDetails } from './reference'
import { buildPersonLookupByInitials, getPersonDisplayName, getPersonFromLookup } from './utils/person'
import { TabListQueryOptions } from './tabularQuery'
import { addNullExactDateToReferenceJoins, referenceWithoutExactDateSelect } from './utils/referenceDate'
export const getAllTimeUnits = async () => {
const result = await nowDb.now_time_unit.findMany({
@@ -53,10 +54,7 @@ export const getTimeUnitDetails = async (id: string) => {
now_tr: {
include: {
ref_ref: {
include: {
ref_authors: true,
ref_journal: true,
},
select: referenceWithoutExactDateSelect,
},
},
},
@@ -85,6 +83,7 @@ export const getTimeUnitDetails = async (id: string) => {
...tau,
tau_coordinator: getPersonDisplayName(coordinatorPerson, tau.tau_coordinator),
tau_authorizer: getPersonDisplayName(authorizerPerson, tau.tau_authorizer),
now_tr: addNullExactDateToReferenceJoins(tau.now_tr),
updates,
}
})
@@ -0,0 +1,39 @@
export const referenceWithoutExactDateSelect = {
rid: true,
ref_type_id: true,
journal_id: true,
title_primary: true,
date_primary: true,
volume: true,
issue: true,
start_page: true,
end_page: true,
publisher: true,
pub_place: true,
title_secondary: true,
date_secondary: true,
title_series: true,
issn_isbn: true,
ref_abstract: true,
web_url: true,
misc_1: true,
misc_2: true,
gen_notes: true,
printed_language: true,
used_morph: true,
used_now: true,
used_gene: true,
ref_authors: true,
ref_journal: true,
} as const
export const addNullExactDateToReference = <T extends object>(reference: T) => ({
...reference,
exact_date: null,
})
export const addNullExactDateToReferenceJoins = <T extends { ref_ref: object }>(references: T[]) =>
references.map(reference => ({
...reference,
ref_ref: addNullExactDateToReference(reference.ref_ref),
}))