diff --git a/Avalonia_Apps/.github/copilot-instructions.md b/Avalonia_Apps/.github/copilot-instructions.md index 9c684e023..c311a9245 100644 --- a/Avalonia_Apps/.github/copilot-instructions.md +++ b/Avalonia_Apps/.github/copilot-instructions.md @@ -1,4 +1,52 @@ -# Copilot Instructions +# Repository instructions for GitHub Copilot -## Projektrichtlinien -- Im Projekt gilt die Regel: eine Klasse pro Datei, Ausnahme nur für zusammengehörige Paare `Foo` und `Foo`. \ No newline at end of file +Apply these defaults when working in this repository unless the user explicitly asks otherwise: + +## General Guidelines +- Document code thoroughly in English. +- Validate changes with relevant builds and tests before finishing. +- If requirements are unclear, ask clarifying questions before starting implementation or planning refinement. +- Avoid UI text strings in core services. Use Enumerations instead, and keep UI-facing strings in the ViewModel/UI layer. +- Prefer one class/interface/struct per file. +- Document changes in a DevOps manner using Markdown, extrapolating bugs, tasks, backlogs, and features. +- Use `DevOps` as the planning directory in this workspace, and treat `.Info.md` as the general planning description file. Team terminology around Azure DevOps backlog items may differ from generic 'story' naming. +- When reviewing build warnings in this repository, ignore unsupported older framework warnings if the project also targets newer supported frameworks. Additionally, ignore `IDE0130` warnings in test projects. +- Keep project-specific decisions in the repository `DevOps` folder; do not store them in memory for this repository. Use memory only for general solution-wide working preferences. +- Planning should be done step by step in the `DevOps` directory with a Scrum-oriented structure. +- Extract complex UI elements into separate widgets/components to keep main windows clean and simple. + +## Testing +- Use `MSTest` in the latest practical version for new or updated tests. +- Use `NSubstitute` for mocks, stubs, and substitutes in tests. +- Prefer `DataRow` for parameterized single-test scenarios. + +## Internationalization +- Keep I18N in mind when writing code, ensuring it can be easily adapted for different languages and regions. + +## Architecture +- Use MVVM architecture for UI components to separate concerns and improve testability, using CommunityToolkit.Mvvm for MVVM implementation. +- Prefer `NotifyPropertyChangedFor` over manual `OnPropertyChanged(nameof(...))` in CommunityToolkit.Mvvm observable properties where applicable. +- Use Dependency Injection to manage dependencies and improve testability, using Microsoft.Extensions.DependencyInjection. +- UI-facing strings and summary formatting should stay in the ViewModel/UI layer, not in extracted application logic services. + +## Naming Conventions +- Distinguish between UI control naming and variable/field naming. +- Use PascalCase for class names, method names, and properties. +- Use `_camelCase` for private fields. +- Use `camelCase` for local variables and parameters. +- Use short 1-character prefixes for simple types only when they meaningfully disambiguate, e.g. + - `s` for `string` + - `i` for signed integer types + - `u` for unsigned integer types + - `x` for `bool` + - `f` for `float`, `double`, or `decimal` +- Prefer meaningful domain names over type prefixes when the intent is already clear. +- In UI code, use short 3-character prefixes for actual controls in views and code-behind, e.g. + - `lst` for list controls + - `btn` for all kinds of buttons + - `edt` for any keyboard input control + - `lbl` for any text output control +- Do not use UI control prefixes for ViewModel properties or other non-UI members. + +## Nullability +- Use strict nullable reference types to indicate when a variable can be null, and handle nullability appropriately in code. diff --git a/Avalonia_Apps/AA16_UserControl/AA16_Usercontrol1/Directory.Packages.props b/Avalonia_Apps/AA16_UserControl/AA16_Usercontrol1/Directory.Packages.props index b2047f1c5..f2e4b2002 100644 --- a/Avalonia_Apps/AA16_UserControl/AA16_Usercontrol1/Directory.Packages.props +++ b/Avalonia_Apps/AA16_UserControl/AA16_Usercontrol1/Directory.Packages.props @@ -9,7 +9,7 @@ - + diff --git a/Avalonia_Apps/AA21_Buttons/Directory.Packages.props b/Avalonia_Apps/AA21_Buttons/Directory.Packages.props index 190c4d639..94540e818 100644 --- a/Avalonia_Apps/AA21_Buttons/Directory.Packages.props +++ b/Avalonia_Apps/AA21_Buttons/Directory.Packages.props @@ -23,7 +23,7 @@ - + diff --git a/Avalonia_Apps/AvlnSamples/Avln_AnimationTiming/Avln_AnimationTiming.csproj b/Avalonia_Apps/AvlnSamples/Avln_AnimationTiming/Avln_AnimationTiming.csproj index 64d1f8953..0dd6d72dc 100644 --- a/Avalonia_Apps/AvlnSamples/Avln_AnimationTiming/Avln_AnimationTiming.csproj +++ b/Avalonia_Apps/AvlnSamples/Avln_AnimationTiming/Avln_AnimationTiming.csproj @@ -44,7 +44,7 @@ - + diff --git a/Avalonia_Apps/AvlnSamples/Avln_AnimationTimingTests/Avln_AnimationTimingTests.csproj b/Avalonia_Apps/AvlnSamples/Avln_AnimationTimingTests/Avln_AnimationTimingTests.csproj index de53f4cc3..f2cb13294 100644 --- a/Avalonia_Apps/AvlnSamples/Avln_AnimationTimingTests/Avln_AnimationTimingTests.csproj +++ b/Avalonia_Apps/AvlnSamples/Avln_AnimationTimingTests/Avln_AnimationTimingTests.csproj @@ -11,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Avalonia_Apps/AvlnSamples/Avln_Brushes/Avln_Brushes.csproj b/Avalonia_Apps/AvlnSamples/Avln_Brushes/Avln_Brushes.csproj index 551245854..4a6c5fb89 100644 --- a/Avalonia_Apps/AvlnSamples/Avln_Brushes/Avln_Brushes.csproj +++ b/Avalonia_Apps/AvlnSamples/Avln_Brushes/Avln_Brushes.csproj @@ -28,7 +28,7 @@ - + diff --git a/Avalonia_Apps/AvlnSamples/Avln_Complex_Layout/Avln_Complex_Layout.csproj b/Avalonia_Apps/AvlnSamples/Avln_Complex_Layout/Avln_Complex_Layout.csproj index 77e663dba..6f6db7d8e 100644 --- a/Avalonia_Apps/AvlnSamples/Avln_Complex_Layout/Avln_Complex_Layout.csproj +++ b/Avalonia_Apps/AvlnSamples/Avln_Complex_Layout/Avln_Complex_Layout.csproj @@ -24,7 +24,7 @@ - + diff --git a/Avalonia_Apps/AvlnSamples/Avln_CustomAnimation/Avln_CustomAnimation.csproj b/Avalonia_Apps/AvlnSamples/Avln_CustomAnimation/Avln_CustomAnimation.csproj index cb18cc10e..38e960e9c 100644 --- a/Avalonia_Apps/AvlnSamples/Avln_CustomAnimation/Avln_CustomAnimation.csproj +++ b/Avalonia_Apps/AvlnSamples/Avln_CustomAnimation/Avln_CustomAnimation.csproj @@ -17,7 +17,7 @@ - + diff --git a/Avalonia_Apps/AvlnSamples/Avln_Geometry/Avln_Geometry.csproj b/Avalonia_Apps/AvlnSamples/Avln_Geometry/Avln_Geometry.csproj index d5a0d1020..2bf00eb81 100644 --- a/Avalonia_Apps/AvlnSamples/Avln_Geometry/Avln_Geometry.csproj +++ b/Avalonia_Apps/AvlnSamples/Avln_Geometry/Avln_Geometry.csproj @@ -30,7 +30,7 @@ - + diff --git a/Avalonia_Apps/AvlnSamples/Avln_Hello_World/Avln_Hello_World.csproj b/Avalonia_Apps/AvlnSamples/Avln_Hello_World/Avln_Hello_World.csproj index fa27176fa..c0634e8b9 100644 --- a/Avalonia_Apps/AvlnSamples/Avln_Hello_World/Avln_Hello_World.csproj +++ b/Avalonia_Apps/AvlnSamples/Avln_Hello_World/Avln_Hello_World.csproj @@ -24,7 +24,7 @@ - + diff --git a/Avalonia_Apps/AvlnSamples/Avln_Hello_WorldTests/Avln_Hello_WorldTests.csproj b/Avalonia_Apps/AvlnSamples/Avln_Hello_WorldTests/Avln_Hello_WorldTests.csproj index be7c90cde..f062d5161 100644 --- a/Avalonia_Apps/AvlnSamples/Avln_Hello_WorldTests/Avln_Hello_WorldTests.csproj +++ b/Avalonia_Apps/AvlnSamples/Avln_Hello_WorldTests/Avln_Hello_WorldTests.csproj @@ -11,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Avalonia_Apps/AvlnSamples/Avln_ImageView/Avln_ImageView.csproj b/Avalonia_Apps/AvlnSamples/Avln_ImageView/Avln_ImageView.csproj index 73c225143..bbc0bfe7f 100644 --- a/Avalonia_Apps/AvlnSamples/Avln_ImageView/Avln_ImageView.csproj +++ b/Avalonia_Apps/AvlnSamples/Avln_ImageView/Avln_ImageView.csproj @@ -18,7 +18,7 @@ - + diff --git a/Avalonia_Apps/AvlnSamples/Avln_IntegrationTestApp/Avln_IntegrationTestApp.csproj b/Avalonia_Apps/AvlnSamples/Avln_IntegrationTestApp/Avln_IntegrationTestApp.csproj index 4843a87a5..11808d1a0 100644 --- a/Avalonia_Apps/AvlnSamples/Avln_IntegrationTestApp/Avln_IntegrationTestApp.csproj +++ b/Avalonia_Apps/AvlnSamples/Avln_IntegrationTestApp/Avln_IntegrationTestApp.csproj @@ -28,7 +28,7 @@ - + diff --git a/Avalonia_Apps/AvlnSamples/Avln_MoveWindow/Avln_MoveWindow.csproj b/Avalonia_Apps/AvlnSamples/Avln_MoveWindow/Avln_MoveWindow.csproj index acb1f3edf..e3cbceb45 100644 --- a/Avalonia_Apps/AvlnSamples/Avln_MoveWindow/Avln_MoveWindow.csproj +++ b/Avalonia_Apps/AvlnSamples/Avln_MoveWindow/Avln_MoveWindow.csproj @@ -24,7 +24,7 @@ - + diff --git a/Avalonia_Apps/AvlnSamples/Avln_MoveWindowTests/Avln_MoveWindowTests.csproj b/Avalonia_Apps/AvlnSamples/Avln_MoveWindowTests/Avln_MoveWindowTests.csproj index eff889143..bc7497dea 100644 --- a/Avalonia_Apps/AvlnSamples/Avln_MoveWindowTests/Avln_MoveWindowTests.csproj +++ b/Avalonia_Apps/AvlnSamples/Avln_MoveWindowTests/Avln_MoveWindowTests.csproj @@ -11,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Avalonia_Apps/AvlnSamples/Avln_RenderDemo/Avln_RenderDemo.csproj b/Avalonia_Apps/AvlnSamples/Avln_RenderDemo/Avln_RenderDemo.csproj index 439aaa42c..cee076ff3 100644 --- a/Avalonia_Apps/AvlnSamples/Avln_RenderDemo/Avln_RenderDemo.csproj +++ b/Avalonia_Apps/AvlnSamples/Avln_RenderDemo/Avln_RenderDemo.csproj @@ -18,7 +18,7 @@ - + diff --git a/Avalonia_Apps/AvlnSamples/Avln_Sample_Template/Avln_Sample_Template.csproj b/Avalonia_Apps/AvlnSamples/Avln_Sample_Template/Avln_Sample_Template.csproj index dc7fbe676..192d1f127 100644 --- a/Avalonia_Apps/AvlnSamples/Avln_Sample_Template/Avln_Sample_Template.csproj +++ b/Avalonia_Apps/AvlnSamples/Avln_Sample_Template/Avln_Sample_Template.csproj @@ -24,7 +24,7 @@ - + diff --git a/Avalonia_Apps/Libraries/Avln_BaseLib/Avln_BaseLib.csproj b/Avalonia_Apps/Libraries/Avln_BaseLib/Avln_BaseLib.csproj index e986b9b5a..7ef5843ed 100644 --- a/Avalonia_Apps/Libraries/Avln_BaseLib/Avln_BaseLib.csproj +++ b/Avalonia_Apps/Libraries/Avln_BaseLib/Avln_BaseLib.csproj @@ -29,7 +29,7 @@ - + diff --git a/Avalonia_Apps/Libraries/Avln_BaseLibTests/Avln_BaseLibTests.csproj b/Avalonia_Apps/Libraries/Avln_BaseLibTests/Avln_BaseLibTests.csproj index 151cd9e6f..f02dc2086 100644 --- a/Avalonia_Apps/Libraries/Avln_BaseLibTests/Avln_BaseLibTests.csproj +++ b/Avalonia_Apps/Libraries/Avln_BaseLibTests/Avln_BaseLibTests.csproj @@ -18,7 +18,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Avalonia_Apps/Libraries/BaseLib/BaseLib.csproj b/Avalonia_Apps/Libraries/BaseLib/BaseLib.csproj index c6fd681ff..e81b727d4 100644 --- a/Avalonia_Apps/Libraries/BaseLib/BaseLib.csproj +++ b/Avalonia_Apps/Libraries/BaseLib/BaseLib.csproj @@ -31,6 +31,6 @@ - + \ No newline at end of file diff --git a/Avalonia_Apps/Libraries/BaseLibTests/BaseLibTests.csproj b/Avalonia_Apps/Libraries/BaseLibTests/BaseLibTests.csproj index 8d729d6ba..838f80605 100644 --- a/Avalonia_Apps/Libraries/BaseLibTests/BaseLibTests.csproj +++ b/Avalonia_Apps/Libraries/BaseLibTests/BaseLibTests.csproj @@ -16,7 +16,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Avalonia_Apps/Libraries/BaseLibTests/Models/FileProxyTests.cs b/Avalonia_Apps/Libraries/BaseLibTests/Models/FileProxyTests.cs index d01734aff..a5821bf1c 100644 --- a/Avalonia_Apps/Libraries/BaseLibTests/Models/FileProxyTests.cs +++ b/Avalonia_Apps/Libraries/BaseLibTests/Models/FileProxyTests.cs @@ -26,7 +26,7 @@ public void TestCleanup() Directory.Delete(_sTestDirectory, recursive: true); } - [DataTestMethod] + [TestMethod] [DataRow(false)] [DataRow(true)] public void Exists_ForFilePresence_ReturnsExpectedResult(bool xCreateFile) @@ -84,7 +84,7 @@ public void OpenRead_ForExistingFile_ReturnsReadableStream() CollectionAssert.AreEqual(rgBytes, stmMemory.ToArray()); } - [DataTestMethod] + [TestMethod] [DataRow("Plain UTF8 text")] [DataRow("äöü ß Ελληνικά")] public void WriteAllText_WithoutEncoding_WritesReadableUtf8Content(string sContents) @@ -96,7 +96,7 @@ public void WriteAllText_WithoutEncoding_WritesReadableUtf8Content(string sConte Assert.AreEqual(sContents, File.ReadAllText(sPath)); } - [DataTestMethod] + [TestMethod] [DataRow("Plain UTF8 text")] [DataRow("äöü ß Ελληνικά")] public void ReadAllText_WithoutEncoding_ReturnsFileContent(string sContents) @@ -168,7 +168,7 @@ public void Delete_RemovesFile() Assert.IsFalse(File.Exists(sPath)); } - [DataTestMethod] + [TestMethod] [DataRow(false, "source")] [DataRow(true, "new")] public void Copy_CopiesFileToDestination(bool xOverwrite, string sExpectedDestinationContent) diff --git a/Avalonia_Apps/Packages.props b/Avalonia_Apps/Packages.props index ddaff1811..354b33d12 100644 --- a/Avalonia_Apps/Packages.props +++ b/Avalonia_Apps/Packages.props @@ -16,7 +16,7 @@ - + @@ -25,16 +25,16 @@ - - - - - + + + + + - + diff --git a/Avalonia_Apps/RenderImage.BaseTests/RenderImage.BaseTests.csproj b/Avalonia_Apps/RenderImage.BaseTests/RenderImage.BaseTests.csproj index 53de2cc54..456a9025f 100644 --- a/Avalonia_Apps/RenderImage.BaseTests/RenderImage.BaseTests.csproj +++ b/Avalonia_Apps/RenderImage.BaseTests/RenderImage.BaseTests.csproj @@ -10,7 +10,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CSharpBible/AboutEx/AboutEx.csproj b/CSharpBible/AboutEx/AboutEx.csproj index 9812e723f..3933b06e0 100644 --- a/CSharpBible/AboutEx/AboutEx.csproj +++ b/CSharpBible/AboutEx/AboutEx.csproj @@ -14,7 +14,7 @@ - + diff --git a/CSharpBible/AboutExTests/AboutExTests.csproj b/CSharpBible/AboutExTests/AboutExTests.csproj index 18492525f..2ee59e5f1 100644 --- a/CSharpBible/AboutExTests/AboutExTests.csproj +++ b/CSharpBible/AboutExTests/AboutExTests.csproj @@ -14,7 +14,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CSharpBible/Basics/Basic_Del00_Template/Basic_Del00_Template.csproj b/CSharpBible/Basics/Basic_Del00_Template/Basic_Del00_Template.csproj index 45cf4cdd8..90eec24df 100644 --- a/CSharpBible/Basics/Basic_Del00_Template/Basic_Del00_Template.csproj +++ b/CSharpBible/Basics/Basic_Del00_Template/Basic_Del00_Template.csproj @@ -16,7 +16,7 @@ - + diff --git a/CSharpBible/Basics/Basic_Del00_TemplateTests/Basic_Del00_TemplateTests.csproj b/CSharpBible/Basics/Basic_Del00_TemplateTests/Basic_Del00_TemplateTests.csproj index c5f6bc9db..840ed1abf 100644 --- a/CSharpBible/Basics/Basic_Del00_TemplateTests/Basic_Del00_TemplateTests.csproj +++ b/CSharpBible/Basics/Basic_Del00_TemplateTests/Basic_Del00_TemplateTests.csproj @@ -15,7 +15,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CSharpBible/Basics/Basic_Del01_Action/Basic_Del01_Action.csproj b/CSharpBible/Basics/Basic_Del01_Action/Basic_Del01_Action.csproj index 34744af43..3dbf05405 100644 --- a/CSharpBible/Basics/Basic_Del01_Action/Basic_Del01_Action.csproj +++ b/CSharpBible/Basics/Basic_Del01_Action/Basic_Del01_Action.csproj @@ -19,7 +19,7 @@ - + diff --git a/CSharpBible/Basics/Basic_Del01_ActionTests/Basic_Del01_ActionTests.csproj b/CSharpBible/Basics/Basic_Del01_ActionTests/Basic_Del01_ActionTests.csproj index 2dfe0441e..24ef99e54 100644 --- a/CSharpBible/Basics/Basic_Del01_ActionTests/Basic_Del01_ActionTests.csproj +++ b/CSharpBible/Basics/Basic_Del01_ActionTests/Basic_Del01_ActionTests.csproj @@ -15,7 +15,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CSharpBible/Basics/Basic_Del02_Filter/Basic_Del02_Filter.csproj b/CSharpBible/Basics/Basic_Del02_Filter/Basic_Del02_Filter.csproj index ba3ec99c5..c766b74af 100644 --- a/CSharpBible/Basics/Basic_Del02_Filter/Basic_Del02_Filter.csproj +++ b/CSharpBible/Basics/Basic_Del02_Filter/Basic_Del02_Filter.csproj @@ -19,7 +19,7 @@ - + diff --git a/CSharpBible/Basics/Basic_Del02_FilterTests/Basic_Del02_FilterTests.csproj b/CSharpBible/Basics/Basic_Del02_FilterTests/Basic_Del02_FilterTests.csproj index c4c3bd395..a4b173e4a 100644 --- a/CSharpBible/Basics/Basic_Del02_FilterTests/Basic_Del02_FilterTests.csproj +++ b/CSharpBible/Basics/Basic_Del02_FilterTests/Basic_Del02_FilterTests.csproj @@ -15,7 +15,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CSharpBible/Basics/Basic_Del03_General/Basic_Del03_General.csproj b/CSharpBible/Basics/Basic_Del03_General/Basic_Del03_General.csproj index a57d3d602..d14fbc4b2 100644 --- a/CSharpBible/Basics/Basic_Del03_General/Basic_Del03_General.csproj +++ b/CSharpBible/Basics/Basic_Del03_General/Basic_Del03_General.csproj @@ -16,7 +16,7 @@ - + diff --git a/CSharpBible/Basics/Basic_Del03_GeneralTests/Basic_Del03_GeneralTests.csproj b/CSharpBible/Basics/Basic_Del03_GeneralTests/Basic_Del03_GeneralTests.csproj index 4866b24ff..a2b91e72b 100644 --- a/CSharpBible/Basics/Basic_Del03_GeneralTests/Basic_Del03_GeneralTests.csproj +++ b/CSharpBible/Basics/Basic_Del03_GeneralTests/Basic_Del03_GeneralTests.csproj @@ -15,7 +15,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CSharpBible/Basics/Basic_Del04_TestImposibleStuff/Basic_Del04_TestImposibleStuff.csproj b/CSharpBible/Basics/Basic_Del04_TestImposibleStuff/Basic_Del04_TestImposibleStuff.csproj index 9cdc5f0c1..502fb53b7 100644 --- a/CSharpBible/Basics/Basic_Del04_TestImposibleStuff/Basic_Del04_TestImposibleStuff.csproj +++ b/CSharpBible/Basics/Basic_Del04_TestImposibleStuff/Basic_Del04_TestImposibleStuff.csproj @@ -16,7 +16,7 @@ - + diff --git a/CSharpBible/Basics/Basic_Del04_TestImposibleStuffTests/Basic_Del04_TestImposibleStuffTests.csproj b/CSharpBible/Basics/Basic_Del04_TestImposibleStuffTests/Basic_Del04_TestImposibleStuffTests.csproj index dffc503a3..4a669f5ba 100644 --- a/CSharpBible/Basics/Basic_Del04_TestImposibleStuffTests/Basic_Del04_TestImposibleStuffTests.csproj +++ b/CSharpBible/Basics/Basic_Del04_TestImposibleStuffTests/Basic_Del04_TestImposibleStuffTests.csproj @@ -15,7 +15,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CSharpBible/Calc/.github/copilot-instructions.md b/CSharpBible/Calc/.github/copilot-instructions.md new file mode 100644 index 000000000..c311a9245 --- /dev/null +++ b/CSharpBible/Calc/.github/copilot-instructions.md @@ -0,0 +1,52 @@ +# Repository instructions for GitHub Copilot + +Apply these defaults when working in this repository unless the user explicitly asks otherwise: + +## General Guidelines +- Document code thoroughly in English. +- Validate changes with relevant builds and tests before finishing. +- If requirements are unclear, ask clarifying questions before starting implementation or planning refinement. +- Avoid UI text strings in core services. Use Enumerations instead, and keep UI-facing strings in the ViewModel/UI layer. +- Prefer one class/interface/struct per file. +- Document changes in a DevOps manner using Markdown, extrapolating bugs, tasks, backlogs, and features. +- Use `DevOps` as the planning directory in this workspace, and treat `.Info.md` as the general planning description file. Team terminology around Azure DevOps backlog items may differ from generic 'story' naming. +- When reviewing build warnings in this repository, ignore unsupported older framework warnings if the project also targets newer supported frameworks. Additionally, ignore `IDE0130` warnings in test projects. +- Keep project-specific decisions in the repository `DevOps` folder; do not store them in memory for this repository. Use memory only for general solution-wide working preferences. +- Planning should be done step by step in the `DevOps` directory with a Scrum-oriented structure. +- Extract complex UI elements into separate widgets/components to keep main windows clean and simple. + +## Testing +- Use `MSTest` in the latest practical version for new or updated tests. +- Use `NSubstitute` for mocks, stubs, and substitutes in tests. +- Prefer `DataRow` for parameterized single-test scenarios. + +## Internationalization +- Keep I18N in mind when writing code, ensuring it can be easily adapted for different languages and regions. + +## Architecture +- Use MVVM architecture for UI components to separate concerns and improve testability, using CommunityToolkit.Mvvm for MVVM implementation. +- Prefer `NotifyPropertyChangedFor` over manual `OnPropertyChanged(nameof(...))` in CommunityToolkit.Mvvm observable properties where applicable. +- Use Dependency Injection to manage dependencies and improve testability, using Microsoft.Extensions.DependencyInjection. +- UI-facing strings and summary formatting should stay in the ViewModel/UI layer, not in extracted application logic services. + +## Naming Conventions +- Distinguish between UI control naming and variable/field naming. +- Use PascalCase for class names, method names, and properties. +- Use `_camelCase` for private fields. +- Use `camelCase` for local variables and parameters. +- Use short 1-character prefixes for simple types only when they meaningfully disambiguate, e.g. + - `s` for `string` + - `i` for signed integer types + - `u` for unsigned integer types + - `x` for `bool` + - `f` for `float`, `double`, or `decimal` +- Prefer meaningful domain names over type prefixes when the intent is already clear. +- In UI code, use short 3-character prefixes for actual controls in views and code-behind, e.g. + - `lst` for list controls + - `btn` for all kinds of buttons + - `edt` for any keyboard input control + - `lbl` for any text output control +- Do not use UI control prefixes for ViewModel properties or other non-UI members. + +## Nullability +- Use strict nullable reference types to indicate when a variable can be null, and handle nullability appropriately in code. diff --git a/CSharpBible/Calc/Directory.Packages.props b/CSharpBible/Calc/Directory.Packages.props index 4c99120d1..83f367407 100644 --- a/CSharpBible/Calc/Directory.Packages.props +++ b/CSharpBible/Calc/Directory.Packages.props @@ -18,7 +18,7 @@ - + @@ -28,7 +28,7 @@ - + diff --git a/CSharpBible/CharGrid/CharGrid.csproj b/CSharpBible/CharGrid/CharGrid.csproj index f78dfc53e..07a77bdb7 100644 --- a/CSharpBible/CharGrid/CharGrid.csproj +++ b/CSharpBible/CharGrid/CharGrid.csproj @@ -11,7 +11,7 @@ - + diff --git a/CSharpBible/ConsoleApps/.github/copilot-instructions.md b/CSharpBible/ConsoleApps/.github/copilot-instructions.md new file mode 100644 index 000000000..c311a9245 --- /dev/null +++ b/CSharpBible/ConsoleApps/.github/copilot-instructions.md @@ -0,0 +1,52 @@ +# Repository instructions for GitHub Copilot + +Apply these defaults when working in this repository unless the user explicitly asks otherwise: + +## General Guidelines +- Document code thoroughly in English. +- Validate changes with relevant builds and tests before finishing. +- If requirements are unclear, ask clarifying questions before starting implementation or planning refinement. +- Avoid UI text strings in core services. Use Enumerations instead, and keep UI-facing strings in the ViewModel/UI layer. +- Prefer one class/interface/struct per file. +- Document changes in a DevOps manner using Markdown, extrapolating bugs, tasks, backlogs, and features. +- Use `DevOps` as the planning directory in this workspace, and treat `.Info.md` as the general planning description file. Team terminology around Azure DevOps backlog items may differ from generic 'story' naming. +- When reviewing build warnings in this repository, ignore unsupported older framework warnings if the project also targets newer supported frameworks. Additionally, ignore `IDE0130` warnings in test projects. +- Keep project-specific decisions in the repository `DevOps` folder; do not store them in memory for this repository. Use memory only for general solution-wide working preferences. +- Planning should be done step by step in the `DevOps` directory with a Scrum-oriented structure. +- Extract complex UI elements into separate widgets/components to keep main windows clean and simple. + +## Testing +- Use `MSTest` in the latest practical version for new or updated tests. +- Use `NSubstitute` for mocks, stubs, and substitutes in tests. +- Prefer `DataRow` for parameterized single-test scenarios. + +## Internationalization +- Keep I18N in mind when writing code, ensuring it can be easily adapted for different languages and regions. + +## Architecture +- Use MVVM architecture for UI components to separate concerns and improve testability, using CommunityToolkit.Mvvm for MVVM implementation. +- Prefer `NotifyPropertyChangedFor` over manual `OnPropertyChanged(nameof(...))` in CommunityToolkit.Mvvm observable properties where applicable. +- Use Dependency Injection to manage dependencies and improve testability, using Microsoft.Extensions.DependencyInjection. +- UI-facing strings and summary formatting should stay in the ViewModel/UI layer, not in extracted application logic services. + +## Naming Conventions +- Distinguish between UI control naming and variable/field naming. +- Use PascalCase for class names, method names, and properties. +- Use `_camelCase` for private fields. +- Use `camelCase` for local variables and parameters. +- Use short 1-character prefixes for simple types only when they meaningfully disambiguate, e.g. + - `s` for `string` + - `i` for signed integer types + - `u` for unsigned integer types + - `x` for `bool` + - `f` for `float`, `double`, or `decimal` +- Prefer meaningful domain names over type prefixes when the intent is already clear. +- In UI code, use short 3-character prefixes for actual controls in views and code-behind, e.g. + - `lst` for list controls + - `btn` for all kinds of buttons + - `edt` for any keyboard input control + - `lbl` for any text output control +- Do not use UI control prefixes for ViewModel properties or other non-UI members. + +## Nullability +- Use strict nullable reference types to indicate when a variable can be null, and handle nullability appropriately in code. diff --git a/CSharpBible/ConsoleApps/ConsoleMouseApp/ConsoleMouseApp.csproj b/CSharpBible/ConsoleApps/ConsoleMouseApp/ConsoleMouseApp.csproj index 9611e8853..b492bf487 100644 --- a/CSharpBible/ConsoleApps/ConsoleMouseApp/ConsoleMouseApp.csproj +++ b/CSharpBible/ConsoleApps/ConsoleMouseApp/ConsoleMouseApp.csproj @@ -24,7 +24,7 @@ - + diff --git a/CSharpBible/ConsoleApps/ConsoleMouseApp/ConsoleMouseApp_net.csproj b/CSharpBible/ConsoleApps/ConsoleMouseApp/ConsoleMouseApp_net.csproj index e154ec1c6..f0c19558e 100644 --- a/CSharpBible/ConsoleApps/ConsoleMouseApp/ConsoleMouseApp_net.csproj +++ b/CSharpBible/ConsoleApps/ConsoleMouseApp/ConsoleMouseApp_net.csproj @@ -28,7 +28,7 @@ - + diff --git a/CSharpBible/ConsoleApps/TestConsoleDemo/TestConsoleDemo.csproj b/CSharpBible/ConsoleApps/TestConsoleDemo/TestConsoleDemo.csproj index a1d1087c2..5b52eee51 100644 --- a/CSharpBible/ConsoleApps/TestConsoleDemo/TestConsoleDemo.csproj +++ b/CSharpBible/ConsoleApps/TestConsoleDemo/TestConsoleDemo.csproj @@ -26,7 +26,7 @@ - + \ No newline at end of file diff --git a/CSharpBible/ConsoleApps/TestConsoleTests/TestConsoleTests.csproj b/CSharpBible/ConsoleApps/TestConsoleTests/TestConsoleTests.csproj index 8fc972ff9..55340c5c9 100644 --- a/CSharpBible/ConsoleApps/TestConsoleTests/TestConsoleTests.csproj +++ b/CSharpBible/ConsoleApps/TestConsoleTests/TestConsoleTests.csproj @@ -20,7 +20,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CSharpBible/ConsoleApps/WaveFuncCol/WaveFunCollapse.csproj b/CSharpBible/ConsoleApps/WaveFuncCol/WaveFunCollapse.csproj index 41f070acf..54fd4d7e9 100644 --- a/CSharpBible/ConsoleApps/WaveFuncCol/WaveFunCollapse.csproj +++ b/CSharpBible/ConsoleApps/WaveFuncCol/WaveFunCollapse.csproj @@ -24,7 +24,7 @@ - + diff --git a/CSharpBible/ConsoleApps/WaveFuncColFrm/WaveFuncColFrm.csproj b/CSharpBible/ConsoleApps/WaveFuncColFrm/WaveFuncColFrm.csproj index ccc0b0859..fc95d949a 100644 --- a/CSharpBible/ConsoleApps/WaveFuncColFrm/WaveFuncColFrm.csproj +++ b/CSharpBible/ConsoleApps/WaveFuncColFrm/WaveFuncColFrm.csproj @@ -25,7 +25,7 @@ - + \ No newline at end of file diff --git a/CSharpBible/DB/DBTest1/DBTest1.csproj b/CSharpBible/DB/DBTest1/DBTest1.csproj index 7370e68b8..0e4836215 100644 --- a/CSharpBible/DB/DBTest1/DBTest1.csproj +++ b/CSharpBible/DB/DBTest1/DBTest1.csproj @@ -12,7 +12,7 @@ --> - + diff --git a/CSharpBible/DB/FoxCon/FoxCon.csproj b/CSharpBible/DB/FoxCon/FoxCon.csproj index 6810f82e6..51d69dd21 100644 --- a/CSharpBible/DB/FoxCon/FoxCon.csproj +++ b/CSharpBible/DB/FoxCon/FoxCon.csproj @@ -20,7 +20,7 @@ - + diff --git a/CSharpBible/DB/MdbBrowser/MdbBrowser.csproj b/CSharpBible/DB/MdbBrowser/MdbBrowser.csproj index a3af86e3a..58e2a2d55 100644 --- a/CSharpBible/DB/MdbBrowser/MdbBrowser.csproj +++ b/CSharpBible/DB/MdbBrowser/MdbBrowser.csproj @@ -28,7 +28,7 @@ - + diff --git a/CSharpBible/DB/OLEDBTest/OleDbTest.csproj b/CSharpBible/DB/OLEDBTest/OleDbTest.csproj index 2f7977719..b4b1cc258 100644 --- a/CSharpBible/DB/OLEDBTest/OleDbTest.csproj +++ b/CSharpBible/DB/OLEDBTest/OleDbTest.csproj @@ -13,7 +13,7 @@ - + diff --git a/CSharpBible/DB/OLEDBTest2/OleDbTest2.csproj b/CSharpBible/DB/OLEDBTest2/OleDbTest2.csproj index b3b3497fb..48555d3f5 100644 --- a/CSharpBible/DB/OLEDBTest2/OleDbTest2.csproj +++ b/CSharpBible/DB/OLEDBTest2/OleDbTest2.csproj @@ -13,7 +13,7 @@ - + diff --git a/Transpiler_pp/.info b/CSharpBible/Data/.Info.md similarity index 100% rename from Transpiler_pp/.info rename to CSharpBible/Data/.Info.md diff --git a/CSharpBible/Data/.github/copilot-instructions.md b/CSharpBible/Data/.github/copilot-instructions.md new file mode 100644 index 000000000..c311a9245 --- /dev/null +++ b/CSharpBible/Data/.github/copilot-instructions.md @@ -0,0 +1,52 @@ +# Repository instructions for GitHub Copilot + +Apply these defaults when working in this repository unless the user explicitly asks otherwise: + +## General Guidelines +- Document code thoroughly in English. +- Validate changes with relevant builds and tests before finishing. +- If requirements are unclear, ask clarifying questions before starting implementation or planning refinement. +- Avoid UI text strings in core services. Use Enumerations instead, and keep UI-facing strings in the ViewModel/UI layer. +- Prefer one class/interface/struct per file. +- Document changes in a DevOps manner using Markdown, extrapolating bugs, tasks, backlogs, and features. +- Use `DevOps` as the planning directory in this workspace, and treat `.Info.md` as the general planning description file. Team terminology around Azure DevOps backlog items may differ from generic 'story' naming. +- When reviewing build warnings in this repository, ignore unsupported older framework warnings if the project also targets newer supported frameworks. Additionally, ignore `IDE0130` warnings in test projects. +- Keep project-specific decisions in the repository `DevOps` folder; do not store them in memory for this repository. Use memory only for general solution-wide working preferences. +- Planning should be done step by step in the `DevOps` directory with a Scrum-oriented structure. +- Extract complex UI elements into separate widgets/components to keep main windows clean and simple. + +## Testing +- Use `MSTest` in the latest practical version for new or updated tests. +- Use `NSubstitute` for mocks, stubs, and substitutes in tests. +- Prefer `DataRow` for parameterized single-test scenarios. + +## Internationalization +- Keep I18N in mind when writing code, ensuring it can be easily adapted for different languages and regions. + +## Architecture +- Use MVVM architecture for UI components to separate concerns and improve testability, using CommunityToolkit.Mvvm for MVVM implementation. +- Prefer `NotifyPropertyChangedFor` over manual `OnPropertyChanged(nameof(...))` in CommunityToolkit.Mvvm observable properties where applicable. +- Use Dependency Injection to manage dependencies and improve testability, using Microsoft.Extensions.DependencyInjection. +- UI-facing strings and summary formatting should stay in the ViewModel/UI layer, not in extracted application logic services. + +## Naming Conventions +- Distinguish between UI control naming and variable/field naming. +- Use PascalCase for class names, method names, and properties. +- Use `_camelCase` for private fields. +- Use `camelCase` for local variables and parameters. +- Use short 1-character prefixes for simple types only when they meaningfully disambiguate, e.g. + - `s` for `string` + - `i` for signed integer types + - `u` for unsigned integer types + - `x` for `bool` + - `f` for `float`, `double`, or `decimal` +- Prefer meaningful domain names over type prefixes when the intent is already clear. +- In UI code, use short 3-character prefixes for actual controls in views and code-behind, e.g. + - `lst` for list controls + - `btn` for all kinds of buttons + - `edt` for any keyboard input control + - `lbl` for any text output control +- Do not use UI control prefixes for ViewModel properties or other non-UI members. + +## Nullability +- Use strict nullable reference types to indicate when a variable can be null, and handle nullability appropriately in code. diff --git a/CSharpBible/Data/Data.sln b/CSharpBible/Data/Data.sln index b430e9315..6f8e9846a 100644 --- a/CSharpBible/Data/Data.sln +++ b/CSharpBible/Data/Data.sln @@ -120,11 +120,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Features", "Features", "{E6 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Backlog-Items", "Backlog-Items", "{69FB2434-DA6E-4623-95FD-103AE1C4E8B4}" ProjectSection(SolutionItems) = preProject - DevOps\BacklogItems\BI-830334-Create-CSV-output-filter.md = DevOps\BacklogItems\BI-830334-Create-CSV-output-filter.md DevOps\BacklogItems\BI-830331-Define-canonical-trace-exchange-model.md = DevOps\BacklogItems\BI-830331-Define-canonical-trace-exchange-model.md DevOps\BacklogItems\BI-830332-Create-pluggable-input-filters-for-initial-source-formats.md = DevOps\BacklogItems\BI-830332-Create-pluggable-input-filters-for-initial-source-formats.md - DevOps\BacklogItems\README.md = DevOps\BacklogItems\README.md + DevOps\BacklogItems\BI-830334-Create-CSV-output-filter.md = DevOps\BacklogItems\BI-830334-Create-CSV-output-filter.md DevOps\BacklogItems\BI-830337-Create-Excel-output-filter.md = DevOps\BacklogItems\BI-830337-Create-Excel-output-filter.md + DevOps\BacklogItems\README.md = DevOps\BacklogItems\README.md EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tasks", "Tasks", "{08C40D64-DCC0-436D-A857-4EF3EA655486}" @@ -134,7 +134,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tasks", "Tasks", "{08C40D64 DevOps\Tasks\T-830302-002-Define-canonical-fields-and-optional-metadata.md = DevOps\Tasks\T-830302-002-Define-canonical-fields-and-optional-metadata.md DevOps\Tasks\T-830302-003-Specify-input-filter-interface-and-selection-strategy.md = DevOps\Tasks\T-830302-003-Specify-input-filter-interface-and-selection-strategy.md DevOps\Tasks\T-830302-004-Specify-CSV-column-mapping-and-export-behavior.md = DevOps\Tasks\T-830302-004-Specify-CSV-column-mapping-and-export-behavior.md + DevOps\Tasks\T-830302-006-Define-base-filter-interface-project-structure.md = DevOps\Tasks\T-830302-006-Define-base-filter-interface-project-structure.md + DevOps\Tasks\T-830302-007-Test-T-830302-003-input-filter-selection-and-analysis.md = DevOps\Tasks\T-830302-007-Test-T-830302-003-input-filter-selection-and-analysis.md + DevOps\Tasks\T-830302-008-Implement-MOVIRUN-trace-text-input-filter.md = DevOps\Tasks\T-830302-008-Implement-MOVIRUN-trace-text-input-filter.md + DevOps\Tasks\T-830302-009-Test-MOVIRUN-trace-text-input-filter.md = DevOps\Tasks\T-830302-009-Test-MOVIRUN-trace-text-input-filter.md + DevOps\Tasks\T-830302-010-Implement-MOVIRUN-XML-trace-input-filter.md = DevOps\Tasks\T-830302-010-Implement-MOVIRUN-XML-trace-input-filter.md + DevOps\Tasks\T-830302-011-Test-MOVIRUN-XML-trace-input-filter.md = DevOps\Tasks\T-830302-011-Test-MOVIRUN-XML-trace-input-filter.md + DevOps\Tasks\T-830302-012-Integrate-TraceCsv2realCsv-with-shared-TraceAnalysis-intake-filters.md = DevOps\Tasks\T-830302-012-Integrate-TraceCsv2realCsv-with-shared-TraceAnalysis-intake-filters.md + DevOps\Tasks\T-830302-013-Test-TraceCsv2realCsv-shared-intake-integration.md = DevOps\Tasks\T-830302-013-Test-TraceCsv2realCsv-shared-intake-integration.md DevOps\Tasks\T-830395-Specify-Excel-workbook-layout-and-export-behavior.md = DevOps\Tasks\T-830395-Specify-Excel-workbook-layout-and-export-behavior.md + DevOps\Tasks\T-830895-Implement-Excel-output-filter-from-canonical-exchange-records.md = DevOps\Tasks\T-830895-Implement-Excel-output-filter-from-canonical-exchange-records.md EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TraceAnalysis.Base", "TraceAnalysis\TraceAnalysis.Base\TraceAnalysis.Base.csproj", "{65231580-7BC5-4956-B1BC-D62133F5D3B1}" @@ -145,6 +154,26 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TraceAnalysis.Base.Tests", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TraceAnalysis.Filter.CSV", "TraceAnalysis\TraceAnalysis.Filter.CSV\TraceAnalysis.Filter.CSV.csproj", "{E0141A8E-6993-D1B2-C82A-1BC6B29377C6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Document.Demo.Gui", "DocumentUtils\Document.Demo.Gui\Document.Demo.Gui.csproj", "{1A23D9EE-E254-2BFB-443F-2C9237B0D719}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TraceAnalysis.Filter.Excel", "TraceAnalysis\TraceAnalysis.Filter.Excel\TraceAnalysis.Filter.Excel.csproj", "{503AE8CE-A1B0-5322-DC8E-75713D21F0A8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestData", "TestData", "{0D3282FC-2260-4D38-957B-4E3439CD23A7}" + ProjectSection(SolutionItems) = preProject + TraceAnalysis\TestData\Trace1.trace = TraceAnalysis\TestData\Trace1.trace + TraceAnalysis\TestData\Trace1.trace.csv = TraceAnalysis\TestData\Trace1.trace.csv + TraceAnalysis\TestData\Trace1.txt = TraceAnalysis\TestData\Trace1.txt + TraceAnalysis\TestData\Trace2_us.trace = TraceAnalysis\TestData\Trace2_us.trace + TraceAnalysis\TestData\Trace2_us.trace.csv = TraceAnalysis\TestData\Trace2_us.trace.csv + TraceAnalysis\TestData\Trace2_us.txt = TraceAnalysis\TestData\Trace2_us.txt + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TraceAnalysis.Filter.MovirunText", "TraceAnalysis\TraceAnalysis.Filter.MovirunText\TraceAnalysis.Filter.MovirunText.csproj", "{FD1D9D5A-C039-86EE-6E92-AF36E0AF9134}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TraceAnalysis.Filter.MovirunTrace", "TraceAnalysis\TraceAnalysis.Filter.MovirunTrace\TraceAnalysis.Filter.MovirunTrace.csproj", "{57448214-72DC-2383-4E82-6697501ACC29}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "DevOps", "DevOps\DevOps.shproj", "{B7D27D6F-34E9-4F5A-BB5F-6A0D3F0F2C7C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -611,6 +640,54 @@ Global {E0141A8E-6993-D1B2-C82A-1BC6B29377C6}.Release|x64.Build.0 = Release|Any CPU {E0141A8E-6993-D1B2-C82A-1BC6B29377C6}.Release|x86.ActiveCfg = Release|Any CPU {E0141A8E-6993-D1B2-C82A-1BC6B29377C6}.Release|x86.Build.0 = Release|Any CPU + {1A23D9EE-E254-2BFB-443F-2C9237B0D719}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1A23D9EE-E254-2BFB-443F-2C9237B0D719}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1A23D9EE-E254-2BFB-443F-2C9237B0D719}.Debug|x64.ActiveCfg = Debug|Any CPU + {1A23D9EE-E254-2BFB-443F-2C9237B0D719}.Debug|x64.Build.0 = Debug|Any CPU + {1A23D9EE-E254-2BFB-443F-2C9237B0D719}.Debug|x86.ActiveCfg = Debug|Any CPU + {1A23D9EE-E254-2BFB-443F-2C9237B0D719}.Debug|x86.Build.0 = Debug|Any CPU + {1A23D9EE-E254-2BFB-443F-2C9237B0D719}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1A23D9EE-E254-2BFB-443F-2C9237B0D719}.Release|Any CPU.Build.0 = Release|Any CPU + {1A23D9EE-E254-2BFB-443F-2C9237B0D719}.Release|x64.ActiveCfg = Release|Any CPU + {1A23D9EE-E254-2BFB-443F-2C9237B0D719}.Release|x64.Build.0 = Release|Any CPU + {1A23D9EE-E254-2BFB-443F-2C9237B0D719}.Release|x86.ActiveCfg = Release|Any CPU + {1A23D9EE-E254-2BFB-443F-2C9237B0D719}.Release|x86.Build.0 = Release|Any CPU + {503AE8CE-A1B0-5322-DC8E-75713D21F0A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {503AE8CE-A1B0-5322-DC8E-75713D21F0A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {503AE8CE-A1B0-5322-DC8E-75713D21F0A8}.Debug|x64.ActiveCfg = Debug|Any CPU + {503AE8CE-A1B0-5322-DC8E-75713D21F0A8}.Debug|x64.Build.0 = Debug|Any CPU + {503AE8CE-A1B0-5322-DC8E-75713D21F0A8}.Debug|x86.ActiveCfg = Debug|Any CPU + {503AE8CE-A1B0-5322-DC8E-75713D21F0A8}.Debug|x86.Build.0 = Debug|Any CPU + {503AE8CE-A1B0-5322-DC8E-75713D21F0A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {503AE8CE-A1B0-5322-DC8E-75713D21F0A8}.Release|Any CPU.Build.0 = Release|Any CPU + {503AE8CE-A1B0-5322-DC8E-75713D21F0A8}.Release|x64.ActiveCfg = Release|Any CPU + {503AE8CE-A1B0-5322-DC8E-75713D21F0A8}.Release|x64.Build.0 = Release|Any CPU + {503AE8CE-A1B0-5322-DC8E-75713D21F0A8}.Release|x86.ActiveCfg = Release|Any CPU + {503AE8CE-A1B0-5322-DC8E-75713D21F0A8}.Release|x86.Build.0 = Release|Any CPU + {FD1D9D5A-C039-86EE-6E92-AF36E0AF9134}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FD1D9D5A-C039-86EE-6E92-AF36E0AF9134}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FD1D9D5A-C039-86EE-6E92-AF36E0AF9134}.Debug|x64.ActiveCfg = Debug|Any CPU + {FD1D9D5A-C039-86EE-6E92-AF36E0AF9134}.Debug|x64.Build.0 = Debug|Any CPU + {FD1D9D5A-C039-86EE-6E92-AF36E0AF9134}.Debug|x86.ActiveCfg = Debug|Any CPU + {FD1D9D5A-C039-86EE-6E92-AF36E0AF9134}.Debug|x86.Build.0 = Debug|Any CPU + {FD1D9D5A-C039-86EE-6E92-AF36E0AF9134}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FD1D9D5A-C039-86EE-6E92-AF36E0AF9134}.Release|Any CPU.Build.0 = Release|Any CPU + {FD1D9D5A-C039-86EE-6E92-AF36E0AF9134}.Release|x64.ActiveCfg = Release|Any CPU + {FD1D9D5A-C039-86EE-6E92-AF36E0AF9134}.Release|x64.Build.0 = Release|Any CPU + {FD1D9D5A-C039-86EE-6E92-AF36E0AF9134}.Release|x86.ActiveCfg = Release|Any CPU + {FD1D9D5A-C039-86EE-6E92-AF36E0AF9134}.Release|x86.Build.0 = Release|Any CPU + {57448214-72DC-2383-4E82-6697501ACC29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57448214-72DC-2383-4E82-6697501ACC29}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57448214-72DC-2383-4E82-6697501ACC29}.Debug|x64.ActiveCfg = Debug|Any CPU + {57448214-72DC-2383-4E82-6697501ACC29}.Debug|x64.Build.0 = Debug|Any CPU + {57448214-72DC-2383-4E82-6697501ACC29}.Debug|x86.ActiveCfg = Debug|Any CPU + {57448214-72DC-2383-4E82-6697501ACC29}.Debug|x86.Build.0 = Debug|Any CPU + {57448214-72DC-2383-4E82-6697501ACC29}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57448214-72DC-2383-4E82-6697501ACC29}.Release|Any CPU.Build.0 = Release|Any CPU + {57448214-72DC-2383-4E82-6697501ACC29}.Release|x64.ActiveCfg = Release|Any CPU + {57448214-72DC-2383-4E82-6697501ACC29}.Release|x64.Build.0 = Release|Any CPU + {57448214-72DC-2383-4E82-6697501ACC29}.Release|x86.ActiveCfg = Release|Any CPU + {57448214-72DC-2383-4E82-6697501ACC29}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -659,8 +736,16 @@ Global {FDA82907-F072-6943-3484-8D582E6131F8} = {51F6C20B-003C-430C-BED7-2A89F834E4C0} {45044F5F-A9F4-4DC9-AB09-AAAF8A5484A2} = {6BB16C4B-D416-4484-ACEF-1A47B631913E} {E0141A8E-6993-D1B2-C82A-1BC6B29377C6} = {6BB16C4B-D416-4484-ACEF-1A47B631913E} + {1A23D9EE-E254-2BFB-443F-2C9237B0D719} = {C72F7201-74F9-66F9-5C2C-ABF0F08448DC} + {503AE8CE-A1B0-5322-DC8E-75713D21F0A8} = {6BB16C4B-D416-4484-ACEF-1A47B631913E} + {0D3282FC-2260-4D38-957B-4E3439CD23A7} = {6BB16C4B-D416-4484-ACEF-1A47B631913E} + {FD1D9D5A-C039-86EE-6E92-AF36E0AF9134} = {6BB16C4B-D416-4484-ACEF-1A47B631913E} + {57448214-72DC-2383-4E82-6697501ACC29} = {6BB16C4B-D416-4484-ACEF-1A47B631913E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {128BE64A-28F5-47C5-A045-2352EF09BFBB} EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + DevOps\DevOps.projitems*{b7d27d6f-34e9-4f5a-bb5f-6a0d3f0f2c7c}*SharedItemsImports = 13 + EndGlobalSection EndGlobal diff --git a/CSharpBible/Data/DataAnalysis/DataAnalysis.Core.Tests/Export/TableExcelExporterTests.cs b/CSharpBible/Data/DataAnalysis/DataAnalysis.Core.Tests/Export/TableExcelExporterTests.cs index 42496f870..eb97b8ca4 100644 --- a/CSharpBible/Data/DataAnalysis/DataAnalysis.Core.Tests/Export/TableExcelExporterTests.cs +++ b/CSharpBible/Data/DataAnalysis/DataAnalysis.Core.Tests/Export/TableExcelExporterTests.cs @@ -36,7 +36,7 @@ private static MethodInfo GetPrivateMethod(string name) => typeof(TableExcelExporter).GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new InvalidOperationException($"Methode {name} nicht gefunden."); - [DataTestMethod] + [TestMethod] [DataRow(TypeCode.Empty, null, "", TypeCode.String)] // null -> "" [DataRow(TypeCode.DBNull, null, "", TypeCode.String)] // DBNull -> "" [DataRow(TypeCode.Boolean, true, true, TypeCode.Boolean)] // true -> 1 diff --git a/CSharpBible/Data/DataAnalysis/DataAnalysis.WPF/DataAnalysis.WPF.csproj b/CSharpBible/Data/DataAnalysis/DataAnalysis.WPF/DataAnalysis.WPF.csproj index 16e1b9d13..e2c020baf 100644 --- a/CSharpBible/Data/DataAnalysis/DataAnalysis.WPF/DataAnalysis.WPF.csproj +++ b/CSharpBible/Data/DataAnalysis/DataAnalysis.WPF/DataAnalysis.WPF.csproj @@ -18,8 +18,8 @@ - - + + diff --git a/CSharpBible/Data/DataAnalysis/DataConvert.Console/DataConvert.Console.csproj b/CSharpBible/Data/DataAnalysis/DataConvert.Console/DataConvert.Console.csproj index 978d08732..77e1fa827 100644 --- a/CSharpBible/Data/DataAnalysis/DataConvert.Console/DataConvert.Console.csproj +++ b/CSharpBible/Data/DataAnalysis/DataConvert.Console/DataConvert.Console.csproj @@ -12,7 +12,7 @@ - + diff --git a/CSharpBible/Data/Data_net.props b/CSharpBible/Data/Data_net.props index 2ad5825d2..b7c354b82 100644 --- a/CSharpBible/Data/Data_net.props +++ b/CSharpBible/Data/Data_net.props @@ -1,7 +1,8 @@ - ..\..\..\bin\$(MSBuildProjectName)\ - ..\..\..\obj.net\$(MSBuildProjectName)\ + ..\..\..\.. + $(UpDir)\bin\$(MSBuildProjectName)\ + $(UpDir)\obj.net\$(MSBuildProjectName)\ $(MSBuildProjectName.Replace(".","_").Replace("_net","")) preview enable diff --git a/CSharpBible/Data/DevOps/.info.md b/CSharpBible/Data/DevOps/.info.md new file mode 100644 index 000000000..e73cfe357 --- /dev/null +++ b/CSharpBible/Data/DevOps/.info.md @@ -0,0 +1,38 @@ +# DevOps Planning Notes + +This repository uses the `DevOps` directory as the local planning area for Azure-DevOps-style work preparation. + +## Working Model + +- Hierarchy: `Epic -> Feature -> Backlog Item -> Task` +- Team terminology prefers `Backlog Item` over `Story` +- Planning files are drafts until they are copied into Azure DevOps +- Each planning file should include scope, assumptions, open questions, and next refinement steps + +## File and Folder Conventions + +- Root planning directory: `DevOps` +- Main folders: + - `DevOps/Epics` + - `DevOps/Features` + - `DevOps/BacklogItems` + - `DevOps/Tasks` +- File naming pattern: `-.md` +- Use stable IDs where available, for example Azure DevOps work item numbers + +## Planning Rules + +- Keep one primary planning item per file +- Record assumptions explicitly instead of hiding uncertainty +- Prefer thin backlog items that can later be refined into implementation tasks +- Link child items to their parent item by ID and title +- Mark unknowns as open questions instead of inventing detail +- For each major coding task, create a dedicated test-task item + +## Refinement Flow + +1. Define the epic goal and boundaries +2. Split the epic into feature candidates +3. Derive backlog items with visible user or process value +4. Add tasks only when implementation planning starts +5. Revisit assumptions and open questions after each refinement pass diff --git a/CSharpBible/Data/DevOps/BacklogItems/BI-830331-Define-canonical-trace-exchange-model.md b/CSharpBible/Data/DevOps/BacklogItems/BI-830331-Define-canonical-trace-exchange-model.md new file mode 100644 index 000000000..1facf3d44 --- /dev/null +++ b/CSharpBible/Data/DevOps/BacklogItems/BI-830331-Define-canonical-trace-exchange-model.md @@ -0,0 +1,56 @@ +# Backlog Item BI-830331 - Define canonical trace exchange model + +## Status + +Draft + +## Parent + +- Epic `830302` - `TraceAnalysis and AGV-reverse simulation` +- Feature `830329` - `Filter-based trace intake and export foundation` + +## Goal + +Define the shared intermediate structure that all input filters produce and all output filters consume. + +## Description + +The canonical exchange model is the contract between source-specific import logic and target-specific export logic. It should be stable enough to support CSV and Excel export without forcing every format-specific concern into downstream processing. + +At the current stage, the only mandatory canonical field is the timestamp. All other imported values remain optional and are initially transferred from input to output without semantic reshaping. + +Current baseline granularity: one canonical record represents one imported observation point at a given timestamp, with zero or more optional value fields. + +Nested source structures are flattened for the first increment through normalized field names. Grouping information is inferred only from explicit structural separators in field names. + +Responsibility boundary for this increment: +- Input filters read and normalize available raw content into canonical records +- Output filters write the canonical content they receive +- Deciding which optional fields become canonical beyond `timestamp` remains intentionally open and outside direct import/export filter scope + +## Acceptance Criteria + +- The structure defines the timestamp as the only mandatory field +- All other imported values are treated as optional fields +- Metadata and payload content are separated in a documented way +- The model supports general metadata and field-specific metadata such as format and type +- The model supports field groups without making them mandatory for every record +- Field groups can remain absent for flat inputs and should only be created from clear naming structures +- Field-group inference prefers `.` as separator, allows `_`, and does not use prefix-only grouping without separators +- The model can represent records imported from multiple source formats +- Optional values can pass through from input to output unchanged in the first increment +- Mapping gaps and unresolved semantics are explicitly listed +- The model is suitable as input for both CSV and Excel export + +## Dependencies + +- Confirmation of the first supported source formats +- Agreement on the minimum record granularity + +## Candidate Tasks + +- `T-830349` - `Define canonical fields and optional metadata` + +## Open Questions + +- Which optional fields should later become canonical fields beyond the timestamp? diff --git a/CSharpBible/Data/DevOps/BacklogItems/BI-830332-Create-pluggable-input-filters-for-initial-source-formats.md b/CSharpBible/Data/DevOps/BacklogItems/BI-830332-Create-pluggable-input-filters-for-initial-source-formats.md new file mode 100644 index 000000000..0ca36110b --- /dev/null +++ b/CSharpBible/Data/DevOps/BacklogItems/BI-830332-Create-pluggable-input-filters-for-initial-source-formats.md @@ -0,0 +1,72 @@ +# Backlog Item BI-830332 - Create pluggable input filters for initial source formats + +## Status + +Draft + +## Parent + +- Epic `830302` - `TraceAnalysis and AGV-reverse simulation` +- Feature `830329` - `Filter-based trace intake and export foundation` + +## Goal + +Support one or more source formats through interchangeable input filters that map imported content into the canonical exchange model. + +## Description + +Input filters should isolate parsing and source-specific transformation logic. New source formats should be addable without redesigning the export path. + +The first design should prefer stream-based input with an additional source identifier instead of a hard file-only contract. The filter contract should support general metadata, field-specific metadata such as format and type, and field groups while keeping technical metadata clearly separated from actual data values. + +Field groups are optional. For flat CSV files, no field groups may exist. Field groups should only be derived when field names show clear shared prefixes or structural paths, for example `AGV1.X` and `AGV1.Y` or `Diag1.Axis1.Speed` and `Diag1.Axis2.Speed`. + +For inferred field groups, prefer `.` as separator, also allow `_`, and do not infer groups from prefix-only naming without a separator. + +The first supported source format is a flat `CSV` file with a header row in the first line. The second supported format is the `CSV` variant from the `TraceCsv2realCsv` project. A third supported source format is the whitespace-separated `MOVIRUN` trace text export with a fixed preamble and a `Zeitstempel(...)` header line. A fourth supported source format is the XML-based `MOVIRUN` `.trace` export that contains the same measurement series in structured `TraceVariable` elements. + +## Acceptance Criteria + +- A documented input filter contract exists +- The selection strategy for input filters is defined +- Deterministic ranking rules are defined when multiple filters match the same source +- At least one initial source format is covered by the design +- Unsupported formats produce a defined failure path +- Parsed records are emitted as canonical exchange records +- The contract supports general metadata, field-specific metadata, and field groups +- Partial results and logged parse errors are part of the design for large files +- Filters are registered via interface plus Dependency Injection +- Project structure direction for base interfaces and input/output separation is documented +- Each major coding task has a dedicated test task item + +## Dependencies + +- `BI-830331` - `Define canonical trace exchange model` + +## Candidate Tasks + +- `T-830302-001` - `Identify first supported source formats` +- `T-830353` - `Specify input filter interface and selection strategy` +- `T-832070` - `Define base filter interface project structure` +- `T-831180` - `Test T-830353 input filter selection and analysis` +- `T-830302-008` - `Implement MOVIRUN trace text input filter` +- `T-830302-009` - `Test MOVIRUN trace text input filter` +- `T-830302-010` - `Implement MOVIRUN XML trace input filter` +- `T-830302-011` - `Test MOVIRUN XML trace input filter` +- `T-830302-012` - `Integrate TraceCsv2realCsv with shared TraceAnalysis intake filters` +- `T-830302-013` - `Test TraceCsv2realCsv shared intake integration` +- `T-830302-014` - `Refactor TraceCsv2realCsv filter composition to use dependency injection` + +## Current Source Format Direction + +- Detect flat `CSV` files primarily by file extension and then confirm them through file inspection (`header + n lines`) +- Detect the `TraceCsv2realCsv` project format by extension plus format-specific decision lines or `n KB` analysis block output +- Detect the `MOVIRUN` trace text export through its signature line, `Zeitstempel(...)` header row, and whitespace-separated sample rows +- Detect the XML-based `MOVIRUN` `.trace` export through the `Trace` root plus `TraceData/TraceRecord/TraceVariable` structure and paired `Values`/`Timestamps` series +- Keep manual override available later when automatic detection cannot distinguish similar `CSV` variants reliably + +## Architecture Direction + +- Provide one or more base interface projects used by input and output filter implementations +- Keep input and output filter implementations in separate projects +- Combine multiple input filters in one project only when this is clearly justified by shared parsing behavior diff --git a/CSharpBible/Data/DevOps/BacklogItems/BI-830334-Create-CSV-output-filter.md b/CSharpBible/Data/DevOps/BacklogItems/BI-830334-Create-CSV-output-filter.md new file mode 100644 index 000000000..05e8ce1f8 --- /dev/null +++ b/CSharpBible/Data/DevOps/BacklogItems/BI-830334-Create-CSV-output-filter.md @@ -0,0 +1,68 @@ +# Backlog Item BI-830334 - Create CSV output filter + +## Status + +Draft + +## Parent + +- Epic `830302` - `TraceAnalysis and AGV-reverse simulation` +- Feature `830329` - `Filter-based trace intake and export foundation` + +## Goal + +Export canonical exchange records to CSV in a deterministic and documented format. + +## Description + +The CSV output filter should serialize the shared intermediate structure with stable column order and predictable formatting rules so that users can inspect and reuse exported data in common tools. + +The contract must keep technical metadata separate from data value columns. `timestamp` is mandatory and must always be exported. Other fields are optional and exported when present. + +`timestamp` uses invariant ISO 8601 UTC format: `yyyy-MM-ddTHH:mm:ss.fffZ`. + +Delimiter handling should support auto-detection (`;` and ``) by probing first lines, with optional user override. Detection heuristics should start with international/general assumptions and continue with country-specific assumptions. + +Output format selection belongs to the output-filter layer: either explicit manual user selection, or extension-based selection with a fixed entropy baseline and no extra analysis. For `.csv`, the default expected output is flat CSV. + +Flat CSV has no dedicated metadata except what can be inferred from first lines. Extended per-column metadata is handled in a separate companion header file. The companion header file uses the same delimiter and column order as the data CSV. + +Companion header file rows: + +1. Column names (alphanumeric plus `.`, `-`, `_`; spaces normalized to `_`) +2. Optional format/type per column +3. Group name per column (optional) + - Empty value means no group (single column) + - Non-empty identifier means group membership, including valid one-column groups +4. Group description, optionally continued in following rows when needed + - Row 4 is the first description line + - Row 5+ are continuation lines in original order + - Continuation ends at end-of-file + - Empty cells in continuation rows add no text for that column + +Multi-value split logic is not part of the direct import filter. Import reads raw format first; any splitting into multiple columns is handled by downstream general filters. + +## Acceptance Criteria + +- Column order is documented +- Headers are defined +- Escaping and delimiter rules are defined +- Missing optional values are handled consistently +- Exported CSV can be produced directly from canonical exchange records +- Metadata is not mixed into data columns +- Companion header file behavior for import and export is documented +- Companion header row schema is documented +- Large-file export behavior and partial-failure reporting are documented +- Delimiter auto-detection and user override behavior are documented + +## Dependencies + +- `BI-830331` - `Define canonical trace exchange model` + +## Candidate Tasks + +- `T-830348` - `Specify CSV column mapping and export behavior` + +## Open Questions + +- No blocking open questions for the first increment diff --git a/CSharpBible/Data/DevOps/BacklogItems/BI-830337-Create-Excel-output-filter.md b/CSharpBible/Data/DevOps/BacklogItems/BI-830337-Create-Excel-output-filter.md new file mode 100644 index 000000000..3e1568a55 --- /dev/null +++ b/CSharpBible/Data/DevOps/BacklogItems/BI-830337-Create-Excel-output-filter.md @@ -0,0 +1,57 @@ +# Backlog Item BI-830337 - Create Excel output filter + +## Status + +Draft + +## Parent + +- Epic `830302` - `TraceAnalysis and AGV-reverse simulation` +- Feature `830329` - `Filter-based trace intake and export foundation` + +## Goal + +Export canonical exchange records to Excel in a structure suitable for inspection and stakeholder review. + +## Description + +The Excel output filter should create a workbook representation of the canonical exchange records while keeping the export contract aligned with the CSV export where practical. + +First baseline: + +- Primary worksheet `Data` with row 1 as header and row 2+ as values +- Column order aligned with CSV baseline (`timestamp` first, then stable lexical order) +- Technical metadata stays separate from data columns +- Metadata worksheet is optional when metadata exists, but mandatory when CSV input has no header row +- No strict worksheet-name standardization is required in the first increment + +The metadata worksheet can follow the same semantics as the CSV companion header file: + +1. column name +2. optional format/type +3. optional group name +4. optional group description + +## Acceptance Criteria + +- Workbook and worksheet structure are defined +- Header formatting rules are defined +- Cell data mapping from canonical records is documented +- Large dataset assumptions are recorded +- Exported Excel output can be produced directly from canonical exchange records +- Metadata handling is documented without mixing technical metadata into data columns +- Metadata worksheet optional/mandatory rule is documented +- Future async-pipelining compatibility is noted + +## Dependencies + +- `BI-830331` - `Define canonical trace exchange model` + +## Candidate Tasks + +- `T-830395` - `Specify Excel workbook layout and export behavior` +- `T-830895` - `Implement Excel output filter from canonical exchange records` + +## Open Questions + +- No blocking open questions for the first increment diff --git a/CSharpBible/Data/DevOps/BacklogItems/README.md b/CSharpBible/Data/DevOps/BacklogItems/README.md new file mode 100644 index 000000000..4ff2d438f --- /dev/null +++ b/CSharpBible/Data/DevOps/BacklogItems/README.md @@ -0,0 +1,8 @@ +# Backlog Items + +Store backlog item planning files in this folder. + +Recommended file name pattern: + +- `-.md` +- If no Azure DevOps ID exists yet, use a temporary local identifier diff --git a/CSharpBible/Data/DevOps/Epics/830302-TraceAnalysis-and-AGV-reverse-simulation.md b/CSharpBible/Data/DevOps/Epics/830302-TraceAnalysis-and-AGV-reverse-simulation.md new file mode 100644 index 000000000..0261e674d --- /dev/null +++ b/CSharpBible/Data/DevOps/Epics/830302-TraceAnalysis-and-AGV-reverse-simulation.md @@ -0,0 +1,180 @@ +# Epic 830302 - TraceAnalysis and AGV-reverse simulation + +## Status + +Draft + +## Goal + +Create a planning baseline for trace analysis and reverse simulation of AGV behavior, so the work can be refined incrementally and later transferred into Azure DevOps. + +## Summary + +This epic is the tactical starting point for a larger initiative. The current document intentionally captures structure, assumptions, and candidate slices without pretending that all detailed requirements are known yet. + +## Expected Outcomes + +- Relevant trace data can be identified and prepared for analysis +- A reverse simulation approach for AGV behavior can be described and validated +- The work can be split into features and backlog items that are ready for gradual refinement + +## In Scope + +- Clarifying the planning structure for the epic +- Identifying major feature candidates +- Capturing initial backlog items for analysis and simulation preparation +- Making assumptions and unknowns visible + +## Out of Scope + +- Detailed technical design for every subsystem +- Final algorithm decisions +- Effort estimates with high confidence +- Production-ready implementation tasks for every backlog item + +## Assumptions + +- Trace data already exists or can be exported from an existing source +- AGV reverse simulation depends on trace interpretation rules that are not fully documented yet +- Domain experts will be needed to validate event semantics and expected simulation behavior +- The backlog will be refined in several iterations instead of one large specification pass + +## Candidate Features + +### Feature 830329 - Filter-based trace intake and export foundation + +- Support one or more input filters for different source formats +- Transform imported records into a shared trace-oriented intermediate structure +- Provide output filters for CSV and Excel export + +### Feature Candidate F-830302-02 - Trace normalization and preparation + +- Define a common structure for simulation-relevant trace events +- Identify transformation rules from raw traces to normalized inputs +- Capture data quality gaps that block simulation + +### Feature Candidate F-830302-03 - AGV reverse simulation model + +- Describe the core simulation objective and boundaries +- Identify the minimum state required to replay or infer AGV movement +- Define how simulation results can be compared with recorded traces + +### Feature Candidate F-830302-04 - Review and validation workflow + +- Define how results will be reviewed with stakeholders +- Capture acceptance signals for trace interpretation and simulation accuracy +- Prepare a feedback loop for backlog refinement + +## Prioritized First Increment + +The first delivery slice focuses on a filter-based import and export foundation. + +### Objective + +Read source data through one or more input filters, normalize the imported content into a shared intermediate structure, and export the result through dedicated CSV and Excel output filters. + +### Why this increment comes first + +- It creates a reusable ingestion path for later trace analysis work +- It reduces early coupling between source formats and downstream processing +- It enables fast inspection of imported data before reverse simulation rules are finalized + +### Planned Feature + +- `830329` - `Filter-based trace intake and export foundation` + +### Planned Backlog Items + +- `BI-830331` - `Define canonical trace exchange model` +- `BI-830332` - `Create pluggable input filters for initial source formats` +- `BI-830334` - `Create CSV output filter` +- `BI-830337` - `Create Excel output filter` + +## Initial Backlog Candidates + +### BI-830302-001 - Inventory available trace sources + +Parent: Epic `830302` + +- Collect known trace producers and export paths +- Record format, owner, and expected availability +- Note obvious access or retention constraints + +### BI-830349 - Define trace event glossary + +Parent: Epic `830302` + +- List known event types and field meanings +- Mark unknown or ambiguous semantics +- Prepare questions for domain validation + +### BI-830353 - Describe normalized trace shape + +Parent: Epic `830302` + +- Define the minimal event structure needed for downstream analysis +- Identify mandatory and optional attributes +- Capture unresolved mapping rules + +### BI-830348 - Outline reverse simulation flow + +Parent: Epic `830302` + +- Describe the replay or inference stages at a high level +- Identify required inputs and expected outputs +- Record critical assumptions that affect feasibility + +### BI-830302-005 - Define validation approach + +Parent: Epic `830302` + +- Describe how simulation output will be compared with trace evidence +- Capture candidate quality metrics or review checkpoints +- Note dependencies on domain expertise or sample data + +### BI-830331 - Define canonical trace exchange model + +Parent: Feature `830329` + +- Define the intermediate record shape used between input and output filters +- Identify required metadata, payload fields, and extensibility points +- Record mapping rules and known uncertainties + +### BI-830332 - Create pluggable input filters for initial source formats + +Parent: Feature `830329` + +- Define how input filters are selected and invoked +- Support one or more initial source formats +- Record unsupported formats and expected extension points + +### BI-830334 - Create CSV output filter + +Parent: Feature `830329` + +- Export the shared intermediate structure as CSV +- Define column ordering, value formatting, and escaping rules +- Capture how missing or optional values are represented + +### BI-830337 - Create Excel output filter + +Parent: Feature `830329` + +- Export the shared intermediate structure as Excel +- Define workbook, worksheet, header, and cell-format rules +- Capture limits or assumptions for large datasets + +## Open Questions + +- Which exact trace systems and file formats are in scope for the first increment? +- What is the operational definition of a successful reverse simulation? +- Which AGV states must be reconstructed, and which can remain inferred or approximate? +- Are there existing tools, schemas, or data contracts that should be reused? +- Which part of the epic is the preferred MVP slice? + +## Next Refinement Steps + +1. Confirm the exact source systems and trace formats +2. Maintain feature `830329` in its dedicated planning file +3. Promote `BI-830331` to `BI-830337` into implementation-ready backlog entries +4. Add tasks for the first increment backlog items diff --git a/CSharpBible/Data/DevOps/Epics/README.md b/CSharpBible/Data/DevOps/Epics/README.md new file mode 100644 index 000000000..e2198ec36 --- /dev/null +++ b/CSharpBible/Data/DevOps/Epics/README.md @@ -0,0 +1,7 @@ +# Epics + +Store one epic file per work item in this folder. + +Recommended file name pattern: + +- `-.md` diff --git a/CSharpBible/Data/DevOps/Features/830329-Filter-based-trace-intake-and-export-foundation.md b/CSharpBible/Data/DevOps/Features/830329-Filter-based-trace-intake-and-export-foundation.md new file mode 100644 index 000000000..8d198b07f --- /dev/null +++ b/CSharpBible/Data/DevOps/Features/830329-Filter-based-trace-intake-and-export-foundation.md @@ -0,0 +1,69 @@ +# Feature 830329 - Filter-based trace intake and export foundation + +## Status + +Draft + +## Parent + +- Epic `830302-TraceAnalysis and AGV-reverse simulation` + +## Goal + +Provide a reusable conversion pipeline that can read source data through one or more input filters, normalize it into a shared intermediate structure, and export it through CSV or Excel output filters. + +## Summary + +This feature establishes the first technical backbone for the epic. It intentionally focuses on import and export capability before deeper analysis or reverse simulation logic is introduced. + +## In Scope + +- Pluggable input filters for different source data formats +- A canonical intermediate structure between import and export +- CSV export of normalized records +- Excel export of normalized records +- Explicit extension points for future source and target formats + +## Out of Scope + +- Full reverse simulation logic +- Domain-complete trace semantics for every event type +- Advanced analytics or visualization +- Final optimization for very large data volumes + +## Acceptance Criteria + +- At least one input filter can be added without changing the output filter contracts +- Imported data is mapped into a documented canonical intermediate structure +- The canonical structure can be exported as CSV +- The canonical structure can be exported as Excel +- Unsupported formats fail in a defined and observable way +- Format-specific parsing rules are isolated from export-specific rules + +## Related Backlog Items + +- `BI-830331` - `Define canonical trace exchange model` +- `BI-830332` - `Create pluggable input filters for initial source formats` +- `BI-830334` - `Create CSV output filter` +- `BI-830337` - `Create Excel output filter` + +## Risks + +- Source formats may differ more strongly than expected +- Required trace fields may not be consistently available across all inputs +- Excel export expectations may require formatting decisions early + +## Open Questions + +- Which exact source formats belong to the first increment? +- Is the canonical structure row-oriented, event-oriented, or hybrid? +- Are there mandatory localization rules for dates, numbers, or text encoding in exports? +- What size limits must CSV and Excel exports support in the first release? + +## Next Refinement Steps + +1. Confirm the first supported source formats +2. Agree on the canonical record structure +3. Define the CSV export contract +4. Define the Excel export contract +5. Add implementation tasks for the first selected backlog item diff --git a/CSharpBible/Data/DevOps/Features/README.md b/CSharpBible/Data/DevOps/Features/README.md new file mode 100644 index 000000000..814c7c2a9 --- /dev/null +++ b/CSharpBible/Data/DevOps/Features/README.md @@ -0,0 +1,8 @@ +# Features + +Store feature planning files in this folder. + +Recommended file name pattern: + +- `-.md` +- If no Azure DevOps ID exists yet, use a temporary local identifier diff --git a/CSharpBible/Data/DevOps/README.md b/CSharpBible/Data/DevOps/README.md new file mode 100644 index 000000000..7ce3b5e2b --- /dev/null +++ b/CSharpBible/Data/DevOps/README.md @@ -0,0 +1,14 @@ +# DevOps Planning + +This directory contains local planning artifacts that mirror an Azure DevOps backlog structure. + +## Structure + +- `Epics` contains large work packages +- `Features` contains slices of epic scope +- `BacklogItems` contains actionable backlog entries +- `Tasks` contains implementation-level work items + +## Current Focus + +- Epic `E...` diff --git a/CSharpBible/Data/DevOps/Tasks/README.md b/CSharpBible/Data/DevOps/Tasks/README.md new file mode 100644 index 000000000..35c86f1ad --- /dev/null +++ b/CSharpBible/Data/DevOps/Tasks/README.md @@ -0,0 +1,8 @@ +# Tasks + +Store implementation task planning files in this folder. + +Recommended file name pattern: + +- `-.md` +- If no Azure DevOps ID exists yet, use a temporary local identifier diff --git a/CSharpBible/Data/DevOps/Tasks/T-830302-003-Specify-input-filter-interface-and-selection-strategy.md b/CSharpBible/Data/DevOps/Tasks/T-830302-003-Specify-input-filter-interface-and-selection-strategy.md new file mode 100644 index 000000000..78f313195 --- /dev/null +++ b/CSharpBible/Data/DevOps/Tasks/T-830302-003-Specify-input-filter-interface-and-selection-strategy.md @@ -0,0 +1,113 @@ +# Task T-830353 - Specify input filter interface and selection strategy + +## Status + +Draft + +## Parent + +- Backlog Item `BI-830332` - `Create pluggable input filters for initial source formats` + +## Goal + +Define how input filters are discovered, selected, and invoked. + +## Current Domain Decision + +- The interface should prefer stream-based input plus an additional source identifier instead of a hard file-only contract +- Filter selection should first use the source extension, then inspect the file header or content signature +- Later, the selection should be overridable through a manually chosen prefiltered list +- Filters should be registered through interface-based Dependency Injection +- The base contract should support general metadata, field-specific metadata such as format and type, and field groups +- Field groups are optional and should only be derived when field names show clear structural prefixes +- Flat CSV input may not contain any field groups at all +- Technical metadata must stay clearly separated from the actual data values +- Processing should support large files and return partial results together with a logged error list + +## Proposed Contract Baseline + +### Input source descriptor + +The source descriptor should be passed together with the input stream and provide detection hints without forcing file-system usage. + +Required baseline hints: +- Source identifier +- Suggested extension +- Optional content type hint +- Optional display name + +### Input filter responsibilities + +Each input filter should: +- Decide whether it can process the source based on descriptor and optional header probe +- Parse records from stream input into canonical exchange records +- Emit technical metadata separately from data values +- Emit field-level metadata (`type`, `format`, optional units) +- Optionally emit field groups +- Report parse issues without losing successful records + +### Result shape expectations + +The filter result should contain: +- Parsed records +- General metadata +- Field metadata +- Optional field groups +- Logged parse errors +- Partial-result indicator + +## Selection Strategy + +1. Build candidate filter set from DI registration +2. Prefilter by source extension where available +3. Validate candidates by file inspection (`header + n lines`) and/or an `n KB` format-analysis block returned by each filter +4. If one filter matches, select it +5. If multiple filters match, apply deterministic ranking and log ambiguity +6. If no filter matches, return unsupported-format outcome +7. Future: allow manual override from the prefiltered candidate set + +## Deterministic Ranking Rules + +When multiple filters match the same source, ranking should be resolved in this order: + +1. Manual override selection (when provided) +2. Highest confidence from format inspection result (`header + n lines` decision lines or `n KB` analysis block) +3. Exact extension match +4. Configured filter priority +5. Stable tie-breaker by filter identifier + +## Field Group Inference Rules + +- Field groups are optional and can be absent +- Prefer `.` as the structural separator for group inference +- Also allow `_` as secondary separator +- Do not infer groups from prefix-only naming without a separator +- Examples: + - `AGV1.X`, `AGV1.Y` + - `Diag1.Axis1.Speed`, `Diag1.Axis2.Speed` + +## Failure and Partial-Result Behavior + +- Continue parsing where feasible for recoverable row-level issues +- Collect errors in a structured error list +- Return partial results when at least one record was parsed successfully +- Separate fatal format errors from row-level conversion errors +- Ensure logged issues include source position references where available + +## Project Structure Direction + +- Introduce one or more base interface projects for shared filter contracts +- Keep input and output filter implementations in separate projects +- Combine multiple input filters into one project only when parsing rules are genuinely close +- `CSV` and `TraceCsv2realCsv` CSV may start together but can be split if rule divergence increases + +## Done Criteria + +- Input filter responsibilities are documented +- The stream-based input contract and source descriptor are documented +- Selection strategy is documented, including extension, header detection, and later manual override +- Failure behavior is documented, including partial results and logged error lists +- Metadata handling is documented for general metadata, field-specific metadata, and field groups +- Optional field-group detection rules are documented with naming examples and separator precedence (`.` before `_`) +- Extension path for new formats through interface plus DI is documented +- Project-structure guidance is documented for base interfaces and input/output filter separation diff --git a/CSharpBible/Data/DevOps/Tasks/T-830302-004-Specify-CSV-column-mapping-and-export-behavior.md b/CSharpBible/Data/DevOps/Tasks/T-830302-004-Specify-CSV-column-mapping-and-export-behavior.md new file mode 100644 index 000000000..8ebbf41f8 --- /dev/null +++ b/CSharpBible/Data/DevOps/Tasks/T-830302-004-Specify-CSV-column-mapping-and-export-behavior.md @@ -0,0 +1,127 @@ +# Task T-830348 - Specify CSV column mapping and export behavior + +## Status + +Draft + +## Parent + +- Backlog Item `BI-830334` - `Create CSV output filter` + +## Goal + +Define the CSV projection of canonical exchange records. + +## Current Domain Context + +- The canonical model requires `timestamp` as the only mandatory field +- All other values are optional and initially passed through from input to output +- Technical metadata must remain clearly separated from actual data values +- Field groups are optional and may be absent for flat CSV input + +## Decisions from Current Refinement + +1. Delimiter strategy: + - Automatic detection between `;` and `` + - Optional user-defined delimiter override +2. Detection approach: + - Probe the first lines + - Apply rules from general international assumptions toward country-specific assumptions +3. Multi-value handling: + - No split logic in the direct import filter + - Raw format is read first + - Multi-value split into separate columns is handled later by a downstream general filter +4. Metadata handling for CSV: + - Flat CSV does not contain dedicated metadata, except what can be inferred from the first lines + - Extended per-column metadata is provided via a separate header file + - Export may also write supplemental per-column metadata into a header file + +## Proposed CSV Contract Baseline + +### Column families + +The CSV output should use explicit column families: +- `timestamp` column (always present) +- Data value columns (dynamic, based on available canonical fields) + +Technical metadata should not be mixed into regular data columns. Metadata that cannot be inferred from first lines should be handled through a companion header file. + +### Deterministic column order + +1. `timestamp` +2. Data value columns in stable lexical order + +### Header naming + +- Preserve canonical field names for data columns +- Keep group-related output optional and avoid forcing group columns when groups are absent +- If a companion header file is present, it follows the same column order and separator as the data CSV + +## Value Formatting Rules + +- `timestamp` is exported in invariant ISO 8601 UTC format: `yyyy-MM-ddTHH:mm:ss.fffZ` +- Empty optional values must be exported as empty cells +- No localized formatting for numbers or dates in the first contract draft +- Multi-value fields are not split in direct import; downstream general filters may transform them later + +## CSV Escaping and Delimiter Rules + +- Try delimiter auto-detection using first-line probing +- Supported auto-detection baseline: `;` and `` +- Allow explicit user override of delimiter +- Values containing delimiter, quotes, or line breaks must be escaped consistently +- Quote escaping must follow one deterministic rule +- Header and value serialization must use the same escaping behavior + +## Output Filter Selection Responsibility + +- Output format selection is handled by the output-filter layer +- Manual output-filter selection by the user has priority +- If no manual selection exists, choose by file extension using a fixed entropy baseline without additional analysis +- For `.csv`, the default expected output is flat CSV +- Specialized CSV variants are only selected manually or through explicit non-generic extension mapping + +## Metadata Companion Header File + +The companion header file uses the same delimiter as the data CSV and the same column order. + +Row schema: +1. Column names + - Allowed characters: alphanumeric plus `.`, `-`, `_` + - Spaces are normalized to `_` + - Delimiter characters are not allowed in column names +2. Optional per-column format or type +3. Group name + - Empty value means no group (single column without grouping) + - A non-empty identifier means the column belongs to that group, even if the group currently contains only one column +4. Optional group description + - Used when row 3 contains a group name + - Can continue in following rows when needed + +Multiline handling rules: +- Row 4 is the first description line +- Row 5+ are continuation lines in original order +- Continuation ends at end-of-file +- Empty cells in continuation rows are treated as "no additional text" for that column +- Export writes one description line per physical row, preserving line order + +## Large-File Behavior + +- Export should be stream-friendly and avoid full in-memory materialization where possible +- Export failures should report row/record position where available +- Partial export outcomes should be detectable and logged + +## Open Decisions for Finalization + +- No blocking open decisions for this task + +## Done Criteria + +- Column order is defined +- Header names are defined +- Escaping behavior is defined +- Missing value handling is defined +- Metadata separation from data columns is documented +- Companion header file behavior for import/export is documented +- Large-file and partial-result behavior is documented +- Delimiter auto-detection and user override behavior are documented diff --git a/CSharpBible/Data/DevOps/Tasks/T-830302-006-Define-base-filter-interface-project-structure.md b/CSharpBible/Data/DevOps/Tasks/T-830302-006-Define-base-filter-interface-project-structure.md new file mode 100644 index 000000000..ba0b1d864 --- /dev/null +++ b/CSharpBible/Data/DevOps/Tasks/T-830302-006-Define-base-filter-interface-project-structure.md @@ -0,0 +1,42 @@ +# Task T-832070 - Define base filter interface project structure + +## Status + +Draft + +## Parent + +- Backlog Item `BI-830332` - `Create pluggable input filters for initial source formats` + +## Goal + +Define one or more shared base interface projects for filter contracts and separate input/output filter implementation projects. + +## Scope + +- Define baseline project split for shared contracts vs. concrete filter implementations +- Define dependency direction to avoid cyclic references +- Define registration approach for Dependency Injection +- Define when multiple input filters may share one project and when they must be split + +## Current Direction + +- Shared contracts are placed in base interface project(s) +- Input filters reference base contracts and stay separate from output filters +- Output filters reference base contracts and stay separate from input filters +- CSV and `TraceCsv2realCsv` CSV may initially share an input-filter project, with a split when parsing divergence becomes relevant + +## Deliverables + +- Proposed project map with responsibilities per project +- Allowed dependency graph (from implementation projects to base contracts) +- Naming proposal for base contracts and implementation projects +- DI registration strategy for discovering input/output filters + +## Done Criteria + +- Base interface project structure is documented +- Input/output separation rules are documented +- Dependency direction rules are documented +- DI registration strategy is documented +- Split/merge criteria for multiple input filters in one project are documented diff --git a/CSharpBible/Data/DevOps/Tasks/T-830302-007-Test-T-830302-003-input-filter-selection-and-analysis.md b/CSharpBible/Data/DevOps/Tasks/T-830302-007-Test-T-830302-003-input-filter-selection-and-analysis.md new file mode 100644 index 000000000..604be610d --- /dev/null +++ b/CSharpBible/Data/DevOps/Tasks/T-830302-007-Test-T-830302-003-input-filter-selection-and-analysis.md @@ -0,0 +1,46 @@ +# Task T-831180 - Test T-830353 input filter selection and analysis + +## Status + +Draft + +## Parent + +- Backlog Item `BI-830332` - `Create pluggable input filters for initial source formats` + +## Goal + +Validate that the deterministic input-filter selection and analysis behavior from `T-830353` works as specified. + +## Scope + +- Verify deterministic ranking order for matching filters +- Verify manual filter override behavior +- Verify unsupported-format outcome when no filter can handle input +- Verify analysis details are returned (`confidence`, extension match, decision lines) +- Verify stream handling is safe across repeated analyses and selection + +## Test Focus + +1. Manual override has highest priority when the chosen filter can handle input +2. Ranking order is deterministic: + - confidence score + - exact extension match + - configured filter priority + - stable tie-breaker by filter identifier +3. Non-seekable stream handling is stable (selection remains deterministic) +4. No matching filter returns a `null` selection with full analysis list +5. Decision lines are preserved in analysis outputs + +## Implementation Notes + +- Use `MSTest` +- Use `DataRow` for parameterized ranking cases where practical +- Use `NSubstitute` for filter test doubles + +## Done Criteria + +- Test cases cover all ranking dimensions +- Test cases cover manual override and no-match paths +- Test cases validate analysis payload shape +- Tests run successfully for the targeted project scope diff --git a/CSharpBible/Data/DevOps/Tasks/T-830302-008-Implement-MOVIRUN-trace-text-input-filter.md b/CSharpBible/Data/DevOps/Tasks/T-830302-008-Implement-MOVIRUN-trace-text-input-filter.md new file mode 100644 index 000000000..bc98409fc --- /dev/null +++ b/CSharpBible/Data/DevOps/Tasks/T-830302-008-Implement-MOVIRUN-trace-text-input-filter.md @@ -0,0 +1,50 @@ +# Task T-830302-008 - Implement MOVIRUN trace text input filter + +## Status + +Draft + +## Parent + +- Backlog Item `BI-830332` - `Create pluggable input filters for initial source formats` + +## Goal + +Implement a robust input filter for the whitespace-separated `MOVIRUN` trace text export format. + +## Scope + +- Detect the `MOVIRUN` text trace signature reliably +- Parse the fixed preamble and `Zeitstempel(...)` header row +- Parse whitespace-separated data rows into canonical trace records +- Keep the timestamp as the canonical mandatory record key +- Preserve successful rows when malformed rows are encountered +- Emit parse errors with line-level context where available + +## Format Baseline + +- Line 1: `MOVIRUN` trace signature +- Line 2: source path or trace-origin text +- Line 3: whitespace-separated header row beginning with `Zeitstempel(...)` +- Line 4+: whitespace-separated data rows + +## Implementation Notes + +- Place the filter in a dedicated input-filter project because the parsing behavior diverges from the CSV-oriented filters +- Use deterministic header and sample-row analysis for `CanHandle` or `Analyze` +- Parse numeric values using invariant culture +- Support at least `Zeitstempel(ms)` and `Zeitstempel(µs)` header variants in the first increment +- Continue collecting partial results for recoverable row issues + +## Dependencies + +- `T-830302-001` - `Identify first supported source formats` +- `T-830353` - `Specify input filter interface and selection strategy` + +## Done Criteria + +- A dedicated MOVIRUN text trace input filter exists +- Format detection works for the known text trace signature +- Header and row parsing produce canonical records +- Row-level parse errors are collected without discarding successful rows +- The implementation supports the known `ms` and `µs` timestamp header variants diff --git a/CSharpBible/Data/DevOps/Tasks/T-830302-009-Test-MOVIRUN-trace-text-input-filter.md b/CSharpBible/Data/DevOps/Tasks/T-830302-009-Test-MOVIRUN-trace-text-input-filter.md new file mode 100644 index 000000000..ce43e6f95 --- /dev/null +++ b/CSharpBible/Data/DevOps/Tasks/T-830302-009-Test-MOVIRUN-trace-text-input-filter.md @@ -0,0 +1,36 @@ +# Task T-830302-009 - Test MOVIRUN trace text input filter + +## Status + +Draft + +## Parent + +- Backlog Item `BI-830332` - `Create pluggable input filters for initial source formats` + +## Goal + +Verify detection, parsing, and partial-result behavior of the MOVIRUN trace text input filter. + +## Test Scope + +- Detect valid `MOVIRUN` text traces +- Reject non-matching content safely +- Parse `Zeitstempel(ms)` input +- Parse `Zeitstempel(µs)` input +- Preserve valid rows when malformed rows are present +- Verify canonical field metadata and record mapping + +## Test Notes + +- Use `MSTest` +- Prefer compact representative text samples for unit tests +- Include parse-error assertions for malformed row scenarios +- Keep assertions deterministic across supported target frameworks + +## Done Criteria + +- Detection tests cover the known format signature +- Parsing tests cover `ms` and `µs` timestamp header variants +- Partial-result behavior is validated with malformed-row input +- Tests pass in the TraceAnalysis test project diff --git a/CSharpBible/Data/DevOps/Tasks/T-830302-010-Implement-MOVIRUN-XML-trace-input-filter.md b/CSharpBible/Data/DevOps/Tasks/T-830302-010-Implement-MOVIRUN-XML-trace-input-filter.md new file mode 100644 index 000000000..51c48a7e9 --- /dev/null +++ b/CSharpBible/Data/DevOps/Tasks/T-830302-010-Implement-MOVIRUN-XML-trace-input-filter.md @@ -0,0 +1,51 @@ +# Task T-830302-010 - Implement MOVIRUN XML trace input filter + +## Status + +Draft + +## Parent + +- Backlog Item `BI-830332` - `Create pluggable input filters for initial source formats` + +## Goal + +Implement a robust input filter for the XML-based `MOVIRUN` `.trace` export format. + +## Scope + +- Detect the `.trace` XML signature reliably +- Parse `TraceData/TraceRecord/TraceVariable` measurement series +- Correlate `Values` and `Timestamps` into canonical trace records by timestamp +- Keep XML configuration data secondary unless it directly affects measurement interpretation +- Preserve successful records when malformed variable series are encountered +- Emit parse errors with variable or series context where available + +## Format Baseline + +- Root element `Trace` +- Configuration section `TraceConfiguration` +- Data section `TraceData` +- One or more `TraceRecord` elements +- `TraceVariable` entries with `VarName`, `Values`, and `Timestamps` + +## Implementation Notes + +- Place the filter in a dedicated input-filter project because the XML parsing behavior diverges from CSV- and text-oriented filters +- Use deterministic XML structure analysis for `CanHandle` or `Analyze` +- Parse numeric values using invariant culture where applicable +- Correlate records by timestamp rather than assuming one flat row block in the source +- Continue collecting partial results for recoverable variable or row issues + +## Dependencies + +- `T-830302-001` - `Identify first supported source formats` +- `T-830353` - `Specify input filter interface and selection strategy` + +## Done Criteria + +- A dedicated MOVIRUN XML trace input filter exists +- Format detection works for the known `.trace` XML structure +- Trace-variable series are merged into canonical records by timestamp +- Row- or series-level parse errors are collected without discarding successful records +- The implementation works for the known `ms` and `µs` sample variants diff --git a/CSharpBible/Data/DevOps/Tasks/T-830302-011-Test-MOVIRUN-XML-trace-input-filter.md b/CSharpBible/Data/DevOps/Tasks/T-830302-011-Test-MOVIRUN-XML-trace-input-filter.md new file mode 100644 index 000000000..d8046657c --- /dev/null +++ b/CSharpBible/Data/DevOps/Tasks/T-830302-011-Test-MOVIRUN-XML-trace-input-filter.md @@ -0,0 +1,36 @@ +# Task T-830302-011 - Test MOVIRUN XML trace input filter + +## Status + +Draft + +## Parent + +- Backlog Item `BI-830332` - `Create pluggable input filters for initial source formats` + +## Goal + +Verify detection, timestamp correlation, and partial-result behavior of the MOVIRUN XML trace input filter. + +## Test Scope + +- Detect valid `.trace` XML files +- Reject non-matching XML safely +- Parse canonical records from `ms`-style samples +- Parse canonical records from `µs`-style samples +- Verify timestamp-based merging across multiple variables +- Preserve valid records when one variable series is malformed + +## Test Notes + +- Use `MSTest` +- Prefer compact representative XML samples for unit tests +- Include parse-error assertions for mismatched `Values` and `Timestamps` +- Keep assertions deterministic across supported target frameworks + +## Done Criteria + +- Detection tests cover the known `.trace` XML structure +- Parsing tests cover timestamp correlation and canonical record mapping +- Partial-result behavior is validated with malformed variable series +- Tests pass in the TraceAnalysis test project diff --git a/CSharpBible/Data/DevOps/Tasks/T-830302-012-Integrate-TraceCsv2realCsv-with-shared-TraceAnalysis-intake-filters.md b/CSharpBible/Data/DevOps/Tasks/T-830302-012-Integrate-TraceCsv2realCsv-with-shared-TraceAnalysis-intake-filters.md new file mode 100644 index 000000000..158e119c5 --- /dev/null +++ b/CSharpBible/Data/DevOps/Tasks/T-830302-012-Integrate-TraceCsv2realCsv-with-shared-TraceAnalysis-intake-filters.md @@ -0,0 +1,41 @@ +# Task T-830302-012 - Integrate TraceCsv2realCsv with shared TraceAnalysis intake filters + +## Status + +Draft + +## Parent + +- Backlog Item `BI-830332` - `Create pluggable input filters for initial source formats` + +## Goal + +Refactor `TraceCsv2realCsv` to use the shared `TraceAnalysis` input-filter selection path instead of direct format-specific parsing. + +## Scope + +- Replace direct `TraceCsv` parsing with selector-based canonical import +- Support `.csv`, `.txt`, and `.trace` inputs through the shared intake path +- Reuse the canonical CSV output filter for converter output +- Keep tool behavior deterministic when multiple filters match the same source + +## Implementation Notes + +- Use `IAnalyzableInputFilter` and `InputFilterSelector` +- Adapt existing CSV-oriented input filters so they participate in deterministic selection +- Keep console entry behavior minimal while moving conversion logic into a testable class +- Preserve the converter's role as a file-to-file transformation tool + +## Dependencies + +- `T-830353` - `Specify input filter interface and selection strategy` +- `T-830302-008` - `Implement MOVIRUN trace text input filter` +- `T-830302-010` - `Implement MOVIRUN XML trace input filter` + +## Done Criteria + +- `TraceCsv2realCsv` uses shared TraceAnalysis intake filters +- Existing CSV inputs still convert successfully +- `.txt` MOVIRUN traces convert through the same intake path +- `.trace` MOVIRUN XML traces convert through the same intake path +- Output writing uses the canonical CSV export path diff --git a/CSharpBible/Data/DevOps/Tasks/T-830302-013-Test-TraceCsv2realCsv-shared-intake-integration.md b/CSharpBible/Data/DevOps/Tasks/T-830302-013-Test-TraceCsv2realCsv-shared-intake-integration.md new file mode 100644 index 000000000..7a8385e7b --- /dev/null +++ b/CSharpBible/Data/DevOps/Tasks/T-830302-013-Test-TraceCsv2realCsv-shared-intake-integration.md @@ -0,0 +1,33 @@ +# Task T-830302-013 - Test TraceCsv2realCsv shared intake integration + +## Status + +Draft + +## Parent + +- Backlog Item `BI-830332` - `Create pluggable input filters for initial source formats` + +## Goal + +Verify that `TraceCsv2realCsv` can convert supported source formats through the shared TraceAnalysis intake path. + +## Test Scope + +- Select the expected CSV-oriented filter for `.trace.csv` input +- Convert MOVIRUN text trace input through the shared intake path +- Convert MOVIRUN XML `.trace` input through the shared intake path +- Verify deterministic output structure from the converter service + +## Test Notes + +- Use `MSTest` +- Prefer compact representative inputs for converter tests +- Keep assertions focused on canonical output structure and key values +- Cover selection and conversion behavior together where practical + +## Done Criteria + +- Converter tests cover `.csv`, `.txt`, and `.trace` input paths +- Shared selector behavior is exercised by the converter tests +- Tests pass in the TraceCsv2realCsv test project diff --git a/CSharpBible/Data/DevOps/Tasks/T-830395-Specify-Excel-workbook-layout-and-export-behavior.md b/CSharpBible/Data/DevOps/Tasks/T-830395-Specify-Excel-workbook-layout-and-export-behavior.md new file mode 100644 index 000000000..0ffa79816 --- /dev/null +++ b/CSharpBible/Data/DevOps/Tasks/T-830395-Specify-Excel-workbook-layout-and-export-behavior.md @@ -0,0 +1,91 @@ +# Task T-830395 - Specify Excel workbook layout and export behavior + +## Status + +Draft + +## Parent + +- Backlog Item `BI-830337` - `Create Excel output filter` + +## Goal + +Define the workbook layout and cell mapping for Excel export. + +## Current Domain Context + +- The canonical model requires `timestamp` as the only mandatory field +- All other fields are optional and initially passed through unchanged +- Technical metadata must stay separated from data values +- Field groups are optional +- CSV contract decisions should be mirrored where practical + +## Proposed Excel Contract Baseline + +### Workbook structure + +- Default workbook contains one primary worksheet named `Data` +- The `Data` worksheet contains canonical record export +- Additional metadata worksheet is optional and only created when metadata exists beyond first-line inference +- Exception: when source CSV has no header row, metadata worksheet becomes mandatory + +### Worksheet layout (`Data`) + +- Row 1: column headers +- Row 2+: data records +- Column order follows CSV contract baseline: + 1. `timestamp` + 2. data columns in stable lexical order + +### Header behavior + +- Preserve canonical field names +- Keep header style minimal and deterministic +- Do not rely on localized header text + +## Cell Mapping Rules + +- `timestamp` is always exported +- Missing optional values are exported as empty cells +- No localized number/date conversion in the first baseline +- Multi-value fields are not split in this export step; downstream general filters may transform them first + +## Metadata Handling in Excel + +- Do not mix technical metadata into regular data columns in `Data` +- If extended metadata is required, write it into a dedicated worksheet (for example `Header`) +- Metadata worksheet can follow the same row semantics used for the CSV companion header file: + 1. column name + 2. optional format/type + 3. optional group name + 4. optional group description + +## Formatting Scope for First Increment + +- Keep formatting intentionally minimal +- Freeze top row is allowed if implemented deterministically +- Auto-filter on header row is allowed if implemented deterministically +- No advanced styling requirements in first increment + +## Large Dataset Behavior + +- Prefer memory-conscious writing patterns +- Keep workbook creation deterministic for large row counts +- Report partial export failures with row-level context where possible +- No fixed hard limits for first increment, but implementation should keep a path open for future async pipelining + +## Finalized Decisions + +- Metadata worksheet is optional, except mandatory when CSV input has no header row +- No strict standardized worksheet naming is required for the first increment +- No fixed performance/size limits are set in this increment + +## Done Criteria + +- Worksheet layout is defined +- Header behavior is defined +- Cell mapping is defined +- Size and formatting assumptions are recorded +- Metadata separation strategy is defined +- Large-dataset behavior is documented +- Future async-pipelining compatibility is noted diff --git a/CSharpBible/Data/DevOps/Tasks/T-830895-Implement-Excel-output-filter-from-canonical-exchange-records.md b/CSharpBible/Data/DevOps/Tasks/T-830895-Implement-Excel-output-filter-from-canonical-exchange-records.md new file mode 100644 index 000000000..06fd117e1 --- /dev/null +++ b/CSharpBible/Data/DevOps/Tasks/T-830895-Implement-Excel-output-filter-from-canonical-exchange-records.md @@ -0,0 +1,92 @@ +# Task T-830895 - Implement Excel output filter from canonical exchange records + +## Status + +Draft + +## Parent + +- Backlog Item `BI-830337` - `Create Excel output filter` + +## Goal + +Implement the first production-ready Excel output filter that exports canonical exchange records into a deterministic workbook layout. + +## Scope + +- Implement workbook creation with a primary `Data` worksheet +- Implement deterministic column projection and ordering aligned with CSV baseline: + 1. `timestamp` + 2. remaining fields in stable lexical order +- Implement row mapping from canonical exchange records to worksheet cells +- Implement optional metadata worksheet creation when metadata exists +- Implement mandatory metadata worksheet creation when source CSV had no header row +- Keep technical metadata out of data columns +- Keep first increment formatting minimal and deterministic + +## Out of Scope + +- Advanced worksheet styling beyond deterministic baseline behavior +- Domain-specific derived columns or value transformations +- Localization-specific number/date formatting +- Async execution pipeline implementation (compatibility only) + +## Implementation Notes + +- Reuse existing output-filter abstractions and dependency injection patterns in `TraceAnalysis` +- Keep one class/interface/struct per file when adding or changing implementation artifacts +- Preserve nullability rules and avoid implicit null assumptions +- Keep worksheet naming flexible in this increment (no strict normalization requirement) +- Ensure the implementation is deterministic for equivalent inputs + +## Data Mapping Baseline + +- Header row is row 1 in worksheet `Data` +- Data starts at row 2 +- Missing optional values are written as empty cells +- `timestamp` is always present in output +- Do not split multi-value fields in this step; write canonical values as provided + +## Metadata Worksheet Behavior + +Create a dedicated metadata worksheet using CSV companion-header-compatible row semantics: +1. column name +2. optional format/type +3. optional group name +4. optional group description + +Rule: +- Optional when metadata exists +- Mandatory when source CSV had no header row + +## Large Dataset and Reliability Considerations + +- Use memory-conscious writing patterns +- Keep behavior stable for large exports +- Surface export failures with meaningful row/record context where available +- Keep code structure compatible with future async pipelining + +## Test Strategy + +- Add unit tests for: + - worksheet existence and structure + - deterministic column order + - empty-value mapping + - metadata worksheet optional/mandatory behavior +- Add integration-style export test for a representative canonical dataset +- Use `MSTest` and `NSubstitute` where mocking is required + +## Dependencies + +- `BI-830331` - `Define canonical trace exchange model` +- `T-830395` - `Specify Excel workbook layout and export behavior` + +## Done Criteria + +- Excel output filter implementation is available through the output-filter layer +- Workbook output for canonical records is generated as defined +- Metadata is separated from data columns +- Optional/mandatory metadata worksheet rule is implemented +- Deterministic column ordering is implemented +- Relevant tests pass for workbook layout and mapping behavior +- Implementation notes future async-pipelining compatibility diff --git a/Transpiler_pp/Trnsp.Show.Pas/App.xaml b/CSharpBible/Data/DocumentUtils/Document.Demo.Gui/App.xaml similarity index 69% rename from Transpiler_pp/Trnsp.Show.Pas/App.xaml rename to CSharpBible/Data/DocumentUtils/Document.Demo.Gui/App.xaml index 9b4327029..09e7c0af4 100644 --- a/Transpiler_pp/Trnsp.Show.Pas/App.xaml +++ b/CSharpBible/Data/DocumentUtils/Document.Demo.Gui/App.xaml @@ -1,9 +1,7 @@ - - diff --git a/CSharpBible/Data/DocumentUtils/Document.Demo.Gui/App.xaml.cs b/CSharpBible/Data/DocumentUtils/Document.Demo.Gui/App.xaml.cs new file mode 100644 index 000000000..668ab8404 --- /dev/null +++ b/CSharpBible/Data/DocumentUtils/Document.Demo.Gui/App.xaml.cs @@ -0,0 +1,7 @@ +using System.Windows; + +namespace Document.Demo.Gui; + +public partial class App : Application +{ +} diff --git a/CSharpBible/Data/DocumentUtils/Document.Demo.Gui/Document.Demo.Gui.csproj b/CSharpBible/Data/DocumentUtils/Document.Demo.Gui/Document.Demo.Gui.csproj new file mode 100644 index 000000000..5b7280c99 --- /dev/null +++ b/CSharpBible/Data/DocumentUtils/Document.Demo.Gui/Document.Demo.Gui.csproj @@ -0,0 +1,24 @@ + + + + WinExe + net9.0-windows + enable + enable + true + + + + + + + + + + + + + + + + diff --git a/CSharpBible/Data/DocumentUtils/Document.Demo.Gui/MainWindow.xaml b/CSharpBible/Data/DocumentUtils/Document.Demo.Gui/MainWindow.xaml new file mode 100644 index 000000000..fefbcf528 --- /dev/null +++ b/CSharpBible/Data/DocumentUtils/Document.Demo.Gui/MainWindow.xaml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + +