Documentation
Tutorials
Workflows
Kebab actions
Daily Work
Dashboard & Reports
Quality Control
ISO 17025
Logs
Contacts
Billing
Analysis Setup
Settings
Initial Setup
Help & Reference
Architecture decisions
Kebab actions
0:000:00

Handle a calibration-overdue block

Goal

When you try to approve an Analysis Record (AR) and approval is blocked because one of the linked instruments has an overdue calibration, this recipe describes the two ELOT EN ISO/IEC 17025:2017-compliant resolution paths:

  • Option A — Calibrate now: the recommended path. Calibrate the instrument, log a fresh CalibrationRecord with an updated next-calibration date, and re-run approval.
  • Option B — Documented override: the exception path. The Lab Director (LAB_DIRECTOR), Quality Manager (QUALITY_MANAGER), or Reviewer (REVIEWER) approves without calibration, logging a justification of ≥20 characters. The override is audited.

Neither path is silent — every approval over an overdue instrument leaves a trace in the system.


Prerequisites

#PrerequisiteWhere verified
1The AR is in status REVIEWED, ready for transition to APPROVED.status field on the Analysis Detail page.
2At least one Measurement on the AR references an Instrument with requiresCalibration = true.Measurements tab on the AR.
3The instrument's nextCalibrationDate is before today.Calibrations tab on the Instrument.
4For Option B, the user holds the LAB_DIRECTOR, QUALITY_MANAGER, or REVIEWER role.User Profile → Roles.
5For Option A, the user can create a CalibrationRecord on that instrument.Role permissions.

Instruments with requiresCalibration = false (e.g. volumetric glassware, manual tools) or with no nextCalibrationDate set are automatically exempt and do not trigger the block.

Pre-flight check before picking a path

Before choosing between A and B, open the Measurements tab on the AR and note:

  • Which instruments are overdue — usually one or two, rarely all. If only one instrument blocks, Option A is almost always the right call.
  • How overdue the calibration is — one day past due needs a different justification than one month past due.
  • Whether a CAPA is already open for the instrument — Option B should be linked to an existing or new corrective action.

Steps

  1. Attempt the approval. On the AR Detail page, open the kebab menu and choose Approve. If an overdue instrument is present, the backend returns an error with extension code APPROVAL_BLOCKED_CALIBRATION_OVERDUE. The frontend recognises the code and opens the Override Dialog instead of a generic snackbar, listing the overdue instruments (name, serial number, calibration expiry date).
  2. Option A — Calibrate now (recommended).
  • Dismiss the Override Dialog with Cancel.
  • Click the instrument link in the list, or navigate manually to Instruments → select the instrument.
  • On the Calibrations tab, log a new CalibrationRecord. Fill in:
  • calibrationDate — today's calibration date.
  • withinTolerance: true — the instrument passed the check.
  • nextCalibrationDate — computed from the SOP frequency (e.g. + 12 months).
  • Supporting document (calibration certificate from an accredited provider or an in-house protocol).
  • Return to the AR and re-run Approve. The guard now passes cleanly and the AR transitions to APPROVED with no override marker on the audit log.
  1. Option B — Documented override (exception path).
  • In the Override Dialog (still open), fill in the override reason text field. The justification should cover:
  • why the calibration cannot be performed immediately,
  • why the results are metrologically defensible anyway (e.g. internal QC against a known reference material remains in control, scope of capability validated),
  • what corrective action is scheduled (CAPA, calibration within N days).
  • The field requires at least 20 characters; shorter submissions are rejected with OVERRIDE_REASON_TOO_SHORT.
  • Click Submit. The AR transitions to APPROVED and an audit event OVERRIDE_CALIBRATION_APPROVE is written with userId, entityType = 'AnalysisRecord', entityId, reason, timestamp, and the list of overdue instruments as changes.
  1. Confirm the audit entry. On the AR, the Override History tab shows the entry with the full justification and the approving user. It is never deleted — it forms part of the assessment record for the ESYD assessor.

On the same tab you can filter by action (OVERRIDE_CALIBRATION_APPROVE) and export CSV for the internal-audit folder. The export carries user, timestamp, justification, and the list of instruments with their nextCalibrationDate values — exactly the data §6.4.7 expects you to have available.

  1. Monitor the queue. From the Business Dashboard, the Calibration-overdue revenue card shows how many ARs are sitting in the queue blocked by overdue calibration and the corresponding billable amount. Use it to prioritise which instruments to calibrate first.

Override-reason template

To avoid repeated rejections for insufficient documentation, structure the justification as:

"Calibration of <instrument name> (S/N <serial>) expired on <date>. It cannot be performed immediately because <reason — e.g. vendor visit scheduled, backup instrument in use>. Metrological confidence is maintained via <internal QC against reference material Lot XXX within limits / duplicate analysis on backup instrument>. CAPA-<number> has been opened and calibration is scheduled for <date>."

What happens behind the scenes

The block logic is implemented in the _enforceCalibrationGuard method of analysis-record.resolver.ts (analysis-record.resolver.ts:1001). For each Measurement on the AR, the distinct instrumentId values are collected and Instrument rows are queried where requiresCalibration = 1, nextCalibrationDate IS NOT NULL, and nextCalibrationDate < CURDATE(). If nothing matches, the guard passes immediately; otherwise, without an overrideReason, the method throws a GraphQLError with extension code APPROVAL_BLOCKED_CALIBRATION_OVERDUE (analysis-record.resolver.ts:1044) and an instruments[] payload carrying id, name, serialNumber, nextCalibrationDate.

The nextCalibrationDate field on Instrument (instrument.entity.ts:65) is a nullable date string — comparison uses MariaDB's CURDATE(), so every instrument within a tenant is checked against a single server-side timezone. Instruments with nextCalibrationDate IS NULL do not trigger the block but surface separately on the dashboard as "uncalibrated".

On the override path the guard performs three checks in order:

  1. The role passes overrideHelper.isOverrideRole(role) — otherwise OVERRIDE_DENIED.
  2. overrideReason.trim().length >= 20 — otherwise OVERRIDE_REASON_TOO_SHORT.
  3. OverrideHelper.recordEvent({ action: 'OVERRIDE_CALIBRATION_APPROVE', ... }) writes the immutable entry to OverrideLog.

The order is intentionally fail-fast: a user without the role will never see a "reason too short" message and therefore cannot probe the system for how to slip past the check.

A short Greek + English narrative is part of the error message itself (analysis-record.resolver.ts:1041), so even tooling that does not surface extensions.instruments (e.g. raw curl) still shows which instrument is overdue.

On the frontend, the AnalysisDetail component (analysis-detail.ts:730) inspects err.errors[0].extensions.code (Apollo v4 shape) and opens the override dialog via showOverrideDialog.set(true), stashing the recordId in pendingApprovalRecordId. Submitting the reason calls the same mutation again, this time with overrideReason set — the guard re-runs, sees the reason, and proceeds to log it.

Edge cases

  • Instrument deleted after the measurement was logged: the guard still sees instrumentId on the measurement. Fix or delete the measurement before retrying approval.
  • Multiple overdue instruments on the same AR: the dialog lists all of them. A single reason covers the lot — you do not file one override per instrument.
  • Out-of-tolerance calibration (withinTolerance: false): does not count as a successful calibration. nextCalibrationDate is not advanced and the AR stays blocked.

Important bulk-approve caveat. The bulk-approve path (analysis-record.resolver.ts:1767) calls _enforceCalibrationGuard(r, undefined, userRole, userId) with overrideReason = undefined, so no override is allowed: every AR with an overdue instrument fails and must be fixed individually with a reason, or by an actual calibration. This is intentional — bulk approval must not become a shortcut for exceptions.

If you need to clear a large queue, the workflow is:

  1. Run bulk-approve to discover which ARs fail.
  2. Group failures by instrument.
  3. Calibrate the instruments that account for the most failures first.
  4. Re-run bulk-approve; remaining failures are handled one by one via the override dialog with full justification.

  • §6.4.6 — Calibration of measuring equipment for traceability. All equipment that affects measurement uncertainty must be calibrated according to a documented programme. Overdue calibration compromises the traceability claim.
  • §6.4.7 — Calibration programme and review. The lab documents calibration frequencies, intermediate checks, and reviews the programme when deviations are detected. The override path should feed a CAPA that informs the next programme review.

For the full clause text, see Reference → ISO/IEC 17025:2017.


Tip for ESYD assessments

ESYD assessors frequently spot-check override examples. A well-structured OverrideLog entry with a clear justification, a CAPA reference, and metrological-confidence evidence (QC charts, replicate measurements on a backup instrument) is strong evidence that the lab is not silently bypassing controls but handling the exception with maturity. Conversely, terse "emergency" justifications are a red flag.

Systematic use of Option B (for example more than 5 overrides per month on the same instrument) should trigger a review of the calibration programme under §6.4.7 and possibly an increase in frequency or a change of provider.

Pair this recipe with the Calibration & maintenance schedule explanation page for a deeper look at how calibration intervals are set and re-evaluated.