diff --git a/core/invertGraph.ts b/core/invertGraph.ts new file mode 100644 index 0000000..d5daff5 --- /dev/null +++ b/core/invertGraph.ts @@ -0,0 +1,72 @@ +import { CategoryName } from './types/Category' +import { Person, PersonList } from './types/Person' +import mappings from './invertedMappings.json' + +type InvertedPerson = { + id: string + name: string + available: boolean + relation: string + relatedTo: string +} + +type InvertedPersonList = Record + +export function defaultRoot(): Person { + return { + id: '0', + name: 'Defunto', + available: false, + degree: 0, + root: null, + category: 'children', + relatives: [], + } +} + +export function invertGraph(root: Person, list: InvertedPersonList): PersonList { + const personList: PersonList = { '0': root } + for (const person of Object.values(list)) { + const degree = relationIdToDegree(person.relation) + const category = relationIdToCategory(person.relation) + const root = person.relatedTo === '' ? '0' : person.relatedTo + + personList[person.id] = { + id: person.id, + name: person.name, + available: person.available, + degree, + root, + category, + relatives: [], + } + } + + for (const person of Object.values(personList)) { + if (!person.root) { + continue + } + + personList[person.root].relatives.push(person.id) + } + + return personList +} + +function relationIdToDegree(relation: string): number { + const mapping = mappings[relation as keyof typeof mappings] + if (!mapping) { + throw new Error('Unknown relation') + } + + return mapping.degree +} + +function relationIdToCategory(relation: string): CategoryName { + const mapping = mappings[relation as keyof typeof mappings] + if (!mapping) { + throw new Error('Unknown relation') + } + + return mapping.category as CategoryName +} diff --git a/core/invertedMappings.json b/core/invertedMappings.json new file mode 100644 index 0000000..695ec15 --- /dev/null +++ b/core/invertedMappings.json @@ -0,0 +1,22 @@ +{ + "figlio": { "category": "children", "degree": 1 }, + "nipote in linea retta": { "category": "children", "degree": 2 }, + "pronipote in linea retta": { "category": "children", "degree": 3 }, + "abnipote in linea retta": { "category": "children", "degree": 4 }, + "genitore": { "category": "ascendants", "degree": 1 }, + "fratello": { "category": "bilinear", "degree": 2 }, + "nipote in linea collaterale": { "category": "children", "degree": 3 }, + "pronipote in linea collaterale": { "category": "children", "degree": 4 }, + "abnipote in linea collaterale": { "category": "children", "degree": 5 }, + "zio": { "category": "others", "degree": 3 }, + "cugino": { "category": "children", "degree": 4 }, + "figlio di cugino": { "category": "children", "degree": 5 }, + "nipote di cugino": { "category": "children", "degree": 6 }, + "nonno": { "category": "ascendants", "degree": 2 }, + "prozio": { "category": "others", "degree": 4 }, + "secondo cugino": { "category": "children", "degree": 5 }, + "figlio di secondo cugino": { "category": "children", "degree": 6 }, + "bisavo": { "category": "ascendants", "degree": 3 }, + "trisavo": { "category": "children", "degree": 4 }, + "coniuge": { "category": "spouse", "degree": 1 } +} diff --git a/package-lock.json b/package-lock.json index 83ea1ea..0403ecb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2652,9 +2652,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001427", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001427.tgz", - "integrity": "sha512-lfXQ73oB9c8DP5Suxaszm+Ta2sr/4tf8+381GkIm1MLj/YdLf+rEDyDSRCzeltuyTVGm+/s18gdZ0q+Wmp8VsQ==", + "version": "1.0.30001584", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001584.tgz", + "integrity": "sha512-LOz7CCQ9M1G7OjJOF9/mzmqmj3jE/7VOmrfw6Mgs0E8cjOsbRXQJHsPBfmBOXDskXKrHLyyW3n7kpDW/4BsfpQ==", "funding": [ { "type": "opencollective", @@ -2663,6 +2663,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ] }, @@ -9477,9 +9481,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001427", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001427.tgz", - "integrity": "sha512-lfXQ73oB9c8DP5Suxaszm+Ta2sr/4tf8+381GkIm1MLj/YdLf+rEDyDSRCzeltuyTVGm+/s18gdZ0q+Wmp8VsQ==" + "version": "1.0.30001584", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001584.tgz", + "integrity": "sha512-LOz7CCQ9M1G7OjJOF9/mzmqmj3jE/7VOmrfw6Mgs0E8cjOsbRXQJHsPBfmBOXDskXKrHLyyW3n7kpDW/4BsfpQ==" }, "chalk": { "version": "4.1.2", diff --git a/pages/api/health.ts b/pages/api/health.ts new file mode 100644 index 0000000..4642b0a --- /dev/null +++ b/pages/api/health.ts @@ -0,0 +1,5 @@ +import { NextApiRequest, NextApiResponse } from 'next' + +export default function handler(req: NextApiRequest, res: NextApiResponse) { + return res.status(200).send('Hello') +} diff --git a/pages/api/inheritance.ts b/pages/api/inheritance.ts index f7be1c0..fcf6330 100644 --- a/pages/api/inheritance.ts +++ b/pages/api/inheritance.ts @@ -2,9 +2,14 @@ import { NextApiRequest, NextApiResponse } from 'next' import { calculateInheritance } from '../../core/inheritance' export default function handler(req: NextApiRequest, res: NextApiResponse) { - if (req.method !== 'POST') return res.status(405).send({ error: 'Method not allowed' }) - if (req.headers['content-type'] !== 'application/json') + if (req.method !== 'POST') { + return res.status(405).send({ error: 'Method not allowed' }) + } + if (req.headers['content-type'] !== 'application/json') { return res.status(400).send({ error: 'Content type not allowed' }) + } + + // TODO: Don't require sender to set back pointers for people, only the relatives array try { const result = calculateInheritance(req.body) diff --git a/pages/api/inverted/inheritance.ts b/pages/api/inverted/inheritance.ts new file mode 100644 index 0000000..fcb7798 --- /dev/null +++ b/pages/api/inverted/inheritance.ts @@ -0,0 +1,21 @@ +import { NextApiRequest, NextApiResponse } from 'next' +import { calculateInheritance } from '../../../core/inheritance' +import { defaultRoot, invertGraph } from '../../../core/invertGraph' + +export default function handler(req: NextApiRequest, res: NextApiResponse) { + if (req.method !== 'POST') { + return res.status(405).send({ error: 'Method not allowed' }) + } + + if (req.headers['content-type'] !== 'application/json') { + return res.status(400).send({ error: 'Content type not allowed' }) + } + + try { + const graph = invertGraph(defaultRoot(), req.body) + const result = calculateInheritance(graph) + return res.json(result) + } catch (error) { + return res.status(500).send({ error: 'Failed to parse body' }) + } +}