InfraForge Docs

InfraNotes Payroll · v0

Welcome

Select a document from the sidebar to read it.

BUG-2 Payroll UUID Identity and /employees/me Not Found Handling

Summary

BUG-2 covered two payroll failures after the platform moved to canonical IAM tenant and principal UUIDs:

  1. Payroll create/list paths still depended on the legacy Core integer-user identity path, which surfaced as Invalid gateway identity signature during staging validation.
  2. GET /api/v1/employees/me returned 500 Internal Server Error when an authenticated IAM principal had no payroll employee projection. That state is a normal business absence and should return 404 Not Found.

The fix shipped in v0.4.1 removes the Core integer identity dependency for UUID identity flows, routes create/self lookup through payroll-side payroll_principals, preserves tenant-scoped context in repository calls, and maps expected employee-not-found service errors to HTTP 404.

Root Cause

  • Payroll was the service outlier in the platform migration. It still mixed legacy user_id ownership with canonical IAM UUID identity and tenant claims.
  • The create path could infer or propagate legacy user_id even when UUID identity mode was enabled.
  • The service and repository layers did not consistently attach the authenticated tenant to repository calls.
  • APix handler not-found mapping was too narrow. It recognized record not found and no rows, but the UUID service path returned employee not found, causing a normal missing employee projection to be reported as 500.

Fix Applied

  • Added payroll-side UUID principal handling through payroll_principals.
  • Required explicit target principal_id for UUID employee creation instead of inferring the acting principal.
  • Prevented UUID-mode creates from copying stale legacy user_id values.
  • Attached tenant context before payroll principal upsert and employee lookup paths.
  • Enforced authenticated tenant precedence over caller-supplied tenant filters.
  • Added tenant-aware repository update behavior and validation for nil UUID principals.
  • Added concurrency guards for shared Kafka writer and GL event consumer state.
  • Updated migration safety for tenant backfill and staged enforcement.
  • Centralized APix employee-not-found detection and mapped employee not found to 404.
  • Added unit and staging validation coverage for the fixed paths.

Release and Rollout

  • Payroll release: v0.4.1
  • Payroll main validation commit: 2ae8825 test: document payroll v0.4.1 staging retest
  • ArgoCD staging image bump: infraforge/infranotes-payroll-api:v0.4.1 and infraforge/infranotes-payroll-worker:v0.4.1
  • Staging ArgoCD status after rollout: Synced and Healthy
  • Runtime flag: ENABLE_PAYROLL_UUID_IDENTITY=true

Validation Evidence

Staging validation on 2026-05-10 confirmed:

  • GET /api/v1/employees/me without a token returns 401.
  • GET /api/v1/employees/me for an authenticated admin without an employee projection returns 404, not 500.
  • GET /api/v1/employees?limit=1 as tenant admin returns 200 and does not emit Invalid gateway identity signature.
  • POST /api/v1/employees without principal_id returns 400 principal_id is required.
  • POST /api/v1/employees with explicit readonly IAM principal_id creates a UUID-only employee projection with no legacy user ownership.
  • GET /api/v1/employees/me as that readonly principal returns 200 for its own employee projection.
  • The readonly principal still receives 403 on GET /api/v1/employees?limit=1, confirming self-access did not grant list access.
  • Database verification confirmed employee 5 is scoped to tenant 019e01cc-a608-7a12-8795-27d26d35377e, linked to readonly IAM principal 019e0de8-8399-7b74-b807-be58002190ea, and attributed to the admin actor principal for create/update audit fields.
  • Recent payroll API logs contained no Invalid gateway identity signature, no Core lookup error, and no employee-not-found server error path.

Detailed request, response, and database evidence is recorded in TEST_LOG.md under the staging v0.4.1 entries.

Residual Observations

  • Duplicate employee create returns the correct 409 Conflict, but the response body uses the existing APix text error format instead of a JSON error envelope.
  • The create service generated employee_number EMP2026b537f94a instead of preserving the submitted E2E employee number. This did not affect UUID identity validation.
  • Staging API and worker logs continue to show Datadog tracer connection-refused messages to the configured agent endpoint. These messages are unrelated to BUG-2 and should be handled separately if staging trace delivery is expected.

Status

BUG-2 is fixed and validated in staging for the canonical IAM UUID identity path and /employees/me not-found behavior.