import mongoose from 'mongoose'; import { CheckInMethod, AttendanceType, CheckInEntry, ObjectIdLike, UserReference, CheckInData, TimeSlotDistribution, TimeSlot, AttendanceStats } from '../types.js'; /** * Check-In Factory * * Centralized creation of check-in entries for consistency across operations. * * @module @classytic/clockin/factories/checkin */ /** * Check-in entry with optional recordedBy for factory use. * In some cases (e.g., system-generated check-ins), recordedBy may not be available. */ type FactoryCheckInEntry = Omit & { recordedBy?: UserReference; }; /** * Parameters for creating a check-in entry. */ interface CreateCheckInParams { /** Check-in timestamp (defaults to now) */ timestamp?: Date; /** Check-in method */ method?: CheckInMethod; /** Attendance type */ attendanceType?: AttendanceType; /** Location information */ location?: CheckInEntry['location']; /** Device information */ device?: CheckInEntry['device']; /** Notes */ notes?: string; /** User who recorded the check-in */ recordedBy?: { userId?: ObjectIdLike; name?: string; role?: string; }; /** Expected check-out time (for auto-checkout) */ expectedCheckOutAt?: Date | null; } /** * Check-In Factory * * Creates check-in entries with sensible defaults and validation. * Centralizes check-in creation logic for consistency. * * @example * ```typescript * // Create a simple check-in * const entry = CheckInFactory.create({ * method: 'qr_code', * }); * * // Create with full context * const entry = CheckInFactory.create({ * timestamp: new Date(), * method: 'mobile_app', * recordedBy: { userId, name, role }, * location: { coordinates: [lng, lat] }, * }); * ``` */ declare class CheckInFactory { /** * Create a single check-in entry with generated _id. * * @param params - Check-in parameters * @returns Complete check-in entry ready for storage */ static create(params?: CreateCheckInParams): FactoryCheckInEntry & { _id: mongoose.Types.ObjectId; }; /** * Create multiple check-in entries at once. * * Useful for bulk imports or batch operations. * * @param items - Array of check-in parameters * @returns Array of check-in entries * * @example * ```typescript * const entries = CheckInFactory.createBatch([ * { method: 'api', timestamp: date1 }, * { method: 'api', timestamp: date2 }, * { method: 'api', timestamp: date3 }, * ]); * ``` */ static createBatch(items: CreateCheckInParams[]): Array; /** * Create a check-in entry from CheckInData (service layer input). * * This is a convenience method that transforms service-layer data * into a check-in entry. * * @param data - Check-in data from service * @param context - Additional context (recordedBy, etc.) * @returns Check-in entry */ static fromCheckInData(data: CheckInData, context?: { userId?: ObjectIdLike; userName?: string; userRole?: string; expectedCheckOutAt?: Date | null; }): FactoryCheckInEntry & { _id: mongoose.Types.ObjectId; }; } /** * Attendance Record Factory * * Centralized creation and computation for attendance records. * * @module @classytic/clockin/factories/attendance */ /** * Parameters for creating an attendance record. */ interface CreateAttendanceRecordParams { /** Organization ID */ organizationId: ObjectIdLike; /** Target model name (e.g., 'Membership', 'Employee') */ targetModel: string; /** Target document ID */ targetId: ObjectIdLike; /** Year (defaults to current year) */ year?: number; /** Month (1-12, defaults to current month) */ month?: number; } /** * Attendance Record Factory * * Creates and computes attendance records with sensible defaults. * * @example * ```typescript * // Create a new attendance record for the current period * const record = AttendanceRecordFactory.createForPeriod({ * organizationId, * targetModel: 'Membership', * targetId: memberId, * }); * * // Create for a specific period * const record = AttendanceRecordFactory.createForPeriod({ * organizationId, * targetModel: 'Employee', * targetId: employeeId, * year: 2024, * month: 6, * }); * ``` */ declare class AttendanceRecordFactory { /** * Create an attendance record for a period. * * Returns a partial attendance record suitable for upsert operations. * * @param params - Record parameters * @returns Partial attendance record */ static createForPeriod(params: CreateAttendanceRecordParams): { organizationId: mongoose.Types.ObjectId; targetModel: string; targetId: mongoose.Types.ObjectId; year: number; month: number; checkIns: CheckInEntry[]; monthlyTotal: number; uniqueDaysVisited: number; visitedDays: string[]; timeSlotDistribution: TimeSlotDistribution; }; /** * Calculate time slot distribution from check-ins. * * @param checkIns - Array of check-in entries * @returns Time slot distribution counts */ static calculateTimeSlotDistribution(checkIns: CheckInEntry[]): TimeSlotDistribution; /** * Calculate unique visited days from check-ins. * * @param checkIns - Array of check-in entries * @returns Array of unique day strings (YYYY-MM-DD) */ static calculateVisitedDays(checkIns: CheckInEntry[]): string[]; /** * Calculate the favorite time slot from check-ins. * * @param checkIns - Array of check-in entries * @returns Most frequent time slot, or undefined if no check-ins */ static calculateFavoriteTimeSlot(checkIns: CheckInEntry[]): TimeSlot | undefined; /** * Calculate attendance record statistics. * * @param checkIns - Array of check-in entries * @returns Computed statistics */ static calculateRecordStats(checkIns: CheckInEntry[]): { monthlyTotal: number; uniqueDaysVisited: number; visitedDays: string[]; timeSlotDistribution: TimeSlotDistribution; }; /** * Create initial attendance stats for a new member. * * @param firstVisitAt - Optional first visit timestamp (defaults to now) * @returns Initial attendance stats */ static createInitialStats(firstVisitAt?: Date): Partial; } export { AttendanceRecordFactory, CheckInFactory, type CreateAttendanceRecordParams, type CreateCheckInParams };