diff --git a/dta/classes/dta_backend_utils.php b/dta/classes/dta_backend_utils.php
index 369b7331381baa93ca540bcceab2bbb5ff16a4ec..1c7aa8da40af4ea2a84f1cdd93a541066b73be1d 100644
--- a/dta/classes/dta_backend_utils.php
+++ b/dta/classes/dta_backend_utils.php
@@ -81,7 +81,7 @@ class dta_backend_utils {
         ];
 
         // If request returned null, return false to indicate failure.
-        if (is_null(self::dta_post($url, $params))) {
+        if (is_null(self::assignsubmission_dta_post($url, $params))) {
             return false;
         } else {
             return true;
diff --git a/dta/classes/db_utils.php b/dta/classes/dta_db_utils.php
similarity index 100%
rename from dta/classes/db_utils.php
rename to dta/classes/dta_db_utils.php
diff --git a/dta/classes/dta_view_submission_utils.php b/dta/classes/dta_view_submission_utils.php
index a85b5519b0563263e68f9ee10021841ac46563d6..aec50aaaab8521b12d6cc05235282b948a2be8d8 100644
--- a/dta/classes/dta_view_submission_utils.php
+++ b/dta/classes/dta_view_submission_utils.php
@@ -1,6 +1,6 @@
 <?php
 // This file is part of Moodle - http://moodle.org/.
-//
+// 
 // Moodle is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // the Free Software Foundation, either version 3 of the License, or
@@ -26,7 +26,6 @@ use assignsubmission_dta\models\dta_recommendation;
  * Utility class for DTA submission plugin result display.
  *
  * @package    assignsubmission_dta
- * @copyright  2023 Your Name <you@example.com>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class dta_view_submission_utils {
@@ -36,70 +35,97 @@ class dta_view_submission_utils {
      */
     public const ASSIGNSUBMISSION_DTA_COMPONENT_NAME = 'assignsubmission_dta';
 
-    /**
-     * Generates a short summary HTML.
-     *
-     * @param int $assignmentid The assignment ID.
-     * @param int $submissionid The submission ID to create a report for.
-     * @return string HTML summary.
-     */
-    public static function assignsubmission_dta_generate_summary_html(
-        int $assignmentid,
-        int $submissionid
-    ): string {
-        // Fetch data.
-        $summary = dta_db_utils::assignsubmission_dta_get_result_summary_from_database(
-            $assignmentid,
-            $submissionid
-        );
-        $html = '';
-
-        // Calculate success rate, if no unknown result states or compilation errors.
-        $successrate = '?';
-        if ($summary->unknown_count() === 0 && $summary->compilation_error_count() === 0) {
-            $successrate = round(($summary->successful_count() / $summary->result_count()) * 100, 2);
-        }
-
-        // Generate HTML.
-        $html .= $summary->successful_count() . '/';
-        if ($summary->compilation_error_count() === 0 && $summary->unknown_count() === 0) {
-            $html .= $summary->result_count() . ' (' . $successrate . '%)';
-        } else {
-            $html .= '?';
-        }
-        $html .= get_string('tests_successful', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) . '<br />';
+   /**
+ * Generates a short summary HTML (like your old plugin).
+ *
+ * @param int $assignmentid The assignment ID.
+ * @param int $submissionid The submission ID to create a report for.
+ * @return string The HTML summary.
+ */
+public static function assignsubmission_dta_generate_summary_html(
+    int $assignmentid,
+    int $submissionid
+): string {
+
+    // 1) Retrieve the summary data from the DB (adjust your DB-utils class as needed).
+    $summary = dta_db_utils::assignsubmission_dta_get_result_summary_from_database($assignmentid, $submissionid);
+
+    // 2) Prepare an HTML buffer.
+    $html = '';
+
+    // 3) Extract counts from your new method names:
+    $unknowncount      = $summary->assignsubmission_dta_unknown_count();
+    $compilecount      = $summary->assignsubmission_dta_compilation_error_count();
+    $successcount      = $summary->assignsubmission_dta_successful_count();
+    $failcount         = $summary->assignsubmission_dta_failed_count();
+    $totalcount        = $summary->assignsubmission_dta_result_count();
+
+    // 4) Compute success rate if no unknown/compile errors and total>0.
+    $successrate = '?';
+    if ($unknowncount === 0 && $compilecount === 0 && $totalcount > 0) {
+        $successrate = round(($successcount / $totalcount) * 100, 2);
+    }
 
-        if ($summary->compilation_error_count() > 0) {
-            $html .= $summary->compilation_error_count()
-                . get_string('compilation_errors', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
-                . '<br />';
-        }
+    // 5) “X/Y (Z%) tests successful” line:
+    //    If either compile errors or unknown exist -> we show "?"
+    //    else X/Y (rate%).
+    $html .= $successcount . '/';
+    if ($compilecount === 0 && $unknowncount === 0) {
+        $html .= ($totalcount > 0)
+            ? ($totalcount . ' (' . $successrate . '%)')
+            : ('0 (' . $successrate . ')');
+    } else {
+        $html .= '?';
+    }
+    $html .= get_string('tests_successful', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) . "<br />";
 
-        if ($summary->unknown_count() > 0) {
-            $html .= $summary->unknown_count()
-                . get_string('unknown_state', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
-                . '<br />';
-        }
+    // 6) If there are compilation errors, show them:
+    if ($compilecount > 0) {
+        $html .= $compilecount
+              . get_string('compilation_errors', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
+              . "<br />";
+    }
 
-        $showncompetencies = explode(';', $summary->successfultestcompetencies);
-        $overallcompetencies = explode(';', $summary->overalltestcompetencies);
+    // 7) If there are unknown results, show them:
+    if ($unknowncount > 0) {
+        $html .= $unknowncount
+              . get_string('unknown_state', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
+              . "<br />";
+    }
 
-        $tmp = '';
-        for ($index = 0, $size = count($showncompetencies); $index < $size; $index++) {
-            $shown = $showncompetencies[$index];
-            $comp = $overallcompetencies[$index];
-            // If the competency was actually assessed, add a summary entry.
-            if ($shown !== '0') {
-                $tmp .= get_string('comp' . $index, self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
-                    . ' ' . (100 * floatval($shown) / floatval($comp)) . '% ' . '<br />';
+    // 8) Competencies (like your old snippet):
+    $showncompetencies   = explode(';', $summary->successfultestcompetencies);
+    $overallcompetencies = explode(';', $summary->overalltestcompetencies);
+
+    $tmp = '';
+    $size = count($showncompetencies);
+    for ($i = 0; $i < $size; $i++) {
+        $shown = $showncompetencies[$i];
+        $comp  = $overallcompetencies[$i];
+
+        // If the competency was actually used (non-zero?), show a row.
+        if ($shown !== '0') {
+            $shownval = floatval($shown);
+            $compval  = floatval($comp);
+
+            // Guard division by zero:
+            $pct = 0;
+            if ($compval > 0) {
+                $pct = 100.0 * $shownval / $compval;
             }
+
+            // “compX XX%<br />”
+            $tmp .= get_string('comp' . $i, self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
+                  . ' ' . round($pct, 2) . '%<br />';
         }
+    }
 
-        $html .= get_string('success_competencies', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
-            . '<br />' . $tmp . '<br />';
+    $html .= get_string('success_competencies', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
+         . "<br />" . $tmp . "<br />";
 
-        return \html_writer::div($html, 'dtaSubmissionSummary');
-    }
+    // 9) Wrap it in a DIV for styling, and return.
+    return \html_writer::div($html, "dtaSubmissionSummary");
+}
 
     /**
      * Generates detailed view HTML.
@@ -126,15 +152,15 @@ class dta_view_submission_utils {
 
         // *** Summary Table ***
         $tableheaderrowattributes = ['class' => 'dtaTableHeaderRow'];
-        $tablerowattributes = ['class' => 'dtaTableRow'];
-        $resultrowattributes = $tablerowattributes;
-        $unknownattributes = 'dtaResultUnknown';
-        $successattributes = 'dtaResultSuccess';
-        $failureattributes = 'dtaResultFailure';
+        $tablerowattributes       = ['class' => 'dtaTableRow'];
+        $resultrowattributes      = $tablerowattributes;
+        $unknownattributes        = 'dtaResultUnknown';
+        $successattributes        = 'dtaResultSuccess';
+        $failureattributes        = 'dtaResultFailure';
         $compilationerrorattributes = 'dtaResultCompilationError';
-        $attributes = ['class' => 'dtaTableData'];
+        $attributes               = ['class' => 'dtaTableData'];
 
-        // Building summary table.
+        // Build the summary table header.
         $tmp = \html_writer::tag(
             'th',
             get_string('summary', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
@@ -146,6 +172,13 @@ class dta_view_submission_utils {
 
         $body = '';
 
+        // Pull the counters from the summary object.
+        $resultcount      = $summary->assignsubmission_dta_result_count();
+        $successfulcount  = $summary->assignsubmission_dta_successful_count();
+        $failedcount      = $summary->assignsubmission_dta_failed_count();
+        $compilationcount = $summary->assignsubmission_dta_compilation_error_count();
+        $unknowncount     = $summary->assignsubmission_dta_unknown_count();
+
         // Total items.
         $tmp = '';
         $tmp .= \html_writer::tag(
@@ -153,8 +186,9 @@ class dta_view_submission_utils {
             get_string('total_items', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
             $attributes
         );
-        $tmp .= \html_writer::tag('td', $summary->result_count(), $attributes);
+        $tmp .= \html_writer::tag('td', $resultcount, $attributes);
         $resultrowattributes = $tablerowattributes;
+        // Original code colors this row as unknown by default:
         $resultrowattributes['class'] .= ' ' . $unknownattributes;
         $body .= \html_writer::tag('tr', $tmp, $resultrowattributes);
 
@@ -165,16 +199,13 @@ class dta_view_submission_utils {
             get_string('tests_successful', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
             $attributes
         );
-        $tmp .= \html_writer::tag('td', $summary->successful_count(), $attributes);
+        $tmp .= \html_writer::tag('td', $successfulcount, $attributes);
         $resultrowattributes = $tablerowattributes;
+
+        // Compute success rate if no unknown or compilation errors, and resultcount > 0.
         $successrate = '?';
-        if ($summary->unknown_count() > 0 || $summary->compilation_error_count() > 0) {
-            $resultrowattributes['class'] .= ' ' . $unknownattributes;
-        } else {
-            $successrate = round(
-                ($summary->successful_count() / $summary->result_count()) * 100,
-                2
-            );
+        if ($unknowncount == 0 && $compilationcount == 0 && $resultcount > 0) {
+            $successrate = round(($successfulcount / $resultcount) * 100, 2);
             if ($successrate < 50) {
                 $resultrowattributes['class'] .= ' ' . $compilationerrorattributes;
             } else if ($successrate < 75) {
@@ -182,6 +213,9 @@ class dta_view_submission_utils {
             } else {
                 $resultrowattributes['class'] .= ' ' . $successattributes;
             }
+        } else {
+            // If unknown or compilation errors => highlight as unknown.
+            $resultrowattributes['class'] .= ' ' . $unknownattributes;
         }
         $body .= \html_writer::tag('tr', $tmp, $resultrowattributes);
 
@@ -192,9 +226,9 @@ class dta_view_submission_utils {
             get_string('failures', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
             $attributes
         );
-        $tmp .= \html_writer::tag('td', $summary->failed_count(), $attributes);
+        $tmp .= \html_writer::tag('td', $failedcount, $attributes);
         $resultrowattributes = $tablerowattributes;
-        if ($summary->failed_count() > 0) {
+        if ($failedcount > 0) {
             $resultrowattributes['class'] .= ' ' . $failureattributes;
         } else {
             $resultrowattributes['class'] .= ' ' . $successattributes;
@@ -208,9 +242,9 @@ class dta_view_submission_utils {
             get_string('compilation_errors', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
             $attributes
         );
-        $tmp .= \html_writer::tag('td', $summary->compilation_error_count(), $attributes);
+        $tmp .= \html_writer::tag('td', $compilationcount, $attributes);
         $resultrowattributes = $tablerowattributes;
-        if ($summary->compilation_error_count() > 0) {
+        if ($compilationcount > 0) {
             $resultrowattributes['class'] .= ' ' . $compilationerrorattributes;
         } else {
             $resultrowattributes['class'] .= ' ' . $successattributes;
@@ -224,68 +258,61 @@ class dta_view_submission_utils {
             get_string('unknown_state', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
             $attributes
         );
-        $tmp .= \html_writer::tag('td', $summary->unknown_count(), $attributes);
+        $tmp .= \html_writer::tag('td', $unknowncount, $attributes);
         $resultrowattributes = $tablerowattributes;
-        if ($summary->unknown_count() > 0) {
+        if ($unknowncount > 0) {
             $resultrowattributes['class'] .= ' ' . $unknownattributes;
         } else {
             $resultrowattributes['class'] .= ' ' . $successattributes;
         }
         $body .= \html_writer::tag('tr', $tmp, $resultrowattributes);
 
-        // Success rate.
+        // Success rate row.
         $tmp = '';
         $tmp .= \html_writer::tag(
             'td',
-            \html_writer::tag(
-                'b',
-                get_string('success_rate', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
-            ),
+            \html_writer::tag('b', get_string('success_rate', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)),
             $attributes
         );
-        $suffix = '?';
-        if ($summary->compilation_error_count() === 0 && $summary->unknown_count() === 0) {
-            $suffix = $summary->result_count() . ' (' . $successrate . '%)';
-        }
+        // If no compilation errors or unknown => show successrate, else "?".
+        $suffix = ($compilationcount == 0 && $unknowncount == 0 && $resultcount > 0)
+            ? ($resultcount . ' (' . $successrate . '%)')
+            : '?';
         $tmp .= \html_writer::tag(
             'td',
-            \html_writer::tag(
-                'b',
-                $summary->successful_count() . '/' . $suffix
-            ),
+            \html_writer::tag('b', $successfulcount . '/' . $suffix),
             $attributes
         );
 
         $resultrowattributes = $tablerowattributes;
-        if ($summary->unknown_count() > 0 || $summary->compilation_error_count() > 0) {
-            $resultrowattributes['class'] .= ' ' . $unknownattributes;
-        } else {
+        if ($compilationcount == 0 && $unknowncount == 0 && $resultcount > 0) {
             if ($successrate !== '?' && $successrate < 50) {
                 $resultrowattributes['class'] .= ' ' . $compilationerrorattributes;
             } else if ($successrate !== '?' && $successrate < 75) {
                 $resultrowattributes['class'] .= ' ' . $failureattributes;
-            } else if ($successrate !== '?') {
+            } else {
                 $resultrowattributes['class'] .= ' ' . $successattributes;
             }
+        } else {
+            $resultrowattributes['class'] .= ' ' . $unknownattributes;
         }
         $body .= \html_writer::tag('tr', $tmp, $resultrowattributes);
 
-        $body = \html_writer::tag('tbody', $body);
+        // Finalize the summary table.
+        $body  = \html_writer::tag('tbody', $body);
         $table = \html_writer::tag('table', $header . $body, ['class' => 'dtaTable']);
-
         $html .= $table;
 
-        // Add empty div for spacing after summary.
+        // Spacing after the summary table.
         $html .= \html_writer::empty_tag('div', ['class' => 'dtaSpacer']);
 
         // *** Recommendations Table ***
         if (!empty($recommendations)) {
-            // Sorting logic.
             $allowedsortfields = ['topic', 'exercise_name', 'difficulty', 'score'];
-            $allowedsortdirs = ['asc', 'desc'];
+            $allowedsortdirs   = ['asc', 'desc'];
 
-            $sortby = isset($_POST['sortby']) ? $_POST['sortby'] : 'score';
-            $sortdir = isset($_POST['sortdir']) ? $_POST['sortdir'] : 'asc';
+            $sortby  = $_POST['sortby']  ?? 'score';
+            $sortdir = $_POST['sortdir'] ?? 'asc';
 
             if (!in_array($sortby, $allowedsortfields)) {
                 $sortby = 'score';
@@ -307,7 +334,6 @@ class dta_view_submission_utils {
                 if ($comparison === 0) {
                     return 0;
                 }
-
                 if ($sortdir === 'asc') {
                     return ($comparison < 0) ? -1 : 1;
                 } else {
@@ -329,27 +355,27 @@ class dta_view_submission_utils {
 
                 // Sort button.
                 $button = \html_writer::empty_tag('input', [
-                    'type' => 'submit',
-                    'name' => 'sortbutton',
+                    'type'  => 'submit',
+                    'name'  => 'sortbutton',
                     'value' => ($newsortdir === 'asc' ? '↑' : '↓'),
                     'class' => 'sort-button',
                 ]);
 
                 // Hidden inputs.
                 $hiddeninputs = \html_writer::empty_tag('input', [
-                    'type' => 'hidden',
-                    'name' => 'sortby',
+                    'type'  => 'hidden',
+                    'name'  => 'sortby',
                     'value' => $columnname,
                 ]);
                 $hiddeninputs .= \html_writer::empty_tag('input', [
-                    'type' => 'hidden',
-                    'name' => 'sortdir',
+                    'type'  => 'hidden',
+                    'name'  => 'sortdir',
                     'value' => $newsortdir,
                 ]);
 
                 $form = \html_writer::start_tag('form', [
                     'method' => 'post',
-                    'style' => 'display:inline',
+                    'style'  => 'display:inline',
                 ]);
                 $form .= $hiddeninputs;
                 $form .= $displayname . ' ' . $button;
@@ -358,7 +384,7 @@ class dta_view_submission_utils {
                 return \html_writer::tag('th', $form, ['class' => $class]);
             };
 
-            // Table header for recommendations.
+            // Build the recommendations table header.
             $tableheader = '';
             $tableheader .= $generatesortableheader(
                 'topic',
@@ -405,13 +431,13 @@ class dta_view_submission_utils {
 
             $html .= \html_writer::tag('table', $tableheader . $tablebody, ['class' => 'dtaTable']);
 
-            // Add empty div for spacing after recommendations.
+            // Spacing after recommendations.
             $html .= \html_writer::empty_tag('div', ['class' => 'dtaSpacer']);
         }
 
         // *** Competency Assessment Table ***
         $body = '';
-        $tmp = '';
+        $tmp  = '';
         $tmp .= \html_writer::tag(
             'th',
             get_string('competencies', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
@@ -421,14 +447,24 @@ class dta_view_submission_utils {
         $header = \html_writer::tag('tr', $tmp, $tableheaderrowattributes);
         $header = \html_writer::tag('thead', $header);
 
-        $showncompetencies = explode(';', $summary->successfultestcompetencies);
+        $showncompetencies   = explode(';', $summary->successfultestcompetencies);
         $overallcompetencies = explode(';', $summary->overalltestcompetencies);
 
         for ($index = 0, $size = count($overallcompetencies); $index < $size; $index++) {
-            $comp = $overallcompetencies[$index];
+            $comp  = $overallcompetencies[$index];
             $shown = $showncompetencies[$index];
-            // If the competency was assessed, add a row in the table.
+
+            // If the competency was actually assessed, add a row in the table.
             if ($comp !== '0') {
+                $compval  = floatval($comp);
+                $shownval = floatval($shown);
+
+                // Guard division by zero:
+                $pct = 0;
+                if ($compval > 0) {
+                    $pct = (100.0 * $shownval / $compval);
+                }
+
                 $resultrowattributes = $tablerowattributes;
                 $tmp = '';
                 $tmp .= \html_writer::tag(
@@ -438,7 +474,7 @@ class dta_view_submission_utils {
                 );
                 $tmp .= \html_writer::tag(
                     'td',
-                    (100 * floatval($shown) / floatval($comp)) . '% (' . $shown . ' / ' . $comp . ')',
+                    round($pct, 2) . '% (' . $shown . ' / ' . $comp . ')',
                     $resultrowattributes
                 );
                 $tmp .= \html_writer::tag(
@@ -449,8 +485,8 @@ class dta_view_submission_utils {
                 $body .= \html_writer::tag('tr', $tmp, $resultrowattributes);
             }
         }
-        $body = \html_writer::tag('tbody', $body);
-        $html .= \html_writer::tag('table', $header . $body, ['class' => 'dtaTable']);
+        $body   = \html_writer::tag('tbody', $body);
+        $html  .= \html_writer::tag('table', $header . $body, ['class' => 'dtaTable']);
 
         // Add empty div for spacing.
         $html .= \html_writer::empty_tag('div', ['class' => 'dtaSpacer']);
@@ -466,7 +502,7 @@ class dta_view_submission_utils {
         $header = \html_writer::tag('tr', $tmp, $tableheaderrowattributes);
         $header = \html_writer::tag('thead', $header);
 
-        $body = '';
+        $body      = '';
         $spacerrow = null;
         foreach ($summary->results as $r) {
             // Add spacer first if not null.
@@ -521,7 +557,7 @@ class dta_view_submission_utils {
             );
             $body .= \html_writer::tag('tr', $tmp, $resultrowattributes);
 
-            // If state is different than successful, show additional info.
+            // If state != 1, show additional info.
             if ($r->state !== 1) {
                 $tmp = '';
                 $tmp .= \html_writer::tag(
diff --git a/dta/classes/models/dta_result_summary.php b/dta/classes/models/dta_result_summary.php
index 7659d47c649930f699a7b1057d81db00d7769e5b..541b02fbf4306ff7ee63abbafd3eca3490a7ab4c 100644
--- a/dta/classes/models/dta_result_summary.php
+++ b/dta/classes/models/dta_result_summary.php
@@ -1,125 +1,60 @@
 <?php
-// This file is part of Moodle - http://moodle.org/.
-// 
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-// 
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Entity class for DTA submission plugin result summary.
- *
- * @package    assignsubmission_dta
- * @copyright  2023 Gero Lueckemeyer and student project teams
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
 namespace assignsubmission_dta\models;
 
 /**
  * Entity class for DTA submission plugin result summary.
- *
- * @package    assignsubmission_dta
- * @copyright  2023 Gero Lueckemeyer and student project teams
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class dta_result_summary {
 
-    /**
-     * @var int $timestamp Timestamp for ordering and deletion of previous results.
-     */
     public $timestamp;
-
-    /**
-     * @var string $globalstacktrace Global stack trace if applicable, empty otherwise.
-     */
     public $globalstacktrace;
-
-    /**
-     * @var string $successfultestcompetencies Successfully tested competencies (tests and weights), or empty string.
-     */
     public $successfultestcompetencies;
-
-    /**
-     * @var string $overalltestcompetencies Overall tested competencies (tests and weights), or empty string.
-     */
     public $overalltestcompetencies;
-
-    /**
-     * @var array $results List of detail results.
-     */
     public $results;
 
-    /**
-     * Decodes the JSON result summary returned by the backend service call into the plugin PHP data structure.
-     *
-     * @param string $jsonstring JSON string containing DtaResultSummary.
-     * @return dta_result_summary The result summary.
-     */
     public static function assignsubmission_dta_decode_json(string $jsonstring): dta_result_summary {
         $response = json_decode($jsonstring);
 
         $summary = new dta_result_summary();
-        $summary->timestamp = $response->timestamp;
-        $summary->globalstacktrace = $response->globalstacktrace;
+        $summary->timestamp = $response->timestamp ?? 0;
+        $summary->globalstacktrace = $response->globalstacktrace ?? '';
 
         $summary->successfultestcompetencies = $response->successfulTestCompetencyProfile ?? '';
-        $summary->overalltestcompetencies = $response->overallTestCompetencyProfile ?? '';
+        $summary->overalltestcompetencies    = $response->overallTestCompetencyProfile ?? '';
 
-        $summary->results = self::assignsubmission_dta_decode_json_result_array($response->results);
+        if (!empty($response->results) && is_array($response->results)) {
+            $summary->results = self::assignsubmission_dta_decode_json_result_array($response->results);
+        } else {
+            $summary->results = [];
+        }
 
         return $summary;
     }
 
-    /**
-     * Decodes an array of JSON detail results into the plugin PHP data structure.
-     *
-     * @param array $jsonarray Decoded JSON array of results.
-     * @return array Array of dta_result objects.
-     */
     private static function assignsubmission_dta_decode_json_result_array(array $jsonarray): array {
         $ret = [];
         foreach ($jsonarray as $entry) {
             $value = new dta_result();
-            $value->packagename = $entry->packageName ?? '';
-            $value->classname = $entry->className ?? '';
-            $value->name = $entry->name ?? '';
-            $value->state = $entry->state ?? 0;
-            $value->failuretype = $entry->failureType ?? '';
-            $value->failurereason = $entry->failureReason ?? '';
-            $value->stacktrace = $entry->stacktrace ?? '';
-            $value->columnnumber = $entry->columnNumber ?? '';
-            $value->linenumber = $entry->lineNumber ?? '';
-            $value->position = $entry->position ?? '';
+            $value->packagename   = $entry->packageName     ?? '';
+            $value->classname     = $entry->className       ?? '';
+            $value->name          = $entry->name            ?? '';
+            $value->state         = $entry->state           ?? 0;
+            $value->failuretype   = $entry->failureType     ?? '';
+            $value->failurereason = $entry->failureReason   ?? '';
+            $value->stacktrace    = $entry->stacktrace      ?? '';
+            $value->columnnumber  = $entry->columnNumber    ?? 0;
+            $value->linenumber    = $entry->lineNumber      ?? 0;
+            $value->position      = $entry->position        ?? 0;
 
             $ret[] = $value;
         }
         return $ret;
     }
 
-    /**
-     * Returns the number of detail results attached to the summary.
-     *
-     * @return int Count of occurrences.
-     */
     public function assignsubmission_dta_result_count(): int {
         return count($this->results);
     }
 
-    /**
-     * Returns the number of detail results with the given state attached to the summary.
-     *
-     * @param int $state State ordinal number.
-     * @return int Count of occurrences for the provided state.
-     */
     public function assignsubmission_dta_state_occurence_count(int $state): int {
         $num = 0;
         foreach ($this->results as $r) {
@@ -130,39 +65,29 @@ class dta_result_summary {
         return $num;
     }
 
-    /**
-     * Returns the number of detail results with compilation errors attached to the summary.
-     *
-     * @return int Count of occurrences.
-     */
     public function assignsubmission_dta_compilation_error_count(): int {
-        return $this->assignsubmission_dta_state_occurence_count(3);
+        return $this->assignsubmission_dta_state_occurence_count(3); // State=3 => compile error
     }
 
-    /**
-     * Returns the number of detail results with test failures attached to the summary.
-     *
-     * @return int Count of occurrences.
-     */
     public function assignsubmission_dta_failed_count(): int {
-        return $this->assignsubmission_dta_state_occurence_count(2);
+        return $this->assignsubmission_dta_state_occurence_count(2); // State=2 => fail
     }
 
-    /**
-     * Returns the number of detail results with successful tests attached to the summary.
-     *
-     * @return int Count of occurrences.
-     */
     public function assignsubmission_dta_successful_count(): int {
-        return $this->assignsubmission_dta_state_occurence_count(1);
+        return $this->assignsubmission_dta_state_occurence_count(1); // State=1 => success
     }
 
-    /**
-     * Returns the number of detail results with an unknown result attached to the summary.
-     *
-     * @return int Count of occurrences.
-     */
     public function assignsubmission_dta_unknown_count(): int {
-        return $this->assignsubmission_dta_state_occurence_count(0);
+        return $this->assignsubmission_dta_state_occurence_count(0); // State=0 => unknown
+    }
+
+    // OPTIONAL: A helper to safely get success rate 0..100
+    public function assignsubmission_dta_success_rate(): float {
+        $count = $this->assignsubmission_dta_result_count();
+        if ($count === 0) {
+            return 0.0; 
+        }
+        $successful = $this->assignsubmission_dta_successful_count();
+        return ($successful / $count) * 100.0;
     }
 }
diff --git a/dta/classes/privacy/provider.php b/dta/classes/privacy/provider.php
index f310b379daf3bbe258ab9925e094b73a41550fec..acadff83f57dd0689c6a403f55f7067b2092516a 100644
--- a/dta/classes/privacy/provider.php
+++ b/dta/classes/privacy/provider.php
@@ -190,6 +190,8 @@ class provider implements \core_privacy\local\metadata\provider,
         // Delete records from assignsubmission_dta tables.
         $DB->delete_records('assignsubmission_dta_result', ['assignmentid' => $assignmentid]);
         $DB->delete_records('assignsubmission_dta_summary', ['assignmentid' => $assignmentid]);
+        $DB->delete_records('assignsubmission_dta_recommendations', ['assignmentid' => $assignmentid]);
+
     }
 
     /**
@@ -218,6 +220,10 @@ class provider implements \core_privacy\local\metadata\provider,
             'assignmentid' => $assignmentid,
             'submissionid' => $submissionid,
             ]);
+            $DB->delete_records('assignsubmission_dta_recommendations', [
+                'assignmentid' => $assignmentid,
+                'submissionid' => $submissionid,
+            ]);
     }
 
     /**
@@ -245,6 +251,7 @@ class provider implements \core_privacy\local\metadata\provider,
         $params['assignid'] = $deletedata->get_assignid();
         $DB->delete_records_select('assignsubmission_dta_result', "assignmentid = :assignid AND submissionid $sql", $params);
         $DB->delete_records_select('assignsubmission_dta_summary', "assignmentid = :assignid AND submissionid $sql", $params);
+        $DB->delete_records_select('assignsubmission_dta_recommendations', "assignmentid = :assignid AND submissionid $sql", $params);
     }
 
     /**
diff --git a/dta/locallib.php b/dta/locallib.php
index b0e9ba95320b9686dcf8c4ffcb6ea888e0be7094..546919d2cb66b35ed7e17ec8066d8dbc5986085e 100644
--- a/dta/locallib.php
+++ b/dta/locallib.php
@@ -55,7 +55,7 @@ class assign_submission_dta extends assign_submission_plugin {
      *
      * @return string
      */
-    public function assignsubmission_dta_get_name(): string {
+    public function get_name(): string {
         return get_string('pluginname', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME);
     }
 
@@ -65,7 +65,7 @@ class assign_submission_dta extends assign_submission_plugin {
      * @param MoodleQuickForm $mform Form to add elements to.
      * @return void
      */
-    public function assignsubmission_dta_get_settings(MoodleQuickForm $mform): void {
+    public function get_settings(MoodleQuickForm $mform): void {
         // Add draft filemanager to form.
         $mform->addElement(
             'filemanager',
@@ -131,7 +131,7 @@ class assign_submission_dta extends assign_submission_plugin {
      * @param stdClass $data Form data.
      * @return bool
      */
-    public function assignsubmission_dta_save_settings(stdClass $data): bool {
+    public function save_settings(stdClass $data): bool {
         // If the assignment has no filemanager for our plugin, just leave.
         $draftfilemanagerid = self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST;
         if (!isset($data->$draftfilemanagerid)) {
@@ -232,8 +232,8 @@ class assign_submission_dta extends assign_submission_plugin {
      * @param stdClass $submission Submission to check.
      * @return bool True if file count is zero.
      */
-    public function assignsubmission_dta_is_empty(stdClass $submission): bool {
-        return ($this->assignsubmission_dta_count_files(
+    public function is_empty(stdClass $submission): bool {
+        return ($this->count_files(
             $submission->id,
             self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION
         ) === 0);
@@ -246,7 +246,7 @@ class assign_submission_dta extends assign_submission_plugin {
      * @param string $areaid Filearea id to count.
      * @return int Number of files submitted in the filearea.
      */
-    private function assignsubmission_dta_count_files(int $submissionid, $areaid): int {
+    private function count_files(int $submissionid, $areaid): int {
         $fs = get_file_storage();
         $files = $fs->get_area_files(
             $this->assignment->get_context()->id,
@@ -279,7 +279,7 @@ class assign_submission_dta extends assign_submission_plugin {
         );
 
         // If submission is empty, leave directly.
-        if ($this->assignsubmission_dta_is_empty($submission)) {
+        if ($this->is_empty($submission)) {
             return true;
         }