diff --git a/Chrono/Build/Program.cs b/Chrono/Build/Program.cs
index c23f396..f3c989a 100644
--- a/Chrono/Build/Program.cs
+++ b/Chrono/Build/Program.cs
@@ -4,7 +4,7 @@ using Model;
var repoRoot = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", ".."));
var docsDir = Path.Combine(repoRoot, "chrono.docs");
-var webWwwRoot = Path.Combine(repoRoot, "Chrono", "Standalone", "wwwroot");
+var webWwwRoot = Path.Combine(repoRoot, "Chrono", "Web", "wwwroot");
var generatedFile = Path.Combine(repoRoot, "Chrono", "Shared", "Generated", "Cards.g.cs");
Console.WriteLine($"Repo root: {repoRoot}");
diff --git a/Chrono/Chrono.sln b/Chrono/Chrono.sln
index aa62017..f424ad5 100644
--- a/Chrono/Chrono.sln
+++ b/Chrono/Chrono.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Standalone", "Standalone\Standalone.csproj", "{18981096-443A-44BF-AE56-6499C2B03AEF}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Web", "Web\Web.csproj", "{80847188-4B2E-40C9-BCD3-2562259E60DE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Build", "Build\Build.csproj", "{36E3775C-0E28-4EAE-AE92-4FB493E3787F}"
EndProject
@@ -10,8 +10,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deploy", "Deploy\Deploy.csp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{90F32056-6983-4224-8A8C-E797C71633F3}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cloud", "Cloud\Cloud.csproj", "{BFB7B73F-EFDD-4DE8-89F2-E1CBE1B55C27}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\Shared.csproj", "{30D8468D-01E1-4D8A-99AF-EE4A75A5E956}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Markdown", "Markdown\Markdown.csproj", "{BA7A908C-FEF7-4AC7-ABCE-437259A6C34C}"
@@ -20,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "md", "md", "{A4C572E4-E709-
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{92ED656F-1D94-4348-97AD-B76094B14A8E}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DatabaseTest", "DatabaseTest\DatabaseTest.csproj", "{2B162358-3332-448C-B0D6-776F9CAAD398}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -30,18 +30,6 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {18981096-443A-44BF-AE56-6499C2B03AEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {18981096-443A-44BF-AE56-6499C2B03AEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {18981096-443A-44BF-AE56-6499C2B03AEF}.Debug|x64.ActiveCfg = Debug|Any CPU
- {18981096-443A-44BF-AE56-6499C2B03AEF}.Debug|x64.Build.0 = Debug|Any CPU
- {18981096-443A-44BF-AE56-6499C2B03AEF}.Debug|x86.ActiveCfg = Debug|Any CPU
- {18981096-443A-44BF-AE56-6499C2B03AEF}.Debug|x86.Build.0 = Debug|Any CPU
- {18981096-443A-44BF-AE56-6499C2B03AEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {18981096-443A-44BF-AE56-6499C2B03AEF}.Release|Any CPU.Build.0 = Release|Any CPU
- {18981096-443A-44BF-AE56-6499C2B03AEF}.Release|x64.ActiveCfg = Release|Any CPU
- {18981096-443A-44BF-AE56-6499C2B03AEF}.Release|x64.Build.0 = Release|Any CPU
- {18981096-443A-44BF-AE56-6499C2B03AEF}.Release|x86.ActiveCfg = Release|Any CPU
- {18981096-443A-44BF-AE56-6499C2B03AEF}.Release|x86.Build.0 = Release|Any CPU
{36E3775C-0E28-4EAE-AE92-4FB493E3787F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{36E3775C-0E28-4EAE-AE92-4FB493E3787F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{36E3775C-0E28-4EAE-AE92-4FB493E3787F}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -90,18 +78,6 @@ Global
{90F32056-6983-4224-8A8C-E797C71633F3}.Release|x64.Build.0 = Release|Any CPU
{90F32056-6983-4224-8A8C-E797C71633F3}.Release|x86.ActiveCfg = Release|Any CPU
{90F32056-6983-4224-8A8C-E797C71633F3}.Release|x86.Build.0 = Release|Any CPU
- {BFB7B73F-EFDD-4DE8-89F2-E1CBE1B55C27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BFB7B73F-EFDD-4DE8-89F2-E1CBE1B55C27}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BFB7B73F-EFDD-4DE8-89F2-E1CBE1B55C27}.Debug|x64.ActiveCfg = Debug|Any CPU
- {BFB7B73F-EFDD-4DE8-89F2-E1CBE1B55C27}.Debug|x64.Build.0 = Debug|Any CPU
- {BFB7B73F-EFDD-4DE8-89F2-E1CBE1B55C27}.Debug|x86.ActiveCfg = Debug|Any CPU
- {BFB7B73F-EFDD-4DE8-89F2-E1CBE1B55C27}.Debug|x86.Build.0 = Debug|Any CPU
- {BFB7B73F-EFDD-4DE8-89F2-E1CBE1B55C27}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BFB7B73F-EFDD-4DE8-89F2-E1CBE1B55C27}.Release|Any CPU.Build.0 = Release|Any CPU
- {BFB7B73F-EFDD-4DE8-89F2-E1CBE1B55C27}.Release|x64.ActiveCfg = Release|Any CPU
- {BFB7B73F-EFDD-4DE8-89F2-E1CBE1B55C27}.Release|x64.Build.0 = Release|Any CPU
- {BFB7B73F-EFDD-4DE8-89F2-E1CBE1B55C27}.Release|x86.ActiveCfg = Release|Any CPU
- {BFB7B73F-EFDD-4DE8-89F2-E1CBE1B55C27}.Release|x86.Build.0 = Release|Any CPU
{30D8468D-01E1-4D8A-99AF-EE4A75A5E956}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{30D8468D-01E1-4D8A-99AF-EE4A75A5E956}.Debug|Any CPU.Build.0 = Debug|Any CPU
{30D8468D-01E1-4D8A-99AF-EE4A75A5E956}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -126,6 +102,30 @@ Global
{BA7A908C-FEF7-4AC7-ABCE-437259A6C34C}.Release|x64.Build.0 = Release|Any CPU
{BA7A908C-FEF7-4AC7-ABCE-437259A6C34C}.Release|x86.ActiveCfg = Release|Any CPU
{BA7A908C-FEF7-4AC7-ABCE-437259A6C34C}.Release|x86.Build.0 = Release|Any CPU
+ {2B162358-3332-448C-B0D6-776F9CAAD398}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2B162358-3332-448C-B0D6-776F9CAAD398}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2B162358-3332-448C-B0D6-776F9CAAD398}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {2B162358-3332-448C-B0D6-776F9CAAD398}.Debug|x64.Build.0 = Debug|Any CPU
+ {2B162358-3332-448C-B0D6-776F9CAAD398}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2B162358-3332-448C-B0D6-776F9CAAD398}.Debug|x86.Build.0 = Debug|Any CPU
+ {2B162358-3332-448C-B0D6-776F9CAAD398}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2B162358-3332-448C-B0D6-776F9CAAD398}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2B162358-3332-448C-B0D6-776F9CAAD398}.Release|x64.ActiveCfg = Release|Any CPU
+ {2B162358-3332-448C-B0D6-776F9CAAD398}.Release|x64.Build.0 = Release|Any CPU
+ {2B162358-3332-448C-B0D6-776F9CAAD398}.Release|x86.ActiveCfg = Release|Any CPU
+ {2B162358-3332-448C-B0D6-776F9CAAD398}.Release|x86.Build.0 = Release|Any CPU
+ {80847188-4B2E-40C9-BCD3-2562259E60DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {80847188-4B2E-40C9-BCD3-2562259E60DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {80847188-4B2E-40C9-BCD3-2562259E60DE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {80847188-4B2E-40C9-BCD3-2562259E60DE}.Debug|x64.Build.0 = Debug|Any CPU
+ {80847188-4B2E-40C9-BCD3-2562259E60DE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {80847188-4B2E-40C9-BCD3-2562259E60DE}.Debug|x86.Build.0 = Debug|Any CPU
+ {80847188-4B2E-40C9-BCD3-2562259E60DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {80847188-4B2E-40C9-BCD3-2562259E60DE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {80847188-4B2E-40C9-BCD3-2562259E60DE}.Release|x64.ActiveCfg = Release|Any CPU
+ {80847188-4B2E-40C9-BCD3-2562259E60DE}.Release|x64.Build.0 = Release|Any CPU
+ {80847188-4B2E-40C9-BCD3-2562259E60DE}.Release|x86.ActiveCfg = Release|Any CPU
+ {80847188-4B2E-40C9-BCD3-2562259E60DE}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Chrono/Cloud/Cloud.csproj b/Chrono/Cloud/Cloud.csproj
deleted file mode 100644
index 35de9bf..0000000
--- a/Chrono/Cloud/Cloud.csproj
+++ /dev/null
@@ -1,35 +0,0 @@
-
Browse all @allCards.Count cards
-No cards match your filters.
- -This is a test page.
diff --git a/Chrono/Cloud/Components/Pages/Login.razor b/Chrono/Cloud/Components/Pages/Login.razor deleted file mode 100644 index e73b95a..0000000 --- a/Chrono/Cloud/Components/Pages/Login.razor +++ /dev/null @@ -1,110 +0,0 @@ -@page "/login" -@rendermode InteractiveServer -@attribute [AllowAnonymous] -@inject IJSRuntime JS -@inject NavigationManager Nav -@inject AuthenticationStateProvider AuthStateProvider - -Use your registered passkey to sign in.
- - } - else - { -No passkey enrolled yet. Register your device to get started.
- - } -@decks.Count deck@(decks.Count != 1 ? "s" : "") saved
-No decks yet. Create your first deck!
- - Build a Deck - -Delete @(string.IsNullOrEmpty(deckToDelete.Name) ? "Untitled Deck" : deckToDelete.Name)? - This cannot be undone.
-Browse, add, edit, and delete notes associated with Chrono CCG cards.
+There are currently no card notes matching your criteria.
+| Card Name (Primary Key) | +Note Content | +Actions | +
|---|---|---|
|
+
+
+ @note.CardName
+
+ |
+
+ @note.Note
+ |
+
+
+
+
+
+ |
+
Are you sure you want to delete the note for:
+This action will remove the record from the database permanently.
+Current count: @currentCount
+ + + +@code { + private int currentCount = 0; + + private void IncrementCount() + { + currentCount++; + } + +} \ No newline at end of file diff --git a/Chrono/DatabaseTest/Components/Pages/DiagnosticsPage.razor b/Chrono/DatabaseTest/Components/Pages/DiagnosticsPage.razor new file mode 100644 index 0000000..cf557fc --- /dev/null +++ b/Chrono/DatabaseTest/Components/Pages/DiagnosticsPage.razor @@ -0,0 +1,360 @@ +@page "/diagnostics" +@implements IDisposable + +Configure database providers, update connection strings, inspect EF Core migrations, and run maintenance tasks.
+Cloud.AppDbContext.
+
+ Request ID: @RequestId
+
+ Swapping to Development environment will display more detailed information about the error that occurred. +
++ The Development environment shouldn't be enabled for deployed applications. + It can result in displaying sensitive information from exceptions to end users. + For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development + and restarting the app. +
+ +@code{ + [CascadingParameter] private HttpContext? HttpContext { get; set; } + + private string? RequestId { get; set; } + private bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + + protected override void OnInitialized() => + RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier; + +} \ No newline at end of file diff --git a/Chrono/DatabaseTest/Components/Pages/Home.razor b/Chrono/DatabaseTest/Components/Pages/Home.razor new file mode 100644 index 0000000..863d494 --- /dev/null +++ b/Chrono/DatabaseTest/Components/Pages/Home.razor @@ -0,0 +1,313 @@ +@page "/" +@implements IDisposable + +Monitor, manage, and validate all database features referenced in Chrono Cloud
++ @(health.ErrorMessage ?? "Could not connect to the database server. Ensure PostgreSQL is running on the configured host/port.") +
+
+ Tracks developer and user strategic card notes with primary key indexing on CardName. Supports live search, adding, updating, and deletion.
+
+ Stores full player decks with native PostgreSQL jsonb mapping for Cards list (with counts) and Divers list.
+
+ Stores WebAuthn / FIDO2 binary credentials (raw byte[] for CredentialId, PublicKey, UserHandle) with counter verification.
+
Sorry, the content you are looking for does not exist.
\ No newline at end of file diff --git a/Chrono/DatabaseTest/Components/Pages/PasskeysPage.razor b/Chrono/DatabaseTest/Components/Pages/PasskeysPage.razor new file mode 100644 index 0000000..610b498 --- /dev/null +++ b/Chrono/DatabaseTest/Components/Pages/PasskeysPage.razor @@ -0,0 +1,509 @@ +@page "/passkeys" +@implements IDisposable +@using System.Security.Cryptography + +Browse, add, edit, and delete WebAuthn / FIDO2 security credentials with raw binary byte arrays.
+No passkey credentials were found in the database.
+| ID | +AAGUID | +Sign Count | +Credential ID (Byte[]) | +Public Key (Byte[]) | +Actions | +
|---|---|---|---|---|---|
| + #@p.Id + | +
+ @(string.IsNullOrEmpty(p.AaGuid) ? "(None)" : p.AaGuid)
+ |
+ + @p.SignCount + | +
+
+ @Convert.ToHexString(p.CredentialId)[..Math.Min(16, p.CredentialId.Length * 2)]... (@p.CredentialId.Length bytes)
+
+ |
+
+
+ @Convert.ToHexString(p.PublicKey)[..Math.Min(16, p.PublicKey.Length * 2)]... (@p.PublicKey.Length bytes)
+
+ |
+
+
+
+
+
+
+ |
+
@Convert.ToHexString(viewedPasskey.CredentialId)+
@Convert.ToBase64String(viewedPasskey.CredentialId)+
@Convert.ToHexString(viewedPasskey.PublicKey)+
@Convert.ToBase64String(viewedPasskey.PublicKey)+
@Convert.ToHexString(viewedPasskey.UserHandle)+
@Convert.ToBase64String(viewedPasskey.UserHandle)+
Are you sure you want to delete passkey credential:
+This will permanently delete the binary security credential from the database.
+Automated end-to-end verification of all database features, constraints, and JSONB mappings referenced in Chrono Cloud.
+Click "Run All Database Tests" above to execute tests against the database.
+ +@test.Description
+ + @if (!string.IsNullOrEmpty(test.ErrorMessage)) + { +Browse, add, edit, and delete deck builds with native JSONB collection mappings.
+No decks were found matching your search.
+| Deck Name | +Season | +Cards (JSONB) | +Divers | +Notes | +Updated (UTC) | +Actions | +
|---|---|---|---|---|---|---|
|
+ @deck.Name
+ ID: @deck.Id
+ |
+ + @(string.IsNullOrEmpty(deck.Season) ? "General" : deck.Season) + | ++ + @totalCards cards + + | ++ + @diverCount + + | +
+
+ @(string.IsNullOrEmpty(deck.Notes) ? "-" : deck.Notes)
+
+ |
+
+
+ @deck.UpdatedAt.ToString("yyyy-MM-dd HH:mm")
+
+ |
+
+
+
+
+
+
+ |
+
@GetFormattedDeckJson(viewedDeck)+
Are you sure you want to delete deck:
+This will remove the deck record and its JSONB associations from the database.
+This component demonstrates showing data.
+ +@if (forecasts == null) +{ ++ Loading... +
+} +else +{ +| Date | +Temp. (C) | +Temp. (F) | +Summary | +
|---|---|---|---|
| @forecast.Date.ToShortDateString() | +@forecast.TemperatureC | +@forecast.TemperatureF | +@forecast.Summary | +