nhance/public/dev_logs/2026-04-04.md

6.6 KiB
Raw Blame History

2026-04-04 — Daily tasks

VidalGetBenefDetailsV2 (Enrollment Dump API)

Context

  • Goal: Add VidalApiController::VidalGetBenefDetailsV2, mirroring VidalGetBenefDetails end-to-end (batch gate, JSON dump, saveVidalAPIData job, employee match, tpa_id update, e-card job, batch file status), but calling the Enrollment info integration used in TestingController::getVidalEnrollmentInfo() for URL, headers, and request body shape only.
  • Reference sample: public/tmp/Enrollment Dump API.docx — HTTP 200 body is status, data (array of member rows), trace, successful.
  • Note on “same format”: The raw Enrollment API uses different field names (beneficiaryName, membershipNo, employeeNo, dateOfBirth, relation, etc.). The implementation normalizes each row to the same internal dependent shape as V1 (name, empNo, relationship, gender, dob, enrollmentId, policyNumber, age) so matching, saveVidalAPIData, and logging stay unchanged.

Plan

  1. HTTP contract (from Testing, env-aware URL)

    • URL: vidalEnrollmentInfoApiUrl() — if VIDAL_API_BASE_URL ends with /api, strip it and append /enrollment/info (matches https://devapigw.vidalhealthtpa.com/partner-integration/enrollment/info); otherwise fall back to that dev URL.
    • Headers: Content-Type: application/json, ocp-apim-subscription-key: {VIDAL_API_SUBSCRIPTION_KEY} (same as getVidalEnrollmentInfo).
    • Body: policyNo, startIndex, endIndex (paginated windows; current page size 100 in code).
  2. Fetch loop

    • Keep the same batch_files prerequisite as V1 (TPA export rows for client_policy_id).
    • Replace V1s perexport-date startDate/endDate calls with pagination until a page returns fewer than pageSize rows or an empty page (after the first).
  3. Response handling

    • Require status === 'SUCCESS'; if successful is present and false, treat as failure.
    • Read rows from data (top-level array in the decoded JSON).
    • Map each row through normalizeVidalEnrollmentRecordToDependentFormat() (reference map from relationship.csv baked into code, membershipNoenrollmentId, beneficiaryNamename, plus si / doj / desc for tpa_api_data — see Relationship & TPA columns below).
  4. Downstream (unchanged from V1)

    • Write merged dependents JSON under writable/tmp/, queue saveVidalAPIData, run the same DB match/update and e-card / batch_file status logic.
    • SQL: V2 uses valid UPDATE employee_polices SET tpa_id = … WHERE id = … (no stray comma before WHERE).
  5. Wiring

    • Route: GET VidalGetBenefDetailsV2VidalApiController::VidalGetBenefDetailsV2.
    • Acl.php: public entry like V1.
    • JobWorker.php: job VidalGetBenefDetailsV2VidalApiController (method name matches job name).
  6. Follow-ups (optional)

    • Switch ApiServiceController TPA pull from VidalGetBenefDetails to VidalGetBenefDetailsV2 when product confirms Enrollment API for all policies.
    • Revisit emp_code ↔ employeeNo matching if dependents share the same employeeNo in real dumps (doc sample shows repeated employeeNo for family members).

Tasks

  • Implement normalizeVidalEnrollmentRecordToDependentFormat, vidalEnrollmentInfoApiUrl, and VidalGetBenefDetailsV2 in VidalApiController.php.
  • Register route, ACL, and JobWorker job VidalGetBenefDetailsV2.
  • Document plan and tasks in this file (2026-04-04.md).

Job payload (same shape as V1)

policy_no, client_policy_id, file_id, return_type (job when queued).

Manual check

  • With valid env and data: enqueue VidalGetBenefDetailsV2 or call GET …/VidalGetBenefDetailsV2 with the same query/body conventions as V1 (if wired), and confirm logs show VIDAL V2 - TPA ID Pull and tpa_api_data rows after saveVidalAPIData.

Vidal relationship.csv → Nhance + tpa_api_data extra columns

Context

  • Reference file: public/tmp/relationship.csv — documentation only (not read at runtime). Column A = Vidal VIDAL_RELSHIP_DESCRIPTION, column C = OUR RELATIONSHIPS (separator ,,). Only rows with a non-empty “ours” value are represented in code (currently eight entries).
  • Scope (per request): Use this mapping only in VidalGetBenefDetailsV2 (via normalizeVidalEnrollmentRecordToDependentFormat) and in saveVidalAPIData. V1 VidalGetBenefDetails / legacy JSON rows without vidal_relation_raw keep the previous behaviour (strtolower(relationship) only).

Plan

  1. Baked-in mapvidalRelationshipReferenceMap() returns the associative array (lowercase Vidal → lowercase Nhance) copied from the reference CSV. Constructor sets $this->vidalRelationshipMap once from that method. To add mappings, edit the PHP array and keep the CSV in sync as documentation.
  2. Map functionmapVidalRelationshipToNhance($vidalRelationDescription) returns a hit from $this->vidalRelationshipMap if present; else Employee / Employeesself; else strtolower(str_replace('-', ' ', $raw)).
  3. V2 normalizationnormalizeVidalEnrollmentRecordToDependentFormat() sets relationship from the mapper, adds vidal_relation_raw for persistence/audit, si from baseSumInsured, doj from dateOfJoining (Y-m-d via normalizeVidalEnrollmentDateToYmd), desc from buildVidalEnrollmentDescForTpaRow() (productName, remarks, insuredName).
  4. saveVidalAPIData — If vidal_relation_raw is present, recompute relation with mapVidalRelationshipToNhance (keeps DB aligned even if JSON is tweaked). Set self from mapped relation === 'self'. Populate desc, si, doj per TpaApiDataModel::$allowedFields. desc stored as Vidal relation: … | … plus JSON desc when both exist.
  5. Model — No schema change; fields already in app/Models/TpaApiDataModel.php: desc, si, doj.

Tasks

  • Add vidalRelationshipReferenceMap() + constructor copy to $vidalRelationshipMap, mapVidalRelationshipToNhance, and date helper on VidalApiController.
  • Extend enrollment normalization with vidal_relation_raw, si, doj, desc.
  • Update saveVidalAPIData mapping and extra columns.
  • Document in 2026-04-04.md.

Caveats

  • CSV lines like Father (2),,Self map that exact Vidal string to Nhance self; ensure API relation strings match the CSV keys (case-insensitive).
  • Rows in the CSV with no “ours” value are ignored; those relations fall through to Employee/Employees or generic lowercasing.