Τροποποίηση εκδομένης αναφοράς (§7.8.8)
Στόχος
Έκδοση τροποποιημένης αναφοράς για ανάλυση που έχει ήδη εγκριθεί και αποσταλεί στον πελάτη, με πλήρη τήρηση του εδαφίου ISO/IEC 17025 §7.8.8 (αμεταβλητότητα: η αρχική έκδοση διατηρείται, η νέα έκδοση προστίθεται με αυξανόμενο αριθμό).
Προϋποθέσεις
- Η ανάλυση (
AnalysisRecord) είναι σε κατάσταση Εγκεκριμένη. - Πρόχειρη, Ακυρωμένη, Ελεγμένη ή ήδη Τροποποιημένη αναλύσεις δεν δέχονται τροποποίηση από το ίδιο σημείο.
- Έχει εκδοθεί τουλάχιστον μία αρχική έκδοση αναφοράς (
ReportVersion v1). - Δημιουργείται αυτόματα κατά την πρώτη έγκριση.
- Ο χρήστης έχει ρόλο LAB_DIRECTOR.
- Reviewer / Analyst δεν επιτρέπεται να τροποποιήσει εκδομένη αναφορά. Το backend απορρίπτει την κλήση με
403 Forbidden. - Έχει συνταχθεί ο λόγος τροποποίησης σε καθαρό κείμενο.
- Προτεινόμενο ελάχιστο μήκος: ≥ 20 χαρακτήρες.
- Υποχρεωτικό μη-κενό από το backend (ελέγχεται με
reason?.trim()). - Έχει εντοπιστεί η αιτία της τροποποίησης. Τυπικά παραδείγματα:
- Λανθασμένη μέτρηση που εντοπίστηκε εκ των υστέρων.
- Λανθασμένη ταυτοποίηση δείγματος (π.χ. swap στο intake).
- Διόρθωση επιλογής μεθόδου.
- Παραλαβή νέων QC δεδομένων που αλλάζουν την κρίση συμμόρφωσης.
- Αναβαθμονόμηση οργάνου εκ των υστέρων.
- Έχει ενημερωθεί ο υπεύθυνος ποιότητας.
- Η τροποποίηση εκδομένης αναφοράς είναι παρατυπία (nonconformity) και ενδέχεται να ενεργοποιήσει διορθωτική ενέργεια (CAPA) σύμφωνα με §8.7.
Βήματα
- Ανοίξτε τη λίστα Αναλύσεις (
/analyses) και εντοπίστε την εγκεκριμένη ανάλυση. Φιλτράρετε με κατάσταση Εγκεκριμένη αν χρειάζεται. - Κάντε κλικ στον κωδικό για να ανοίξει η σελίδα λεπτομερειών (
/analyses/:id). - Πατήστε το μενού kebab (τρεις κάθετες κουκίδες) στην επάνω-δεξιά γωνία της κάρτας λεπτομερειών.
- Επιλέξτε «Τροποποίηση» (Amend). Η ενέργεια εμφανίζεται μόνο όταν η κατάσταση είναι Εγκεκριμένη και ο χρήστης είναι LAB_DIRECTOR.
- Στο prompt συμπληρώστε τον λόγο τροποποίησης.
- Παράδειγμα: «Διόρθωση τιμής pH από 6.8 σε 7.2 λόγω επαναβαθμονόμησης ηλεκτροδίου στις 22/05/2026. Επαναμέτρηση από αναλυτή Παπαδόπουλο.»
- Αναφέρετε: τι αλλάζει, γιατί, ποιος, πότε.
- Επιβεβαιώστε. Το backend:
- αλλάζει την κατάσταση σε Τροποποιημένη,
- μηδενίζει τις στήλες
reviewedById/reviewedAt/approvedById/approvedAt, - επιστρέφει επιτυχία και ενεργοποιεί push notification στους reviewers.
- Επεξεργαστείτε τις μετρήσεις / στοιχεία που χρειάζεται να διορθωθούν. Η εγγραφή βρίσκεται ξανά σε επεξεργάσιμη κατάσταση.
- Στείλτε ξανά για Έλεγχο (Reviewer) και κατόπιν Έγκριση (LAB_DIRECTOR).
- Με τη νέα έγκριση δημιουργείται αυτόματα μια νέα
ReportVersion (v2, v3, ...). - Αποστέλλεται το email REPORT_AMENDED στον πελάτη.
- Επιβεβαιώστε στην καρτέλα Ιστορικό Εκδόσεων ότι η νέα έκδοση εμφανίζεται με τη σωστή αρίθμηση, χρονοσφραγίδα και αναγνωριστικό συντάκτη.
Τι συμβαίνει στο παρασκήνιο
- Frontend κλήση mutation. Η ενέργεια του kebab καλεί την Apollo mutation
amendAnalysisRecord(analysisRecordId, reason). - Υλοποίηση:
apps/agrometrisis/src/app/analyses/analysis-detail.ts:861-885 (amendRecord() με window.prompt για τον λόγο). - Backend mutation handler. Εκτελείται στο
apps/agrometrisis-api/src/app/modules/analysis-records/analysis-record.resolver.ts:1451-1493 (amendAnalysisRecord, @Roles('LAB_DIRECTOR')). - Επικυρώνει την κατάσταση Εγκεκριμένη.
- Επικυρώνει ότι ο λόγος δεν είναι κενός.
- Ενημερώνει την εγγραφή με κατάσταση Τροποποιημένη,
amendmentReason=reason.trim(). - Μηδενίζει τα
reviewedById/reviewedAt/approvedById/approvedAt. - Real-time broadcast. Η αλλαγή κατάστασης δημοσιεύεται μέσω
pubSub.publish('analysisRecordStatusChanged', ...) ώστε όλοι οι συνδεδεμένοι clients να ανανεωθούν αυτόματα. - Push notification στους χρήστες του εργαστηρίου. Καλείται το
PushNotificationService.notifyReportAmended(sampleCode, analysisRecordId, reason, excludeUserId) (στο push-notification.service.ts:315-332). - Στέλνει FCM ειδοποίηση
report.amended.title / report.amended.body. - Στόχος: όλοι οι χρήστες με
NotificationPreference.statusChanges = true. - Εξαιρεί τον συντάκτη της ενέργειας (
excludeUserId). - Νέα
ReportVersion — όχι τώρα, στην επόμενη έγκριση. Η νέα έκδοση δεν δημιουργείται κατά την τροποποίηση. - Δημιουργείται κατά την επόμενη έγκριση, στο
analysis-record.resolver.ts:1422 (this.reportVersionService.createSnapshot(analysisRecordId, userId)). - Η
createSnapshot() υπολογίζει nextVersion = lastVersion.version + 1 (δείτε report-version.service.ts:22-34). - Αποθηκεύει πλήρες JSON snapshot στη στήλη
snapshot longtext, μαζί με generatedById. - Έτσι η v1 παραμένει αμετάβλητη και η v2 προστίθεται ως νέα γραμμή — η ουσιαστική απαίτηση της §7.8.8.1.
- Banner στο PDF. Στο PDF της νέας έκδοσης ενσωματώνεται banner τροποποίησης.
- Κείμενο: «Η παρούσα έκδοση τροποποιεί την προηγούμενη — η αρχική παραμένει σε ισχύ για ιστορική αναφορά».
- Απαιτείται από §7.8.8.2 (αναγνωρίσιμη ως τροποποίηση).
- Audit trail. Το
AnalysisRecordStatusLog καταγράφει την μετάβαση Εγκεκριμένη → Τροποποιημένη. noteCode = REPORT_AMENDED, χρονοσφραγίδα, χρήστης, λόγος.- Το ίδιο log καταγράφει και την επόμενη Τροποποιημένη → Εγκεκριμένη μετάβαση.
- Email προς πελάτη. Το
ClientEmailService.queueEmail(ClientEmailType.REPORT_AMENDED, contactId, analysisRecordId, …) ενεργοποιείται από την επόμενη έγκριση. - Το deduplication γίνεται ανά
AnalysisRecord. - Δεύτερη τροποποίηση στην ίδια εγγραφή δεν στέλνει διπλό email αν η προηγούμενη ροή είναι ακόμα ενεργή στην ουρά.
- Παράδοση στον πελάτη. Ο πελάτης παραλαμβάνει email με τύπο
REPORT_AMENDED και link προς την νέα έκδοση. - Η αρχική έκδοση παραμένει προσβάσιμη μέσω του ReportVersion ιστορικού (
findAllByAnalysisRecord στο report-version.service.ts:39-54).
Συνήθη λάθη
- Παράκαμψη του kebab. Μην προσπαθήσετε να επεξεργαστείτε απευθείας τις μετρήσεις μέσω άλλης διαδρομής. Όσο η κατάσταση είναι Εγκεκριμένη, η εγγραφή είναι κλειδωμένη. Η μόνη νόμιμη οδός είναι η
Τροποποίηση από το kebab. - Λόγος < 20 χαρακτήρων. Το backend δέχεται οποιοδήποτε μη-κενό string, αλλά ο ESYD αξιολογητής θα ζητήσει ουσιαστική τεκμηρίωση. Γράψτε τι, γιατί, ποιος και πότε.
- Διαγραφή της αρχικής αναφοράς. Δεν επιτρέπεται και δεν είναι δυνατή — η v1 παραμένει στον πίνακα
reportVersions ως αμετάβλητη γραμμή. Η §7.8.8 απαιτεί διατήρηση. - Χρήση «Ακύρωση» (Cancel) αντί για «Τροποποίηση». Η Ακύρωση (
cancelAnalysisRecord) είναι τερματική και προορίζεται για περιπτώσεις όπου η ανάλυση δεν θα επανεκδοθεί ποτέ. Αν θέλετε διορθωμένη αναφορά, χρησιμοποιείτε πάντα Τροποποίηση. - Επανειλημμένες τροποποιήσεις. Επιτρέπονται (v3, v4, ...), αλλά κάθε επιπλέον τροποποίηση είναι κόκκινη σημαία για audit. Αν χρειάζονται 3+ τροποποιήσεις, εξετάστε ανάκληση μέσω §7.10 (παρατυπίες) και επανέκδοση πλήρως νέας αναφοράς υπό §7.8.8.3.
Σχετικά εδάφια
- ISO/IEC 17025 §7.8.8.1 — Όταν εκδομένη αναφορά απαιτεί αλλαγή, τροποποίηση ή επανέκδοση, οποιαδήποτε μεταβολή πληροφορίας πρέπει να αναγνωρίζεται σαφώς και, όπου χρειάζεται, να περιλαμβάνει την αιτία της αλλαγής.
- ISO/IEC 17025 §7.8.8.2 — Οι τροποποιήσεις σε ήδη εκδομένη αναφορά γίνονται μόνο με τη μορφή ξεχωριστού εγγράφου ή μεταβίβασης δεδομένων, που περιλαμβάνει τη δήλωση: «Τροποποίηση της αναφοράς, αριθμός σειράς … [ή άλλος προσδιορισμός]» ή ισοδύναμη διατύπωση.
- ISO/IEC 17025 §7.8.8.3 — Όταν είναι αναγκαία η έκδοση πλήρους νέας αναφοράς, αυτή πρέπει να φέρει μοναδική ταυτοποίηση και να περιλαμβάνει αναφορά στο πρωτότυπο που αντικαθιστά.
- ESYD ΚΟ-Δ-ΕΜ §6.4 — Ο φορέας διαπίστευσης απαιτεί ιχνηλασιμότητα όλων των εκδόσεων αναφορών και τήρηση των πρωτότυπων για τουλάχιστον τον χρόνο διατήρησης αρχείων του εργαστηρίου.
- Σχετικές διαδικασίες:
workflow-reports — πλήρης κύκλος έκδοσης αναφοράς.workflow-analyses — state machine ανάλυσης και πύλες έγκρισης.