Skip to content

Latest commit

 

History

History
26 lines (22 loc) · 6.01 KB

AGENTS.md

File metadata and controls

26 lines (22 loc) · 6.01 KB

AGENTS.md

Repo state — Blazor host + SDK classlib

  • Solution TextBox.slnx contains two projects: src/TextBox/TextBox.csproj (Blazor Web App, net10.0, Server interactivity) + src/TextBox.Sdk/TextBox.Sdk.csproj (NSwag-generated NuGet client, netstandard2.0). Phone-style dashboard at / (Components/Pages/Home.razor = conversation list + HomeAside side panel, Conversation.razor = chat + detail modal, Sdk.razor = SDK docs at /sdk via full-width DocsLayout; MainLayout.razor is the static phone shell and TopNavbar/BlazorErrorUi are shared across both layouts — see DESIGN.md §3, pages render only inner content), SMS mock API at /api/messages (Endpoints/MessageEndpoints.cs, LiteDB-backed async store in Services/LiteDbMessageStore.cs with IMemoryCache read-through, contracts in Services/IMessageStore.cs, models in Models/SmsMessage.cs). DB path via MessageStore:Path (default Data/textbox.db, gitignored). POST /api/messages optionally requires an API key (ASP.NET Core auth pipeline in Auth/: ApiKeyAuthOptions.cs scheme options + ApiKeyAuthHandler.cs, enforced via RequireAuthorization() when a key is configured, ApiKey section in appsettings.json, open by default; Auth/ApiKeyService.cs is the single source of truth for the key — never read IOptions<> directly, the scheme binds the named instance). Message timestamps are monotonic per store instance (LiteDB persists ms precision, so back-to-back sends would tie — do not revert to raw UtcNow). Realtime fanout over SignalR (Hubs/MessageHub.cs at /hubs/messages, Hubs/MessageNotifier.cs, per-circuit Services/MessageLiveFeed.cs client). Scalar API docs at /scalar (OpenAPI at /openapi/v1.json, mapped in all environments).
  • SDK (src/TextBox.Sdk/, TextBox.Sdk 0.1.0, netstandard2.0): NSwag 14.7.1 CSharpClient generated from committed openapi.json snapshot (export via running server /openapi/v1.json with a key configured so the Bearer scheme is present; regenerate manually — cd src/TextBox.Sdk then nswag run nswag.json, never on build; global NSwag.ConsoleCore tool + "runtime": "Net100" in nswag.json; spec/input paths resolve from CWD). Generated TextBoxClient (Generated/TextBoxClient.g.cs, ITextBoxClient, op-style methods) is the public API; hand-written partials add ApiKey (PrepareRequest hook), options ctors (TextBoxOptions), friendly aliases (SendAsync/ListAsync/GetAsync/ClearAsync), SendSmsRequest.Create, optional AddTextBoxClient() DI. IsExternalInit.cs shim + System.ComponentModel.Annotations ref are netstandard2.0 requirements — do not remove. NuGet PackageIcon must be PNG (SVG fails NU5045): icon.png copied from branding-assets/ (256px). Branding source of truth is branding-assets/ (SVGs + PNGs, spacey filenames — copy to clean names); wwwroot/favicon.svg (xs variant) + favicon.png fallback linked in App.razor.
  • Legacy TextBox.sln still present but unused — always specify TextBox.slnx explicitly (bare dotnet sln list / dotnet build fails with "Found more than one solution file").
  • Docker: src/TextBox/Dockerfile (standard base/build/publish/final stages, non-root aspnet runtime, port 8080; context is the repo root — docker build -f src/TextBox/Dockerfile .; SDK csproj + package.json copied before dotnet restore/npm ci for layer caching); DB lives at /app/Data — mount -v textbox-data:/app/Data to persist. CI: .github/workflows/ci.yml (build + test + SDK pack artifact + docker build on push/PR to master, pushes image to GHCR on master; sdk-publish job pushes to NuGet only on textbox-sdk-v* tags via trusted publishing (OIDC NuGet/login@v1 as ParsaG72, no stored key — policy must allow repo ParsaGachkar/TextBox, workflow ci.yml; no tags pushed yet).
  • Contributions: follow CONTRIBUTING.md — Conventional Commits (type(scope): subject), PR titles linted in CI.
  • Git is pre-initial-commit on master, no remote, no commits. bin/, obj/, packages/ are gitignored.

Stack & toolchain

  • .NET SDK 10.0.302 available (dotnet --version). Host targets net10.0, SDK targets netstandard2.0 with <LangVersion>latest</LangVersion> (netstandard2.0 defaults to C# 7.3, which the generated client cannot compile against) — see each .csproj TargetFramework.
  • Node.js + npm required: the build runs the Tailwind v4 CLI (node ./node_modules/@tailwindcss/cli/dist/index.mjs -i ./Styles/app.css -o ./wwwroot/css/app.css) via a .csproj target; daisyUI theme (#512bd4 primary) lives in Styles/app.css. For live CSS rebuilds run npm run watch:css in src/TextBox. The Dockerfile additionally runs npm run build:css as an explicit step (with a file-existence check) so a broken stylesheet fails the image build instead of 404ing at runtime.
  • IDE is Rider (JetBrains). .idea/ is nested at .idea/.idea.TextBox/.idea/ — do not commit; root .gitignore already ignores bin//obj/ but not .idea/ at this path, so avoid staging it.

Commands (PowerShell 5.1, win32)

  • Build all: dotnet build TextBox.slnx
  • Run API/dashboard (single host): dotnet run --project src/TextBox/TextBox.csproj
  • Test (xUnit + NSubstitute + bUnit in tests/TextBox.Tests): dotnet test TextBox.slnx / single test: dotnet test TextBox.slnx --filter <TestName>
  • Add project to solution: dotnet new <template> -n <Name> -o <Dir> then dotnet sln TextBox.slnx add <Dir>/<Name>.csproj
  • Verify solution state: dotnet sln TextBox.slnx list (bare dotnet sln list fails — two solution files)
  • Repo helper scripts (scripts/, PowerShell 5.1): Set-SdkVersion.ps1 -Version <semver>, Update-OpenApiSnapshot.ps1 (needs built app), Regen-SdkClient.ps1 (needs global NSwag.ConsoleCore tool), Seed-FakeData.ps1 -ApiKey <key> [-ClearFirst] (needs running server; pass byte-encoded UTF8 bodies — PS 5.1 mangles non-ASCII string bodies)

Gotchas

  • TextBox.sln is legacy/empty — ignore it, always build TextBox.slnx.
  • Use workdir param for tool calls instead of Set-Location/cd in PowerShell.