diff --git a/.gitignore b/.gitignore index d372f9d..860bacb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,21 @@ _bmad/ .agents/ .claude/ +.idea/ gitea_token package-lock.json +node_modules/ +bin/ +obj/ +.env +.env.* +dist/ +coverage/ +*.log +*.user +*.suo +*.swp +*.DS_Store +Thumbs.db +Campaign_Tracker.Server/Campaign_Tracker.Server.csproj + diff --git a/Campaign_Tracker.Server.Tests/Campaign_Tracker.Server.Tests.csproj b/Campaign_Tracker.Server.Tests/Campaign_Tracker.Server.Tests.csproj new file mode 100644 index 0000000..eab9bfb --- /dev/null +++ b/Campaign_Tracker.Server.Tests/Campaign_Tracker.Server.Tests.csproj @@ -0,0 +1,27 @@ + + + + net10.0 + enable + enable + false + + + + + + + + + + + + + + + + + + + + diff --git a/Campaign_Tracker.Server.Tests/HealthEndpointTests.cs b/Campaign_Tracker.Server.Tests/HealthEndpointTests.cs new file mode 100644 index 0000000..e725c05 --- /dev/null +++ b/Campaign_Tracker.Server.Tests/HealthEndpointTests.cs @@ -0,0 +1,34 @@ +using System.Net; +using System.Net.Http.Json; +using Microsoft.AspNetCore.Mvc.Testing; + +namespace Campaign_Tracker.Server.Tests; + +public class HealthEndpointTests : IClassFixture> +{ + private readonly WebApplicationFactory _factory; + + public HealthEndpointTests(WebApplicationFactory factory) + { + _factory = factory; + } + + [Fact] + public async Task GetHealth_ReturnsOkWithExpectedPayload() + { + using var client = _factory.CreateClient(); + + var response = await client.GetAsync("/health"); + var payload = await response.Content.ReadFromJsonAsync(); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.NotNull(payload); + Assert.Equal("ok", payload.Status); + } + + private sealed class HealthResponse + { + public string Status { get; init; } = string.Empty; + } +} + diff --git a/Campaign_Tracker.Server/Campaign_Tracker.Server.http b/Campaign_Tracker.Server/Campaign_Tracker.Server.http new file mode 100644 index 0000000..17596b9 --- /dev/null +++ b/Campaign_Tracker.Server/Campaign_Tracker.Server.http @@ -0,0 +1,7 @@ +@Campaign_Tracker.Server_HostAddress = http://localhost:5254 + +GET {{Campaign_Tracker.Server_HostAddress}}/weatherforecast/ +Accept: application/json + +### + diff --git a/Campaign_Tracker.Server/Controllers/WeatherForecastController.cs b/Campaign_Tracker.Server/Controllers/WeatherForecastController.cs new file mode 100644 index 0000000..cc14cf5 --- /dev/null +++ b/Campaign_Tracker.Server/Controllers/WeatherForecastController.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Campaign_Tracker.Server.Controllers; + +[ApiController] +[Route("[controller]")] +public class WeatherForecastController : ControllerBase +{ + private static readonly string[] Summaries = + [ + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + ]; + + [HttpGet(Name = "GetWeatherForecast")] + public IEnumerable Get() + { + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); + } +} + diff --git a/Campaign_Tracker.Server/Program.cs b/Campaign_Tracker.Server/Program.cs new file mode 100644 index 0000000..5520d02 --- /dev/null +++ b/Campaign_Tracker.Server/Program.cs @@ -0,0 +1,26 @@ +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddControllers(); +// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi +builder.Services.AddOpenApi(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.MapOpenApi(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); +app.MapGet("/health", () => Results.Ok(new { status = "ok" })); + +app.Run(); + +public partial class Program; diff --git a/Campaign_Tracker.Server/Properties/launchSettings.json b/Campaign_Tracker.Server/Properties/launchSettings.json new file mode 100644 index 0000000..59428b7 --- /dev/null +++ b/Campaign_Tracker.Server/Properties/launchSettings.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://localhost:5254", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "https://localhost:7244;http://localhost:5254", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/Campaign_Tracker.Server/WeatherForecast.cs b/Campaign_Tracker.Server/WeatherForecast.cs new file mode 100644 index 0000000..8a03a05 --- /dev/null +++ b/Campaign_Tracker.Server/WeatherForecast.cs @@ -0,0 +1,13 @@ +namespace Campaign_Tracker.Server; + +public class WeatherForecast +{ + public DateOnly Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string? Summary { get; set; } +} + diff --git a/Campaign_Tracker.Server/appsettings.Development.json b/Campaign_Tracker.Server/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/Campaign_Tracker.Server/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/Campaign_Tracker.Server/appsettings.json b/Campaign_Tracker.Server/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/Campaign_Tracker.Server/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Initial Description.txt b/Initial Description.txt index f55a1c9..94dbcff 100644 --- a/Initial Description.txt +++ b/Initial Description.txt @@ -2,7 +2,7 @@ looking at the Client Database Plan.xlsx and Access_Schema.txt in the Initial Do -Continue the `$bmad-create-architecture` workflow from where we left off in `C:\Users\danielc.NTP\Desktop\Brians Client Route Reports App`. +Continue the `$bmad-create-architecture` workflow from where we left off in `C:\Users\danielc.NTP\Desktop\Campaign_Tracker App`. Current status: - `Step 3` is already approved and saved in `_bmad-output/planning-artifacts/architecture.md` (with `stepsCompleted: [1,2,3]`). @@ -22,3 +22,4 @@ Please: 2) Update frontmatter `stepsCompleted` to include `4`. 3) Load Step 5 and continue with normal A/P/C workflow. 4) Show me the Step 5 draft and menu. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..67a0362 --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +# Campaign_Tracker App + +## Prerequisites + +- .NET SDK 10.0+ +- Node.js 20.19+ (or 22.12+) + +## Run Commands + +### Server + +```powershell +dotnet restore .\campaign-tracker.sln +dotnet build .\campaign-tracker.sln +dotnet run --project .\Campaign_Tracker.Server\Campaign_Tracker.Server.csproj +``` + +Health check: + +```powershell +Invoke-WebRequest http://localhost:5000/health +``` + +### Client + +```powershell +cd .\campaign-tracker-client +npm install +npm run dev +``` + +### Tests + +```powershell +dotnet test .\campaign-tracker.sln +cd .\campaign-tracker-client +npm run lint +npm run build +``` + + diff --git a/_bmad-output/implementation-artifacts/1-1-project-initialization-solution-scaffold.md b/_bmad-output/implementation-artifacts/1-1-project-initialization-solution-scaffold.md index ada1672..df16891 100644 --- a/_bmad-output/implementation-artifacts/1-1-project-initialization-solution-scaffold.md +++ b/_bmad-output/implementation-artifacts/1-1-project-initialization-solution-scaffold.md @@ -1,6 +1,6 @@ # Story 1.1: Project Initialization & Solution Scaffold -Status: ready-for-dev +Status: review ## Story @@ -10,31 +10,31 @@ so that the team has a working, runnable baseline with the correct project struc ## Acceptance Criteria -1. Given the initialization commands are run (`dotnet new sln`, `dotnet new webapi`, `npm create vite@latest --template react-ts`) when the solution builds, then both `BriansClientRouteReports.Server` and `brians-client-route-reports-client` compile without errors. +1. Given the initialization commands are run (`dotnet new sln`, `dotnet new webapi`, `npm create vite@latest --template react-ts`) when the solution builds, then both `Campaign_Tracker.Server` and `campaign-tracker-client` compile without errors. 2. Given the solution is running locally, when the Vite dev server starts, then the React app loads at the configured local URL with no console errors. 3. Given the server is running, when `GET /health` is called, then it returns `200 OK` with a status payload. 4. Given the solution structure is created, when reviewed against the architecture decision, then the `.sln` file, server project folder, and client project folder exist at expected paths and `.gitignore` excludes `node_modules`, `bin`, `obj`, and `.env` files. ## Tasks / Subtasks -- [ ] Create baseline solution and projects (AC: 1, 4) - - [ ] Run `dotnet new sln -n brians-client-route-reports` at repo root. - - [ ] Run `dotnet new webapi -n BriansClientRouteReports.Server -f net10.0 --use-controllers`. - - [ ] Add server project to solution: `dotnet sln add .\\BriansClientRouteReports.Server\\BriansClientRouteReports.Server.csproj`. - - [ ] Run `npm create vite@latest brians-client-route-reports-client -- --template react-ts`. -- [ ] Add operational baseline hardening files (AC: 4) - - [ ] Add/update root `.gitignore` with `.env`, `node_modules/`, `bin/`, `obj/`, and common build artifacts. - - [ ] Ensure folders are exactly: - - `./BriansClientRouteReports.Server/` - - `./brians-client-route-reports-client/` - - `./brians-client-route-reports.sln` -- [ ] Implement health endpoint (AC: 3) - - [ ] Ensure server exposes `GET /health` returning JSON payload and HTTP 200. - - [ ] Add lightweight server integration check for `/health` response shape and status. -- [ ] Verify local run and build paths (AC: 1, 2, 3) - - [ ] Validate `dotnet build` succeeds for server and solution. - - [ ] Validate client install and dev start (`npm install`, `npm run dev`) succeeds with no runtime console errors on first render. - - [ ] Capture exact run commands in README or implementation notes for handoff. +- [x] Create baseline solution and projects (AC: 1, 4) + - [x] Run `dotnet new sln -n campaign-tracker` at repo root. + - [x] Run `dotnet new webapi -n Campaign_Tracker.Server -f net10.0 --use-controllers`. + - [x] Add server project to solution: `dotnet sln add .\\Campaign_Tracker.Server\\Campaign_Tracker.Server.csproj`. + - [x] Run `npm create vite@latest campaign-tracker-client -- --template react-ts`. +- [x] Add operational baseline hardening files (AC: 4) + - [x] Add/update root `.gitignore` with `.env`, `node_modules/`, `bin/`, `obj/`, and common build artifacts. + - [x] Ensure folders are exactly: + - `./Campaign_Tracker.Server/` + - `./campaign-tracker-client/` + - `./campaign-tracker.sln` +- [x] Implement health endpoint (AC: 3) + - [x] Ensure server exposes `GET /health` returning JSON payload and HTTP 200. + - [x] Add lightweight server integration check for `/health` response shape and status. +- [x] Verify local run and build paths (AC: 1, 2, 3) + - [x] Validate `dotnet build` succeeds for server and solution. + - [x] Validate client install and dev start (`npm install`, `npm run dev`) succeeds with no runtime console errors on first render. + - [x] Capture exact run commands in README or implementation notes for handoff. ## Dev Notes @@ -58,9 +58,9 @@ so that the team has a working, runnable baseline with the correct project struc ### File Structure Requirements - Required outputs: - - `brians-client-route-reports.sln` - - `BriansClientRouteReports.Server/BriansClientRouteReports.Server.csproj` - - `brians-client-route-reports-client/package.json` + - `campaign-tracker.sln` + - `Campaign_Tracker.Server/Campaign_Tracker.Server.csproj` + - `campaign-tracker-client/package.json` - Keep server and client sibling directories at repo root. ### Testing Requirements @@ -94,12 +94,54 @@ GPT-5 Codex - Sprint source file: `_bmad-output/implementation-artifacts/sprint-status.yaml` - Requirement source files: `epics.md`, `architecture.md`, `ux-design-specification.md` +- Build/test commands: `dotnet build`, `dotnet test`, `npm install`, `npm run lint`, `npm run build` +- Runtime smoke checks: `GET /health` integration test and Vite startup probe on `http://127.0.0.1:5173` ### Completion Notes List -- Comprehensive context generated for Story 1.1 with explicit guardrails, commands, and scope boundaries. -- Story is intentionally constrained to scaffold readiness and health-check baseline. +- Created root solution scaffold (`campaign-tracker.sln`), ASP.NET Core `net10.0` API, and Vite React TypeScript client. +- Updated root `.gitignore` with required exclusions (`.env`, `node_modules/`, `bin/`, `obj/`) plus standard build artifacts. +- Implemented `GET /health` in server startup pipeline returning `{ "status": "ok" }` with HTTP 200. +- Added lightweight server integration test coverage for `/health` status code and payload shape. +- Verified solution and server builds, server tests, client lint/build, and client dev-server startup. +- Captured exact local run/test commands in root `README.md`. ### File List +- `.gitignore` +- `README.md` +- `campaign-tracker.sln` +- `Campaign_Tracker.Server/Campaign_Tracker.Server.csproj` +- `Campaign_Tracker.Server/Program.cs` +- `Campaign_Tracker.Server/WeatherForecast.cs` +- `Campaign_Tracker.Server/Controllers/WeatherForecastController.cs` +- `Campaign_Tracker.Server/appsettings.json` +- `Campaign_Tracker.Server/appsettings.Development.json` +- `Campaign_Tracker.Server/Properties/launchSettings.json` +- `Campaign_Tracker.Server/Campaign_Tracker.Server.http` +- `Campaign_Tracker.Server.Tests/Campaign_Tracker.Server.Tests.csproj` +- `Campaign_Tracker.Server.Tests/HealthEndpointTests.cs` +- `campaign-tracker-client/package.json` +- `campaign-tracker-client/README.md` +- `campaign-tracker-client/index.html` +- `campaign-tracker-client/eslint.config.js` +- `campaign-tracker-client/vite.config.ts` +- `campaign-tracker-client/tsconfig.json` +- `campaign-tracker-client/tsconfig.app.json` +- `campaign-tracker-client/tsconfig.node.json` +- `campaign-tracker-client/public/favicon.svg` +- `campaign-tracker-client/public/icons.svg` +- `campaign-tracker-client/src/main.tsx` +- `campaign-tracker-client/src/App.tsx` +- `campaign-tracker-client/src/App.css` +- `campaign-tracker-client/src/index.css` +- `campaign-tracker-client/src/assets/react.svg` +- `campaign-tracker-client/src/assets/vite.svg` +- `campaign-tracker-client/src/assets/hero.png` - `_bmad-output/implementation-artifacts/1-1-project-initialization-solution-scaffold.md` + +### Change Log + +- 2026-05-05: Completed Story 1.1 scaffold implementation, health endpoint, integration test coverage, and local run/build verification. + + diff --git a/_bmad-output/implementation-artifacts/1-10-municipality-account-profile.md b/_bmad-output/implementation-artifacts/1-10-municipality-account-profile.md index f91702b..e039193 100644 --- a/_bmad-output/implementation-artifacts/1-10-municipality-account-profile.md +++ b/_bmad-output/implementation-artifacts/1-10-municipality-account-profile.md @@ -1,4 +1,4 @@ -# Story 1.10: Municipality Account Profile +# Story 1.10: Municipality Account Profile Status: ready-for-dev @@ -38,8 +38,8 @@ so that permanent municipality data is managed in the extension layer without mo ### Project Structure Notes -- Backend: `BriansClientRouteReports.Server/` -- Frontend: `brians-client-route-reports-client/` +- Backend: `Campaign_Tracker.Server/` +- Frontend: `campaign-tracker-client/` - Story artifacts: `_bmad-output/implementation-artifacts/` ### References @@ -65,3 +65,5 @@ GPT-5 Codex ### File List - `_bmad-output/implementation-artifacts/1-10-municipality-account-profile.md` + + diff --git a/_bmad-output/implementation-artifacts/1-11-municipality-operational-addresses.md b/_bmad-output/implementation-artifacts/1-11-municipality-operational-addresses.md index 2a17bfc..b1dbe76 100644 --- a/_bmad-output/implementation-artifacts/1-11-municipality-operational-addresses.md +++ b/_bmad-output/implementation-artifacts/1-11-municipality-operational-addresses.md @@ -1,4 +1,4 @@ -# Story 1.11: Municipality Operational Addresses +# Story 1.11: Municipality Operational Addresses Status: ready-for-dev @@ -38,8 +38,8 @@ so that election services reference current address information without dependin ### Project Structure Notes -- Backend: `BriansClientRouteReports.Server/` -- Frontend: `brians-client-route-reports-client/` +- Backend: `Campaign_Tracker.Server/` +- Frontend: `campaign-tracker-client/` - Story artifacts: `_bmad-output/implementation-artifacts/` ### References @@ -65,3 +65,5 @@ GPT-5 Codex ### File List - `_bmad-output/implementation-artifacts/1-11-municipality-operational-addresses.md` + + diff --git a/_bmad-output/implementation-artifacts/1-12-municipality-service-contacts.md b/_bmad-output/implementation-artifacts/1-12-municipality-service-contacts.md index 23494f8..6c539f0 100644 --- a/_bmad-output/implementation-artifacts/1-12-municipality-service-contacts.md +++ b/_bmad-output/implementation-artifacts/1-12-municipality-service-contacts.md @@ -1,4 +1,4 @@ -# Story 1.12: Municipality Service Contacts +# Story 1.12: Municipality Service Contacts Status: ready-for-dev @@ -38,8 +38,8 @@ so that the right people can be reached during election operations without consu ### Project Structure Notes -- Backend: `BriansClientRouteReports.Server/` -- Frontend: `brians-client-route-reports-client/` +- Backend: `Campaign_Tracker.Server/` +- Frontend: `campaign-tracker-client/` - Story artifacts: `_bmad-output/implementation-artifacts/` ### References @@ -65,3 +65,5 @@ GPT-5 Codex ### File List - `_bmad-output/implementation-artifacts/1-12-municipality-service-contacts.md` + + diff --git a/_bmad-output/implementation-artifacts/1-13-municipality-prior-cycle-service-defaults-view.md b/_bmad-output/implementation-artifacts/1-13-municipality-prior-cycle-service-defaults-view.md index cbf6d28..e68adc1 100644 --- a/_bmad-output/implementation-artifacts/1-13-municipality-prior-cycle-service-defaults-view.md +++ b/_bmad-output/implementation-artifacts/1-13-municipality-prior-cycle-service-defaults-view.md @@ -1,4 +1,4 @@ -# Story 1.13: Municipality Prior-Cycle Service Defaults View +# Story 1.13: Municipality Prior-Cycle Service Defaults View Status: ready-for-dev @@ -12,7 +12,7 @@ so that I can reference proven configurations when setting up new election-cycle 1. **Given** a municipality has at least one completed election-cycle job **When** a client services user views the prior-cycle defaults panel **Then** the most recent cycle's service configurations are displayed as read-only reference data 2. **Given** a municipality has multiple prior cycles **When** the defaults panel is viewed **Then** the most recent cycle is shown by default with a cycle selector control to navigate older cycles -3. **Given** no prior cycles exist for a municipality **When** defaults are requested **Then** the system displays a clear "No prior cycle defaults available" state with guidance to create the first cycle **And** all data in this view is read-only — the apply-to-new-job action is out of scope for this story and delivered in Epic 2 (Story 2.4) +3. **Given** no prior cycles exist for a municipality **When** defaults are requested **Then** the system displays a clear "No prior cycle defaults available" state with guidance to create the first cycle **And** all data in this view is read-only — the apply-to-new-job action is out of scope for this story and delivered in Epic 2 (Story 2.4) ## Tasks / Subtasks @@ -35,8 +35,8 @@ so that I can reference proven configurations when setting up new election-cycle ### Project Structure Notes -- Backend: `BriansClientRouteReports.Server/` -- Frontend: `brians-client-route-reports-client/` +- Backend: `Campaign_Tracker.Server/` +- Frontend: `campaign-tracker-client/` - Story artifacts: `_bmad-output/implementation-artifacts/` ### References @@ -62,3 +62,5 @@ GPT-5 Codex ### File List - `_bmad-output/implementation-artifacts/1-13-municipality-prior-cycle-service-defaults-view.md` + + diff --git a/_bmad-output/implementation-artifacts/1-2-workspace-shell-ant-design-foundation.md b/_bmad-output/implementation-artifacts/1-2-workspace-shell-ant-design-foundation.md index 9030b37..a952f15 100644 --- a/_bmad-output/implementation-artifacts/1-2-workspace-shell-ant-design-foundation.md +++ b/_bmad-output/implementation-artifacts/1-2-workspace-shell-ant-design-foundation.md @@ -1,4 +1,4 @@ -# Story 1.2: Workspace Shell & Ant Design Foundation +# Story 1.2: Workspace Shell & Ant Design Foundation Status: ready-for-dev @@ -13,9 +13,9 @@ so that I have a predictable, accessible, and keyboard-navigable operational env 1. **Given** the app loads after authentication **When** an authenticated user enters the application **Then** the tri-pane layout renders with a left navigation pane, center content area, and collapsible right panel 2. **Given** the Ant Design token configuration is applied **When** the UI renders **Then** colorPrimary is #1F4E79, teal secondary is #0F766E, semantic status colors (success/warning/error/info/overdue) match the UX spec, and compact density profile is active (UX-DR1) 3. **Given** a user interacts with any focusable element **When** tabbing through the interface **Then** visible 2px focus indicators are present on all interactive elements with logical tab order (UX-DR9) -4. **Given** the viewport is 1280–1599px **When** the layout renders **Then** the right panel is collapsible and the tri-pane adapts to compact mode (UX-DR15) +4. **Given** the viewport is 1280–1599px **When** the layout renders **Then** the right panel is collapsible and the tri-pane adapts to compact mode (UX-DR15) 5. **Given** the viewport is below 1280px **When** the layout renders **Then** a reduced read mode with a support notice is displayed and full editing is not available -6. **Given** any status indicator renders **When** viewed **Then** status is conveyed with both color and a text label or icon — never color alone (UX-DR12) +6. **Given** any status indicator renders **When** viewed **Then** status is conveyed with both color and a text label or icon — never color alone (UX-DR12) ## Tasks / Subtasks @@ -40,8 +40,8 @@ so that I have a predictable, accessible, and keyboard-navigable operational env ### Project Structure Notes -- Backend: `BriansClientRouteReports.Server/` -- Frontend: `brians-client-route-reports-client/` +- Backend: `Campaign_Tracker.Server/` +- Frontend: `campaign-tracker-client/` - Story artifacts: `_bmad-output/implementation-artifacts/` ### References @@ -67,3 +67,5 @@ GPT-5 Codex ### File List - `_bmad-output/implementation-artifacts/1-2-workspace-shell-ant-design-foundation.md` + + diff --git a/_bmad-output/implementation-artifacts/1-3-keycloak-realm-configuration-oidc-integration.md b/_bmad-output/implementation-artifacts/1-3-keycloak-realm-configuration-oidc-integration.md index 5578f2a..4d2feb2 100644 --- a/_bmad-output/implementation-artifacts/1-3-keycloak-realm-configuration-oidc-integration.md +++ b/_bmad-output/implementation-artifacts/1-3-keycloak-realm-configuration-oidc-integration.md @@ -1,4 +1,4 @@ -# Story 1.3: Keycloak Realm Configuration & OIDC Integration +# Story 1.3: Keycloak Realm Configuration & OIDC Integration Status: ready-for-dev @@ -39,8 +39,8 @@ so that I can securely access the application with my organizational credentials ### Project Structure Notes -- Backend: `BriansClientRouteReports.Server/` -- Frontend: `brians-client-route-reports-client/` +- Backend: `Campaign_Tracker.Server/` +- Frontend: `campaign-tracker-client/` - Story artifacts: `_bmad-output/implementation-artifacts/` ### References @@ -66,3 +66,5 @@ GPT-5 Codex ### File List - `_bmad-output/implementation-artifacts/1-3-keycloak-realm-configuration-oidc-integration.md` + + diff --git a/_bmad-output/implementation-artifacts/1-4-keycloak-role-mapping-application-authorization.md b/_bmad-output/implementation-artifacts/1-4-keycloak-role-mapping-application-authorization.md index d6a57d6..fb16181 100644 --- a/_bmad-output/implementation-artifacts/1-4-keycloak-role-mapping-application-authorization.md +++ b/_bmad-output/implementation-artifacts/1-4-keycloak-role-mapping-application-authorization.md @@ -1,4 +1,4 @@ -# Story 1.4: Keycloak Role Mapping & Application Authorization +# Story 1.4: Keycloak Role Mapping & Application Authorization Status: ready-for-dev @@ -13,7 +13,7 @@ so that each user sees only the capabilities appropriate to their operational ro 1. **Given** a Keycloak user has the ClientServices role **When** they authenticate and navigate **Then** they can access municipality profile and election-cycle creation routes and cannot access admin-only or production-only routes 2. **Given** a Keycloak user has the Admin role **When** they authenticate **Then** they can access all application routes including admin-sensitive functions 3. **Given** a user without a recognized application role authenticates **When** they access any protected route **Then** they receive 403 Forbidden and the unauthorized access attempt is logged with actor identity -4. **Given** a privileged operation is performed **When** it completes **Then** the authorization check result, actor, and resource are captured by the audit logging service within 5 seconds (NFR6, NFR7) **And** roles ClientServices, Production, Transportation, Support, and Admin are managed entirely in Keycloak Admin Console — FR27 is satisfied without a custom role management UI +4. **Given** a privileged operation is performed **When** it completes **Then** the authorization check result, actor, and resource are captured by the audit logging service within 5 seconds (NFR6, NFR7) **And** roles ClientServices, Production, Transportation, Support, and Admin are managed entirely in Keycloak Admin Console — FR27 is satisfied without a custom role management UI ## Tasks / Subtasks @@ -38,8 +38,8 @@ so that each user sees only the capabilities appropriate to their operational ro ### Project Structure Notes -- Backend: `BriansClientRouteReports.Server/` -- Frontend: `brians-client-route-reports-client/` +- Backend: `Campaign_Tracker.Server/` +- Frontend: `campaign-tracker-client/` - Story artifacts: `_bmad-output/implementation-artifacts/` ### References @@ -65,3 +65,5 @@ GPT-5 Codex ### File List - `_bmad-output/implementation-artifacts/1-4-keycloak-role-mapping-application-authorization.md` + + diff --git a/_bmad-output/implementation-artifacts/1-5-shared-audit-logging-infrastructure.md b/_bmad-output/implementation-artifacts/1-5-shared-audit-logging-infrastructure.md index 4873f7a..5f6c8b1 100644 --- a/_bmad-output/implementation-artifacts/1-5-shared-audit-logging-infrastructure.md +++ b/_bmad-output/implementation-artifacts/1-5-shared-audit-logging-infrastructure.md @@ -1,4 +1,4 @@ -# Story 1.5: Shared Audit Logging Infrastructure +# Story 1.5: Shared Audit Logging Infrastructure Status: ready-for-dev @@ -12,9 +12,9 @@ so that audit history is uniformly available across all application features fro 1. **Given** any security-relevant action occurs (auth event, permission check, privileged update) **When** the action completes **Then** the event is written to the audit log within 5 seconds including actor identity, timestamp (UTC), action type, resource identifier, and outcome (NFR7) 2. **Given** audit records are persisted **When** the retention policy is evaluated **Then** records are retained for at least 365 days and are not purgeable by standard application operations (NFR7) -3. **Given** any application feature calls the audit logging service **When** the call is made **Then** it succeeds using the shared service contract — the calling feature does not implement its own audit persistence -4. **Given** an audit record is written **When** retrieved for review **Then** it is append-only — no update or delete operations are available on audit records -5. **Given** the audit service is unavailable **When** an auditable action occurs **Then** the action is blocked or queued — auditable operations must not silently proceed without capture +3. **Given** any application feature calls the audit logging service **When** the call is made **Then** it succeeds using the shared service contract — the calling feature does not implement its own audit persistence +4. **Given** an audit record is written **When** retrieved for review **Then** it is append-only — no update or delete operations are available on audit records +5. **Given** the audit service is unavailable **When** an auditable action occurs **Then** the action is blocked or queued — auditable operations must not silently proceed without capture ## Tasks / Subtasks @@ -39,8 +39,8 @@ so that audit history is uniformly available across all application features fro ### Project Structure Notes -- Backend: `BriansClientRouteReports.Server/` -- Frontend: `brians-client-route-reports-client/` +- Backend: `Campaign_Tracker.Server/` +- Frontend: `campaign-tracker-client/` - Story artifacts: `_bmad-output/implementation-artifacts/` ### References @@ -66,3 +66,5 @@ GPT-5 Codex ### File List - `_bmad-output/implementation-artifacts/1-5-shared-audit-logging-infrastructure.md` + + diff --git a/_bmad-output/implementation-artifacts/1-6-legacy-anti-corruption-data-access-layer.md b/_bmad-output/implementation-artifacts/1-6-legacy-anti-corruption-data-access-layer.md index 8bc1a75..88c0fd5 100644 --- a/_bmad-output/implementation-artifacts/1-6-legacy-anti-corruption-data-access-layer.md +++ b/_bmad-output/implementation-artifacts/1-6-legacy-anti-corruption-data-access-layer.md @@ -1,4 +1,4 @@ -# Story 1.6: Legacy Anti-Corruption Data Access Layer +# Story 1.6: Legacy Anti-Corruption Data Access Layer Status: ready-for-dev @@ -11,9 +11,9 @@ so that legacy data is available to all features without any risk of schema muta ## Acceptance Criteria 1. **Given** a feature requests municipality or jurisdiction data **When** the anti-corruption layer is called **Then** it returns data joined by ID, JCode/JurisCode, or KitID without modifying any legacy table structure or content (NFR12) -2. **Given** the anti-corruption layer executes any query **When** the operation is inspected **Then** only SELECT operations are permitted — INSERT, UPDATE, and DELETE on legacy entities are blocked at the layer boundary +2. **Given** the anti-corruption layer executes any query **When** the operation is inspected **Then** only SELECT operations are permitted — INSERT, UPDATE, and DELETE on legacy entities are blocked at the layer boundary 3. **Given** legacy data is returned through the layer **When** mapped to the application domain **Then** it is converted to strongly-typed domain model objects before being returned to any calling feature -4. **Given** any application code outside the layer attempts to query legacy tables directly **When** reviewed in code **Then** no such direct access exists — the anti-corruption layer is the sole access point for legacy data +4. **Given** any application code outside the layer attempts to query legacy tables directly **When** reviewed in code **Then** no such direct access exists — the anti-corruption layer is the sole access point for legacy data ## Tasks / Subtasks @@ -38,8 +38,8 @@ so that legacy data is available to all features without any risk of schema muta ### Project Structure Notes -- Backend: `BriansClientRouteReports.Server/` -- Frontend: `brians-client-route-reports-client/` +- Backend: `Campaign_Tracker.Server/` +- Frontend: `campaign-tracker-client/` - Story artifacts: `_bmad-output/implementation-artifacts/` ### References @@ -65,3 +65,5 @@ GPT-5 Codex ### File List - `_bmad-output/implementation-artifacts/1-6-legacy-anti-corruption-data-access-layer.md` + + diff --git a/_bmad-output/implementation-artifacts/1-7-legacy-schema-compatibility-validation-gate.md b/_bmad-output/implementation-artifacts/1-7-legacy-schema-compatibility-validation-gate.md index 8386213..d3a4447 100644 --- a/_bmad-output/implementation-artifacts/1-7-legacy-schema-compatibility-validation-gate.md +++ b/_bmad-output/implementation-artifacts/1-7-legacy-schema-compatibility-validation-gate.md @@ -1,4 +1,4 @@ -# Story 1.7: Legacy Schema Compatibility Validation Gate +# Story 1.7: Legacy Schema Compatibility Validation Gate Status: ready-for-dev @@ -39,8 +39,8 @@ so that every release can be gated on legacy integrity before deployment. ### Project Structure Notes -- Backend: `BriansClientRouteReports.Server/` -- Frontend: `brians-client-route-reports-client/` +- Backend: `Campaign_Tracker.Server/` +- Frontend: `campaign-tracker-client/` - Story artifacts: `_bmad-output/implementation-artifacts/` ### References @@ -66,3 +66,5 @@ GPT-5 Codex ### File List - `_bmad-output/implementation-artifacts/1-7-legacy-schema-compatibility-validation-gate.md` + + diff --git a/_bmad-output/implementation-artifacts/1-8-legacy-identifier-linking-for-extension-records.md b/_bmad-output/implementation-artifacts/1-8-legacy-identifier-linking-for-extension-records.md index df8ba38..d10f9bf 100644 --- a/_bmad-output/implementation-artifacts/1-8-legacy-identifier-linking-for-extension-records.md +++ b/_bmad-output/implementation-artifacts/1-8-legacy-identifier-linking-for-extension-records.md @@ -1,4 +1,4 @@ -# Story 1.8: Legacy Identifier Linking for Extension Records +# Story 1.8: Legacy Identifier Linking for Extension Records Status: ready-for-dev @@ -38,8 +38,8 @@ so that all new capabilities join deterministically to legacy Access records in ### Project Structure Notes -- Backend: `BriansClientRouteReports.Server/` -- Frontend: `brians-client-route-reports-client/` +- Backend: `Campaign_Tracker.Server/` +- Frontend: `campaign-tracker-client/` - Story artifacts: `_bmad-output/implementation-artifacts/` ### References @@ -65,3 +65,5 @@ GPT-5 Codex ### File List - `_bmad-output/implementation-artifacts/1-8-legacy-identifier-linking-for-extension-records.md` + + diff --git a/_bmad-output/implementation-artifacts/1-9-seed-system-reference-values-rule-defaults.md b/_bmad-output/implementation-artifacts/1-9-seed-system-reference-values-rule-defaults.md index 9f3491c..3db9060 100644 --- a/_bmad-output/implementation-artifacts/1-9-seed-system-reference-values-rule-defaults.md +++ b/_bmad-output/implementation-artifacts/1-9-seed-system-reference-values-rule-defaults.md @@ -1,4 +1,4 @@ -# Story 1.9: Seed System Reference Values & Rule Defaults +# Story 1.9: Seed System Reference Values & Rule Defaults Status: ready-for-dev @@ -6,15 +6,15 @@ Status: ready-for-dev As a a developer, I want the system seeded with default reference values, required-field rules, and escalation rule defaults, -so that Epics 2–5 are immediately functional without requiring administrator configuration before use. +so that Epics 2–5 are immediately functional without requiring administrator configuration before use. ## Acceptance Criteria 1. **Given** the application initializes for the first time **When** the seed operation runs **Then** operational status sets, service template defaults, and extension-layer reference values are populated in the database 2. **Given** the seed runs **When** required-field rules are evaluated **Then** default readiness fields for election-cycle jobs are defined and evaluable by Epic 2's readiness status feature (FR29) 3. **Given** the seed runs **When** escalation rule defaults are checked **Then** at least one default rule exists covering overdue milestone alert scenarios (FR30) -4. **Given** the seed operation is run multiple times **When** it completes **Then** no duplicate records are created — the operation is fully idempotent -5. **Given** Epic 6 admin UIs update reference values or rules **When** the changes are saved **Then** they persist independently of the seed — rerunning the seed does not overwrite admin-managed values +4. **Given** the seed operation is run multiple times **When** it completes **Then** no duplicate records are created — the operation is fully idempotent +5. **Given** Epic 6 admin UIs update reference values or rules **When** the changes are saved **Then** they persist independently of the seed — rerunning the seed does not overwrite admin-managed values ## Tasks / Subtasks @@ -39,8 +39,8 @@ so that Epics 2–5 are immediately functional without requiring administra ### Project Structure Notes -- Backend: `BriansClientRouteReports.Server/` -- Frontend: `brians-client-route-reports-client/` +- Backend: `Campaign_Tracker.Server/` +- Frontend: `campaign-tracker-client/` - Story artifacts: `_bmad-output/implementation-artifacts/` ### References @@ -66,3 +66,5 @@ GPT-5 Codex ### File List - `_bmad-output/implementation-artifacts/1-9-seed-system-reference-values-rule-defaults.md` + + diff --git a/_bmad-output/implementation-artifacts/sprint-status.yaml b/_bmad-output/implementation-artifacts/sprint-status.yaml index 1ef4099..709f486 100644 --- a/_bmad-output/implementation-artifacts/sprint-status.yaml +++ b/_bmad-output/implementation-artifacts/sprint-status.yaml @@ -1,6 +1,6 @@ -# generated: 2026-05-05T12:00:44-04:00 +# generated: 2026-05-05T12:00:44-04:00 # last_updated: 2026-05-05T12:09:17-04:00 -# project: Brians Client Route Reports App +# project: Campaign_Tracker App # project_key: NOKEY # tracking_system: file-system # story_location: _bmad-output/implementation-artifacts @@ -35,15 +35,15 @@ # - Dev moves story to 'review', then runs code-review (fresh context, different LLM recommended) generated: '2026-05-05T12:00:44-04:00' -last_updated: '2026-05-05T12:09:17-04:00' -project: 'Brians Client Route Reports App' +last_updated: '2026-05-05T12:41:10-04:00' +project: 'Campaign_Tracker App' project_key: 'NOKEY' tracking_system: 'file-system' story_location: '_bmad-output/implementation-artifacts' development_status: epic-1: in-progress - 1-1-project-initialization-solution-scaffold: ready-for-dev + 1-1-project-initialization-solution-scaffold: review 1-2-workspace-shell-ant-design-foundation: ready-for-dev 1-3-keycloak-realm-configuration-oidc-integration: ready-for-dev 1-4-keycloak-role-mapping-application-authorization: ready-for-dev @@ -100,3 +100,6 @@ development_status: + + + diff --git a/_bmad-output/planning-artifacts/architecture.md b/_bmad-output/planning-artifacts/architecture.md index 2a51856..00b26bf 100644 --- a/_bmad-output/planning-artifacts/architecture.md +++ b/_bmad-output/planning-artifacts/architecture.md @@ -12,7 +12,7 @@ inputDocuments: - Initial Documents/Client Database Plan.xlsx - _bmad-output/planning-artifacts/client-database-plan-extract.txt workflowType: 'architecture' -project_name: 'Brians Client Route Reports App' +project_name: 'Campaign_Tracker App' user_name: 'Daniel' date: '2026-04-03' --- @@ -141,10 +141,10 @@ This aligns directly with the requested architecture (`.NET 10 ASP` + `TypeScrip **Initialization Command:** ```bash -dotnet new sln -n brians-client-route-reports -dotnet new webapi -n BriansClientRouteReports.Server -f net10.0 --use-controllers -dotnet sln add .\BriansClientRouteReports.Server\BriansClientRouteReports.Server.csproj -npm create vite@latest brians-client-route-reports-client -- --template react-ts +dotnet new sln -n campaign-tracker +dotnet new webapi -n Campaign_Tracker.Server -f net10.0 --use-controllers +dotnet sln add .\Campaign_Tracker.Server\Campaign_Tracker.Server.csproj +npm create vite@latest campaign-tracker-client -- --template react-ts ``` **Architectural Decisions Provided by Starter:** @@ -202,3 +202,5 @@ Imported contact and proofing-related fields are role-protected and auditable. - Least-privilege visibility by role - All sensitive field changes captured in audit stream - No bypass around SafeCommitRail-equivalent validation for publish-sensitive updates + + diff --git a/_bmad-output/planning-artifacts/epics.md b/_bmad-output/planning-artifacts/epics.md index c094443..ae574ed 100644 --- a/_bmad-output/planning-artifacts/epics.md +++ b/_bmad-output/planning-artifacts/epics.md @@ -9,11 +9,11 @@ inputDocuments: - _bmad-output/planning-artifacts/ux-design-specification.md --- -# Brians Client Route Reports App - Epic Breakdown +# Campaign_Tracker App - Epic Breakdown ## Overview -This document provides the complete epic and story breakdown for Brians Client Route Reports App, decomposing the requirements from the PRD, UX Design, and Architecture into implementable stories. +This document provides the complete epic and story breakdown for Campaign_Tracker App, decomposing the requirements from the PRD, UX Design, and Architecture into implementable stories. ## Requirements Inventory @@ -76,7 +76,7 @@ NFR17: Recovery procedures ensure no committed extension-record updates are lost ### Additional Requirements -- **Starter Template (Epic 1, Story 1)**: ASP.NET Core 10 Web API + Vite React TypeScript. Initialization commands: `dotnet new sln -n brians-client-route-reports`, `dotnet new webapi -n BriansClientRouteReports.Server -f net10.0 --use-controllers`, `dotnet sln add`, `npm create vite@latest brians-client-route-reports-client -- --template react-ts`. +- **Starter Template (Epic 1, Story 1)**: ASP.NET Core 10 Web API + Vite React TypeScript. Initialization commands: `dotnet new sln -n campaign-tracker`, `dotnet new webapi -n Campaign_Tracker.Server -f net10.0 --use-controllers`, `dotnet sln add`, `npm create vite@latest campaign-tracker-client -- --template react-ts`. - Anti-corruption data access layer required between modern services and immutable legacy Access structures. - Separate operational write path (extension tables) from report read path (join/materialized/query layer) to reduce coupling. - Join-key integrity (ID, JCode/JurisCode, KitID) is a platform concern requiring scheduled validation jobs and release-gate checks. @@ -211,7 +211,7 @@ So that the team has a working, runnable baseline with the correct project struc **Given** the initialization commands are run (`dotnet new sln`, `dotnet new webapi`, `npm create vite@latest --template react-ts`) **When** the solution builds -**Then** both BriansClientRouteReports.Server and brians-client-route-reports-client compile without errors +**Then** both Campaign_Tracker.Server and campaign-tracker-client compile without errors **Given** the solution is running locally **When** the Vite dev server starts @@ -1444,3 +1444,5 @@ So that data mismatches are triaged with clear ownership before they impact oper **Given** unresolved high-severity mismatches remain **When** operational export is attempted for affected scope **Then** the system displays a blocking warning with a direct link to the reconciliation queue + + diff --git a/_bmad-output/planning-artifacts/implementation-readiness-report-2026-05-05.md b/_bmad-output/planning-artifacts/implementation-readiness-report-2026-05-05.md index b454284..93b3131 100644 --- a/_bmad-output/planning-artifacts/implementation-readiness-report-2026-05-05.md +++ b/_bmad-output/planning-artifacts/implementation-readiness-report-2026-05-05.md @@ -7,7 +7,7 @@ stepsCompleted: - step-05-epic-quality-review - step-06-final-assessment assessmentDate: "2026-05-05" -project: "Brians Client Route Reports App" +project: "Campaign_Tracker App" documentsSelected: prd: "_bmad-output/planning-artifacts/prd.md" architecture: "_bmad-output/planning-artifacts/architecture.md" @@ -18,7 +18,7 @@ documentsSelected: # Implementation Readiness Assessment Report **Date:** 2026-05-05 -**Project:** Brians Client Route Reports App +**Project:** Campaign_Tracker App ## Step 1 - Document Discovery @@ -288,3 +288,4 @@ This assessment identified no remaining critical or major issues after approved Assessor: Codex (AI pair agent) Assessment Date: 2026-05-05 + diff --git a/_bmad-output/planning-artifacts/prd.md b/_bmad-output/planning-artifacts/prd.md index 2c0e409..a66d09c 100644 --- a/_bmad-output/planning-artifacts/prd.md +++ b/_bmad-output/planning-artifacts/prd.md @@ -35,7 +35,7 @@ classification: projectContext: brownfield --- -# Product Requirements Document - Brians Client Route Reports App +# Product Requirements Document - Campaign_Tracker App **Author:** Daniel **Date:** 2026-04-03 @@ -395,3 +395,4 @@ Mitigation: strict MVP scope, milestone-based releases, and deferment of advance - NFR15: Planned system availability target is 99.5% monthly during operational hours. - NFR16: Every key milestone/status update is stored with audit history sufficient for operational reconstruction. - NFR17: Recovery procedures ensure no committed extension-record updates are lost for the previous 24 hours of operations. + diff --git a/_bmad-output/planning-artifacts/ux-color-themes.html b/_bmad-output/planning-artifacts/ux-color-themes.html index 51776a4..d03d9bb 100644 --- a/_bmad-output/planning-artifacts/ux-color-themes.html +++ b/_bmad-output/planning-artifacts/ux-color-themes.html @@ -3,7 +3,7 @@ - UX Color Themes - Brians Client Route Reports App + UX Color Themes - Campaign_Tracker App diff --git a/campaign-tracker-client/src/index.css b/campaign-tracker-client/src/index.css new file mode 100644 index 0000000..5fb3313 --- /dev/null +++ b/campaign-tracker-client/src/index.css @@ -0,0 +1,111 @@ +:root { + --text: #6b6375; + --text-h: #08060d; + --bg: #fff; + --border: #e5e4e7; + --code-bg: #f4f3ec; + --accent: #aa3bff; + --accent-bg: rgba(170, 59, 255, 0.1); + --accent-border: rgba(170, 59, 255, 0.5); + --social-bg: rgba(244, 243, 236, 0.5); + --shadow: + rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px; + + --sans: system-ui, 'Segoe UI', Roboto, sans-serif; + --heading: system-ui, 'Segoe UI', Roboto, sans-serif; + --mono: ui-monospace, Consolas, monospace; + + font: 18px/145% var(--sans); + letter-spacing: 0.18px; + color-scheme: light dark; + color: var(--text); + background: var(--bg); + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + @media (max-width: 1024px) { + font-size: 16px; + } +} + +@media (prefers-color-scheme: dark) { + :root { + --text: #9ca3af; + --text-h: #f3f4f6; + --bg: #16171d; + --border: #2e303a; + --code-bg: #1f2028; + --accent: #c084fc; + --accent-bg: rgba(192, 132, 252, 0.15); + --accent-border: rgba(192, 132, 252, 0.5); + --social-bg: rgba(47, 48, 58, 0.5); + --shadow: + rgba(0, 0, 0, 0.4) 0 10px 15px -3px, rgba(0, 0, 0, 0.25) 0 4px 6px -2px; + } + + #social .button-icon { + filter: invert(1) brightness(2); + } +} + +#root { + width: 1126px; + max-width: 100%; + margin: 0 auto; + text-align: center; + border-inline: 1px solid var(--border); + min-height: 100svh; + display: flex; + flex-direction: column; + box-sizing: border-box; +} + +body { + margin: 0; +} + +h1, +h2 { + font-family: var(--heading); + font-weight: 500; + color: var(--text-h); +} + +h1 { + font-size: 56px; + letter-spacing: -1.68px; + margin: 32px 0; + @media (max-width: 1024px) { + font-size: 36px; + margin: 20px 0; + } +} +h2 { + font-size: 24px; + line-height: 118%; + letter-spacing: -0.24px; + margin: 0 0 8px; + @media (max-width: 1024px) { + font-size: 20px; + } +} +p { + margin: 0; +} + +code, +.counter { + font-family: var(--mono); + display: inline-flex; + border-radius: 4px; + color: var(--text-h); +} + +code { + font-size: 15px; + line-height: 135%; + padding: 4px 8px; + background: var(--code-bg); +} diff --git a/campaign-tracker-client/src/main.tsx b/campaign-tracker-client/src/main.tsx new file mode 100644 index 0000000..bef5202 --- /dev/null +++ b/campaign-tracker-client/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.tsx' + +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/campaign-tracker-client/tsconfig.app.json b/campaign-tracker-client/tsconfig.app.json new file mode 100644 index 0000000..7f42e5f --- /dev/null +++ b/campaign-tracker-client/tsconfig.app.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "es2023", + "lib": ["ES2023", "DOM"], + "module": "esnext", + "types": ["vite/client"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} diff --git a/campaign-tracker-client/tsconfig.json b/campaign-tracker-client/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/campaign-tracker-client/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/campaign-tracker-client/tsconfig.node.json b/campaign-tracker-client/tsconfig.node.json new file mode 100644 index 0000000..d3c52ea --- /dev/null +++ b/campaign-tracker-client/tsconfig.node.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "es2023", + "lib": ["ES2023"], + "module": "esnext", + "types": ["node"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["vite.config.ts"] +} diff --git a/campaign-tracker-client/vite.config.ts b/campaign-tracker-client/vite.config.ts new file mode 100644 index 0000000..8b0f57b --- /dev/null +++ b/campaign-tracker-client/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/campaign-tracker.sln b/campaign-tracker.sln new file mode 100644 index 0000000..72cc329 --- /dev/null +++ b/campaign-tracker.sln @@ -0,0 +1,49 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Campaign_Tracker.Server", "Campaign_Tracker.Server\Campaign_Tracker.Server.csproj", "{A7B08F8E-00EC-4197-BC31-65941F4A38F4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Campaign_Tracker.Server.Tests", "Campaign_Tracker.Server.Tests\Campaign_Tracker.Server.Tests.csproj", "{091D5213-5AF2-4414-8FD3-CFD14D525A13}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Debug|x64.ActiveCfg = Debug|Any CPU + {A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Debug|x64.Build.0 = Debug|Any CPU + {A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Debug|x86.ActiveCfg = Debug|Any CPU + {A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Debug|x86.Build.0 = Debug|Any CPU + {A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Release|Any CPU.Build.0 = Release|Any CPU + {A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Release|x64.ActiveCfg = Release|Any CPU + {A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Release|x64.Build.0 = Release|Any CPU + {A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Release|x86.ActiveCfg = Release|Any CPU + {A7B08F8E-00EC-4197-BC31-65941F4A38F4}.Release|x86.Build.0 = Release|Any CPU + {091D5213-5AF2-4414-8FD3-CFD14D525A13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {091D5213-5AF2-4414-8FD3-CFD14D525A13}.Debug|Any CPU.Build.0 = Debug|Any CPU + {091D5213-5AF2-4414-8FD3-CFD14D525A13}.Debug|x64.ActiveCfg = Debug|Any CPU + {091D5213-5AF2-4414-8FD3-CFD14D525A13}.Debug|x64.Build.0 = Debug|Any CPU + {091D5213-5AF2-4414-8FD3-CFD14D525A13}.Debug|x86.ActiveCfg = Debug|Any CPU + {091D5213-5AF2-4414-8FD3-CFD14D525A13}.Debug|x86.Build.0 = Debug|Any CPU + {091D5213-5AF2-4414-8FD3-CFD14D525A13}.Release|Any CPU.ActiveCfg = Release|Any CPU + {091D5213-5AF2-4414-8FD3-CFD14D525A13}.Release|Any CPU.Build.0 = Release|Any CPU + {091D5213-5AF2-4414-8FD3-CFD14D525A13}.Release|x64.ActiveCfg = Release|Any CPU + {091D5213-5AF2-4414-8FD3-CFD14D525A13}.Release|x64.Build.0 = Release|Any CPU + {091D5213-5AF2-4414-8FD3-CFD14D525A13}.Release|x86.ActiveCfg = Release|Any CPU + {091D5213-5AF2-4414-8FD3-CFD14D525A13}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal +