/**
* @module person
* @description Person/Member Management Router
*
* This router provides comprehensive endpoints for managing persons/members within the
* member management system. It handles all aspects of person data management including
* profile information, group memberships, historical tracking, and administrative functions.
*
* Key Features:
* - Person profile creation and management
* - Group membership management with historical tracking
* - Age calculation and automatic updates
* - Duplicate detection and merging
* - Leadership role and job assignments
* - Permission-based access control
* - Family relationship management
* - Contact information synchronization
*
* Business Rules:
* - Persons can belong to multiple groups with different roles
* - Family relationships sync contact information automatically
* - Age is calculated from birth date and updated periodically
* - Duplicate detection uses phonetic matching
* - Historical data tracks all membership and role changes
* - Permissions are hierarchical based on organizational structure
*
* @requires express - Web framework for routing
* @requires @/utils/authChecks - Authentication and authorization utilities
* @requires @/utils/requestLogger - Request logging middleware
* @requires ./person/controller - Person business logic controller
*/
import express from 'express';
import { checkObjectAdmin, checkVisible, checkAdmin } from '../utils/authChecks.js';
import { requestUpdateLogger, readLogger } from '../utils/requestLogger.js';
import * as personController from './person/controller.js';
const api = express.Router();
/**
* @route GET /api/kpe20/person/ageUpdate
* @group Person Management
* @description Update age for all persons in the organization based on their birth dates
* This is typically run as a scheduled maintenance task
* @returns {object} Update result
* @returns {boolean} .success - Whether the operation was successful
* @returns {number} .updated - Number of persons whose age was updated
* @example
* GET /api/kpe20/person/ageUpdate
* Response: {"success": true, "updated": 150}
*/
api.get('/ageUpdate', checkAdmin, requestUpdateLogger, personController.ageUpdate);
// Update group membership for a person
/**
* @route POST /api/kpe20/person/:group/:UID
* @group Person Management
* @description Update a person's membership in a specific group
* @param {string} group - UUID of the group
* @param {string} UID - UUID of the person
* @param {object} body - Membership update data
* @param {string} [body.role] - New role in the group (member, leader, guest)
* @param {string} [body.startDate] - Membership start date (ISO format)
* @param {string} [body.endDate] - Membership end date (ISO format)
* @param {object} [body.additionalData] - Additional membership-specific data
* @returns {object} Update result
* @returns {boolean} .success - Whether the update was successful
* @returns {object} .result - Updated membership information
* @example
* POST /api/kpe20/person/UUID-group-123/UUID-person-456
* Body: {"role": "leader", "startDate": "2024-01-01"}
*/
api.post('/:group/:UID', requestUpdateLogger, personController.updateGroupMembership);
// Update person data
/**
* @route POST /api/kpe20/person/:UID
* @group Person Management
* @description Update a person's profile information
* @param {string} UID - UUID of the person to update
* @param {object} body - Updated person data
* @param {string} [body.firstName] - First name
* @param {string} [body.lastName] - Last name
* @param {string} [body.birthDate] - Birth date (ISO format)
* @param {string} [body.gender] - Gender (M=Male, F=Female)
* @param {object[]} [body.addresses] - Contact addresses
* @param {object[]} [body.phoneNumbers] - Phone numbers
* @param {object[]} [body.emails] - Email addresses
* @param {object} [body.additionalData] - Additional profile data
* @returns {object} Update result
* @returns {boolean} .success - Whether the update was successful
* @returns {object} .result - Updated person information
* @example
* POST /api/kpe20/person/UUID-person-123
* Body: {"firstName": "John", "lastName": "Doe", "birthDate": "1990-01-01"}
*/
api.post('/:UID', requestUpdateLogger, personController.updatePerson);
// Create or update person in group
/**
* @route PUT /api/kpe20/person/:group
* @group Person Management
* @description Create a new person and add them to a group, or update existing person
* @param {string} group - UUID of the group to add the person to
* @param {object} body - Person creation data
* @param {string} body.firstName - First name (required)
* @param {string} body.lastName - Last name (required)
* @param {string} body.birthDate - Birth date (ISO format, required)
* @param {string} body.gender - Gender (M=Male, F=Female, required)
* @param {object[]} [body.addresses] - Contact addresses
* @param {object[]} [body.phoneNumbers] - Phone numbers
* @param {object[]} [body.emails] - Email addresses
* @param {string} [body.familyUID] - UUID of existing family to join
* @param {object} [body.additionalData] - Additional profile data
* @returns {object} Creation result
* @returns {boolean} .success - Whether the operation was successful
* @returns {object} .result - Created/updated person information
* @returns {string} .result.UID - Person's UUID
* @returns {boolean} .result.isNew - Whether a new person was created
* @example
* PUT /api/kpe20/person/UUID-group-123
* Body: {
* "firstName": "Jane",
* "lastName": "Smith",
* "birthDate": "1995-03-15",
* "gender": "F"
* }
*/
api.put('/:group', requestUpdateLogger, checkObjectAdmin, personController.putPerson);
// Get person details with optional related data
/**
* @route GET /api/kpe20/person/:UID
* @group Person Management
* @description Get detailed information about a person including profile, memberships, and related data
* @param {string} UID - UUID of the person to retrieve
* @param {string} [include] - Comma-separated list of related data to include (groups,family,jobs,history)
* @returns {object} Person information
* @returns {boolean} .success - Whether the request was successful
* @returns {object} .result - Complete person data
* @returns {string} .result.firstName - First name
* @returns {string} .result.lastName - Last name
* @returns {string} .result.birthDate - Birth date
* @returns {number} .result.age - Calculated age
* @returns {object[]} .result.groups - Group memberships (if included)
* @returns {object} .result.family - Family information (if included)
* @returns {object[]} .result.jobs - Leadership roles (if included)
* @example
* GET /api/kpe20/person/UUID-person-123?include=groups,family
*/
api.get('/:UID', readLogger, personController.getPerson);
// Get person's group membership history
/**
* @route GET /api/kpe20/person/history/:UID
* @group Person Management
* @description Get the complete membership history for a person across all groups
* @param {string} UID - UUID of the person
* @param {string} [startDate] - Start date for history filter (ISO format)
* @param {string} [endDate] - End date for history filter (ISO format)
* @returns {object} Membership history
* @returns {boolean} .success - Whether the request was successful
* @returns {object[]} .result - Array of historical membership records
* @returns {string} .result[].groupName - Name of the group
* @returns {string} .result[].role - Role in the group
* @returns {string} .result[].startDate - Membership start date
* @returns {string} .result[].endDate - Membership end date (if applicable)
* @example
* GET /api/kpe20/person/history/UUID-person-123
*/
api.get('/history/:UID', checkVisible, personController.personHistorie);
// Check admin rights for person
/**
* @route GET /api/kpe20/person/admin/:UID
* @group Person Management
* @description Check if the current user has admin privileges for the specified person
* @param {string} UID - UUID of the person to check
* @returns {object} Admin status
* @returns {boolean} .success - Whether the request was successful
* @returns {boolean} .result - Whether user has admin rights for this person
* @example
* GET /api/kpe20/person/admin/UUID-person-123
* Response: {"success": true, "result": true}
*/
api.get('/admin/:UID', personController.personAdmin);
// Get person's leadership roles/jobs
/**
* @route GET /api/kpe20/person/leaders/:UID
* @group Person Management
* @description Get all leadership roles and jobs held by a person
* @param {string} UID - UUID of the person
* @returns {object} Leadership information
* @returns {boolean} .success - Whether the request was successful
* @returns {object[]} .result - Array of leadership roles
* @returns {string} .result[].title - Job/office title
* @returns {string} .result[].groupName - Group where the role is held
* @returns {string} .result[].startDate - Role start date
* @returns {string} .result[].endDate - Role end date (if applicable)
* @example
* GET /api/kpe20/person/leaders/UUID-person-123
*/
api.get('/leaders/:UID', checkVisible, personController.doCheckVisible);
// Find duplicate persons by name
/**
* @route GET /api/kpe20/person/duplicates/:firstName/:lastName
* @group Person Management
* @description Find potential duplicate persons using phonetic name matching
* @param {string} firstName - First name to search for
* @param {string} lastName - Last name to search for
* @param {string} [birthDate] - Optional birth date filter (ISO format)
* @returns {object} Duplicate search results
* @returns {boolean} .success - Whether the search was successful
* @returns {object[]} .result - Array of potential duplicate persons
* @returns {string} .result[].UID - Person UUID
* @returns {string} .result[].firstName - First name
* @returns {string} .result[].lastName - Last name
* @returns {string} .result[].birthDate - Birth date
* @returns {number} .result[].similarity - Similarity score (0-100)
* @example
* GET /api/kpe20/person/duplicates/John/Doe
*/
api.get('/duplicates/:firstName/:lastName', personController.personDuplicates);
// Get person's jobs (ungrouped)
/**
* @route GET /api/kpe20/person/jobs/:UID
* @group Person Management
* @description Get all jobs/roles held by a person (ungrouped list)
* @param {string} UID - UUID of the person
* @returns {object} Jobs information
* @returns {boolean} .success - Whether the request was successful
* @returns {object[]} .result - Array of all jobs held by the person
* @returns {string} .result[].title - Job title
* @returns {string} .result[].groupName - Associated group name
* @returns {string} .result[].startDate - Job start date
* @returns {string} .result[].endDate - Job end date (if applicable)
* @example
* GET /api/kpe20/person/jobs/UUID-person-123
*/
api.get('/jobs/:UID', checkVisible, personController.jobgroups('visible', false));
// Get person's job groups (grouped by main group)
/**
* @route GET /api/kpe20/person/jobgroups/:UID
* @group Person Management
* @description Get person's jobs grouped by their main group
* @param {string} UID - UUID of the person
* @returns {object} Grouped jobs information
* @returns {boolean} .success - Whether the request was successful
* @returns {object} .result - Jobs grouped by main group
* @returns {object} .result.mainGroup - Primary group jobs
* @returns {object[]} .result.otherGroups - Jobs in other groups
* @example
* GET /api/kpe20/person/jobgroups/UUID-person-123
*/
api.get('/jobgroups/:UID', checkVisible, personController.jobgroups('visible', true));
// Get person's changeable job groups
/**
* @route GET /api/kpe20/person/jobgroups/changeable/:UID
* @group Person Management
* @description Get person's jobs that can be modified by the current user
* @param {string} UID - UUID of the person
* @returns {object} Changeable jobs information
* @returns {boolean} .success - Whether the request was successful
* @returns {object} .result - Jobs the user can modify
* @returns {object[]} .result.canModify - Jobs user has permission to change
* @returns {object[]} .result.readOnly - Jobs user can only view
* @example
* GET /api/kpe20/person/jobgroups/changeable/UUID-person-123
*/
api.get('/jobgroups/changeable/:UID', checkVisible, personController.jobgroups('changeable', true));
// Export helper functions for other modules
export const publishChangeEvent = personController.publishChangeEvent;
export const updatePerson = personController.updatePerson;
export const getPerson = personController.getPerson;
export const personAdmin = personController.personAdmin;
export const personHistorie = personController.personHistorie;
export const personDuplicates = personController.personDuplicates;
export const ageUpdate = personController.ageUpdate;
export default api;