# Face ID Job Verification Implementation Plan

## Overview

Add face recognition as a third verification method alongside existing OTP and QR code methods. This will reuse the existing face recognition system but adapt it for job verification.

## Language File Updates

Add to `web/application/language/english/job_verification_lang.php`:
```php
// Face verification strings
$lang['verify_entry_with_face'] = 'Verify Entry with Face';
$lang['verify_exit_with_face'] = 'Verify Exit with Face';
$lang['face_verification_modal_title'] = 'Face Verification';
$lang['capture_face'] = 'Capture Face';
$lang['face_verification_successful'] = 'Face verification successful';
$lang['face_not_recognized'] = 'Face not recognized';
$lang['face_verification_failed'] = 'Face verification failed';
$lang['outside_verification_window'] = 'Outside verification window';
$lang['camera_permission_required'] = 'Camera permission required for face verification';
$lang['face_verification_not_available'] = 'Face verification not available - enrollment required';
$lang['face_verification_in_progress'] = 'Verifying face...';
$lang['face_verification_error'] = 'Error during face verification';
$lang['face_verification_cancelled'] = 'Face verification cancelled';
$lang['try_again'] = 'Try Again';
$lang['cancel'] = 'Cancel';
```

## Implementation Plan

### 1. Modify Candidate Job List View

Update `web/application/modules/candidate/views/candidate_job_list_ajax.php`:

```php
// Add face verification button alongside existing buttons
if (($time['job_status'] == 3 || $time['job_status'] == 5) && $time['time_wise_show_flag'] == 1) {
    // First check if user has face enrollment
    if (has_face_enrollment($candidate_id)) {
        echo '<button class="get_entry_face">' . $this->lang->line('verify_entry_with_face') . '</button>';
        echo '<button class="get_exit_face">' . $this->lang->line('verify_exit_with_face') . '</button>';
    }
    // Existing buttons remain
    echo '<button class="get_entry_otp">' . $this->lang->line('get_entry_otp') . '</button>';
    echo '<button class="get_entry_qrcode">' . $this->lang->line('get_entry_qr_code') . '</button>';
}
```

### 2. Add Face Verification Controller Methods

Create new methods in `web/application/modules/candidate/controllers/job_verification.php`:

```php
public function verify_entry_face() {
    if (!$this->session->userdata(CANDIDATE_LOGGED_IN)) {
        return error_response($this->lang->line('not_logged_in'));
    }

    $job_id = $this->input->post('job_id');
    $job_avability_id = $this->input->post('job_avability_id');
    $image_data = $this->input->post('image');
    
    // 1. Verify time window
    $entry_exit_status = $this->verification->check_jobid_wise_exit_status($job_id);
    if (!validate_time_window($entry_exit_status)) {
        return error_response($this->lang->line('outside_verification_window'));
    }

    // 2. Verify face using existing recognition
    $recognized_user_id = $this->face->searchFaces($image_data);
    if ($recognized_user_id != $this->session->userdata(CANDIDATE_LOGGED_IN)['id']) {
        return error_response($this->lang->line('face_not_recognized'));
    }

    // 3. Record entry with face verification type
    $this->sql->insert_data('job_employee', array(
        'job_id' => $job_id,
        'job_avability_id' => $job_avability_id,
        'employee_id' => $recognized_user_id,
        'approved_time' => time(),
        'entry_loaction' => json_encode(get_location_data()),
        'entry_verify_type' => 5, // New type for face verification
        'status' => 1
    ));

    return success_response($this->lang->line('face_verification_successful'));
}

public function verify_exit_face() {
    if (!$this->session->userdata(CANDIDATE_LOGGED_IN)) {
        return error_response($this->lang->line('not_logged_in'));
    }

    $job_id = $this->input->post('job_id');
    $job_avability_id = $this->input->post('job_avability_id');
    $image_data = $this->input->post('image');
    
    // 1. Check for existing entry
    $get_entry_exit_data = $this->verification->get_entry_exit_data($job_id, $this->session->userdata(CANDIDATE_LOGGED_IN)['id'], $job_avability_id);
    if (empty($get_entry_exit_data) || $get_entry_exit_data['approved_time'] == "") {
        return error_response($this->lang->line('entry_required'));
    }

    // 2. Verify face
    $recognized_user_id = $this->face->searchFaces($image_data);
    if ($recognized_user_id != $this->session->userdata(CANDIDATE_LOGGED_IN)['id']) {
        return error_response($this->lang->line('face_not_recognized'));
    }

    // 3. Record exit
    $total_work_time = time() - $get_entry_exit_data['approved_time'];
    $this->sql->update_data('job_employee',
        array(
            'id' => $get_entry_exit_data['id'],
            'job_id' => $job_id,
            'job_avability_id' => $job_avability_id,
            'employee_id' => $recognized_user_id
        ),
        array(
            'approved_time_exit' => time(),
            'exit_loaction' => json_encode(get_location_data()),
            'exit_verify_type' => 5,
            'total_work_time' => $total_work_time
        )
    );

    return success_response($this->lang->line('face_verification_successful'));
}
```

### 3. Add Face Verification UI Component

Create new file `web/application/views/face_verification_modal.php`:
```php
<div id="faceVerificationModal" class="modal">
    <div class="modal-content">
        <h2><?php echo $this->lang->line('face_verification_modal_title'); ?></h2>
        <video id="faceVideo" autoplay></video>
        <canvas id="faceCanvas" style="display:none"></canvas>
        <div class="button-group">
            <button id="captureFace" class="primary-button">
                <?php echo $this->lang->line('capture_face'); ?>
            </button>
            <button id="retryFace" class="secondary-button" style="display:none">
                <?php echo $this->lang->line('try_again'); ?>
            </button>
            <button id="cancelFace" class="cancel-button">
                <?php echo $this->lang->line('cancel'); ?>
            </button>
        </div>
        <div id="faceStatus" class="status-message"></div>
    </div>
</div>
```

### 4. Add JavaScript for Face Capture

Add to `web/assets/js/candidate_job_list.js`:
```javascript
// Initialize translations object
const translations = {
    camera_permission_required: '<?php echo $this->lang->line("camera_permission_required"); ?>',
    face_verification_successful: '<?php echo $this->lang->line("face_verification_successful"); ?>',
    face_verification_in_progress: '<?php echo $this->lang->line("face_verification_in_progress"); ?>',
    face_verification_error: '<?php echo $this->lang->line("face_verification_error"); ?>',
    face_verification_cancelled: '<?php echo $this->lang->line("face_verification_cancelled"); ?>'
};

// Face verification button handlers
$('.get_entry_face, .get_exit_face').click(function() {
    const isEntry = $(this).hasClass('get_entry_face');
    const jobId = $(this).data('job_id');
    const jobAviId = $(this).data('job_avi_id');
    let stream = null;
    
    // Show face capture modal
    $('#faceVerificationModal').show();
    $('#faceStatus').text('').hide();
    $('#captureFace').show();
    $('#retryFace').hide();
    
    // Initialize video
    navigator.mediaDevices.getUserMedia({ video: true })
        .then(videoStream => {
            stream = videoStream;
            document.getElementById('faceVideo').srcObject = stream;
        })
        .catch(() => {
            showError(translations.camera_permission_required);
            $('#faceVerificationModal').hide();
        });
    
    // Capture and verify handler
    $('#captureFace').click(function() {
        const canvas = document.getElementById('faceCanvas');
        const video = document.getElementById('faceVideo');
        
        $('#faceStatus').text(translations.face_verification_in_progress).show();
        
        // Capture frame
        canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
        const imageData = canvas.toDataURL('image/jpeg');
        
        // Send to server
        $.ajax({
            url: isEntry ? 'verify_entry_face' : 'verify_exit_face',
            method: 'POST',
            data: {
                job_id: jobId,
                job_avability_id: jobAviId,
                image: imageData
            },
            success: function(response) {
                if (response.success) {
                    showSuccess(translations.face_verification_successful);
                    $('#faceVerificationModal').hide();
                    refreshJobList();
                } else {
                    $('#faceStatus').text(response.message).show();
                    $('#captureFace').hide();
                    $('#retryFace').show();
                }
            },
            error: function() {
                $('#faceStatus').text(translations.face_verification_error).show();
                $('#captureFace').hide();
                $('#retryFace').show();
            }
        });
    });

    // Retry handler
    $('#retryFace').click(function() {
        $('#faceStatus').text('').hide();
        $('#retryFace').hide();
        $('#captureFace').show();
    });

    // Cancel handler
    $('#cancelFace').click(function() {
        if (stream) {
            stream.getTracks().forEach(track => track.stop());
        }
        $('#faceVerificationModal').hide();
        showInfo(translations.face_verification_cancelled);
    });

    // Cleanup on modal close
    $('#faceVerificationModal').on('hidden.bs.modal', function() {
        if (stream) {
            stream.getTracks().forEach(track => track.stop());
        }
    });
});
```

### 5. Database Updates

Add new verification type to existing schema:
```sql
ALTER TABLE job_employee
MODIFY COLUMN entry_verify_type ENUM('1','2','3','4','5') 
COMMENT '1=JobID, 2=OTP, 3=QR, 4=Admin, 5=Face';

ALTER TABLE job_employee
MODIFY COLUMN exit_verify_type ENUM('1','2','3','4','5')
COMMENT '1=JobID, 2=OTP, 3=QR, 4=Admin, 5=Face';
```

### 6. Helper Functions

Add to appropriate helper file:
```php
function has_face_enrollment($user_id) {
    $CI =& get_instance();
    return $CI->db->where('user_id', $user_id)
                  ->count_all_results('user_faces') > 0;
}

function validate_time_window($entry_exit_status) {
    $start_time = $entry_exit_status['start_time'] - jobVerificationStartTime();
    $end_time = $entry_exit_status['end_time'] + jobVerificationEndTime();
    return $start_time <= time() && $end_time >= time();
}

function error_response($message) {
    return array(
        'success' => false,
        'message' => $message
    );
}

function success_response($message) {
    return array(
        'success' => true,
        'message' => $message
    );
}
```

## Security Considerations

1. Face Verification Specific:
- Ensure live face detection (already implemented in face recognition)
- Verify user ID matches session
- Store face verification attempts for audit

2. General Security:
- Maintain same time window validation as other methods
- Require prior entry before exit
- Capture location data
- Prevent multiple active entries

## Testing Plan

1. Enrollment Status:
- Verify face button only shows for enrolled users
- Other methods remain available for non-enrolled users

2. Face Verification:
- Test successful entry/exit with enrolled face
- Test rejection of non-enrolled face
- Test rejection of photo/video replay
- Verify location capture
- Test time window restrictions

3. Integration:
- Verify face verification records in job_employee table
- Test switching between verification methods
- Verify proper status updates in UI
- Test all language strings display correctly

## Implementation Steps

1. Database Updates:
- Add face verification type to enums
- Add any needed indexes

2. Backend Changes:
- Add language strings
- Add face verification controller methods
- Add helper functions
- Integrate with existing face recognition

3. Frontend Changes:
- Add face capture modal
- Add verification buttons
- Add JavaScript handlers
- Update job list view
- Integrate language strings

4. Testing:
- Unit tests for new methods
- Integration tests for face verification
- UI/UX testing for face capture
- Verify all text uses language strings

5. Documentation:
- Update API documentation
- Add face verification to user guide
- Document new verification type codes
- Document language string usage

## Rollout Plan

1. Deploy database changes
2. Deploy backend changes with feature flag
3. Deploy frontend changes
4. Enable for test group
5. Monitor for issues
6. Full rollout

The implementation maintains the existing verification workflow but adds face recognition as a new method, reusing the proven face recognition system while maintaining all security measures of the job verification system. All user-facing text is handled through the language system for proper internationalization.
