mirror of
https://github.com/nowcommunity/nowdatabase.git
synced 2026-10-12 19:13:52 +03:00
Harden reference date reads
This commit is contained in:
@@ -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,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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),
|
||||
})),
|
||||
])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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),
|
||||
}))
|
||||
Reference in New Issue
Block a user