Conversation
…ice: Introduce `onboarding-assistant.component.spec.ts` with comprehensive component behavior tests. Refactor `AuthService` for improved logout handling and inject dependencies. Update `auth.interceptor` to call `logoutLocally` on unauthorized errors.
…edgeCoverageController` for managing AI doc trees, implemented `FolderNodeDto` for hierarchical structure, enhanced telemetry logs, and added new frontend components for document tree display and filtering.
…mated cross-document consistency evaluations, introduced `AiConsistencyController` and DTOs to manage and expose consistency reports via API, and updated frontend to display results.
…anup and maintainability.
… for improved documentation organization. Reorganize AI architecture poster into the backlog and add comprehensive updates for AI-Arch doc. Polish Copilot UI layout and enhance layout consistency.
…ormalization with updates to AI-UI-INTEL-02 and ADR linkage. Add ADR-0075 and ADR-0099 references for formal decision tracking and archival.
…document cleanup and consistency. Update coverage report timestamps for synchronization. Adjust iterations and update timestamps in AI task documents for standardized tracking. Add related task references to multiple ADRs for improved traceability.
…tation for improved compliance and accountability.
… efficiency. Reorganize software development description in presentation, adjust risk item list initialization in backend, and ensure response list mutability in tests. Optimize HTML loops with $index tracking and synchronize SQL index conventions. Add user
…. Adjust AI documentation paths in `ai-admin.service.spec.ts` tests for improved accuracy. Update AI Knowledge Coverage Report timestamps for consistency.
…. Adjust AI documentation paths in `ai-admin.service.spec.ts` tests for improved accuracy. Update AI Knowledge Coverage Report timestamps for consistency.
- Switch Sonar project key to `JuergGood_angularai` for scripting and configuration - Add comprehensive unit tests for AI client retry logic - Introduce new frontend unit test suite for `BaseAiComponent` - Implement intro slides generating doc template - Expand `AiApplicationServiceTest` with delegation tests - Integrate branch detection in `sonar-analysis.sh` - Update `SonarProjectVersion` to `2.1.0` - Add `RiskRadarUseCaseImplTest` for risk analysis validation
…ed readability. Update image caption and adjust timeline details.
…, and other DTOs. Update dependencies and configuration in `pom.xml`. Adapt multiple test classes to `WebMvcTest`, introduce Mockito beans, and enhance IP masking logic in `ActionLogServiceTest`. Adjust `TaskParserService` date and time parsing, and refine presentation content for better readability.
# Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
…r enhanced clarity. Adjust column formatting for consistent layout in `goodone-intro.md` and `goodone-intro-img.md`.
…arity and consistency. Adjust descriptions and improve narrative flow.
…arity and consistency. Adjust phrasing, headings, and narrative flow to enhance readability and comprehension.
…arity and consistency. Adjust phrasing, headings, and narrative flow to enhance readability and comprehension.
…arity and consistency. Adjust phrasing, headings, and narrative flow for improved readability and comprehension.
…ed column layouts in `goodone-intro.md`. Adjust content for improved comprehension and consistency.
… for enhanced content structure and clarity.
| @@ -1,6 +1,6 @@ | |||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||
| import { AdrDriftComponent } from './adr-drift.component'; | |||
| import { AiService } from '../../services/ai.service'; | |||
| import { AiService, TaskGroup, TaskGroupType } from '../../services/ai.service'; | |||
Check notice
Code scanning / CodeQL
Unused variable, import, function or class Note test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 6 days ago
In general, unused imports should be removed or minimized so only the actually used symbols are imported. This improves readability and avoids confusion about expected usage.
Here, the best fix is to keep importing AiService (which is used in the TestBed provider configuration) and drop TaskGroup and TaskGroupType from the import statement. This is a simple textual change confined to the import line at the top of frontend/src/app/components/adr-drift/adr-drift.component.spec.ts. No new methods, variables, or additional imports are required.
| @@ -1,6 +1,6 @@ | ||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
| import { AdrDriftComponent } from './adr-drift.component'; | ||
| import { AiService, TaskGroup, TaskGroupType } from '../../services/ai.service'; | ||
| import { AiService } from '../../services/ai.service'; | ||
| import { AuthService } from '../../services/auth.service'; | ||
| import { SystemService } from '../../services/system.service'; | ||
| import { GoogleRecaptchaService } from '../../services/google-recaptcha.service'; |
| @@ -11,6 +11,7 @@ | |||
| import { describe, it, expect, beforeEach, vi } from 'vitest'; | |||
| import { provideRouter } from '@angular/router'; | |||
| import { MatDatepickerInputEvent } from '@angular/material/datepicker'; | |||
| import { AdrDriftResponse } from '../../models/retrospective.model'; | |||
Check notice
Code scanning / CodeQL
Unused variable, import, function or class Note test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 6 days ago
In general, to fix an unused import, you either start using it meaningfully in the code (if it was intended to be used) or remove it if it is unnecessary. Since none of the tests in this spec file use AdrDriftResponse, the simplest, behavior-preserving fix is to delete the unused import line.
Concretely, in frontend/src/app/components/adr-drift/adr-drift.component.spec.ts, remove line 14:
import { AdrDriftResponse } from '../../models/retrospective.model';No additional code, imports, or definitions are needed. This change does not affect runtime behavior or the existing test logic; it only cleans up an unused symbol.
| @@ -11,8 +11,8 @@ | ||
| import { describe, it, expect, beforeEach, vi } from 'vitest'; | ||
| import { provideRouter } from '@angular/router'; | ||
| import { MatDatepickerInputEvent } from '@angular/material/datepicker'; | ||
| import { AdrDriftResponse } from '../../models/retrospective.model'; | ||
|
|
||
|
|
||
| describe('AdrDriftComponent', () => { | ||
| let component: AdrDriftComponent; | ||
| let fixture: ComponentFixture<AdrDriftComponent>; |
| @@ -1,4 +1,4 @@ | |||
| import { Component, inject } from '@angular/core'; | |||
| import { Component, inject, signal } from '@angular/core'; | |||
Check notice
Code scanning / CodeQL
Unused variable, import, function or class Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 6 days ago
In general, unused imports should be removed from the import statement to keep the code clean and avoid linter/static-analysis violations.
Here, the best fix is to update the import from @angular/core so that it only imports the actually used symbols Component and inject, and drop signal. No other parts of the file need updating, since signal is not referenced anywhere else. This change is confined to frontend/src/app/components/error-boundary/error-boundary.component.ts, at the top of the file on line 1.
No additional methods, imports, or definitions are required; we only adjust the existing import list.
| @@ -1,4 +1,4 @@ | ||
| import { Component, inject, signal } from '@angular/core'; | ||
| import { Component, inject } from '@angular/core'; | ||
| import { CommonModule } from '@angular/common'; | ||
| import { MatCardModule } from '@angular/material/card'; | ||
| import { MatButtonModule } from '@angular/material/button'; |
| public AdrDriftResponse execute(AdrDriftRequest request) { | ||
| log.info("Detecting ADR drift for request: {}", request); | ||
| try { | ||
| log.info("Detecting ADR drift for request: {}", request); |
Check failure
Code scanning / CodeQL
Log Injection High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 6 days ago
In general, to fix log injection when logging user-provided data, either (a) avoid logging the raw user-controlled object/string entirely, or (b) sanitize it to remove or neutralize control characters (particularly \r and \n) and other problematic content before logging. Another option is to log only specific, non-sensitive, and simple fields (such as IDs) instead of the full request body.
For this specific case, the simplest fix that preserves existing functionality (diagnostic logging) while preventing injection is to stop logging the full AdrDriftRequest’s toString() and instead log a safe summary that does not depend on potentially multiline user content. For example, log just an identifier such as the sprint, and possibly a boolean indicating which options are set. Since we are constrained to only edit the shown snippets, the change will be confined to AdrDriftUseCaseImpl.execute. I will replace log.info("Detecting ADR drift for request: {}", request); with a log statement that uses a short, explicit message including only selected, low-risk fields from request (e.g., request.getSprintId() if available) or even no fields at all if we cannot safely access them without seeing the DTO. To stay within the visible code, the safest and minimal change is to drop the interpolation of request entirely, e.g., log.info("Detecting ADR drift for incoming request");, which removes the tainted sink while maintaining a useful trace that the method was invoked.
No new imports or helper methods are required; we only change the logging line in backend/src/main/java/ch/goodone/backend/ai/application/AdrDriftUseCaseImpl.java.
| @@ -59,7 +59,7 @@ | ||
| @Transactional(readOnly = true) | ||
| public AdrDriftResponse execute(AdrDriftRequest request) { | ||
| try { | ||
| log.info("Detecting ADR drift for request: {}", request); | ||
| log.info("Detecting ADR drift for incoming request"); | ||
|
|
||
| List<DocSource> adrSources = resolveAdrSources(request); | ||
| if (adrSources.isEmpty()) { |
| } | ||
|
|
||
| public OllamaBenchmarkDto runBenchmark(String feature, int iterations) { | ||
| log.info("Starting Ollama latency benchmark for feature: {}, iterations: {}", feature, iterations); |
Check failure
Code scanning / CodeQL
Log Injection High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 6 days ago
General fix approach: Sanitize or validate any user-provided data before logging it. For plain-text logs, this typically means stripping or normalizing control characters (especially \r/\n) and potentially restricting to a safer character set. The logging call should then use the sanitized value instead of the raw user input.
Best fix here: Introduce a small helper method in OllamaBenchmarkService that sanitizes log arguments by removing carriage return and newline characters from feature (and any future strings we choose to pass through it). Then, in runBenchmark, use this sanitized value in the log.info call, leaving the rest of the logic unchanged so functionality is preserved. We do not need new dependencies; a simple String.replace or regex replacement suffices.
Concrete changes:
-
In
backend/src/main/java/ch/goodone/backend/ai/evaluation/OllamaBenchmarkService.java:- Add a private helper
sanitizeForLog(String input)that returnsnullunchanged and otherwise strips\rand\n(and optionally other control characters if desired) from the string. - Modify the log statement on line 34 to call this helper for
feature, e.g.:String safeFeature = sanitizeForLog(feature); log.info("Starting Ollama latency benchmark for feature: {}, iterations: {}", safeFeature, iterations);
- Keep all other code intact.
- Add a private helper
-
No changes are required in
AiBenchmarkController, because we are not altering behavior, only how the value is logged.
No additional imports or external libraries are necessary; we rely purely on core String operations.
| @@ -30,8 +30,17 @@ | ||
| this.chatModel = chatModel; | ||
| } | ||
|
|
||
| private String sanitizeForLog(String input) { | ||
| if (input == null) { | ||
| return null; | ||
| } | ||
| // Remove CR and LF characters to prevent log injection via line breaks | ||
| return input.replace("\r", "").replace("\n", ""); | ||
| } | ||
|
|
||
| public OllamaBenchmarkDto runBenchmark(String feature, int iterations) { | ||
| log.info("Starting Ollama latency benchmark for feature: {}, iterations: {}", feature, iterations); | ||
| String safeFeature = sanitizeForLog(feature); | ||
| log.info("Starting Ollama latency benchmark for feature: {}, iterations: {}", safeFeature, iterations); | ||
| List<OllamaBenchmarkDto.CallSample> samples = new ArrayList<>(); | ||
|
|
||
| String testPrompt = getBaselinePrompt(feature); |
| .feature(feature) | ||
| .iterations(iterations) | ||
| .successfulCalls(successful) | ||
| .failedCalls(iterations - successful) |
Check failure
Code scanning / CodeQL
User-controlled data in arithmetic expression High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 6 days ago
In general, arithmetic on user-controlled integers should be guarded by validating or normalizing the input before use, or by constraining the result to a safe, non-negative range. Here, we are computing failedCalls as iterations - successful, where iterations may be negative or otherwise inconsistent with the actual number of samples. The best fix that preserves existing functionality is to derive failedCalls in a way that (a) does not underflow and (b) matches what the code conceptually means: number of calls attempted minus number of successful calls. Since samples already contains one entry per attempted iteration, and successful is the number of successful entries, we can compute failedCalls as samples.size() - successful. Both quantities are non‑negative and bounded by Integer.MAX_VALUE, so the subtraction cannot underflow in the current data model. Additionally, to avoid other oddities from pathological iterations values, we can clamp or validate iterations once in runBenchmark (e.g., enforce a minimum of 0 and a reasonable maximum) and propagate the normalized value through to aggregateResults. Within the constraints given, we will (1) change the failedCalls calculation to use samples.size() - successful, and (2) add a small normalization step for iterations in runBenchmark so extremely negative or huge values are not used directly in the loop or DTO.
Concretely:
- In
OllamaBenchmarkService.runBenchmark, introduce a localint normalizedIterationsthat ensuresiterationsis at least 0 and at most some safe upper bound (for example, 10_000), use it in the loop and when invokingaggregateResults. - In
OllamaBenchmarkService.aggregateResults, change.failedCalls(iterations - successful)to.failedCalls(samples.size() - successful). Both operands are non-negativeints, so no underflow arises, and the value correctly reflects the number of failed samples.
No new methods or external libraries are required; we only adjust existing logic.
| @@ -31,12 +31,14 @@ | ||
| } | ||
|
|
||
| public OllamaBenchmarkDto runBenchmark(String feature, int iterations) { | ||
| log.info("Starting Ollama latency benchmark for feature: {}, iterations: {}", feature, iterations); | ||
| // Normalize iterations to avoid negative or excessively large values from user input | ||
| int normalizedIterations = Math.max(0, Math.min(iterations, 10_000)); | ||
| log.info("Starting Ollama latency benchmark for feature: {}, iterations: {}", feature, normalizedIterations); | ||
| List<OllamaBenchmarkDto.CallSample> samples = new ArrayList<>(); | ||
|
|
||
| String testPrompt = getBaselinePrompt(feature); | ||
|
|
||
| for (int i = 0; i < iterations; i++) { | ||
| for (int i = 0; i < normalizedIterations; i++) { | ||
| long start = System.currentTimeMillis(); | ||
| try { | ||
| ChatResponse response = chatModel.call(new Prompt(new UserMessage(testPrompt))); | ||
| @@ -70,7 +68,7 @@ | ||
| } | ||
| } | ||
|
|
||
| return aggregateResults(feature, iterations, samples); | ||
| return aggregateResults(feature, normalizedIterations, samples); | ||
| } | ||
|
|
||
| private String getBaselinePrompt(String feature) { | ||
| @@ -122,7 +120,7 @@ | ||
| .feature(feature) | ||
| .iterations(iterations) | ||
| .successfulCalls(successful) | ||
| .failedCalls(iterations - successful) | ||
| .failedCalls(samples.size() - successful) | ||
| .averageLatencyMs(avgLatency) | ||
| .minLatencyMs(min) | ||
| .maxLatencyMs(max) |
| private NodeType type; | ||
| private DocumentCoverageDto metadata; | ||
| @Builder.Default | ||
| private List<FolderNodeDto> children = new ArrayList<>(); |
Check notice
Code scanning / CodeQL
Exposing internal representation Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 6 days ago
In general, to fix this problem we must prevent callers from obtaining and mutating the actual children list instance held inside FolderNodeDto. This can be done either by (1) returning an unmodifiable view of the list, or (2) returning a defensive copy (and similarly copying incoming lists in setters/constructors). Both approaches avoid exposing the mutable internal representation.
The best fix here, without changing existing functionality too much, is:
- Disable Lombok’s automatically generated getter and setter for
children. - Provide custom
getChildren()andsetChildren(...)methods:getChildren()should return an unmodifiable view (Collections.unmodifiableList(children)), which preserves the actual contents while preventing external modification through the returned reference.setChildren(List<FolderNodeDto> children)should make a defensive copy of the provided list (e.g.,this.children = new ArrayList<>(children);) or initialize an empty list ifnullis passed.
- We must also import
java.util.Collectionsto create the unmodifiable view. - All changes are confined to
backend/src/main/java/ch/goodone/backend/dto/FolderNodeDto.java. We will keep@Datafor the other fields, but override the generated accessors forchildrenby defining explicit methods with the same signatures.
| @@ -6,8 +6,8 @@ | ||
| import lombok.NoArgsConstructor; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
|
|
||
| /** | ||
| * DTO for hierarchical document tree nodes. | ||
| */ | ||
| @@ -23,6 +22,26 @@ | ||
| @Builder.Default | ||
| private List<FolderNodeDto> children = new ArrayList<>(); | ||
|
|
||
| /** | ||
| * Returns an unmodifiable view of the children list to avoid exposing | ||
| * the internal mutable representation. | ||
| */ | ||
| public List<FolderNodeDto> getChildren() { | ||
| return Collections.unmodifiableList(children); | ||
| } | ||
|
|
||
| /** | ||
| * Sets the children list using a defensive copy to avoid retaining | ||
| * references to externally mutable collections. | ||
| */ | ||
| public void setChildren(List<FolderNodeDto> children) { | ||
| if (children == null) { | ||
| this.children = new ArrayList<>(); | ||
| } else { | ||
| this.children = new ArrayList<>(children); | ||
| } | ||
| } | ||
|
|
||
| public enum NodeType { | ||
| FOLDER, FILE | ||
| } |
Qodana Community for JVM4 new problems were found
💡 Qodana analysis was run in the pull request mode: only the changed files were checked View the detailed Qodana reportTo be able to view the detailed Qodana report, you can either:
To get - name: 'Qodana Scan'
uses: JetBrains/qodana-action@v2024.3.4
with:
upload-result: trueContact Qodana teamContact us at qodana-support@jetbrains.com
|
…ile settings, and update test coverage for AI Copilot and routing services.
…clude index page references.
UX / UI Change PR
Scope
Acceptance criteria (must be explicit)
What changed (systemic first)
Screens / viewports verified
UX Regression Checklist (must all be ✅)
Theme & contrast
mat-icon-button+ destructive actions)Mobile space & layout
Responsive patterns
Maintainability
!important(or justified below)Justifications (required if any)
!importantadded because: