teqo-backup/src/lib/relationship.ts
Francisco Ignácio Fontoura Solla 4806c417c8 Engineering Pass 3: consolidate patterns and lock them with guards.
Fold duplicated campanha access, loaders, list/filter/form shells, and scripts into shared modules; reorganize utilities by domain; stabilize e2e; and document prevention-first audit workflow so the same smells cannot creep back in.
2026-07-29 06:11:29 -03:00

35 lines
1.4 KiB
TypeScript

export type PopulatedRelationship = { id: number }
const isRelationshipId = (value: unknown): value is number =>
typeof value === 'number' && Number.isSafeInteger(value) && value > 0
export const isPopulatedRelationship = <Relationship extends PopulatedRelationship>(
value: unknown,
): value is Relationship =>
typeof value === 'object' && value !== null && 'id' in value && isRelationshipId(value.id)
export const relationshipId = (value: unknown): number | null => {
if (isRelationshipId(value)) return value
return isPopulatedRelationship(value) ? value.id : null
}
/** Display name from a populated `Contact` relation (or `fallback` when unpopulated). */
export const populatedContactName = (contact: unknown, fallback = 'Contato'): string => {
if (typeof contact !== 'object' || contact === null || !('name' in contact)) return fallback
const { name } = contact
return typeof name === 'string' && name.length > 0 ? name : fallback
}
export const requireRelationshipId = (
value: unknown,
message = 'Relacionamento inválido.',
): number => {
const id = relationshipId(value)
if (id === null) throw new Error(message)
return id
}
/** Normalizes a `hasMany` relationship field (ids or populated docs, any depth) into a deduped id list. */
export const uniqueRelationshipIds = (values: readonly unknown[] | null | undefined): number[] => [
...new Set((values ?? []).map(relationshipId).filter((id): id is number => id !== null)),
]