diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f4d2fe96..7bb6e0a5 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -115,5 +115,5 @@ jobs:
dotnet tool install -g NSwag.ConsoleCore
export PATH="$PATH:$HOME/.dotnet/tools"
(cd services/Bff && nswag run nswag.json)
- git diff --exit-code services/Bff/src/Bff.Application/Generated/FastApiClient.g.cs \
+ git diff --exit-code services/Bff/src/Bff.Api/Application/Generated/FastApiClient.g.cs \
|| (echo "::error::FastApiClient.g.cs is stale — run services/Bff/generate-client.sh and commit." && exit 1)
diff --git a/AGENT.md b/AGENT.md
index a1006589..c92a4986 100644
--- a/AGENT.md
+++ b/AGENT.md
@@ -13,14 +13,13 @@ Developer reference for agents and contributors. User-facing overview: [README.m
**Key paths**
- `src/website_profiling/` -- `cli.py`, `config.py`, `crawl/`, `db/storage.py`, `lighthouse/`, `reporting/`, `analysis/`, `ai_service_client.py`, `tools/`
-- `services/Bff/` -- .NET BFF (auth, CORS, `/api/*` proxy to FastAPI + AiService + Data)
+- `services/Bff/` -- .NET BFF (auth, CORS, `/api/*` proxy to FastAPI + CoreService + AiService; port 8090)
+- `services/CoreService/` -- .NET core service (report build & orchestration, data queries & PDF/Excel export, Google/Bing integrations; port 8094). See `services/CoreService/README.md`
- `services/AiService/` -- .NET AI (chat, secrets, LLM config, MCP, enrichment; port 8092)
-- `services/Data/` -- .NET data service (report payloads, portfolio, issue status, typed config, PDF/Excel/CSV/JSON/sitemap export; port 8091)
-- `services/ReportService/` -- .NET report build + pipeline orchestration (port 8094). Worker runs crawl+Lighthouse; report via `REPORT_SERVICE_URL`
- `web/src/` -- React SPA (`AppRoutes.tsx`, `views/`, `components/`); pipeline UI: `PipelineRunnerFab`, `PipelineContext`
- `services/Schema/` -- EF Core schema migrations (schema owner)
-**Local dev:** `./local-run` (Postgres in Docker `wp-pg`, Data `:8091`, AiService `:8092`, ReportService `:8094`, FastAPI `:8096`, BFF `:8090`, Vite `:3000`; default `DATABASE_URL`: `postgres://postgres:dev@127.0.0.1:5432/website_profiling`). See `scripts/local-run.sh`. **Local tests:** `./local-test` runs **three** Python coverage gates (core 100%, reporting 100%, tools 100%) plus web and .NET checks — mirrors CI; Docker CI is separate (see `.github/workflows/ci.yml`). `./local-test browser` for `@pytest.mark.browser` integration tests — see `scripts/local-test.sh`. Mocked browser unit tests: `tests/test_browser_fetcher_unit.py`.
+**Local dev:** `./local-run` (Postgres in Docker `wp-pg`, CoreService `:8094`, AiService `:8092`, FastAPI `:8096`, BFF `:8090`, Vite `:3000`; default `DATABASE_URL`: `postgres://postgres:dev@127.0.0.1:5432/website_profiling`). See `scripts/local-run.sh`. **Local tests:** `./local-test` runs **three** Python coverage gates (core 100%, reporting 100%, tools 100%) plus web and .NET checks — mirrors CI; Docker CI is separate (see `.github/workflows/ci.yml`). `./local-test browser` for `@pytest.mark.browser` integration tests — see `scripts/local-test.sh`. Mocked browser unit tests: `tests/test_browser_fetcher_unit.py`.
**JavaScript crawl (optional):** Config keys `crawl_render_mode` (`static` | `javascript` | `auto`) and `crawl_js_*` in pipeline config / `pipelineConfigSchema.ts`. JS/auto crawls can capture browser console errors and uncaught exceptions (`crawl_js_capture_console`, stored under `page_analysis.browser`). **Auto mode** uses static-first fetch, pre-parse SPA heuristics (`needs_js_render`), then post-parse low-outlink fallback (`needs_js_render_after_parse`) in `crawler.py`. **Preflight:** `GET /api/crawl/browser-status` (localhost) spawns Python `browser_status()`; Run audit settings/run validation calls it when render mode is `javascript` or `auto`. Browser deps: Playwright from `requirements.txt` (installed by `./local-run setup` and `./local-test`). Runtime needs Chromium on `PATH` or `CHROME_PATH` (Docker sets `CHROME_PATH=/usr/bin/chromium`). Integration tests: `@pytest.mark.browser` — excluded by default in `pytest.ini`; Docker CI runs `tests/test_crawl_fetchers.py` and `tests/test_crawler_browser_e2e.py -m browser`; locally `./local-test browser`.
@@ -32,20 +31,20 @@ Developer reference for agents and contributors. User-facing overview: [README.m
- **`DATABASE_URL`** env: PostgreSQL connection string (required). **`DATA_DIR`**: local artifacts (Docker: `/data`); settings and API keys live in Postgres.
- **Pipeline storage** (crawl, edges, nodes, report payload, Lighthouse, keywords, warnings) lives in **PostgreSQL only**. Deliverables use the Export view, `GET /api/report/export`, or MCP `export_*` tools — not files written by the main pipeline step.
- **Pool tuning:** `DB_POOL_MIN` / `DB_POOL_MAX` (Python). Bulk crawl writes via `executemany`; optional **`crawl_stream_to_db`** streams rows during fetch. Per-URL raw HTML: `crawl_page_html` table (migration `015`); API `GET/POST /api/crawl/page-html`.
-- **Browser API (BFF):** All `/api/*` routes are served by `services/Bff/`. **FastAPI:** `/api/run`, `/api/jobs/*`, `/api/pipeline-config`, crawl, integrations (OAuth reads), properties, content drafts, etc. **ReportService:** report build + full-audit orchestration (internal; worker uses `REPORT_SERVICE_URL`). **IntegrationsService:** Google/Bing OAuth and fetch (browser + internal report enrichment). **AiService:** `/api/chat` (SSE), `/api/llm-settings`, `/api/secrets`, `/api/ollama/status`, etc. **Data:** report payload reads, portfolio, issue status, saved filters, `/api/pipeline-settings`, `/api/ui-preferences`, `/api/client-preferences` (see `DATA_ROUTES`), and PDF/workbook export. `PipelineRunnerFab` saves pipeline config (FastAPI) and LLM state (`PUT /api/llm-settings` → AiService) before each run.
+- **Browser API (BFF):** All `/api/*` routes are served by `services/Bff/`. **FastAPI:** crawl, pipeline worker CLI, audit-tool CLI bridge. **CoreService:** report build + full-audit orchestration, data reads (portfolio, payload, issue status, saved filters, typed config), PDF/workbook exports, Google/Bing OAuth and data fetching. **AiService:** `/api/chat` (SSE), `/api/llm-settings`, `/api/secrets`, `/api/ollama/status`, MCP catalog. `PipelineRunnerFab` saves pipeline config (FastAPI) and LLM state (`PUT /api/llm-settings` → AiService) before each run.
- **MCP:** AiService (.NET) — stdio host or HTTP at `/mcp` when `WP_MCP_HTTP=1` on `:8092`. Configure at **`/mcp`** in the web UI. See `docs/MCP.md` and [services/AiService/README.md](services/AiService/README.md).
- **AI Chat UI:** `/chat` — property-scoped chat with saved sessions (`chat_sessions`, `chat_messages`; migration `012_chat_sessions`).
- **Job store:** PostgreSQL `pipeline_jobs` (FastAPI); live job status via `/api/jobs/*` through the BFF.
-- **Docker:** Root `Dockerfile` (Python backend); `web/Dockerfile` (Vite SPA + nginx); `docker-compose.yml` (postgres + fastapi + worker + report + integrations + ai + data + bff + web); **`docker-compose.prod.yml`** (production + optional MCP profile mapping host `:8000` → AiService `:8092`); **`docker-compose.pull.yml`** for pre-built images (`BACKEND_IMAGE`, `WEB_IMAGE`); **`LIGHTHOUSE_CHROME_FLAGS`**
+- **Docker:** Root `Dockerfile` (Python backend); `web/Dockerfile` (Vite SPA + nginx); `docker-compose.yml` (postgres + fastapi + core + ai + bff + web); **`docker-compose.prod.yml`** (production + optional MCP profile mapping host `:8000` → AiService `:8092`); **`docker-compose.pull.yml`** for pre-built images (`BACKEND_IMAGE`, `WEB_IMAGE`); **`LIGHTHOUSE_CHROME_FLAGS`**
**Where to edit**
| Task | Where |
|------|--------|
| Crawl | `crawl/crawler.py`, `crawl/fetchers/`, `parsing/links.py` (`normalize_link` preserves trailing slashes from `href`) |
-| Report (native build) | `services/ReportService/src/ReportService.Application/Build/` |
-| Report (Python bridge) | `reporting/builder.py`, `reporting/categories/` |
-| PDF / workbook export | `services/Data/src/Data.Rendering/` (rendering), `Data.Api/Controllers/ReportExportController.cs`; BFF routes `/api/report/export` and `/api/report/export-workbook` to Data |
+| Report (native build) | `services/CoreService/src/CoreService.Api/Application/Build/` |
+| PDF / workbook export | `services/CoreService/src/CoreService.Api/Rendering/`, `Controllers/ReportExportController.cs` |
+| Integrations (Google/Bing) | `services/CoreService/src/CoreService.Api/Providers/Google/`, `IntegrationsApplication/` |
| DB schema | `services/Schema/src/Schema.Model/` |
| Local analysis | `analysis/local.py`, `requirements.txt` |
| AI insights (LLM) | `services/AiService/` (browser-facing + MCP + native audit tools), `ai_service_client.py` (worker), `llm_config.py` (typed loader) |
diff --git a/AGENTS.md b/AGENTS.md
index 758bbd50..9a4bb239 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -13,11 +13,9 @@ This file is the canonical entry point for agents. For full detail see [AGENT.md
- `src/website_profiling/` — Python crawl/Lighthouse engine
- `crawl/`, `lighthouse/`, `worker/`, `api/` (jobs, crawl, internal bridges), `reporting/` (bridge-only until C# port completes)
- `web/` — Vite + React SPA (static nginx in prod); browser calls `services/Bff/` for all `/api/*`
-- `services/Bff/` — .NET BFF (auth, CORS, proxy to FastAPI + ReportService + IntegrationsService + Data + AiService)
-- `services/Data/` — .NET data service (report payloads, portfolio, issue status, filters, typed config, PDF/Excel/CSV/JSON/sitemap export; port 8091). Export profiles: `executive|standard|full|premium`. Env: `REPORT_API_URL` (branding lookup).
-- `services/ReportService/` — .NET report build + pipeline orchestration (port 8094). See [services/ReportService/README.md](services/ReportService/README.md)
+- `services/Bff/` — .NET BFF (auth, CORS, proxy to FastAPI + CoreService + AiService; port 8090)
+- `services/CoreService/` — .NET core service (report build & orchestration, data queries & PDF/Excel exports, Google/Bing integrations; port 8094). See [services/CoreService/README.md](services/CoreService/README.md)
- `services/AiService/` — .NET AI service (Microsoft.Extensions.AI, chat, enrichment, MCP, **secrets/llm-settings writes**; port 8092). See [services/AiService/README.md](services/AiService/README.md)
-- `services/IntegrationsService/` — .NET Google/Bing integrations (GSC/GA4 fetch, OAuth, page-live, keyword reads; port 8093). See [services/IntegrationsService/README.md](services/IntegrationsService/README.md)
- `services/Schema/` — EF Core DB migrations (schema owner)
- `services/WebsiteProfiling.slnx` — unified .NET solution (all services + shared libs)
- `docs/` — documentation index
@@ -26,7 +24,7 @@ This file is the canonical entry point for agents. For full detail see [AGENT.md
**Run / dev**
```bash
-./local-run # Start Postgres + Data + AiService + ReportService + IntegrationsService + worker + FastAPI + BFF + Vite
+./local-run # Start Postgres + CoreService + AiService + worker + FastAPI + BFF + Vite
./local-test # Python + web + .NET tests (CI parity; dotnet: services/WebsiteProfiling.slnx)
python -m src # Run audit pipeline
# MCP: AiService stdio/HTTP — see services/AiService/README.md and docs/MCP.md
@@ -41,7 +39,9 @@ python -m src # Run audit pipeline
| Task | Where |
|------|-------|
| Crawl | `src/website_profiling/crawl/` |
-| Report (native C#) | `services/ReportService/src/ReportService.Application/Build/` |
+| Report (native C#) | `services/CoreService/src/CoreService.Api/Application/Build/` |
+| Data reads & exports | `services/CoreService/src/CoreService.Api/Rendering/`, `DataApplication/` |
+| Integrations (Google/Bing) | `services/CoreService/src/CoreService.Api/Providers/Google/`, `IntegrationsApplication/` |
| Report (Python bridge) | `src/website_profiling/reporting/` |
| Typed settings / config | `config/typed_config_manifest.json`, `src/website_profiling/db/typed_config/` |
| GEO / AEO / Agent readiness | `src/website_profiling/tools/audit_tools/geo/geo_tools.py`, `geo/agent_readiness.py` |
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c6c5a07f..bcd37126 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -39,7 +39,7 @@ CI also runs a **Docker** job (image build, browser pytest in container, compose
When adding tools coverage tests, register new files in `scripts/local-test.sh`, `scripts/local-test.ps1`, and `.github/workflows/ci.yml` (see [AGENT.md](AGENT.md)).
-**.NET DI validation:** Every API service (`AiService`, `Bff`, `Data`, `IntegrationsService`, `ReportService`) enables `ValidateOnBuild` / `ValidateScopes` in `Program.cs` and includes `ServiceRegistrationValidationTests` — a `WebApplicationFactory` smoke test that builds the real host graph. Add the same when introducing a new .NET API project.
+**.NET DI validation:** Every API service (`AiService`, `Bff`, `CoreService`) enables `ValidateOnBuild` / `ValidateScopes` in `Program.cs` and includes `ServiceRegistrationValidationTests` — a `WebApplicationFactory` smoke test that builds the real host graph. Add the same when introducing a new .NET API project.
## How to contribute
diff --git a/README.md b/README.md
index 30e30526..cf4df7a0 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,7 @@
# Site Audit
-**Developer-friendly SEO audit platform** — open-source crawl and technical audit tooling built with **React, Python, PostgreSQL, and .NET**. The stack is split into focused services: **Python FastAPI** (crawl, pipeline jobs), **.NET ReportService** (report build + orchestration), **.NET IntegrationsService** (Google/Bing OAuth, GSC/GA4 fetch, keywords), **.NET AiService** (AI chat, LLM settings, secrets, MCP), **.NET Data** (report reads, portfolio, issue status, typed config, PDF/Excel/CSV/JSON/sitemap export), and a **.NET BFF** as the single browser-facing API gateway.
+**Developer-friendly SEO audit platform** — open-source crawl and technical audit tooling built with **React, Python, PostgreSQL, and .NET**. The stack is split into focused services: **Python FastAPI** (crawl, pipeline jobs), **.NET CoreService** (reports, pipeline orchestration, data reads, PDF/Excel exports, Google/Bing integrations), **.NET AiService** (AI chat, LLM settings, secrets, MCP), and a **.NET BFF** as the single browser-facing API gateway.
## Overview
@@ -149,39 +149,31 @@ flowchart TB
subgraph BffRoutes["BFF upstream routing"]
direction LR
- BFF --> FastAPI["fastapi :8096
Crawl · jobs"]
- BFF --> Report["report :8094
Report build · orchestration"]
- BFF --> Integrations["integrations :8093
Google/Bing · GSC/GA4 · keywords"]
+ BFF --> FastAPI["fastapi :8096
Crawl · jobs · bridge"]
+ BFF --> Core["core :8094
Reports · data reads · exports · Google/Bing"]
BFF --> Ai["ai :8092
Chat · LLM · secrets · MCP"]
- BFF --> Data["data :8091
Report reads · portfolio · issues · typed config · PDF/Excel export"]
end
subgraph Pipeline["Background pipeline"]
Worker["worker
Crawl + Lighthouse jobs"]
- Worker -->|"REPORT_SERVICE_URL"| Report
- Worker -->|"INTEGRATIONS_SERVICE_URL"| Integrations
+ Worker -->|"CORE_SERVICE_URL"| Core
Worker -->|"AI_SERVICE_URL"| Ai
end
subgraph Internal["Service-to-service HTTP (internal)"]
direction TB
- Report -->|"Python bridge · strangler proxy"| FastAPI
- Report -->|"GET /internal/integrations/report/enrichment"| Integrations
- Integrations -->|"keyword / GSC bridge"| FastAPI
+ Core -->|"Python bridge · CLI fallback"| FastAPI
Ai -->|"audit-tool bridge"| FastAPI
- Files -->|"REPORT_API_URL — payload · meta · branding"| FastAPI
end
Postgres[("postgres
Audit data · typed settings")]
FastAPI --- Postgres
Worker --- Postgres
- Report --- Postgres
- Integrations --- Postgres
+ Core --- Postgres
Ai --- Postgres
- Data --- Postgres
- Integrations --> Google[(Google / Bing APIs)]
+ Core --> Google[(Google / Bing APIs)]
Ai --> LLM[(LLM · Ollama)]
MCP([IDE / agent]) -.->|"MCP stdio or HTTP"| Ai
```
@@ -189,19 +181,13 @@ flowchart TB
| From | To | When |
| ---- | -- | ---- |
| **Browser** | BFF → FastAPI | Crawl jobs, pipeline config/settings, most `/api/*` |
-| **Browser** | BFF → Data | Report payload/meta, portfolio, issue status, saved filters, pipeline settings, UI/client preferences (`DATA_ROUTES`) |
-| **Browser** | BFF → Integrations | Google/Bing OAuth, GSC/GA4, keywords (`INTEGRATIONS_ROUTES`) |
+| **Browser** | BFF → CoreService | Report payload/meta, portfolio, issue status, saved filters, pipeline settings, UI/client preferences (`DATA_ROUTES`), Google/Bing (`INTEGRATIONS_ROUTES`), compare runs & dashboards (`REPORT_ROUTES`), PDF/Excel exports |
| **Browser** | BFF → AiService | Chat (SSE), secrets, LLM settings, content AI, MCP catalog (`AI_ROUTES`) |
-| **Browser** | BFF → ReportService | Compare runs, dashboards (`REPORT_ROUTES`; strangler proxy to FastAPI) |
-| **Browser** | BFF → Data | Report PDF/Excel export (`/api/report/export`) |
-| **Worker** | ReportService | Post-crawl report build and full-pipeline orchestration |
-| **Worker** | IntegrationsService | Google fetch, keyword enrichment |
+| **Worker** | CoreService | Post-crawl report build, pipeline orchestration, Google fetch, keyword enrichment |
| **Worker** | AiService | ML enrichment, page coach, structured completions |
-| **ReportService** | FastAPI | Python report bridge; dashboard/compare strangler |
-| **ReportService** | IntegrationsService | Google/keyword/GSC snapshots for native report build |
-| **IntegrationsService** | FastAPI | Keyword enrich + GSC link import when Python bridge is enabled |
+| **CoreService** | FastAPI | Python report bridge; keyword enrich + GSC link import CLI bridge |
| **AiService** | FastAPI | Audit tools not yet ported to C# |
-| **Data · Ai · Report · Integrations · FastAPI · worker** | Postgres | Direct reads/writes to typed settings and audit tables |
+| **Core · Ai · FastAPI · worker** | Postgres | Direct reads/writes to typed settings and audit tables |
```
WebsiteProfiling/
@@ -227,10 +213,8 @@ WebsiteProfiling/
│ ├── src/lib/ # Client helpers, BFF apiUrl/apiFetch
│ └── public/ # Static assets (logo, favicon)
├── services/Bff/ # .NET BFF — auth + /api/* proxy (port 8090)
-├── services/ReportService/ # .NET report build + pipeline orchestration (port 8094)
-├── services/IntegrationsService/ # .NET Google/Bing integrations — OAuth, GSC/GA4, keywords (port 8093)
+├── services/CoreService/ # .NET core backend — reports, data reads & exports, Google/Bing integrations (port 8094)
├── services/AiService/ # .NET AI — chat, secrets, LLM config, MCP, enrichment (port 8092)
-├── services/Data/ # .NET data service — report/portfolio/issue reads, typed config (port 8091)
├── services/Schema/ # EF Core schema migrations (PostgreSQL schema owner)
├── tests/ # pytest suite + fixtures
├── docs/ # Glossary, MCP, ops, brand assets
@@ -252,13 +236,9 @@ WebsiteProfiling/
| ------------------------------------- | ------------------------------------------------------------------------------ |
| `src/website_profiling/` | Crawl, analyze, report, Lighthouse — run via `python -m src` |
| `src/website_profiling/api/` | FastAPI — pipeline jobs, crawl, pipeline-config / pipeline-settings / ui-preferences |
-| `services/Bff/` | Browser API gateway — auth, CORS, routes `/api/*` to FastAPI, ReportService, IntegrationsService, AiService, Data |
-| `services/IntegrationsService/` | Google/Bing OAuth, GSC/GA4 fetch, keywords, page-live — see [services/IntegrationsService/README.md](services/IntegrationsService/README.md) |
+| `services/Bff/` | Browser API gateway — auth, CORS, routes `/api/*` to FastAPI, CoreService, AiService |
+| `services/CoreService/` | Report build & pipeline orchestration, data queries & PDF/Excel exports, Google/Bing integrations — see [services/CoreService/README.md](services/CoreService/README.md) |
| `services/AiService/` | AI chat, secrets, LLM settings, MCP, enrichment — see [services/AiService/README.md](services/AiService/README.md) |
-| `services/Data/` | .NET read/mutation service for report payloads, portfolio, issue status, saved filters, typed config (pipeline settings, UI/client preferences), and PDF/Excel/CSV/JSON/sitemap report export |
-| `web/src/lib/publicBase.ts` | BFF base URL (`VITE_BFF_BASE_URL`) and `apiFetch` / `apiUrl` |
-| `web/src/lib/pipelineConfigSchema.ts` | Audit settings schema (UI ↔ PostgreSQL) |
-| `services/ReportService/` | .NET report build + full-audit orchestration — see [services/ReportService/README.md](services/ReportService/README.md) |
| `config/typed_config_manifest.json` | Typed PostgreSQL settings schema (pipeline, LLM, secrets, UI prefs) |
| `services/Schema/` | EF Core schema migrations — run `./local-run migrate` |
| `tests/` | Backend tests; `./local-test browser` for Playwright crawl integration |
@@ -277,7 +257,7 @@ For layout details and common development patterns, see [AGENT.md](AGENT.md).
| **Docker** | Postgres container (local dev) and full-stack compose |
| **Python 3.12+** | Audit engine, FastAPI, pipeline worker, tests |
| **Node 20+** | Vite + React SPA |
-| **.NET SDK 10+** | BFF, IntegrationsService, AiService, Data, and ReportService (required for `./local-run`; optional if you only use Docker) |
+| **.NET SDK 10+** | BFF, CoreService, and AiService (required for `./local-run`; optional if you only use Docker) |
When using `./local-run`, missing tools above are auto-installed via **Homebrew** (macOS) or **winget** (Windows) when available. On Linux, `apt-get` is used when supported. Set `WP_SKIP_SYSTEM_INSTALL=1` to disable system tool auto-install.
@@ -289,9 +269,9 @@ Build and run the full dev stack from source:
docker compose up --build
```
-Services: **postgres**, **migrator** (one-shot EF Core schema migration, exits after applying), **fastapi** (`:8096`, internal), **worker**, **report** (`:8094`, internal), **integrations** (`:8093`, internal), **ai** (`:8092`, internal), **data** (`:8091`, internal), **bff** (`:8090`), **web** (`:3000`).
+Services: **postgres**, **migrator** (one-shot EF Core schema migration, exits after applying), **fastapi** (`:8096`, internal), **core** (`:8094`, internal), **ai** (`:8092`, internal), **bff** (`:8090`), **web** (`:3000`).
-Open [http://localhost:3000/home](http://localhost:3000/home). The browser talks only to the **BFF** (`:8090`); the BFF proxies to FastAPI (crawl/pipeline), IntegrationsService (Google/Bing), AiService (AI/secrets), and Data (report reads, typed config, PDF/workbook export).
+Open [http://localhost:3000/home](http://localhost:3000/home). The browser talks only to the **BFF** (`:8090`); the BFF proxies to FastAPI (crawl/pipeline), CoreService (reports, data reads, exports, Google/Bing), and AiService (AI/secrets).
Production deployment: `docker-compose.prod.yml` — set `POSTGRES_USER`, `POSTGRES_PASSWORD`, `AUTH_SECRET`, `BFF_ALLOWED_ORIGINS`, and `BFF_PUBLIC_URL`. Optional remote MCP: `docker compose -f docker-compose.prod.yml --profile mcp up`. Pre-built images: `docker-compose.pull.yml` (`BACKEND_IMAGE`, `WEB_IMAGE`). Schema is applied by the one-shot `migrator` service before any dependent service starts; don't run a Postgres-backed service in isolation with `docker run` unless its schema was already migrated (`docker compose run migrator` or `dotnet run --project services/Schema/src/Schema.Migrator`).
@@ -308,7 +288,7 @@ Production deployment: `docker-compose.prod.yml` — set `POSTGRES_USER`, `POSTG
Optional env flags: `WP_SKIP_SYSTEM_INSTALL=1` (do not auto-install Docker/Node/Python/.NET), `WP_SKIP_DEPS_SYNC=1` (skip pip/npm/dotnet restore on start).
-`./local-run` starts (in order): **Data** `:8091` (reports, portfolio, issues, typed config, PDF/Excel export), **AiService** `:8092` (MCP HTTP enabled), **ReportService** `:8094`, **IntegrationsService** `:8093`, **FastAPI** `:8096` (Python bridge), **BFF** `:8090`, and **Vite** `:3000`. Use `localhost` (not `127.0.0.1`) for pipeline APIs so CORS and cookies match the BFF origin.
+`./local-run` starts (in order): **CoreService** `:8094` (reports, portfolio, issues, typed config, PDF/Excel export, Google/Bing), **AiService** `:8092` (MCP HTTP enabled), **FastAPI** `:8096` (Python bridge), **BFF** `:8090`, and **Vite** `:3000`. Use `localhost` (not `127.0.0.1`) for pipeline APIs so CORS and cookies match the BFF origin.
Default local `DATABASE_URL`: `postgres://postgres:dev@127.0.0.1:5432/website_profiling` (Docker Compose dev stack uses `profiling:profiling`).
@@ -319,10 +299,8 @@ With `./local-run`, each service runs in **Development** and exposes interactive
| Service | Port | Swagger UI | OpenAPI JSON |
| ------- | ---- | ---------- | ------------ |
| **BFF** | 8090 | [http://localhost:8090/docs](http://localhost:8090/docs) | `/swagger/v1/swagger.json` |
-| **Data** | 8091 | [http://localhost:8091/docs](http://localhost:8091/docs) | `/swagger/v1/swagger.json` |
| **AiService** | 8092 | [http://localhost:8092/docs](http://localhost:8092/docs) | `/swagger/v1/swagger.json` |
-| **IntegrationsService** | 8093 | [http://localhost:8093/docs](http://localhost:8093/docs) | `/swagger/v1/swagger.json` |
-| **ReportService** | 8094 | [http://localhost:8094/docs](http://localhost:8094/docs) | `/swagger/v1/swagger.json` |
+| **CoreService** | 8094 | [http://localhost:8094/docs](http://localhost:8094/docs) | `/swagger/v1/swagger.json` |
| **Python bridge** (FastAPI) | 8096 | [http://localhost:8096/docs](http://localhost:8096/docs) | `/openapi.json` |
Swagger UI is disabled when `ASPNETCORE_ENVIRONMENT=Production`. The legacy `web/openapi.json` reflects the old monolithic FastAPI app and is not a complete map of the current C# services.
@@ -423,9 +401,8 @@ Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for setup and
| [docs/COMPANY_STANDARDS.md](docs/COMPANY_STANDARDS.md) | Data and security policy |
| [docs/MCP.md](docs/MCP.md) | MCP server setup |
| [docs/OPS.md](docs/OPS.md) | Scheduled audits, alerts, production ops |
-| [services/ReportService/README.md](services/ReportService/README.md) | Report build + pipeline orchestration (port 8094) |
+| [services/CoreService/README.md](services/CoreService/README.md) | Reports, data reads & exports, Google/Bing integrations (port 8094) |
| [services/AiService/README.md](services/AiService/README.md) | AI chat, secrets, LLM settings, MCP |
-| [services/IntegrationsService/README.md](services/IntegrationsService/README.md) | Google/Bing OAuth, GSC/GA4, keywords |
## Star History
diff --git a/diagram.html b/diagram.html
index 38746ad8..6e200847 100644
--- a/diagram.html
+++ b/diagram.html
@@ -193,27 +193,23 @@
};
const nodesData = [
- // Top — browser stack, centred on x=650
+ // Top — browser stack, centred on x=560
{ id: 'browser', label: 'Browser', sub: 'Client', x: 560, y: 40, type: 'client', desc: 'End-user web browser interacting with the application.' },
{ id: 'web', label: 'Web', sub: ':3000 • React SPA', x: 560, y: 160, type: 'frontend', desc: 'Main frontend single-page application built in React.' },
{ id: 'bff', label: 'BFF', sub: ':8090 • Auth • Proxy', x: 560, y: 290, type: 'gateway', desc: 'Backend-for-Frontend serving as the entry point. Handles authentication, CORS, and reverse proxy routing.' },
// MCP to the right of BFF
- { id: 'mcp', label: 'MCP', sub: 'IDE / Agent', x: 980, y: 290, type: 'client', desc: 'Model Context Protocol or Machine Control client interacting with the AI subsystem via stdio or HTTP.' },
-
- // Services row — 5 nodes, 200 px apart, centred under BFF
- // ConfigService and FileService were both merged into Data (typed config +
- // PDF/Excel/CSV/JSON/sitemap export).
- // span = 4 × 200 = 800 → start at 650 − 400 = 250... (kept fastapi anchor at 50)
- { id: 'fastapi', label: 'FastAPI', sub: ':8096 • Crawl/Jobs', x: 50, y: 470, type: 'service', desc: 'Core Python service handling crawling and jobs. Acts as the strangler proxy target.' },
- { id: 'report', label: 'Report', sub: ':8094 • Build', x: 250, y: 470, type: 'service', desc: 'Service dedicated to report building and orchestrating complex multi-step processes.' },
- { id: 'integrations', label: 'Integrations', sub: ':8093 • APIs', x: 450, y: 470, type: 'service', desc: 'Manages third-party connections including Google/Bing APIs, GSC, GA4, and keyword processing.' },
- { id: 'ai', label: 'AI', sub: ':8092 • Chat/LLM', x: 650, y: 470, type: 'service', desc: 'AI orchestration service managing chat interfaces, LLM connections, secrets, and MCP.' },
- { id: 'data', label: 'Data', sub: ':8091 • Portfolio · Config · Export', x: 850, y: 470, type: 'service', desc: 'Data access layer for report reads, portfolio management, system issue tracking, typed configuration (pipeline settings, UI/client preferences), and PDF/Excel/CSV/JSON/sitemap report export — absorbed the former ConfigService and FileService.' },
-
- // Middle-lower row — Worker under FastAPI/Report, external services under Integrations/AI
- { id: 'worker', label: 'Worker', sub: 'Crawl + Lighthouse', x: 150, y: 660, type: 'worker', desc: 'Background asynchronous pipeline worker executing heavy crawl and Lighthouse audit jobs.' },
- { id: 'google', label: 'Google / Bing APIs', sub: 'External', x: 450, y: 660, type: 'external', desc: 'External search and analytics APIs consumed by the Integrations service.' },
- { id: 'llm', label: 'LLM', sub: 'Ollama', x: 650, y: 660, type: 'external', desc: 'Large Language Model provider, heavily utilized for text and chat generation.' },
+ { id: 'mcp', label: 'MCP', sub: 'IDE / Agent', x: 920, y: 290, type: 'client', desc: 'Model Context Protocol client interacting with the AI subsystem via stdio or HTTP (369 audit tools).' },
+
+ // Services row — 3 unified services, 360 px apart, centred under BFF
+ // CoreService consolidates Report, Data, and Integrations (reports + pipeline + direct Postgres reads/exports + Google/Bing APIs).
+ { id: 'fastapi', label: 'FastAPI', sub: ':8096 • Crawl/Jobs/Bridge', x: 200, y: 470, type: 'service', desc: 'Core Python service handling crawling, Lighthouse, and pipeline jobs. Acts as the strangler proxy target and CLI bridge.' },
+ { id: 'core', label: 'Core', sub: ':8094 • Reports · Data · APIs', x: 560, y: 470, type: 'service', desc: 'Unified .NET backend consolidating report generation & pipeline orchestration, direct Postgres data access & PDF/Excel exports, and Google/Bing integrations.' },
+ { id: 'ai', label: 'AI', sub: ':8092 • Chat/LLM/MCP', x: 920, y: 470, type: 'service', desc: 'AI orchestration service managing chat interfaces, LLM connections, secrets writes, and 369 MCP tools.' },
+
+ // Middle-lower row — Worker under FastAPI, Google under Core, LLM under AI
+ { id: 'worker', label: 'Worker', sub: 'Crawl + Lighthouse', x: 200, y: 660, type: 'worker', desc: 'Background asynchronous pipeline worker executing heavy crawl and Lighthouse audit jobs.' },
+ { id: 'google', label: 'Google / Bing APIs', sub: 'External', x: 560, y: 660, type: 'external', desc: 'External search and analytics APIs consumed by CoreService.' },
+ { id: 'llm', label: 'LLM', sub: 'Ollama', x: 920, y: 660, type: 'external', desc: 'Large Language Model provider, heavily utilized for text and chat generation.' },
// Bottom — Postgres centred
{ id: 'postgres', label: 'Postgres', sub: 'Audit • Settings', x: 560, y: 860, type: 'database', desc: 'Primary relational data store holding audit data and typed system settings.' },
@@ -223,31 +219,23 @@
{ id: 'e1', source: 'browser', target: 'web' },
{ id: 'e2', source: 'web', target: 'bff', label: '"/api/*"' },
{ id: 'e3', source: 'bff', target: 'fastapi' },
- { id: 'e4', source: 'bff', target: 'report' },
- { id: 'e5', source: 'bff', target: 'integrations' },
- { id: 'e6', source: 'bff', target: 'ai' },
- { id: 'e7', source: 'bff', target: 'data' },
-
- { id: 'e9', source: 'worker', target: 'report', label: 'REPORT_SERVICE_URL' },
- { id: 'e10', source: 'worker', target: 'integrations', label: 'INTEGRATIONS_SERVICE_URL' },
- { id: 'e11', source: 'worker', target: 'ai', label: 'AI_SERVICE_URL' },
+ { id: 'e4', source: 'bff', target: 'core' },
+ { id: 'e5', source: 'bff', target: 'ai' },
+
+ { id: 'e6', source: 'worker', target: 'core', label: 'CORE_SERVICE_URL' },
+ { id: 'e7', source: 'worker', target: 'ai', label: 'AI_SERVICE_URL' },
- { id: 'e12', source: 'report', target: 'fastapi', label: 'Python bridge', dashed: true },
- { id: 'e13', source: 'report', target: 'integrations', label: 'GET enrichment', dashed: true },
- { id: 'e14', source: 'integrations', target: 'fastapi', label: 'keyword/GSC bridge', dashed: true },
- { id: 'e15', source: 'ai', target: 'fastapi', label: 'audit-tool bridge', dashed: true },
- { id: 'e16', source: 'data', target: 'fastapi', label: 'branding lookup', dashed: true },
+ { id: 'e8', source: 'core', target: 'fastapi', label: 'Python bridge', dashed: true },
+ { id: 'e9', source: 'ai', target: 'fastapi', label: 'audit-tool bridge', dashed: true },
- { id: 'e17', source: 'fastapi', target: 'postgres' },
- { id: 'e18', source: 'worker', target: 'postgres' },
- { id: 'e19', source: 'report', target: 'postgres' },
- { id: 'e20', source: 'integrations', target: 'postgres' },
- { id: 'e21', source: 'ai', target: 'postgres' },
- { id: 'e22', source: 'data', target: 'postgres' },
+ { id: 'e10', source: 'fastapi', target: 'postgres' },
+ { id: 'e11', source: 'worker', target: 'postgres' },
+ { id: 'e12', source: 'core', target: 'postgres' },
+ { id: 'e13', source: 'ai', target: 'postgres' },
- { id: 'e23', source: 'integrations', target: 'google' },
- { id: 'e24', source: 'ai', target: 'llm' },
- { id: 'e25', source: 'mcp', target: 'ai', label: 'MCP stdio/HTTP', dashed: true },
+ { id: 'e14', source: 'core', target: 'google' },
+ { id: 'e15', source: 'ai', target: 'llm' },
+ { id: 'e16', source: 'mcp', target: 'ai', label: 'MCP stdio/HTTP', dashed: true },
];
let transform = { x: 0, y: 0, scale: 0.8 };
diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml
index 06678076..eb59c79b 100644
--- a/docker-compose.prod.yml
+++ b/docker-compose.prod.yml
@@ -52,7 +52,8 @@ services:
LIGHTHOUSE_CHROME_FLAGS: --headless --no-sandbox --disable-dev-shm-usage --disable-gpu
DEPRECATE_PYTHON_INTEGRATIONS: "1"
DEPRECATE_PYTHON_REPORT_ROUTES: "1"
- REPORT_SERVICE_URL: http://report:8094
+ CORE_SERVICE_URL: http://core:8094
+ REPORT_SERVICE_URL: http://core:8094
volumes:
- profiling-data:/data
healthcheck:
@@ -62,16 +63,23 @@ services:
retries: 3
start_period: 30s
- data:
- container_name: wp-data
+ core:
+ container_name: wp-core
build:
context: .
- dockerfile: services/Data/Dockerfile
+ dockerfile: services/CoreService/Dockerfile
environment:
DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-website_profiling}
- ASPNETCORE_URLS: http://+:8091
+ ASPNETCORE_URLS: http://+:8094
+ FASTAPI_URL: http://fastapi:8096
+ AI_SERVICE_URL: http://ai:8092
WEBSITE_PROFILING_ROOT: /app
- REPORT_API_URL: http://fastapi:8096
+ REPORT_SERVICE_USE_PYTHON_BRIDGE: "0"
+ USE_FASTAPI_PYTHON_BRIDGE: "1"
+ REPORT_SERVICE_WORKER_ENABLED: "1"
+ AUTH_SECRET: ${AUTH_SECRET:?set AUTH_SECRET}
+ APP_PUBLIC_URL: ${APP_PUBLIC_URL:-}
+ GOOGLE_REDIRECT_URI: ${GOOGLE_REDIRECT_URI:-}
depends_on:
postgres:
condition: service_healthy
@@ -80,11 +88,11 @@ services:
fastapi:
condition: service_started
healthcheck:
- test: ['CMD', 'curl', '-fsS', 'http://127.0.0.1:8091/health']
+ test: ['CMD', 'curl', '-fsS', 'http://127.0.0.1:8094/health']
interval: 30s
timeout: 5s
retries: 3
- start_period: 15s
+ start_period: 20s
ai:
container_name: wp-ai
@@ -110,64 +118,6 @@ services:
retries: 3
start_period: 20s
- integrations:
- container_name: wp-integrations
- build:
- context: ./services
- dockerfile: IntegrationsService/Dockerfile
- environment:
- DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-website_profiling}
- ASPNETCORE_URLS: http://+:8093
- FASTAPI_URL: http://fastapi:8096
- USE_FASTAPI_PYTHON_BRIDGE: "1"
- ASPNETCORE_ENVIRONMENT: Production
- AUTH_SECRET: ${AUTH_SECRET:?set AUTH_SECRET}
- APP_PUBLIC_URL: ${APP_PUBLIC_URL:-}
- GOOGLE_REDIRECT_URI: ${GOOGLE_REDIRECT_URI:-}
- depends_on:
- postgres:
- condition: service_healthy
- migrator:
- condition: service_completed_successfully
- fastapi:
- condition: service_started
- healthcheck:
- test: ['CMD', 'curl', '-fsS', 'http://127.0.0.1:8093/health']
- interval: 30s
- timeout: 5s
- retries: 3
- start_period: 20s
-
- report:
- container_name: wp-report
- build:
- context: .
- dockerfile: services/ReportService/Dockerfile
- environment:
- DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-website_profiling}
- ASPNETCORE_URLS: http://+:8094
- FASTAPI_URL: http://fastapi:8096
- INTEGRATIONS_SERVICE_URL: http://integrations:8093
- AI_SERVICE_URL: http://ai:8092
- REPORT_SERVICE_USE_PYTHON_BRIDGE: "0"
- USE_FASTAPI_PYTHON_BRIDGE: "1"
- REPORT_SERVICE_WORKER_ENABLED: "1"
- depends_on:
- postgres:
- condition: service_healthy
- migrator:
- condition: service_completed_successfully
- fastapi:
- condition: service_started
- integrations:
- condition: service_healthy
- healthcheck:
- test: ['CMD', 'curl', '-fsS', 'http://127.0.0.1:8094/health']
- interval: 30s
- timeout: 5s
- retries: 3
- start_period: 20s
-
bff:
container_name: wp-bff
build:
@@ -176,22 +126,19 @@ services:
depends_on:
fastapi:
condition: service_started
- data:
+ core:
condition: service_healthy
ai:
condition: service_healthy
- integrations:
- condition: service_healthy
- report:
- condition: service_healthy
ports:
- '${BFF_PORT:-8090}:8090'
environment:
FASTAPI_URL: http://fastapi:8096
- DATA_SERVICE_URL: http://data:8091
+ CORE_SERVICE_URL: http://core:8094
+ DATA_SERVICE_URL: http://core:8094
AI_SERVICE_URL: http://ai:8092
- INTEGRATIONS_SERVICE_URL: http://integrations:8093
- REPORT_SERVICE_URL: http://report:8094
+ INTEGRATIONS_SERVICE_URL: http://core:8094
+ REPORT_SERVICE_URL: http://core:8094
REPORT_ROUTES: "/api/compare,/api/dashboards,/api/run,/api/jobs,/api/schedule,/api/crawl,/api/pipeline-preview"
DATA_ROUTES: "/api/report/meta,/api/report/payload,/api/report/history,/api/report/crawl-payload,/api/report/mobile-delta,/api/report/portfolio,/api/portfolio,/api/issues/status,/api/filters,/api/properties,/api/content-drafts,/api/content/score,/api/keywords,/api/page-markdown,/api/alerts,/api/logs,/api/backlinks,/api/pipeline-settings,/api/ui-preferences,/api/client-preferences"
AI_ROUTES: "/api/chat,/api/links/page-coach,/api/issues/fix-suggestion,/api/issues/action-plan,/api/ai/fix-suggestion,/api/dashboards/ai-generate,/api/content/analyze,/api/content/wizard,/api/llm-settings,/api/secrets,/api/ollama/status,/api/report/audit-tool,/api/mcp-tools"
diff --git a/docker-compose.pull.yml b/docker-compose.pull.yml
index 716ebdda..9a2264cc 100644
--- a/docker-compose.pull.yml
+++ b/docker-compose.pull.yml
@@ -54,7 +54,8 @@ services:
FASTAPI_ALLOWED_ORIGINS: "http://localhost:8090"
DEPRECATE_PYTHON_INTEGRATIONS: "1"
DEPRECATE_PYTHON_REPORT_ROUTES: "1"
- REPORT_SERVICE_URL: http://report:8094
+ CORE_SERVICE_URL: http://core:8094
+ REPORT_SERVICE_URL: http://core:8094
volumes:
- profiling-data:/data
healthcheck:
@@ -64,16 +65,25 @@ services:
retries: 3
start_period: 30s
- data:
- container_name: wp-data
+ core:
+ container_name: wp-core
build:
context: .
- dockerfile: services/Data/Dockerfile
+ dockerfile: services/CoreService/Dockerfile
+ ports:
+ - "8094:8094"
environment:
DATABASE_URL: postgres://profiling:profiling@postgres:5432/website_profiling
- ASPNETCORE_URLS: http://+:8091
+ ASPNETCORE_URLS: http://+:8094
+ FASTAPI_URL: http://fastapi:8096
+ AI_SERVICE_URL: http://ai:8092
WEBSITE_PROFILING_ROOT: /app
- REPORT_API_URL: http://fastapi:8096
+ REPORT_SERVICE_USE_PYTHON_BRIDGE: "0"
+ USE_FASTAPI_PYTHON_BRIDGE: "1"
+ REPORT_SERVICE_WORKER_ENABLED: "1"
+ AUTH_SECRET: ${AUTH_SECRET:-}
+ GOOGLE_REDIRECT_URI: ${GOOGLE_REDIRECT_URI:-http://localhost:8090/api/integrations/google/callback}
+ APP_PUBLIC_URL: ${APP_PUBLIC_URL:-http://localhost:3000}
depends_on:
postgres:
condition: service_healthy
@@ -82,11 +92,11 @@ services:
fastapi:
condition: service_started
healthcheck:
- test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8091/health"]
+ test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8094/health"]
interval: 30s
timeout: 5s
retries: 3
- start_period: 15s
+ start_period: 20s
ai:
container_name: wp-ai
@@ -111,62 +121,6 @@ services:
retries: 3
start_period: 20s
- integrations:
- container_name: wp-integrations
- build:
- context: ./services
- dockerfile: IntegrationsService/Dockerfile
- environment:
- DATABASE_URL: postgres://profiling:profiling@postgres:5432/website_profiling
- ASPNETCORE_URLS: http://+:8093
- FASTAPI_URL: http://fastapi:8096
- USE_FASTAPI_PYTHON_BRIDGE: "1"
- AUTH_SECRET: ${AUTH_SECRET:-}
- GOOGLE_REDIRECT_URI: ${GOOGLE_REDIRECT_URI:-http://localhost:8090/api/integrations/google/callback}
- APP_PUBLIC_URL: ${APP_PUBLIC_URL:-http://localhost:3000}
- depends_on:
- postgres:
- condition: service_healthy
- migrator:
- condition: service_completed_successfully
- fastapi:
- condition: service_started
- healthcheck:
- test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8093/health"]
- interval: 30s
- timeout: 5s
- retries: 3
- start_period: 20s
-
- report:
- container_name: wp-report
- build:
- context: .
- dockerfile: services/ReportService/Dockerfile
- environment:
- DATABASE_URL: postgres://profiling:profiling@postgres:5432/website_profiling
- ASPNETCORE_URLS: http://+:8094
- FASTAPI_URL: http://fastapi:8096
- INTEGRATIONS_SERVICE_URL: http://integrations:8093
- REPORT_SERVICE_USE_PYTHON_BRIDGE: "0"
- USE_FASTAPI_PYTHON_BRIDGE: "1"
- REPORT_SERVICE_WORKER_ENABLED: "1"
- depends_on:
- postgres:
- condition: service_healthy
- migrator:
- condition: service_completed_successfully
- fastapi:
- condition: service_started
- integrations:
- condition: service_healthy
- healthcheck:
- test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8094/health"]
- interval: 30s
- timeout: 5s
- retries: 3
- start_period: 20s
-
bff:
container_name: wp-bff
build:
@@ -176,10 +130,11 @@ services:
- "8090:8090"
environment:
FASTAPI_URL: http://fastapi:8096
- DATA_SERVICE_URL: http://data:8091
+ CORE_SERVICE_URL: http://core:8094
+ DATA_SERVICE_URL: http://core:8094
AI_SERVICE_URL: http://ai:8092
- INTEGRATIONS_SERVICE_URL: http://integrations:8093
- REPORT_SERVICE_URL: http://report:8094
+ INTEGRATIONS_SERVICE_URL: http://core:8094
+ REPORT_SERVICE_URL: http://core:8094
REPORT_ROUTES: "/api/compare,/api/dashboards,/api/run,/api/jobs,/api/schedule,/api/crawl,/api/pipeline-preview"
BFF_ALLOWED_ORIGINS: "http://localhost:3000"
DATA_ROUTES: "/api/report/meta,/api/report/payload,/api/report/history,/api/report/crawl-payload,/api/report/mobile-delta,/api/report/portfolio,/api/portfolio,/api/issues/status,/api/filters,/api/properties,/api/content-drafts,/api/content/score,/api/keywords,/api/page-markdown,/api/alerts,/api/logs,/api/backlinks,/api/pipeline-settings,/api/ui-preferences,/api/client-preferences"
@@ -188,14 +143,10 @@ services:
depends_on:
fastapi:
condition: service_started
- data:
+ core:
condition: service_healthy
ai:
condition: service_healthy
- integrations:
- condition: service_healthy
- report:
- condition: service_healthy
web:
container_name: wp-web
diff --git a/docker-compose.yml b/docker-compose.yml
index f0711ff3..59354489 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -53,7 +53,8 @@ services:
FASTAPI_ALLOWED_ORIGINS: "http://localhost:8090"
DEPRECATE_PYTHON_INTEGRATIONS: "1"
DEPRECATE_PYTHON_REPORT_ROUTES: "1"
- REPORT_SERVICE_URL: http://report:8094
+ CORE_SERVICE_URL: http://core:8094
+ REPORT_SERVICE_URL: http://core:8094
volumes:
- profiling-data:/data
healthcheck:
@@ -63,18 +64,27 @@ services:
retries: 3
start_period: 20s
- # .NET read microservice — reads Postgres directly, incrementally replacing FastAPI reads.
- # Internal: only the BFF reaches it (no published host port).
- data:
- container_name: wp-data
+ # .NET Core Service — unified backend for reports, pipeline orchestration, data queries,
+ # exports, and Google/Bing integrations. Replaced separate data, integrations, and report containers.
+ core:
+ container_name: wp-core
build:
context: .
- dockerfile: services/Data/Dockerfile
+ dockerfile: services/CoreService/Dockerfile
+ ports:
+ - "8094:8094"
environment:
DATABASE_URL: postgres://profiling:profiling@postgres:5432/website_profiling
- ASPNETCORE_URLS: http://+:8091
+ ASPNETCORE_URLS: http://+:8094
+ FASTAPI_URL: http://fastapi:8096
+ AI_SERVICE_URL: http://ai:8092
WEBSITE_PROFILING_ROOT: /app
- REPORT_API_URL: http://fastapi:8096
+ REPORT_SERVICE_USE_PYTHON_BRIDGE: "0"
+ USE_FASTAPI_PYTHON_BRIDGE: "1"
+ REPORT_SERVICE_WORKER_ENABLED: "1"
+ AUTH_SECRET: ${AUTH_SECRET:-}
+ GOOGLE_REDIRECT_URI: ${GOOGLE_REDIRECT_URI:-http://localhost:8090/api/integrations/google/callback}
+ APP_PUBLIC_URL: ${APP_PUBLIC_URL:-http://localhost:3000}
depends_on:
postgres:
condition: service_healthy
@@ -83,11 +93,11 @@ services:
fastapi:
condition: service_started
healthcheck:
- test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8091/health"]
+ test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8094/health"]
interval: 30s
timeout: 5s
retries: 3
- start_period: 15s
+ start_period: 20s
ai:
container_name: wp-ai
@@ -113,63 +123,6 @@ services:
retries: 3
start_period: 20s
- integrations:
- container_name: wp-integrations
- build:
- context: ./services
- dockerfile: IntegrationsService/Dockerfile
- environment:
- DATABASE_URL: postgres://profiling:profiling@postgres:5432/website_profiling
- ASPNETCORE_URLS: http://+:8093
- FASTAPI_URL: http://fastapi:8096
- USE_FASTAPI_PYTHON_BRIDGE: "1"
- AUTH_SECRET: ${AUTH_SECRET:-}
- GOOGLE_REDIRECT_URI: ${GOOGLE_REDIRECT_URI:-http://localhost:8090/api/integrations/google/callback}
- APP_PUBLIC_URL: ${APP_PUBLIC_URL:-http://localhost:3000}
- depends_on:
- postgres:
- condition: service_healthy
- migrator:
- condition: service_completed_successfully
- fastapi:
- condition: service_started
- healthcheck:
- test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8093/health"]
- interval: 30s
- timeout: 5s
- retries: 3
- start_period: 20s
-
- report:
- container_name: wp-report
- build:
- context: .
- dockerfile: services/ReportService/Dockerfile
- environment:
- DATABASE_URL: postgres://profiling:profiling@postgres:5432/website_profiling
- ASPNETCORE_URLS: http://+:8094
- FASTAPI_URL: http://fastapi:8096
- INTEGRATIONS_SERVICE_URL: http://integrations:8093
- AI_SERVICE_URL: http://ai:8092
- REPORT_SERVICE_USE_PYTHON_BRIDGE: "0"
- USE_FASTAPI_PYTHON_BRIDGE: "1"
- REPORT_SERVICE_WORKER_ENABLED: "1"
- depends_on:
- postgres:
- condition: service_healthy
- migrator:
- condition: service_completed_successfully
- fastapi:
- condition: service_started
- integrations:
- condition: service_healthy
- healthcheck:
- test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8094/health"]
- interval: 30s
- timeout: 5s
- retries: 3
- start_period: 20s
-
# .NET BFF — the single browser-facing API surface (owns auth + CORS).
bff:
container_name: wp-bff
@@ -181,10 +134,11 @@ services:
environment:
FASTAPI_URL: http://fastapi:8096
BFF_ALLOWED_ORIGINS: "http://localhost:3000"
- DATA_SERVICE_URL: http://data:8091
+ CORE_SERVICE_URL: http://core:8094
+ DATA_SERVICE_URL: http://core:8094
AI_SERVICE_URL: http://ai:8092
- INTEGRATIONS_SERVICE_URL: http://integrations:8093
- REPORT_SERVICE_URL: http://report:8094
+ INTEGRATIONS_SERVICE_URL: http://core:8094
+ REPORT_SERVICE_URL: http://core:8094
REPORT_ROUTES: "/api/compare,/api/dashboards,/api/run,/api/jobs,/api/schedule,/api/crawl,/api/pipeline-preview"
AUTH_SECRET: ${AUTH_SECRET:-}
DATA_ROUTES: "/api/report/meta,/api/report/payload,/api/report/history,/api/report/crawl-payload,/api/report/mobile-delta,/api/report/portfolio,/api/portfolio,/api/issues/status,/api/filters,/api/properties,/api/content-drafts,/api/content/score,/api/keywords,/api/page-markdown,/api/alerts,/api/logs,/api/backlinks,/api/pipeline-settings,/api/ui-preferences,/api/client-preferences"
@@ -193,14 +147,10 @@ services:
depends_on:
fastapi:
condition: service_started
- data:
+ core:
condition: service_healthy
ai:
condition: service_healthy
- integrations:
- condition: service_healthy
- report:
- condition: service_healthy
# Vite SPA (nginx). The browser calls the BFF (:8090) for all /api/*.
web:
diff --git a/docs/MCP.md b/docs/MCP.md
index 3a129a48..bdd366e4 100644
--- a/docs/MCP.md
+++ b/docs/MCP.md
@@ -227,12 +227,12 @@ Export tools write artifact files with a 24-hour TTL; in-app chat renders downlo
| Deliverable | Generator | Env / notes |
|-------------|-----------|-------------|
-| PDF | **Data service** (`GET /v1/reports/{id}/pdf`) | `DATA_SERVICE_URL` on MCP/web (default `http://127.0.0.1:8091`); Data must be running |
-| Excel workbook | **Data service** (`GET /v1/reports/{id}/workbook`) | Same as PDF |
+| PDF | **CoreService** (`GET /v1/reports/{id}/pdf`) | `CORE_SERVICE_URL` / `DATA_SERVICE_URL` on MCP/web (default `http://127.0.0.1:8094`); CoreService must be running |
+| Excel workbook | **CoreService** (`GET /v1/reports/{id}/workbook`) | Same as PDF |
| CSV / JSON audit export | Python (`export_audit_report`, `GET /api/report/export`) | Reads Postgres via report payload — no separate export service required |
| Compare / list CSV | Python | `export_compare_csv`, `export_list_as_csv` |
-The Data service reads report payloads directly from Postgres; it only calls out over HTTP for PDF branding (`REPORT_API_URL` → `/api/ui-preferences` for brand name/logo).
+CoreService reads report payloads directly from Postgres; it only calls out over HTTP for PDF branding (`REPORT_API_URL` → `/api/ui-preferences` for brand name/logo).
### Image audit
diff --git a/docs/OPS.md b/docs/OPS.md
index ac3faf04..30c1e26c 100644
--- a/docs/OPS.md
+++ b/docs/OPS.md
@@ -259,16 +259,18 @@ docker compose -f docker-compose.pull.yml up # pre-built WEB_IMAGE
Do not run the application container in isolation with `docker run` unless you provide a reachable `DATABASE_URL` whose schema has already been migrated (e.g. `docker compose run migrator`).
-### Data service (report reads, typed config, PDF/Excel export)
+### CoreService (reports, data reads, exports, Google/Bing integrations)
-The `data` service (port **8091**) reads report payloads, portfolio, issue status, and typed config (pipeline settings, UI/client preferences) directly from Postgres, and renders audit PDFs, Excel workbooks, CSV/JSON, and sitemaps at `/v1/reports/*` (formerly a separate FileService, now `Data.Rendering`/`ReportExportController`).
+The `core` service (port **8094**) unifies report build and orchestration, direct Postgres reads (report payloads, portfolio, issue status, saved filters, typed config), Google/Bing integrations and OAuth, and audit PDF, Excel workbook, CSV/JSON, and sitemap rendering at `/v1/reports/*`.
| Variable | Service | Purpose |
|----------|---------|---------|
-| `DATA_SERVICE_URL` | `bff`, MCP | Where clients call the Data service (default `http://data:8091` in Compose) |
-| `REPORT_API_URL` | `data` | Branding/logo lookup base URL for PDF exports (Compose: `http://fastapi:8096`) |
+| `CORE_SERVICE_URL` | `bff`, `worker` | Where clients call the Core service (default `http://core:8094` in Compose) |
+| `DATA_SERVICE_URL` | `bff`, MCP | Aliased to `CORE_SERVICE_URL` for backward compatibility |
+| `REPORT_SERVICE_URL` | `bff`, `worker` | Aliased to `CORE_SERVICE_URL` for report build and orchestration |
+| `INTEGRATIONS_SERVICE_URL` | `bff`, `worker` | Aliased to `CORE_SERVICE_URL` for Google/Bing integrations |
-PDF or workbook downloads fail if `data` is not running.
+PDF or workbook downloads fail if `core` is not running.
---
diff --git a/docs/README.md b/docs/README.md
index c6c6d558..1daaa8d5 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -15,10 +15,8 @@ This directory contains product, integration, and operations documentation for *
| [COMPANY_STANDARDS.md](COMPANY_STANDARDS.md) | Agencies / operators | Data classification, crawl scope, security policy |
| [MCP.md](MCP.md) | Integrators | Model Context Protocol server configuration and tool reference |
| [OPS.md](OPS.md) | Operators | Scheduled audits, alerts, migrations, production notes |
-| [services/ReportService/README.md](../services/ReportService/README.md) | Developers | Report build + pipeline orchestration (port 8094) |
+| [services/CoreService/README.md](../services/CoreService/README.md) | Developers | Reports, data reads & exports, Google/Bing integrations (port 8094) |
| [services/AiService/README.md](../services/AiService/README.md) | Developers | AI chat, secrets, LLM settings, MCP, enrichment (port 8092) |
-| [services/IntegrationsService/README.md](../services/IntegrationsService/README.md) | Developers | Google/Bing OAuth, GSC/GA4 fetch, keywords (port 8093) |
-| `services/Data/` | Developers | .NET data service — report payloads, portfolio, issue status, saved filters, typed config, PDF/Excel/CSV/JSON/sitemap export (port 8091) |
---
@@ -29,10 +27,8 @@ All `/api/*` calls from the SPA go to the **BFF** (`:8090`). The BFF forwards su
| Upstream | Examples |
|----------|----------|
| **FastAPI** (`:8096`) | `/api/run`, `/api/jobs/*`, `/api/pipeline-config`, crawl, properties |
-| **ReportService** (`:8094`, internal) | Report build and full-audit orchestration (worker; not browser-facing) |
-| **IntegrationsService** (`:8093`) | `/api/integrations/google/*`, `/api/integrations/bing/*`, property Google config |
+| **CoreService** (`:8094`) | Report build & orchestration, data reads (portfolio, payload, issues), PDF/Excel exports, Google/Bing integrations |
| **AiService** (`:8092`) | `/api/chat`, `/api/secrets`, `/api/llm-settings`, MCP-related APIs |
-| **Data** (`:8091`) | Report payload reads, portfolio, issue status, saved filters, `/api/pipeline-settings`, `/api/ui-preferences`, `/api/client-preferences`, PDF/Excel export |
**Internal service-to-service:** ReportService reads Google/keyword snapshots from IntegrationsService (`GET /internal/integrations/report/enrichment`) during native report build — not via the BFF.
@@ -45,10 +41,8 @@ During local development (`./local-run`, `ASPNETCORE_ENVIRONMENT=Development`),
| Service | Port | Swagger UI |
| ------- | ---- | ---------- |
| BFF | 8090 | [http://localhost:8090/docs](http://localhost:8090/docs) |
-| Data | 8091 | [http://localhost:8091/docs](http://localhost:8091/docs) |
| AiService | 8092 | [http://localhost:8092/docs](http://localhost:8092/docs) |
-| IntegrationsService | 8093 | [http://localhost:8093/docs](http://localhost:8093/docs) |
-| ReportService | 8094 | [http://localhost:8094/docs](http://localhost:8094/docs) |
+| CoreService | 8094 | [http://localhost:8094/docs](http://localhost:8094/docs) |
| Python bridge | 8096 | [http://localhost:8096/docs](http://localhost:8096/docs) |
OpenAPI JSON for .NET services: `/swagger/v1/swagger.json`. See the main [README.md](../README.md#api-documentation-swagger) for details.
diff --git a/scripts/local-prod.sh b/scripts/local-prod.sh
index 218c5eaf..baceb60d 100755
--- a/scripts/local-prod.sh
+++ b/scripts/local-prod.sh
@@ -140,7 +140,7 @@ cmd_start() {
log "DATABASE_URL=$DATABASE_URL"
log "DATA_DIR=$DATA_DIR"
log "VITE_BFF_BASE_URL=$VITE_BFF_BASE_URL"
- log "INTEGRATIONS_SERVICE_URL=${INTEGRATIONS_SERVICE_URL:-http://127.0.0.1:8093}"
+ log "CORE_SERVICE_URL=${CORE_SERVICE_URL:-http://127.0.0.1:8094}"
cd "$ROOT"
export DATABASE_URL DATA_DIR PYTHON WEBSITE_PROFILING_ROOT PYTHONPATH NODE_ENV
export VITE_BFF_BASE_URL DEPRECATE_PYTHON_INTEGRATIONS USE_FASTAPI_PYTHON_BRIDGE
@@ -148,6 +148,9 @@ cmd_start() {
WORKER_PID=""
UVICORN_PID=""
NPM_PID=""
+ CORE_PID=""
+ AI_PID=""
+ BFF_PID=""
_CLEANUP_DONE=0
set +m
@@ -174,19 +177,19 @@ cmd_start() {
trap cleanup_prod EXIT INT TERM
start_host_dotnet_base "$ROOT" Production
- start_host_report_service "$ROOT" Production
- disown_bg "$DATA_PID"
+ disown_bg "$CORE_PID"
disown_bg "$AI_PID"
- disown_bg "$REPORT_PID"
+ export CORE_SERVICE_URL="${CORE_SERVICE_URL:-http://127.0.0.1:8094}"
export AI_SERVICE_URL="${AI_SERVICE_URL:-http://127.0.0.1:8092}"
- export INTEGRATIONS_SERVICE_URL="${INTEGRATIONS_SERVICE_URL:-http://127.0.0.1:8093}"
- export REPORT_SERVICE_URL="${REPORT_SERVICE_URL:-http://127.0.0.1:8094}"
+ export INTEGRATIONS_SERVICE_URL="${INTEGRATIONS_SERVICE_URL:-$CORE_SERVICE_URL}"
+ export REPORT_SERVICE_URL="${REPORT_SERVICE_URL:-$CORE_SERVICE_URL}"
+ export DATA_SERVICE_URL="${DATA_SERVICE_URL:-$CORE_SERVICE_URL}"
export PIPELINE_ORCHESTRATE_VIA_REPORT_SERVICE="${PIPELINE_ORCHESTRATE_VIA_REPORT_SERVICE:-1}"
export PYTHON="${PYTHON:-$ROOT/.venv/bin/python}"
export WEBSITE_PROFILING_ROOT="$ROOT"
- log "Pipeline jobs run in ReportService C# worker"
+ log "Pipeline jobs run in CoreService C# worker"
log "Starting Python bridge (audit-tool + keyword enrich CLI) on port 8096"
export FASTAPI_URL="http://127.0.0.1:8096"
export FASTAPI_ALLOWED_ORIGINS="http://localhost:8090"
@@ -197,7 +200,6 @@ cmd_start() {
wait_for_http "http://127.0.0.1:8096/api/health" "FastAPI" 90 || die "FastAPI failed to start"
start_host_integrations_bff "$ROOT" Production
- disown_bg "$INTEGRATIONS_PID"
disown_bg "$BFF_PID"
cd "$WEB"
diff --git a/scripts/local-run-common.sh b/scripts/local-run-common.sh
index 14797535..c68b6646 100644
--- a/scripts/local-run-common.sh
+++ b/scripts/local-run-common.sh
@@ -36,21 +36,29 @@ start_host_dotnet_base() {
local root="$1"
local mode="${2:-Development}"
- export REPORT_API_URL="${REPORT_API_URL:-http://127.0.0.1:8096}"
+ export CORE_SERVICE_URL="${CORE_SERVICE_URL:-http://127.0.0.1:8094}"
+ export REPORT_SERVICE_URL="${REPORT_SERVICE_URL:-$CORE_SERVICE_URL}"
+ export DATA_SERVICE_URL="${DATA_SERVICE_URL:-$CORE_SERVICE_URL}"
+ export INTEGRATIONS_SERVICE_URL="${INTEGRATIONS_SERVICE_URL:-$CORE_SERVICE_URL}"
export AI_SERVICE_URL="${AI_SERVICE_URL:-http://127.0.0.1:8092}"
- export INTEGRATIONS_SERVICE_URL="${INTEGRATIONS_SERVICE_URL:-http://127.0.0.1:8093}"
- export REPORT_SERVICE_URL="${REPORT_SERVICE_URL:-http://127.0.0.1:8094}"
- free_port 8091
- printf '\033[1;36m→\033[0m Starting Data service on port 8091\n'
- (cd "$root/services/Data" && \
+ free_port 8094
+ printf '\033[1;36m→\033[0m Starting CoreService on port 8094\n'
+ (cd "$root/services/CoreService" && \
DATABASE_URL="$DATABASE_URL" \
+ FASTAPI_URL="http://127.0.0.1:8096" \
+ AI_SERVICE_URL="$AI_SERVICE_URL" \
WEBSITE_PROFILING_ROOT="$root" \
- REPORT_API_URL="$REPORT_API_URL" \
- ASPNETCORE_URLS="http://127.0.0.1:8091" \
+ DATA_DIR="${DATA_DIR:-$root/data}" \
+ PYTHON="${PYTHON:-$root/.venv/bin/python}" \
+ REPORT_SERVICE_USE_PYTHON_BRIDGE="${REPORT_SERVICE_USE_PYTHON_BRIDGE:-0}" \
+ REPORT_SERVICE_VALIDATE_NATIVE="${REPORT_SERVICE_VALIDATE_NATIVE:-1}" \
+ REPORT_SERVICE_WORKER_ENABLED="${REPORT_SERVICE_WORKER_ENABLED:-1}" \
+ USE_FASTAPI_PYTHON_BRIDGE="${USE_FASTAPI_PYTHON_BRIDGE:-1}" \
+ ASPNETCORE_URLS="http://127.0.0.1:8094" \
ASPNETCORE_ENVIRONMENT="$mode" \
- dotnet run --project src/Data.Api --no-launch-profile) &
- DATA_PID=$!
+ dotnet run --project src/CoreService.Api --no-launch-profile) &
+ CORE_PID=$!
free_port 8092
printf '\033[1;36m→\033[0m Starting AiService on port 8092\n'
@@ -63,61 +71,26 @@ start_host_dotnet_base() {
dotnet run --project src/AiService.Api --no-launch-profile) &
AI_PID=$!
- wait_for_http "http://127.0.0.1:8091/health" "Data service"
+ wait_for_http "http://127.0.0.1:8094/health" "CoreService"
wait_for_http "http://127.0.0.1:8092/health" "AiService"
}
start_host_report_service() {
- local root="$1"
- local mode="${2:-Development}"
-
- free_port 8094
- printf '\033[1;36m→\033[0m Starting ReportService on port 8094\n'
- (cd "$root/services/ReportService" && \
- DATABASE_URL="$DATABASE_URL" \
- FASTAPI_URL="http://127.0.0.1:8096" \
- INTEGRATIONS_SERVICE_URL="$INTEGRATIONS_SERVICE_URL" \
- AISERVICE_URL="${AISERVICE_URL:-${AI_SERVICE_URL:-http://127.0.0.1:8092}}" \
- WEBSITE_PROFILING_ROOT="$root" \
- DATA_DIR="${DATA_DIR:-$root/data}" \
- PYTHON="${PYTHON:-$root/.venv/bin/python}" \
- REPORT_SERVICE_USE_PYTHON_BRIDGE="${REPORT_SERVICE_USE_PYTHON_BRIDGE:-0}" \
- REPORT_SERVICE_VALIDATE_NATIVE="${REPORT_SERVICE_VALIDATE_NATIVE:-1}" \
- REPORT_SERVICE_WORKER_ENABLED="${REPORT_SERVICE_WORKER_ENABLED:-1}" \
- ASPNETCORE_URLS="http://127.0.0.1:8094" \
- ASPNETCORE_ENVIRONMENT="$mode" \
- dotnet run --project src/ReportService.Api --no-launch-profile) &
- REPORT_PID=$!
- wait_for_http "http://127.0.0.1:8094/health" "ReportService"
+ : # No-op: absorbed into start_host_dotnet_base (CoreService on port 8094)
}
start_host_integrations_bff() {
local root="$1"
local mode="${2:-Development}"
- free_port 8093
- printf '\033[1;36m→\033[0m Starting IntegrationsService on port 8093\n'
- (cd "$root/services/IntegrationsService" && \
- DATABASE_URL="$DATABASE_URL" \
- FASTAPI_URL="http://127.0.0.1:8096" \
- USE_FASTAPI_PYTHON_BRIDGE="${USE_FASTAPI_PYTHON_BRIDGE:-1}" \
- ASPNETCORE_URLS="http://127.0.0.1:8093" \
- ASPNETCORE_ENVIRONMENT="$mode" \
- AUTH_SECRET="${AUTH_SECRET:-}" \
- SESSION_SECRET="${SESSION_SECRET:-}" \
- GOOGLE_REDIRECT_URI="${GOOGLE_REDIRECT_URI:-http://localhost:8090/api/integrations/google/callback}" \
- APP_PUBLIC_URL="${APP_PUBLIC_URL:-http://localhost:3000}" \
- dotnet run --project src/IntegrationsService.Api --no-launch-profile) &
- INTEGRATIONS_PID=$!
- wait_for_http "http://127.0.0.1:8093/health" "IntegrationsService"
-
free_port 8090
printf '\033[1;36m→\033[0m Starting BFF on port 8090\n'
(cd "$root/services/Bff" && \
FASTAPI_URL="http://127.0.0.1:8096" \
- DATA_SERVICE_URL="http://127.0.0.1:8091" \
+ CORE_SERVICE_URL="${CORE_SERVICE_URL:-http://127.0.0.1:8094}" \
+ DATA_SERVICE_URL="${DATA_SERVICE_URL:-http://127.0.0.1:8094}" \
AI_SERVICE_URL="$AI_SERVICE_URL" \
- INTEGRATIONS_SERVICE_URL="$INTEGRATIONS_SERVICE_URL" \
+ INTEGRATIONS_SERVICE_URL="${INTEGRATIONS_SERVICE_URL:-http://127.0.0.1:8094}" \
REPORT_SERVICE_URL="${REPORT_SERVICE_URL:-http://127.0.0.1:8094}" \
REPORT_ROUTES="${REPORT_ROUTES:-/api/compare,/api/dashboards,/api/run,/api/jobs,/api/schedule,/api/crawl,/api/pipeline-preview}" \
DATA_ROUTES="${DATA_ROUTES:-/api/report/meta,/api/report/payload,/api/report/history,/api/report/crawl-payload,/api/report/mobile-delta,/api/report/portfolio,/api/portfolio,/api/issues/status,/api/filters,/api/properties,/api/content-drafts,/api/content/score,/api/keywords,/api/page-markdown,/api/alerts,/api/logs,/api/backlinks,/api/pipeline-settings,/api/ui-preferences,/api/client-preferences}" \
@@ -139,7 +112,6 @@ start_host_dotnet_stack() {
local root="$1"
local mode="${2:-Development}"
start_host_dotnet_base "$root" "$mode"
- start_host_report_service "$root" "$mode"
start_host_integrations_bff "$root" "$mode"
}
@@ -147,12 +119,8 @@ stop_host_dotnet_stack() {
local stop_service_fn="$1"
"$stop_service_fn" "BFF" "${BFF_PID:-}" 8090
BFF_PID=""
- "$stop_service_fn" "IntegrationsService" "${INTEGRATIONS_PID:-}" 8093
- INTEGRATIONS_PID=""
- "$stop_service_fn" "ReportService" "${REPORT_PID:-}" 8094
- REPORT_PID=""
+ "$stop_service_fn" "CoreService" "${CORE_PID:-}" 8094
+ CORE_PID=""
"$stop_service_fn" "AiService" "${AI_PID:-}" 8092
AI_PID=""
- "$stop_service_fn" "Data" "${DATA_PID:-}" 8091
- DATA_PID=""
}
diff --git a/scripts/local-run.sh b/scripts/local-run.sh
index c65631a8..f50028c4 100755
--- a/scripts/local-run.sh
+++ b/scripts/local-run.sh
@@ -177,10 +177,9 @@ cmd_start() {
WORKER_PID=""
UVICORN_PID=""
- DATA_PID=""
+ CORE_PID=""
AI_PID=""
BFF_PID=""
- INTEGRATIONS_PID=""
_CLEANUP_DONE=0
set +m
@@ -209,25 +208,23 @@ cmd_start() {
if command -v dotnet >/dev/null 2>&1; then
start_host_dotnet_base "$ROOT" Development
- start_host_report_service "$ROOT" Development
- disown_bg "$DATA_PID"
+ disown_bg "$CORE_PID"
disown_bg "$AI_PID"
- disown_bg "$REPORT_PID"
else
- warn "dotnet not found — Data service (PDF export, typed config) unavailable on port 8091"
+ warn "dotnet not found — CoreService unavailable on port 8094"
warn "dotnet not found — AiService unavailable on port 8092"
- warn "dotnet not found — ReportService unavailable on port 8094"
- warn "dotnet not found — IntegrationsService unavailable on port 8093"
fi
+ export CORE_SERVICE_URL="${CORE_SERVICE_URL:-http://127.0.0.1:8094}"
export AI_SERVICE_URL="${AI_SERVICE_URL:-http://127.0.0.1:8092}"
- export INTEGRATIONS_SERVICE_URL="${INTEGRATIONS_SERVICE_URL:-http://127.0.0.1:8093}"
- export REPORT_SERVICE_URL="${REPORT_SERVICE_URL:-http://127.0.0.1:8094}"
+ export INTEGRATIONS_SERVICE_URL="${INTEGRATIONS_SERVICE_URL:-$CORE_SERVICE_URL}"
+ export REPORT_SERVICE_URL="${REPORT_SERVICE_URL:-$CORE_SERVICE_URL}"
+ export DATA_SERVICE_URL="${DATA_SERVICE_URL:-$CORE_SERVICE_URL}"
export PIPELINE_ORCHESTRATE_VIA_REPORT_SERVICE="${PIPELINE_ORCHESTRATE_VIA_REPORT_SERVICE:-1}"
export PYTHON="${PYTHON:-$VENV/bin/python}"
export WEBSITE_PROFILING_ROOT="$ROOT"
- log "Pipeline jobs run in ReportService C# worker (Python subprocess for crawl/lighthouse only)"
+ log "Pipeline jobs run in CoreService C# worker (Python subprocess for crawl/lighthouse only)"
log "Starting Python bridge (audit-tool + keyword enrich CLI only) on port 8096"
export FASTAPI_URL="http://127.0.0.1:8096"
export FASTAPI_ALLOWED_ORIGINS="http://localhost:8090"
@@ -241,7 +238,6 @@ cmd_start() {
if command -v dotnet >/dev/null 2>&1; then
start_host_integrations_bff "$ROOT" Development
- disown_bg "$INTEGRATIONS_PID"
disown_bg "$BFF_PID"
else
warn "dotnet not found — browser API calls need the BFF (see services/Bff/)"
diff --git a/scripts/local-test.sh b/scripts/local-test.sh
index 1bd80a19..c737aca6 100755
--- a/scripts/local-test.sh
+++ b/scripts/local-test.sh
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# Local test runner — mirrors .github/workflows/ci.yml on your machine.
# Usage: ./local-test [command] [--no-cov]
-# (default) all — Postgres + migrations + Python + web + .NET (Data, Bff)
+# (default) all — Postgres + migrations + Python + web + .NET (CoreService, AiService, Bff)
# python — DB + pytest + CLI smoke only
# web — build, typecheck, lint, vitest (no Postgres)
# dotnet — dotnet test services/WebsiteProfiling.slnx + Bff OpenAPI drift gate
@@ -242,7 +242,7 @@ run_bff_openapi_drift_gate() {
return 2
fi
(cd "$ROOT/services/Bff" && nswag run nswag.json) || return 1
- git diff --exit-code services/Bff/src/Bff.Application/Generated/FastApiClient.g.cs
+ git diff --exit-code services/Bff/src/Bff.Api/Application/Generated/FastApiClient.g.cs
}
run_step_or_skip_browser() {
diff --git a/services/AiService/CHAT_DOTNET_MIGRATION.md b/services/AiService/CHAT_DOTNET_MIGRATION.md
index 74256f0d..ff2a4d9c 100644
--- a/services/AiService/CHAT_DOTNET_MIGRATION.md
+++ b/services/AiService/CHAT_DOTNET_MIGRATION.md
@@ -86,12 +86,12 @@ out not to exist in the real tool-metadata taxonomy — those 2 tools are actual
**Finding**: the Python `/api/chat/artifacts/{id}` FastAPI route this used to proxy to doesn't
exist anywhere in the current codebase (`read_artifact_bytes` had zero callers) — the old proxy
was already dead. This port fixes the feature rather than just relocating it.
-- `export_audit_report`'s PDF/CSV/JSON paths call the .NET **Data service**'s existing
- `v1/reports/{id}/{pdf,csv,json}` endpoints (`services/Data/src/Data.Api/Controllers/ReportExportController.cs`)
- via a new `DataServiceClient` (`services/AiService/src/AiService.Tools/Bridge/DataServiceClient.cs`,
- env `DATA_SERVICE_URL`) — reuses the Data service's canonical export implementation rather than
+- `export_audit_report`'s PDF/CSV/JSON paths call .NET **CoreService**'s existing
+ `v1/reports/{id}/{pdf,csv,json}` endpoints (`services/CoreService/src/CoreService.Api/Controllers/ReportExportController.cs`)
+ via a new `DataServiceClient` (`services/AiService/src/AiService.Api/Tools/Bridge/DataServiceClient.cs`,
+ env `CORE_SERVICE_URL` / `DATA_SERVICE_URL`) — reuses CoreService's canonical export implementation rather than
re-porting Python's bespoke CSV column layout (`export_audit.py`/`export_audit_data.py` were NOT
- ported; Data service's version is now the one true implementation).
+ ported; CoreService's version is now the one true implementation).
- `export_list_as_csv` recursively calls back into `ToolDispatcher.DispatchAsync` (its own allowlisted
target tool may be native or still Python-bridged — dispatch handles both transparently). Verified
no circular-DI issue: `ToolDispatcher`/`DataServiceClient` are resolved *lazily inside* the
diff --git a/services/AiService/Dockerfile b/services/AiService/Dockerfile
index 06e96b07..9b3b52d6 100644
--- a/services/AiService/Dockerfile
+++ b/services/AiService/Dockerfile
@@ -1,20 +1,9 @@
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
-COPY Shared/WebsiteProfiling.Hosting/WebsiteProfiling.Hosting.csproj Shared/WebsiteProfiling.Hosting/
-COPY Shared/WebsiteProfiling.Contracts/WebsiteProfiling.Contracts.csproj Shared/WebsiteProfiling.Contracts/
-COPY Shared/WebsiteProfiling.Data/WebsiteProfiling.Data.csproj Shared/WebsiteProfiling.Data/
-COPY Shared/WebsiteProfiling.Data.EntityFrameworkCore/WebsiteProfiling.Data.EntityFrameworkCore.csproj Shared/WebsiteProfiling.Data.EntityFrameworkCore/
-COPY AiService/src/AiService.Domain/AiService.Domain.csproj AiService/src/AiService.Domain/
-COPY AiService/src/AiService.Providers/AiService.Providers.csproj AiService/src/AiService.Providers/
-COPY AiService/src/AiService.Tools/AiService.Tools.csproj AiService/src/AiService.Tools/
-COPY AiService/src/AiService.Application/AiService.Application.csproj AiService/src/AiService.Application/
-COPY AiService/src/AiService.Mcp/AiService.Mcp.csproj AiService/src/AiService.Mcp/
+COPY Shared/WebsiteProfiling.Shared/WebsiteProfiling.Shared.csproj Shared/WebsiteProfiling.Shared/
COPY AiService/src/AiService.Api/AiService.Api.csproj AiService/src/AiService.Api/
RUN dotnet restore AiService/src/AiService.Api/AiService.Api.csproj
-COPY Shared/WebsiteProfiling.Hosting/ Shared/WebsiteProfiling.Hosting/
-COPY Shared/WebsiteProfiling.Contracts/ Shared/WebsiteProfiling.Contracts/
-COPY Shared/WebsiteProfiling.Data/ Shared/WebsiteProfiling.Data/
-COPY Shared/WebsiteProfiling.Data.EntityFrameworkCore/ Shared/WebsiteProfiling.Data.EntityFrameworkCore/
+COPY Shared/WebsiteProfiling.Shared/ Shared/WebsiteProfiling.Shared/
COPY AiService/src/ AiService/src/
RUN dotnet publish AiService/src/AiService.Api/AiService.Api.csproj -c Release -o /app/publish --no-restore
diff --git a/services/AiService/README.md b/services/AiService/README.md
index 15266b9f..59e1eb05 100644
--- a/services/AiService/README.md
+++ b/services/AiService/README.md
@@ -81,12 +81,8 @@ Python worker → POST /internal/enrichment/* and ai_service_client → AiServic
| Project | Role |
|---------|------|
-| `AiService.Api` | HTTP controllers (paths match former FastAPI routes) |
-| `AiService.Application` | Services, repos, chat agent, enrichment, secrets |
-| `AiService.Providers` | `IChatClientFactory`, structured JSON completions |
-| `AiService.Tools` | Audit tool catalog, dispatch, payload slices |
-| `AiService.Mcp` | Model Context Protocol server |
-| `AiService.Domain` | Entities and repository interfaces |
+| `AiService.Api` | Web host, controllers, services, LLM providers, 369-tool catalog, MCP server |
+| `AiService.Tests` | Comprehensive test suite (chat, providers, secrets, tools) |
## OpenAPI
diff --git a/services/AiService/src/AiService.Api/AiService.Api.csproj b/services/AiService/src/AiService.Api/AiService.Api.csproj
index afbb0cfb..8b0ccfc9 100644
--- a/services/AiService/src/AiService.Api/AiService.Api.csproj
+++ b/services/AiService/src/AiService.Api/AiService.Api.csproj
@@ -7,10 +7,26 @@
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
diff --git a/services/AiService/src/AiService.Api/AiServiceHostRegistration.cs b/services/AiService/src/AiService.Api/AiServiceHostRegistration.cs
index fcd0cdab..8f776466 100644
--- a/services/AiService/src/AiService.Api/AiServiceHostRegistration.cs
+++ b/services/AiService/src/AiService.Api/AiServiceHostRegistration.cs
@@ -1,5 +1,5 @@
-using AiService.Application;
-using AiService.Mcp;
+using AiService.Api.Application;
+using AiService.Api.Mcp;
using Microsoft.Extensions.DependencyInjection;
namespace AiService.Api;
diff --git a/services/AiService/src/AiService.Application/Chat/AuditChatToolsBuilder.cs b/services/AiService/src/AiService.Api/Application/Chat/AuditChatToolsBuilder.cs
similarity index 93%
rename from services/AiService/src/AiService.Application/Chat/AuditChatToolsBuilder.cs
rename to services/AiService/src/AiService.Api/Application/Chat/AuditChatToolsBuilder.cs
index 7e73f1e3..a94e9c15 100644
--- a/services/AiService/src/AiService.Application/Chat/AuditChatToolsBuilder.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/AuditChatToolsBuilder.cs
@@ -1,9 +1,9 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Registry;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Registry;
using Microsoft.Extensions.AI;
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
/// Builds MEAI tools from the audit catalog for a chat turn.
public sealed class AuditChatToolsBuilder(ToolCatalog toolCatalog, ToolDispatcher toolDispatcher)
diff --git a/services/AiService/src/AiService.Application/Chat/ChatAgentConfig.cs b/services/AiService/src/AiService.Api/Application/Chat/ChatAgentConfig.cs
similarity index 95%
rename from services/AiService/src/AiService.Application/Chat/ChatAgentConfig.cs
rename to services/AiService/src/AiService.Api/Application/Chat/ChatAgentConfig.cs
index 17e65cd3..30d23fa7 100644
--- a/services/AiService/src/AiService.Application/Chat/ChatAgentConfig.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/ChatAgentConfig.cs
@@ -1,9 +1,9 @@
-using AiService.Application.Prompts;
-using AiService.Domain;
-using AiService.Domain.Models;
-using AiService.Providers.Chat;
+using AiService.Api.Application.Prompts;
+using AiService.Api.Domain;
+using AiService.Api.Domain.Models;
+using AiService.Api.Providers.Chat;
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
/// Chat agent constants and config resolution ported from Python llm/agent.py.
public static class ChatAgentConfig
diff --git a/services/AiService/src/AiService.Application/Chat/ChatAgentLoop.cs b/services/AiService/src/AiService.Api/Application/Chat/ChatAgentLoop.cs
similarity index 97%
rename from services/AiService/src/AiService.Application/Chat/ChatAgentLoop.cs
rename to services/AiService/src/AiService.Api/Application/Chat/ChatAgentLoop.cs
index 6aea0784..05ea1035 100644
--- a/services/AiService/src/AiService.Application/Chat/ChatAgentLoop.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/ChatAgentLoop.cs
@@ -1,11 +1,11 @@
using System.Text.Json.Nodes;
-using AiService.Domain.Models;
-using AiService.Tools.Context;
-using AiService.Tools.Registry;
-using AiService.Tools.Selection;
+using AiService.Api.Domain.Models;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Registry;
+using AiService.Api.Tools.Selection;
using Microsoft.Extensions.AI;
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
///
/// Manual multi-round tool loop (ports Python run_agent_turn inner loop) with parallel
diff --git a/services/AiService/src/AiService.Application/Chat/ChatModels.cs b/services/AiService/src/AiService.Api/Application/Chat/ChatModels.cs
similarity index 97%
rename from services/AiService/src/AiService.Application/Chat/ChatModels.cs
rename to services/AiService/src/AiService.Api/Application/Chat/ChatModels.cs
index c265f5c3..bfe87f25 100644
--- a/services/AiService/src/AiService.Application/Chat/ChatModels.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/ChatModels.cs
@@ -1,4 +1,4 @@
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
public sealed record ChatMessageRecord(string Role, string Content);
diff --git a/services/AiService/src/AiService.Application/Chat/ChatNarrativeFallback.cs b/services/AiService/src/AiService.Api/Application/Chat/ChatNarrativeFallback.cs
similarity index 99%
rename from services/AiService/src/AiService.Application/Chat/ChatNarrativeFallback.cs
rename to services/AiService/src/AiService.Api/Application/Chat/ChatNarrativeFallback.cs
index 706bc0cb..6a5bfc9a 100644
--- a/services/AiService/src/AiService.Application/Chat/ChatNarrativeFallback.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/ChatNarrativeFallback.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
///
/// Builds a user-facing narrative from tool results when LLM synthesis fails.
diff --git a/services/AiService/src/AiService.Application/Chat/ChatNarrativeParser.cs b/services/AiService/src/AiService.Api/Application/Chat/ChatNarrativeParser.cs
similarity index 98%
rename from services/AiService/src/AiService.Application/Chat/ChatNarrativeParser.cs
rename to services/AiService/src/AiService.Api/Application/Chat/ChatNarrativeParser.cs
index dc550729..fc15a61e 100644
--- a/services/AiService/src/AiService.Application/Chat/ChatNarrativeParser.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/ChatNarrativeParser.cs
@@ -1,10 +1,10 @@
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Providers.Chat;
+using AiService.Api.Providers.Chat;
using WebsiteProfiling.Contracts.Chat;
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
/// Parse and validate chat narrative JSON from LLM output.
public static class ChatNarrativeParser
diff --git a/services/AiService/src/AiService.Application/Chat/ChatNarrativeSynthesizer.cs b/services/AiService/src/AiService.Api/Application/Chat/ChatNarrativeSynthesizer.cs
similarity index 96%
rename from services/AiService/src/AiService.Application/Chat/ChatNarrativeSynthesizer.cs
rename to services/AiService/src/AiService.Api/Application/Chat/ChatNarrativeSynthesizer.cs
index a1f29c14..300be40b 100644
--- a/services/AiService/src/AiService.Application/Chat/ChatNarrativeSynthesizer.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/ChatNarrativeSynthesizer.cs
@@ -1,10 +1,10 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Application.Prompts;
-using AiService.Domain.Models;
-using AiService.Providers.Chat;
+using AiService.Api.Application.Prompts;
+using AiService.Api.Domain.Models;
+using AiService.Api.Providers.Chat;
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
public sealed class ChatNarrativeSynthesizer(StructuredCompletionService completionService)
{
diff --git a/services/AiService/src/AiService.Application/Chat/ChatPersistenceMapper.cs b/services/AiService/src/AiService.Api/Application/Chat/ChatPersistenceMapper.cs
similarity index 97%
rename from services/AiService/src/AiService.Application/Chat/ChatPersistenceMapper.cs
rename to services/AiService/src/AiService.Api/Application/Chat/ChatPersistenceMapper.cs
index 3e976874..e913d571 100644
--- a/services/AiService/src/AiService.Application/Chat/ChatPersistenceMapper.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/ChatPersistenceMapper.cs
@@ -3,7 +3,7 @@
using WebsiteProfiling.Contracts.Chat;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
/// Maps a completed chat turn to the JSON stored in chat_messages.tool_result.
public static class ChatPersistenceMapper
diff --git a/services/AiService/src/AiService.Application/Chat/ChatSseSerializer.cs b/services/AiService/src/AiService.Api/Application/Chat/ChatSseSerializer.cs
similarity index 98%
rename from services/AiService/src/AiService.Application/Chat/ChatSseSerializer.cs
rename to services/AiService/src/AiService.Api/Application/Chat/ChatSseSerializer.cs
index 4476db2c..d6dac831 100644
--- a/services/AiService/src/AiService.Application/Chat/ChatSseSerializer.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/ChatSseSerializer.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
/// Maps typed chat events to wire-format JSON at the HTTP boundary only.
public static class ChatSseSerializer
diff --git a/services/AiService/src/AiService.Application/Chat/ChatStreamPersistence.cs b/services/AiService/src/AiService.Api/Application/Chat/ChatStreamPersistence.cs
similarity index 89%
rename from services/AiService/src/AiService.Application/Chat/ChatStreamPersistence.cs
rename to services/AiService/src/AiService.Api/Application/Chat/ChatStreamPersistence.cs
index 194ceeae..348507b3 100644
--- a/services/AiService/src/AiService.Application/Chat/ChatStreamPersistence.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/ChatStreamPersistence.cs
@@ -1,4 +1,4 @@
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
/// Post-SSE chat persistence guards (testable without HTTP/SSE wiring).
public static class ChatStreamPersistence
diff --git a/services/AiService/src/AiService.Application/Chat/ChatTextSanitize.cs b/services/AiService/src/AiService.Api/Application/Chat/ChatTextSanitize.cs
similarity index 96%
rename from services/AiService/src/AiService.Application/Chat/ChatTextSanitize.cs
rename to services/AiService/src/AiService.Api/Application/Chat/ChatTextSanitize.cs
index d81ffe0f..d34506e1 100644
--- a/services/AiService/src/AiService.Application/Chat/ChatTextSanitize.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/ChatTextSanitize.cs
@@ -1,6 +1,6 @@
using System.Text;
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
/// Unicode sanitization for chat messages (ports Python text_sanitize.strip_surrogates).
public static class ChatTextSanitize
diff --git a/services/AiService/src/AiService.Application/Chat/ChatTurnProgress.cs b/services/AiService/src/AiService.Api/Application/Chat/ChatTurnProgress.cs
similarity index 97%
rename from services/AiService/src/AiService.Application/Chat/ChatTurnProgress.cs
rename to services/AiService/src/AiService.Api/Application/Chat/ChatTurnProgress.cs
index b93bf55d..67eb8fdf 100644
--- a/services/AiService/src/AiService.Application/Chat/ChatTurnProgress.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/ChatTurnProgress.cs
@@ -1,10 +1,10 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Registry;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Registry;
using Microsoft.Extensions.AI;
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
/// Collects tool invocations and emits typed SSE events for a single chat turn.
public sealed class ChatTurnProgress(Action? emit)
diff --git a/services/AiService/src/AiService.Application/Chat/JsonScalar.cs b/services/AiService/src/AiService.Api/Application/Chat/JsonScalar.cs
similarity index 92%
rename from services/AiService/src/AiService.Application/Chat/JsonScalar.cs
rename to services/AiService/src/AiService.Api/Application/Chat/JsonScalar.cs
index fcdeb10c..00fa61f6 100644
--- a/services/AiService/src/AiService.Application/Chat/JsonScalar.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/JsonScalar.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Nodes;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
///
/// Safe scalar extraction from values. Delegates to
diff --git a/services/AiService/src/AiService.Application/Chat/StreamingNarrativeExtractor.cs b/services/AiService/src/AiService.Api/Application/Chat/StreamingNarrativeExtractor.cs
similarity index 96%
rename from services/AiService/src/AiService.Application/Chat/StreamingNarrativeExtractor.cs
rename to services/AiService/src/AiService.Api/Application/Chat/StreamingNarrativeExtractor.cs
index 06df330c..ca121442 100644
--- a/services/AiService/src/AiService.Application/Chat/StreamingNarrativeExtractor.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/StreamingNarrativeExtractor.cs
@@ -1,6 +1,6 @@
using System.Text;
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
/// Extracts incremental narrative bullets from a streaming JSON buffer.
public sealed class StreamingNarrativeExtractor
diff --git a/services/AiService/src/AiService.Application/Chat/ToolConcurrency.cs b/services/AiService/src/AiService.Api/Application/Chat/ToolConcurrency.cs
similarity index 97%
rename from services/AiService/src/AiService.Application/Chat/ToolConcurrency.cs
rename to services/AiService/src/AiService.Api/Application/Chat/ToolConcurrency.cs
index 819ca34b..c1d92a85 100644
--- a/services/AiService/src/AiService.Application/Chat/ToolConcurrency.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/ToolConcurrency.cs
@@ -1,4 +1,4 @@
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
///
/// Bounded parallel tool dispatch (ports Python website_profiling.concurrency.tool_concurrency).
diff --git a/services/AiService/src/AiService.Application/Chat/ToolResultCompactor.cs b/services/AiService/src/AiService.Api/Application/Chat/ToolResultCompactor.cs
similarity index 99%
rename from services/AiService/src/AiService.Application/Chat/ToolResultCompactor.cs
rename to services/AiService/src/AiService.Api/Application/Chat/ToolResultCompactor.cs
index 1e8f08f3..d2419bd6 100644
--- a/services/AiService/src/AiService.Application/Chat/ToolResultCompactor.cs
+++ b/services/AiService/src/AiService.Api/Application/Chat/ToolResultCompactor.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Slice;
-namespace AiService.Application.Chat;
+namespace AiService.Api.Application.Chat;
///
/// Produces compact tool result JSON for LLM follow-up rounds and UI-sized slices for SSE.
diff --git a/services/AiService/src/AiService.Application/DependencyInjection.cs b/services/AiService/src/AiService.Api/Application/DependencyInjection.cs
similarity index 85%
rename from services/AiService/src/AiService.Application/DependencyInjection.cs
rename to services/AiService/src/AiService.Api/Application/DependencyInjection.cs
index 1bbc3c30..fa3a0f68 100644
--- a/services/AiService/src/AiService.Application/DependencyInjection.cs
+++ b/services/AiService/src/AiService.Api/Application/DependencyInjection.cs
@@ -1,17 +1,15 @@
-using AiService.Application.Chat;
-using AiService.Application.Options;
-using AiService.Application.Persistence;
-using AiService.Application.Repositories;
-using AiService.Application.Services;
-using AiService.Domain.Repositories;
-using AiService.Providers;
-using AiService.Tools;
-using AiService.Tools.Registry;
-using Microsoft.Extensions.DependencyInjection;
+using AiService.Api.Application.Chat;
+using AiService.Api.Application.Options;
+using AiService.Api.Application.Persistence;
+using AiService.Api.Application.Repositories;
+using AiService.Api.Application.Services;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Providers;
+using AiService.Api.Tools;
+using AiService.Api.Tools.Registry;
using WebsiteProfiling.Data;
-using WebsiteProfiling.Data.EntityFrameworkCore;
-namespace AiService.Application;
+namespace AiService.Api.Application;
public static class DependencyInjection
{
diff --git a/services/AiService/src/AiService.Application/Dto/ChatDtos.cs b/services/AiService/src/AiService.Api/Application/Dto/ChatDtos.cs
similarity index 88%
rename from services/AiService/src/AiService.Application/Dto/ChatDtos.cs
rename to services/AiService/src/AiService.Api/Application/Dto/ChatDtos.cs
index bd38d74a..d97b3384 100644
--- a/services/AiService/src/AiService.Application/Dto/ChatDtos.cs
+++ b/services/AiService/src/AiService.Api/Application/Dto/ChatDtos.cs
@@ -1,4 +1,4 @@
-namespace AiService.Application.Dto;
+namespace AiService.Api.Application.Dto;
public sealed class ChatRequest
{
diff --git a/services/AiService/src/AiService.Application/Dto/JsonRefreshExtensions.cs b/services/AiService/src/AiService.Api/Application/Dto/JsonRefreshExtensions.cs
similarity index 82%
rename from services/AiService/src/AiService.Application/Dto/JsonRefreshExtensions.cs
rename to services/AiService/src/AiService.Api/Application/Dto/JsonRefreshExtensions.cs
index 49fde951..9c2d03e1 100644
--- a/services/AiService/src/AiService.Application/Dto/JsonRefreshExtensions.cs
+++ b/services/AiService/src/AiService.Api/Application/Dto/JsonRefreshExtensions.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-namespace AiService.Application.Dto;
+namespace AiService.Api.Application.Dto;
public static class JsonRefreshExtensions
{
diff --git a/services/AiService/src/AiService.Application/Dto/RefreshRequestBody.cs b/services/AiService/src/AiService.Api/Application/Dto/RefreshRequestBody.cs
similarity index 79%
rename from services/AiService/src/AiService.Application/Dto/RefreshRequestBody.cs
rename to services/AiService/src/AiService.Api/Application/Dto/RefreshRequestBody.cs
index 21cb476d..d26ef1ed 100644
--- a/services/AiService/src/AiService.Application/Dto/RefreshRequestBody.cs
+++ b/services/AiService/src/AiService.Api/Application/Dto/RefreshRequestBody.cs
@@ -1,4 +1,4 @@
-namespace AiService.Application.Dto;
+namespace AiService.Api.Application.Dto;
/// Shared refresh flag for enrichment/issue endpoints.
public sealed class RefreshRequestBody
diff --git a/services/AiService/src/AiService.Application/Handlers/LlmToolHandlers.cs b/services/AiService/src/AiService.Api/Application/Handlers/LlmToolHandlers.cs
similarity index 96%
rename from services/AiService/src/AiService.Application/Handlers/LlmToolHandlers.cs
rename to services/AiService/src/AiService.Api/Application/Handlers/LlmToolHandlers.cs
index 0454d148..3e880982 100644
--- a/services/AiService/src/AiService.Application/Handlers/LlmToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Application/Handlers/LlmToolHandlers.cs
@@ -1,21 +1,19 @@
using System.Text.Json.Nodes;
-using AiService.Application.Services;
-using AiService.Application.Repositories;
-using AiService.Domain.Repositories;
-using AiService.Providers.Chat;
-using AiService.Tools.Context;
-using AiService.Tools.Handlers.Geo;
-using AiService.Tools.Handlers.Insight;
-using AiService.Tools.Handlers.Issues;
-using AiService.Tools.Handlers.Report;
-using AiService.Tools.Handlers.Core;
-using AiService.Tools.Registry;
-using AiService.Tools.Slice;
-using Microsoft.Extensions.DependencyInjection;
+using AiService.Api.Application.Services;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Providers.Chat;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Handlers.Core;
+using AiService.Api.Tools.Handlers.Geo;
+using AiService.Api.Tools.Handlers.Insight;
+using AiService.Api.Tools.Handlers.Issues;
+using AiService.Api.Tools.Handlers.Report;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Registry;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Json;
-using AiService.Tools.Persistence;
-namespace AiService.Application.Handlers;
+namespace AiService.Api.Application.Handlers;
/// LLM-powered audit tools — ports Python integrations/llm_tools.py.
public static class LlmToolHandlers
diff --git a/services/AiService/src/AiService.Application/Json/JsonNodeCopy.cs b/services/AiService/src/AiService.Api/Application/Json/JsonNodeCopy.cs
similarity index 92%
rename from services/AiService/src/AiService.Application/Json/JsonNodeCopy.cs
rename to services/AiService/src/AiService.Api/Application/Json/JsonNodeCopy.cs
index 2325775c..d1147112 100644
--- a/services/AiService/src/AiService.Application/Json/JsonNodeCopy.cs
+++ b/services/AiService/src/AiService.Api/Application/Json/JsonNodeCopy.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-namespace AiService.Application.Json;
+namespace AiService.Api.Application.Json;
///
/// Safe JsonNode patterns — each JsonNode has a single parent; copy at boundaries.
diff --git a/services/AiService/src/AiService.Application/Mcp/McpAuthCacheKeys.cs b/services/AiService/src/AiService.Api/Application/Mcp/McpAuthCacheKeys.cs
similarity index 83%
rename from services/AiService/src/AiService.Application/Mcp/McpAuthCacheKeys.cs
rename to services/AiService/src/AiService.Api/Application/Mcp/McpAuthCacheKeys.cs
index 3860f64e..3f795340 100644
--- a/services/AiService/src/AiService.Application/Mcp/McpAuthCacheKeys.cs
+++ b/services/AiService/src/AiService.Api/Application/Mcp/McpAuthCacheKeys.cs
@@ -1,4 +1,4 @@
-namespace AiService.Application.Mcp;
+namespace AiService.Api.Application.Mcp;
/// Shared IMemoryCache keys for MCP HTTP auth (see AiService.Mcp.McpBearerAuthFilter).
public static class McpAuthCacheKeys
diff --git a/services/AiService/src/AiService.Application/Options/UpstreamOptions.cs b/services/AiService/src/AiService.Api/Application/Options/UpstreamOptions.cs
similarity index 84%
rename from services/AiService/src/AiService.Application/Options/UpstreamOptions.cs
rename to services/AiService/src/AiService.Api/Application/Options/UpstreamOptions.cs
index ffda71da..ed842c45 100644
--- a/services/AiService/src/AiService.Application/Options/UpstreamOptions.cs
+++ b/services/AiService/src/AiService.Api/Application/Options/UpstreamOptions.cs
@@ -1,4 +1,4 @@
-namespace AiService.Application.Options;
+namespace AiService.Api.Application.Options;
/// Upstream FastAPI bridge for Python audit tools (FASTAPI_URL).
public sealed class UpstreamOptions
diff --git a/services/AiService/src/AiService.Application/Persistence/AiDbContext.cs b/services/AiService/src/AiService.Api/Application/Persistence/AiDbContext.cs
similarity index 99%
rename from services/AiService/src/AiService.Application/Persistence/AiDbContext.cs
rename to services/AiService/src/AiService.Api/Application/Persistence/AiDbContext.cs
index 2c3f0377..f2c8e472 100644
--- a/services/AiService/src/AiService.Application/Persistence/AiDbContext.cs
+++ b/services/AiService/src/AiService.Api/Application/Persistence/AiDbContext.cs
@@ -1,7 +1,7 @@
-using AiService.Domain.Entities;
+using AiService.Api.Domain.Entities;
using Microsoft.EntityFrameworkCore;
-namespace AiService.Application.Persistence;
+namespace AiService.Api.Application.Persistence;
///
/// EF Core context over the schema owned by services/Schema. Never calls Migrate() or EnsureCreated().
diff --git a/services/AiService/src/AiService.Application/Prompts/Prompts.cs b/services/AiService/src/AiService.Api/Application/Prompts/Prompts.cs
similarity index 99%
rename from services/AiService/src/AiService.Application/Prompts/Prompts.cs
rename to services/AiService/src/AiService.Api/Application/Prompts/Prompts.cs
index f80db6b8..a6f32a27 100644
--- a/services/AiService/src/AiService.Application/Prompts/Prompts.cs
+++ b/services/AiService/src/AiService.Api/Application/Prompts/Prompts.cs
@@ -1,4 +1,4 @@
-namespace AiService.Application.Prompts;
+namespace AiService.Api.Application.Prompts;
/// Versioned prompts ported from src/website_profiling/llm/prompts.py.
public static class LlmPrompts
diff --git a/services/AiService/src/AiService.Application/Repositories/ChatSessionRepository.cs b/services/AiService/src/AiService.Api/Application/Repositories/ChatSessionRepository.cs
similarity index 95%
rename from services/AiService/src/AiService.Application/Repositories/ChatSessionRepository.cs
rename to services/AiService/src/AiService.Api/Application/Repositories/ChatSessionRepository.cs
index 4a55bb42..2854b2ca 100644
--- a/services/AiService/src/AiService.Application/Repositories/ChatSessionRepository.cs
+++ b/services/AiService/src/AiService.Api/Application/Repositories/ChatSessionRepository.cs
@@ -1,9 +1,9 @@
-using AiService.Application.Persistence;
-using AiService.Domain.Entities;
-using AiService.Domain.Repositories;
+using AiService.Api.Application.Persistence;
+using AiService.Api.Domain.Entities;
+using AiService.Api.Domain.Repositories;
using Microsoft.EntityFrameworkCore;
-namespace AiService.Application.Repositories;
+namespace AiService.Api.Application.Repositories;
public sealed class ChatSessionRepository(AiDbContext db) : IChatSessionRepository
{
diff --git a/services/AiService/src/AiService.Application/Repositories/GoogleAppSettingsRepository.cs b/services/AiService/src/AiService.Api/Application/Repositories/GoogleAppSettingsRepository.cs
similarity index 95%
rename from services/AiService/src/AiService.Application/Repositories/GoogleAppSettingsRepository.cs
rename to services/AiService/src/AiService.Api/Application/Repositories/GoogleAppSettingsRepository.cs
index d73ea699..d3b722a0 100644
--- a/services/AiService/src/AiService.Application/Repositories/GoogleAppSettingsRepository.cs
+++ b/services/AiService/src/AiService.Api/Application/Repositories/GoogleAppSettingsRepository.cs
@@ -1,10 +1,10 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Application.Persistence;
-using AiService.Domain.Repositories;
+using AiService.Api.Application.Persistence;
+using AiService.Api.Domain.Repositories;
using Microsoft.EntityFrameworkCore;
-namespace AiService.Application.Repositories;
+namespace AiService.Api.Application.Repositories;
public sealed class GoogleAppSettingsRepository(AiDbContext db) : IGoogleAppSettingsRepository
{
diff --git a/services/AiService/src/AiService.Application/Repositories/LlmCacheRepository.cs b/services/AiService/src/AiService.Api/Application/Repositories/LlmCacheRepository.cs
similarity index 93%
rename from services/AiService/src/AiService.Application/Repositories/LlmCacheRepository.cs
rename to services/AiService/src/AiService.Api/Application/Repositories/LlmCacheRepository.cs
index bf8fd2f4..c0cb0cd8 100644
--- a/services/AiService/src/AiService.Application/Repositories/LlmCacheRepository.cs
+++ b/services/AiService/src/AiService.Api/Application/Repositories/LlmCacheRepository.cs
@@ -1,12 +1,12 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Application.Json;
-using AiService.Application.Persistence;
-using AiService.Domain.Entities;
-using AiService.Domain.Repositories;
+using AiService.Api.Application.Json;
+using AiService.Api.Application.Persistence;
+using AiService.Api.Domain.Entities;
+using AiService.Api.Domain.Repositories;
using Microsoft.EntityFrameworkCore;
-namespace AiService.Application.Repositories;
+namespace AiService.Api.Application.Repositories;
public sealed class LlmCacheRepository(AiDbContext db) : ILlmCacheRepository
{
diff --git a/services/AiService/src/AiService.Application/Repositories/LlmSettingsRepository.cs b/services/AiService/src/AiService.Api/Application/Repositories/LlmSettingsRepository.cs
similarity index 97%
rename from services/AiService/src/AiService.Application/Repositories/LlmSettingsRepository.cs
rename to services/AiService/src/AiService.Api/Application/Repositories/LlmSettingsRepository.cs
index da133376..d398ef6c 100644
--- a/services/AiService/src/AiService.Application/Repositories/LlmSettingsRepository.cs
+++ b/services/AiService/src/AiService.Api/Application/Repositories/LlmSettingsRepository.cs
@@ -1,9 +1,9 @@
-using AiService.Application.Persistence;
-using AiService.Domain.Models;
-using AiService.Domain.Repositories;
+using AiService.Api.Application.Persistence;
+using AiService.Api.Domain.Models;
+using AiService.Api.Domain.Repositories;
using Microsoft.EntityFrameworkCore;
-namespace AiService.Application.Repositories;
+namespace AiService.Api.Application.Repositories;
public sealed class LlmSettingsRepository(AiDbContext db) : ILlmSettingsRepository
{
diff --git a/services/AiService/src/AiService.Application/Repositories/LlmSettingsSecretMask.cs b/services/AiService/src/AiService.Api/Application/Repositories/LlmSettingsSecretMask.cs
similarity index 93%
rename from services/AiService/src/AiService.Application/Repositories/LlmSettingsSecretMask.cs
rename to services/AiService/src/AiService.Api/Application/Repositories/LlmSettingsSecretMask.cs
index b1b97bc5..e8a37c76 100644
--- a/services/AiService/src/AiService.Application/Repositories/LlmSettingsSecretMask.cs
+++ b/services/AiService/src/AiService.Api/Application/Repositories/LlmSettingsSecretMask.cs
@@ -1,4 +1,4 @@
-namespace AiService.Application.Repositories;
+namespace AiService.Api.Application.Repositories;
public static class LlmSettingsSecretMask
{
diff --git a/services/AiService/src/AiService.Application/Repositories/TypedConfigRepositories.cs b/services/AiService/src/AiService.Api/Application/Repositories/TypedConfigRepositories.cs
similarity index 96%
rename from services/AiService/src/AiService.Application/Repositories/TypedConfigRepositories.cs
rename to services/AiService/src/AiService.Api/Application/Repositories/TypedConfigRepositories.cs
index 72750b7b..88926795 100644
--- a/services/AiService/src/AiService.Application/Repositories/TypedConfigRepositories.cs
+++ b/services/AiService/src/AiService.Api/Application/Repositories/TypedConfigRepositories.cs
@@ -1,11 +1,11 @@
-using AiService.Application.Mcp;
-using AiService.Application.Persistence;
-using AiService.Domain.Models;
-using AiService.Domain.Repositories;
+using AiService.Api.Application.Mcp;
+using AiService.Api.Application.Persistence;
+using AiService.Api.Domain.Models;
+using AiService.Api.Domain.Repositories;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
-namespace AiService.Application.Repositories;
+namespace AiService.Api.Application.Repositories;
public sealed class IntegrationSecretsRepository(AiDbContext db) : IIntegrationSecretsRepository
{
diff --git a/services/AiService/src/AiService.Application/Services/ChatAgentService.cs b/services/AiService/src/AiService.Api/Application/Services/ChatAgentService.cs
similarity index 94%
rename from services/AiService/src/AiService.Application/Services/ChatAgentService.cs
rename to services/AiService/src/AiService.Api/Application/Services/ChatAgentService.cs
index a0bd9a80..760c11ab 100644
--- a/services/AiService/src/AiService.Application/Services/ChatAgentService.cs
+++ b/services/AiService/src/AiService.Api/Application/Services/ChatAgentService.cs
@@ -1,13 +1,13 @@
-using AiService.Application.Chat;
-using AiService.Domain;
-using AiService.Domain.Models;
-using AiService.Domain.Repositories;
-using AiService.Providers.Chat;
-using AiService.Tools.Context;
-using AiService.Tools.Selection;
+using AiService.Api.Application.Chat;
+using AiService.Api.Domain;
+using AiService.Api.Domain.Models;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Providers.Chat;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Selection;
using Microsoft.Extensions.AI;
-namespace AiService.Application.Services;
+namespace AiService.Api.Application.Services;
///
/// Chat agent turn orchestration — ports Python run_agent_turn using a manual tool loop.
diff --git a/services/AiService/src/AiService.Application/Services/ContentAnalyzeService.cs b/services/AiService/src/AiService.Api/Application/Services/ContentAnalyzeService.cs
similarity index 97%
rename from services/AiService/src/AiService.Application/Services/ContentAnalyzeService.cs
rename to services/AiService/src/AiService.Api/Application/Services/ContentAnalyzeService.cs
index e9300b9b..3b0cee21 100644
--- a/services/AiService/src/AiService.Application/Services/ContentAnalyzeService.cs
+++ b/services/AiService/src/AiService.Api/Application/Services/ContentAnalyzeService.cs
@@ -2,13 +2,13 @@
using System.Text;
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
-using AiService.Application.Json;
-using AiService.Application.Prompts;
-using AiService.Application.Repositories;
-using AiService.Domain.Repositories;
-using AiService.Providers.Chat;
+using AiService.Api.Application.Json;
+using AiService.Api.Application.Prompts;
+using AiService.Api.Application.Repositories;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Providers.Chat;
-namespace AiService.Application.Services;
+namespace AiService.Api.Application.Services;
public sealed class ContentAnalyzeService(
ILlmSettingsRepository configRepository,
diff --git a/services/AiService/src/AiService.Application/Services/ContentWizardService.cs b/services/AiService/src/AiService.Api/Application/Services/ContentWizardService.cs
similarity index 98%
rename from services/AiService/src/AiService.Application/Services/ContentWizardService.cs
rename to services/AiService/src/AiService.Api/Application/Services/ContentWizardService.cs
index edbffdc8..cbad0069 100644
--- a/services/AiService/src/AiService.Application/Services/ContentWizardService.cs
+++ b/services/AiService/src/AiService.Api/Application/Services/ContentWizardService.cs
@@ -1,12 +1,11 @@
-using System.Net.Http.Json;
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
-using AiService.Application.Prompts;
-using AiService.Domain.Models;
-using AiService.Domain.Repositories;
-using AiService.Providers.Chat;
+using AiService.Api.Application.Prompts;
+using AiService.Api.Domain.Models;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Providers.Chat;
-namespace AiService.Application.Services;
+namespace AiService.Api.Application.Services;
public sealed class ContentWizardService(
ILlmSettingsRepository configRepository,
diff --git a/services/AiService/src/AiService.Application/Services/DashboardAiService.cs b/services/AiService/src/AiService.Api/Application/Services/DashboardAiService.cs
similarity index 90%
rename from services/AiService/src/AiService.Application/Services/DashboardAiService.cs
rename to services/AiService/src/AiService.Api/Application/Services/DashboardAiService.cs
index 7e176de4..8923b55d 100644
--- a/services/AiService/src/AiService.Application/Services/DashboardAiService.cs
+++ b/services/AiService/src/AiService.Api/Application/Services/DashboardAiService.cs
@@ -1,9 +1,9 @@
-using AiService.Application.Prompts;
-using AiService.Domain.Models;
-using AiService.Domain.Repositories;
-using AiService.Providers.Chat;
+using AiService.Api.Application.Prompts;
+using AiService.Api.Domain.Models;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Providers.Chat;
-namespace AiService.Application.Services;
+namespace AiService.Api.Application.Services;
public sealed class DashboardAiService(
ILlmSettingsRepository configRepository,
diff --git a/services/AiService/src/AiService.Application/Services/EnrichmentService.cs b/services/AiService/src/AiService.Api/Application/Services/EnrichmentService.cs
similarity index 98%
rename from services/AiService/src/AiService.Application/Services/EnrichmentService.cs
rename to services/AiService/src/AiService.Api/Application/Services/EnrichmentService.cs
index 6967c614..6d4ac40b 100644
--- a/services/AiService/src/AiService.Application/Services/EnrichmentService.cs
+++ b/services/AiService/src/AiService.Api/Application/Services/EnrichmentService.cs
@@ -1,15 +1,13 @@
-using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Application.Json;
-using AiService.Application.Prompts;
-using AiService.Application.Repositories;
-using AiService.Domain;
-using AiService.Domain.Models;
-using AiService.Domain.Repositories;
-using AiService.Providers.Chat;
-using Microsoft.Extensions.Logging;
-
-namespace AiService.Application.Services;
+using AiService.Api.Application.Json;
+using AiService.Api.Application.Prompts;
+using AiService.Api.Application.Repositories;
+using AiService.Api.Domain;
+using AiService.Api.Domain.Models;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Providers.Chat;
+
+namespace AiService.Api.Application.Services;
///
/// LLM enrichment endpoints for /internal/enrichment/* — ports enrich.py, issue_fixes.py, audit_summary.py.
diff --git a/services/AiService/src/AiService.Application/Services/FixSuggestionService.cs b/services/AiService/src/AiService.Api/Application/Services/FixSuggestionService.cs
similarity index 95%
rename from services/AiService/src/AiService.Application/Services/FixSuggestionService.cs
rename to services/AiService/src/AiService.Api/Application/Services/FixSuggestionService.cs
index f60723c8..f757473a 100644
--- a/services/AiService/src/AiService.Application/Services/FixSuggestionService.cs
+++ b/services/AiService/src/AiService.Api/Application/Services/FixSuggestionService.cs
@@ -1,13 +1,12 @@
using System.Security.Cryptography;
using System.Text;
-using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Application.Prompts;
-using AiService.Application.Repositories;
-using AiService.Domain.Repositories;
-using AiService.Providers.Chat;
+using AiService.Api.Application.Prompts;
+using AiService.Api.Application.Repositories;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Providers.Chat;
-namespace AiService.Application.Services;
+namespace AiService.Api.Application.Services;
public sealed class FixSuggestionService(
ILlmSettingsRepository configRepository,
diff --git a/services/AiService/src/AiService.Application/Services/IssuesActionPlanService.cs b/services/AiService/src/AiService.Api/Application/Services/IssuesActionPlanService.cs
similarity index 96%
rename from services/AiService/src/AiService.Application/Services/IssuesActionPlanService.cs
rename to services/AiService/src/AiService.Api/Application/Services/IssuesActionPlanService.cs
index 5592d4d7..73ed686e 100644
--- a/services/AiService/src/AiService.Application/Services/IssuesActionPlanService.cs
+++ b/services/AiService/src/AiService.Api/Application/Services/IssuesActionPlanService.cs
@@ -1,14 +1,13 @@
using System.Security.Cryptography;
using System.Text;
-using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Application.Json;
-using AiService.Application.Prompts;
-using AiService.Application.Repositories;
-using AiService.Domain.Repositories;
-using AiService.Providers.Chat;
+using AiService.Api.Application.Json;
+using AiService.Api.Application.Prompts;
+using AiService.Api.Application.Repositories;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Providers.Chat;
-namespace AiService.Application.Services;
+namespace AiService.Api.Application.Services;
public sealed class IssuesActionPlanService(
ILlmSettingsRepository configRepository,
diff --git a/services/AiService/src/AiService.Application/Services/LlmTaskCache.cs b/services/AiService/src/AiService.Api/Application/Services/LlmTaskCache.cs
similarity index 83%
rename from services/AiService/src/AiService.Application/Services/LlmTaskCache.cs
rename to services/AiService/src/AiService.Api/Application/Services/LlmTaskCache.cs
index 25e719e3..d086021e 100644
--- a/services/AiService/src/AiService.Application/Services/LlmTaskCache.cs
+++ b/services/AiService/src/AiService.Api/Application/Services/LlmTaskCache.cs
@@ -2,13 +2,11 @@
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Application.Prompts;
-using AiService.Application.Repositories;
-using AiService.Domain.Models;
-using AiService.Domain.Repositories;
-using AiService.Providers.Chat;
+using AiService.Api.Application.Prompts;
+using AiService.Api.Application.Repositories;
+using AiService.Api.Domain.Models;
-namespace AiService.Application.Services;
+namespace AiService.Api.Application.Services;
internal static class LlmTaskCache
{
diff --git a/services/AiService/src/AiService.Application/Services/OllamaCatalogService.cs b/services/AiService/src/AiService.Api/Application/Services/OllamaCatalogService.cs
similarity index 98%
rename from services/AiService/src/AiService.Application/Services/OllamaCatalogService.cs
rename to services/AiService/src/AiService.Api/Application/Services/OllamaCatalogService.cs
index 377ede7a..81ed3d74 100644
--- a/services/AiService/src/AiService.Application/Services/OllamaCatalogService.cs
+++ b/services/AiService/src/AiService.Api/Application/Services/OllamaCatalogService.cs
@@ -1,12 +1,10 @@
-using System.Net.Http.Json;
using System.Net.Sockets;
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
-using AiService.Application.Json;
-using AiService.Domain;
-using Microsoft.Extensions.Logging;
+using AiService.Api.Application.Json;
+using AiService.Api.Domain;
-namespace AiService.Application.Services;
+namespace AiService.Api.Application.Services;
/// Port of ollama_catalog.py — local + cloud Ollama model catalog.
public sealed class OllamaCatalogService(IHttpClientFactory httpClientFactory, ILogger logger)
diff --git a/services/AiService/src/AiService.Application/Services/OllamaConnectionHealth.cs b/services/AiService/src/AiService.Api/Application/Services/OllamaConnectionHealth.cs
similarity index 96%
rename from services/AiService/src/AiService.Application/Services/OllamaConnectionHealth.cs
rename to services/AiService/src/AiService.Api/Application/Services/OllamaConnectionHealth.cs
index 140addb9..829b8dd6 100644
--- a/services/AiService/src/AiService.Application/Services/OllamaConnectionHealth.cs
+++ b/services/AiService/src/AiService.Api/Application/Services/OllamaConnectionHealth.cs
@@ -1,4 +1,4 @@
-namespace AiService.Application.Services;
+namespace AiService.Api.Application.Services;
/// Tiered Ollama reachability — local probe failure is not always fatal.
public static class OllamaConnectionHealth
diff --git a/services/AiService/src/AiService.Application/Services/PageCoachService.cs b/services/AiService/src/AiService.Api/Application/Services/PageCoachService.cs
similarity index 94%
rename from services/AiService/src/AiService.Application/Services/PageCoachService.cs
rename to services/AiService/src/AiService.Api/Application/Services/PageCoachService.cs
index 9c882678..12d81ce3 100644
--- a/services/AiService/src/AiService.Application/Services/PageCoachService.cs
+++ b/services/AiService/src/AiService.Api/Application/Services/PageCoachService.cs
@@ -2,14 +2,14 @@
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Application.Persistence;
-using AiService.Application.Prompts;
-using AiService.Application.Repositories;
-using AiService.Domain.Repositories;
-using AiService.Providers.Chat;
+using AiService.Api.Application.Persistence;
+using AiService.Api.Application.Prompts;
+using AiService.Api.Application.Repositories;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Providers.Chat;
using Microsoft.EntityFrameworkCore;
-namespace AiService.Application.Services;
+namespace AiService.Api.Application.Services;
public sealed class PageCoachService(
ILlmSettingsRepository configRepository,
diff --git a/services/AiService/src/AiService.Application/Services/SecretsKeyCatalog.cs b/services/AiService/src/AiService.Api/Application/Services/SecretsKeyCatalog.cs
similarity index 99%
rename from services/AiService/src/AiService.Application/Services/SecretsKeyCatalog.cs
rename to services/AiService/src/AiService.Api/Application/Services/SecretsKeyCatalog.cs
index 8d7beb03..900e24fa 100644
--- a/services/AiService/src/AiService.Application/Services/SecretsKeyCatalog.cs
+++ b/services/AiService/src/AiService.Api/Application/Services/SecretsKeyCatalog.cs
@@ -1,4 +1,4 @@
-namespace AiService.Application.Services;
+namespace AiService.Api.Application.Services;
/// Key routing for unified secrets API — mirrors web/src/lib/secretsConfigSchema.ts.
internal static class SecretsKeyCatalog
diff --git a/services/AiService/src/AiService.Application/Services/SecretsService.cs b/services/AiService/src/AiService.Api/Application/Services/SecretsService.cs
similarity index 98%
rename from services/AiService/src/AiService.Application/Services/SecretsService.cs
rename to services/AiService/src/AiService.Api/Application/Services/SecretsService.cs
index 87106029..05bf2d0c 100644
--- a/services/AiService/src/AiService.Application/Services/SecretsService.cs
+++ b/services/AiService/src/AiService.Api/Application/Services/SecretsService.cs
@@ -1,10 +1,10 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Application.Repositories;
-using AiService.Domain.Models;
-using AiService.Domain.Repositories;
+using AiService.Api.Application.Repositories;
+using AiService.Api.Domain.Models;
+using AiService.Api.Domain.Repositories;
-namespace AiService.Application.Services;
+namespace AiService.Api.Application.Services;
public sealed class SecretsService(
ILlmSettingsRepository llmSettings,
diff --git a/services/AiService/src/AiService.Application/ToolRegistryExtensions.cs b/services/AiService/src/AiService.Api/Application/ToolRegistryExtensions.cs
similarity index 74%
rename from services/AiService/src/AiService.Application/ToolRegistryExtensions.cs
rename to services/AiService/src/AiService.Api/Application/ToolRegistryExtensions.cs
index dfd42f4d..4c38cd9a 100644
--- a/services/AiService/src/AiService.Application/ToolRegistryExtensions.cs
+++ b/services/AiService/src/AiService.Api/Application/ToolRegistryExtensions.cs
@@ -1,9 +1,8 @@
-using AiService.Application.Handlers;
-using AiService.Tools.Modules;
-using AiService.Tools.Registry;
-using Microsoft.Extensions.DependencyInjection;
+using AiService.Api.Application.Handlers;
+using AiService.Api.Tools.Modules;
+using AiService.Api.Tools.Registry;
-namespace AiService.Application;
+namespace AiService.Api.Application;
public static class ToolRegistryExtensions
{
diff --git a/services/AiService/src/AiService.Api/Controllers/AuditToolController.cs b/services/AiService/src/AiService.Api/Controllers/AuditToolController.cs
index 9209957b..b959ee40 100644
--- a/services/AiService/src/AiService.Api/Controllers/AuditToolController.cs
+++ b/services/AiService/src/AiService.Api/Controllers/AuditToolController.cs
@@ -1,5 +1,5 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Registry;
+using AiService.Api.Tools.Registry;
using Microsoft.AspNetCore.Mvc;
namespace AiService.Api.Controllers;
diff --git a/services/AiService/src/AiService.Api/Controllers/ChatController.cs b/services/AiService/src/AiService.Api/Controllers/ChatController.cs
index d1603682..2d5f711d 100644
--- a/services/AiService/src/AiService.Api/Controllers/ChatController.cs
+++ b/services/AiService/src/AiService.Api/Controllers/ChatController.cs
@@ -1,13 +1,13 @@
using System.Text.Json.Nodes;
using System.Threading.Channels;
-using AiService.Application.Chat;
-using AiService.Application.Dto;
-using AiService.Application.Services;
-using AiService.Domain;
-using AiService.Domain.Repositories;
-using AiService.Tools.Artifacts;
-using AiService.Tools.Context;
+using AiService.Api.Application.Chat;
+using AiService.Api.Application.Dto;
+using AiService.Api.Application.Services;
+using AiService.Api.Domain;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Tools.Context;
using Microsoft.AspNetCore.Mvc;
+using ArtifactStore = AiService.Api.Tools.Artifacts.ArtifactStore;
namespace AiService.Api.Controllers;
diff --git a/services/AiService/src/AiService.Api/Controllers/ContentController.cs b/services/AiService/src/AiService.Api/Controllers/ContentController.cs
index 7da106e1..723b8d34 100644
--- a/services/AiService/src/AiService.Api/Controllers/ContentController.cs
+++ b/services/AiService/src/AiService.Api/Controllers/ContentController.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-using AiService.Application.Dto;
-using AiService.Application.Services;
+using AiService.Api.Application.Dto;
+using AiService.Api.Application.Services;
using Microsoft.AspNetCore.Mvc;
namespace AiService.Api.Controllers;
diff --git a/services/AiService/src/AiService.Api/Controllers/ControllerHelpers.cs b/services/AiService/src/AiService.Api/Controllers/ControllerHelpers.cs
index 541034b0..95aac6d8 100644
--- a/services/AiService/src/AiService.Api/Controllers/ControllerHelpers.cs
+++ b/services/AiService/src/AiService.Api/Controllers/ControllerHelpers.cs
@@ -1,9 +1,9 @@
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
-using AiService.Application.Chat;
-using AiService.Domain;
-using AiService.Domain.Entities;
+using AiService.Api.Application.Chat;
+using AiService.Api.Domain;
+using AiService.Api.Domain.Entities;
namespace AiService.Api.Controllers;
diff --git a/services/AiService/src/AiService.Api/Controllers/DashboardsController.cs b/services/AiService/src/AiService.Api/Controllers/DashboardsController.cs
index 12949a33..d5cbc83b 100644
--- a/services/AiService/src/AiService.Api/Controllers/DashboardsController.cs
+++ b/services/AiService/src/AiService.Api/Controllers/DashboardsController.cs
@@ -1,5 +1,5 @@
-using AiService.Application.Services;
-using AiService.Domain.Models;
+using AiService.Api.Application.Services;
+using AiService.Api.Domain.Models;
using Microsoft.AspNetCore.Mvc;
namespace AiService.Api.Controllers;
diff --git a/services/AiService/src/AiService.Api/Controllers/Internal/CompletionController.cs b/services/AiService/src/AiService.Api/Controllers/Internal/CompletionController.cs
index 2ce6a589..365f58c2 100644
--- a/services/AiService/src/AiService.Api/Controllers/Internal/CompletionController.cs
+++ b/services/AiService/src/AiService.Api/Controllers/Internal/CompletionController.cs
@@ -1,7 +1,6 @@
using System.Text.Json.Nodes;
-using AiService.Application.Repositories;
-using AiService.Domain.Repositories;
-using AiService.Providers.Chat;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Providers.Chat;
using Microsoft.AspNetCore.Mvc;
namespace AiService.Api.Controllers.Internal;
diff --git a/services/AiService/src/AiService.Api/Controllers/Internal/EnrichmentController.cs b/services/AiService/src/AiService.Api/Controllers/Internal/EnrichmentController.cs
index 2abb9e32..49e367bb 100644
--- a/services/AiService/src/AiService.Api/Controllers/Internal/EnrichmentController.cs
+++ b/services/AiService/src/AiService.Api/Controllers/Internal/EnrichmentController.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-using AiService.Application.Dto;
-using AiService.Application.Services;
+using AiService.Api.Application.Dto;
+using AiService.Api.Application.Services;
using Microsoft.AspNetCore.Mvc;
namespace AiService.Api.Controllers.Internal;
diff --git a/services/AiService/src/AiService.Api/Controllers/Internal/ExtractionController.cs b/services/AiService/src/AiService.Api/Controllers/Internal/ExtractionController.cs
index d09a6835..130a6b3d 100644
--- a/services/AiService/src/AiService.Api/Controllers/Internal/ExtractionController.cs
+++ b/services/AiService/src/AiService.Api/Controllers/Internal/ExtractionController.cs
@@ -1,7 +1,7 @@
using System.Text;
using System.Text.Json.Nodes;
-using AiService.Domain.Repositories;
-using AiService.Providers.Chat;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Providers.Chat;
using Microsoft.AspNetCore.Mvc;
namespace AiService.Api.Controllers.Internal;
diff --git a/services/AiService/src/AiService.Api/Controllers/IssuesController.cs b/services/AiService/src/AiService.Api/Controllers/IssuesController.cs
index 05ad6ad3..1e5f18ad 100644
--- a/services/AiService/src/AiService.Api/Controllers/IssuesController.cs
+++ b/services/AiService/src/AiService.Api/Controllers/IssuesController.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-using AiService.Application.Dto;
-using AiService.Application.Services;
+using AiService.Api.Application.Dto;
+using AiService.Api.Application.Services;
using Microsoft.AspNetCore.Mvc;
namespace AiService.Api.Controllers;
diff --git a/services/AiService/src/AiService.Api/Controllers/LlmSettingsController.cs b/services/AiService/src/AiService.Api/Controllers/LlmSettingsController.cs
index b85e1bf6..a0de8c8e 100644
--- a/services/AiService/src/AiService.Api/Controllers/LlmSettingsController.cs
+++ b/services/AiService/src/AiService.Api/Controllers/LlmSettingsController.cs
@@ -1,6 +1,6 @@
-using AiService.Domain.Models;
-using AiService.Domain.Repositories;
-using AiService.Providers.Chat;
+using AiService.Api.Domain.Models;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Providers.Chat;
using Microsoft.AspNetCore.Mvc;
namespace AiService.Api.Controllers;
diff --git a/services/AiService/src/AiService.Api/Controllers/McpToolsController.cs b/services/AiService/src/AiService.Api/Controllers/McpToolsController.cs
index 60d8e37d..1896c11e 100644
--- a/services/AiService/src/AiService.Api/Controllers/McpToolsController.cs
+++ b/services/AiService/src/AiService.Api/Controllers/McpToolsController.cs
@@ -1,4 +1,4 @@
-using AiService.Mcp;
+using AiService.Api.Mcp;
using Microsoft.AspNetCore.Mvc;
namespace AiService.Api.Controllers;
diff --git a/services/AiService/src/AiService.Api/Controllers/OllamaController.cs b/services/AiService/src/AiService.Api/Controllers/OllamaController.cs
index 7edfe7ff..5dadc5f4 100644
--- a/services/AiService/src/AiService.Api/Controllers/OllamaController.cs
+++ b/services/AiService/src/AiService.Api/Controllers/OllamaController.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Nodes;
-using AiService.Application.Services;
-using AiService.Domain;
-using AiService.Domain.Repositories;
+using AiService.Api.Application.Services;
+using AiService.Api.Domain;
+using AiService.Api.Domain.Repositories;
using Microsoft.AspNetCore.Mvc;
namespace AiService.Api.Controllers;
diff --git a/services/AiService/src/AiService.Api/Controllers/PageCoachController.cs b/services/AiService/src/AiService.Api/Controllers/PageCoachController.cs
index 5936902c..ff952e4e 100644
--- a/services/AiService/src/AiService.Api/Controllers/PageCoachController.cs
+++ b/services/AiService/src/AiService.Api/Controllers/PageCoachController.cs
@@ -1,4 +1,4 @@
-using AiService.Application.Services;
+using AiService.Api.Application.Services;
using Microsoft.AspNetCore.Mvc;
namespace AiService.Api.Controllers;
diff --git a/services/AiService/src/AiService.Api/Controllers/SecretsController.cs b/services/AiService/src/AiService.Api/Controllers/SecretsController.cs
index e16ea857..8ba000ac 100644
--- a/services/AiService/src/AiService.Api/Controllers/SecretsController.cs
+++ b/services/AiService/src/AiService.Api/Controllers/SecretsController.cs
@@ -1,5 +1,5 @@
using System.Text.Json.Nodes;
-using AiService.Application.Services;
+using AiService.Api.Application.Services;
using Microsoft.AspNetCore.Mvc;
namespace AiService.Api.Controllers;
diff --git a/services/AiService/src/AiService.Domain/ChatRoles.cs b/services/AiService/src/AiService.Api/Domain/ChatRoles.cs
similarity index 83%
rename from services/AiService/src/AiService.Domain/ChatRoles.cs
rename to services/AiService/src/AiService.Api/Domain/ChatRoles.cs
index ea70aec1..fe9f8e60 100644
--- a/services/AiService/src/AiService.Domain/ChatRoles.cs
+++ b/services/AiService/src/AiService.Api/Domain/ChatRoles.cs
@@ -1,4 +1,4 @@
-namespace AiService.Domain;
+namespace AiService.Api.Domain;
public static class ChatRoles
{
diff --git a/services/AiService/src/AiService.Domain/Entities/ChatMessage.cs b/services/AiService/src/AiService.Api/Domain/Entities/ChatMessage.cs
similarity index 87%
rename from services/AiService/src/AiService.Domain/Entities/ChatMessage.cs
rename to services/AiService/src/AiService.Api/Domain/Entities/ChatMessage.cs
index a089f259..4c5660ec 100644
--- a/services/AiService/src/AiService.Domain/Entities/ChatMessage.cs
+++ b/services/AiService/src/AiService.Api/Domain/Entities/ChatMessage.cs
@@ -1,6 +1,4 @@
-namespace AiService.Domain.Entities;
-
-using AiService.Domain;
+namespace AiService.Api.Domain.Entities;
public sealed class ChatMessage
{
diff --git a/services/AiService/src/AiService.Domain/Entities/ChatSession.cs b/services/AiService/src/AiService.Api/Domain/Entities/ChatSession.cs
similarity index 89%
rename from services/AiService/src/AiService.Domain/Entities/ChatSession.cs
rename to services/AiService/src/AiService.Api/Domain/Entities/ChatSession.cs
index 5d340ef6..f1398eb4 100644
--- a/services/AiService/src/AiService.Domain/Entities/ChatSession.cs
+++ b/services/AiService/src/AiService.Api/Domain/Entities/ChatSession.cs
@@ -1,4 +1,4 @@
-namespace AiService.Domain.Entities;
+namespace AiService.Api.Domain.Entities;
public sealed class ChatSession
{
diff --git a/services/AiService/src/AiService.Domain/Entities/FeatureFlagsEntry.cs b/services/AiService/src/AiService.Api/Domain/Entities/FeatureFlagsEntry.cs
similarity index 91%
rename from services/AiService/src/AiService.Domain/Entities/FeatureFlagsEntry.cs
rename to services/AiService/src/AiService.Api/Domain/Entities/FeatureFlagsEntry.cs
index 5548b100..dd169999 100644
--- a/services/AiService/src/AiService.Domain/Entities/FeatureFlagsEntry.cs
+++ b/services/AiService/src/AiService.Api/Domain/Entities/FeatureFlagsEntry.cs
@@ -1,4 +1,4 @@
-namespace AiService.Domain.Entities;
+namespace AiService.Api.Domain.Entities;
public sealed class FeatureFlagsEntry
{
diff --git a/services/AiService/src/AiService.Domain/Entities/GoogleAppSettingsEntry.cs b/services/AiService/src/AiService.Api/Domain/Entities/GoogleAppSettingsEntry.cs
similarity index 91%
rename from services/AiService/src/AiService.Domain/Entities/GoogleAppSettingsEntry.cs
rename to services/AiService/src/AiService.Api/Domain/Entities/GoogleAppSettingsEntry.cs
index bc18d189..b9ea7316 100644
--- a/services/AiService/src/AiService.Domain/Entities/GoogleAppSettingsEntry.cs
+++ b/services/AiService/src/AiService.Api/Domain/Entities/GoogleAppSettingsEntry.cs
@@ -1,4 +1,4 @@
-namespace AiService.Domain.Entities;
+namespace AiService.Api.Domain.Entities;
public sealed class GoogleAppSettingsEntry
{
diff --git a/services/AiService/src/AiService.Domain/Entities/IntegrationSecretsEntry.cs b/services/AiService/src/AiService.Api/Domain/Entities/IntegrationSecretsEntry.cs
similarity index 91%
rename from services/AiService/src/AiService.Domain/Entities/IntegrationSecretsEntry.cs
rename to services/AiService/src/AiService.Api/Domain/Entities/IntegrationSecretsEntry.cs
index 870cc25e..ff9b384c 100644
--- a/services/AiService/src/AiService.Domain/Entities/IntegrationSecretsEntry.cs
+++ b/services/AiService/src/AiService.Api/Domain/Entities/IntegrationSecretsEntry.cs
@@ -1,4 +1,4 @@
-namespace AiService.Domain.Entities;
+namespace AiService.Api.Domain.Entities;
public sealed class IntegrationSecretsEntry
{
diff --git a/services/AiService/src/AiService.Domain/Entities/LlmCacheEntry.cs b/services/AiService/src/AiService.Api/Domain/Entities/LlmCacheEntry.cs
similarity index 82%
rename from services/AiService/src/AiService.Domain/Entities/LlmCacheEntry.cs
rename to services/AiService/src/AiService.Api/Domain/Entities/LlmCacheEntry.cs
index e6b0d75b..20e7e803 100644
--- a/services/AiService/src/AiService.Domain/Entities/LlmCacheEntry.cs
+++ b/services/AiService/src/AiService.Api/Domain/Entities/LlmCacheEntry.cs
@@ -1,4 +1,4 @@
-namespace AiService.Domain.Entities;
+namespace AiService.Api.Domain.Entities;
public sealed class LlmCacheEntry
{
diff --git a/services/AiService/src/AiService.Domain/Entities/LlmConfigEntry.cs b/services/AiService/src/AiService.Api/Domain/Entities/LlmConfigEntry.cs
similarity index 84%
rename from services/AiService/src/AiService.Domain/Entities/LlmConfigEntry.cs
rename to services/AiService/src/AiService.Api/Domain/Entities/LlmConfigEntry.cs
index 3f5cda3d..92e51904 100644
--- a/services/AiService/src/AiService.Domain/Entities/LlmConfigEntry.cs
+++ b/services/AiService/src/AiService.Api/Domain/Entities/LlmConfigEntry.cs
@@ -1,4 +1,4 @@
-namespace AiService.Domain.Entities;
+namespace AiService.Api.Domain.Entities;
public sealed class LlmConfigEntry
{
diff --git a/services/AiService/src/AiService.Domain/Entities/LlmProviderProfileEntry.cs b/services/AiService/src/AiService.Api/Domain/Entities/LlmProviderProfileEntry.cs
similarity index 85%
rename from services/AiService/src/AiService.Domain/Entities/LlmProviderProfileEntry.cs
rename to services/AiService/src/AiService.Api/Domain/Entities/LlmProviderProfileEntry.cs
index 6fc57e12..15a95eb2 100644
--- a/services/AiService/src/AiService.Domain/Entities/LlmProviderProfileEntry.cs
+++ b/services/AiService/src/AiService.Api/Domain/Entities/LlmProviderProfileEntry.cs
@@ -1,4 +1,4 @@
-namespace AiService.Domain.Entities;
+namespace AiService.Api.Domain.Entities;
public sealed class LlmProviderProfileEntry
{
diff --git a/services/AiService/src/AiService.Domain/Entities/LlmSettingsEntry.cs b/services/AiService/src/AiService.Api/Domain/Entities/LlmSettingsEntry.cs
similarity index 95%
rename from services/AiService/src/AiService.Domain/Entities/LlmSettingsEntry.cs
rename to services/AiService/src/AiService.Api/Domain/Entities/LlmSettingsEntry.cs
index a2dd003f..cc359e1a 100644
--- a/services/AiService/src/AiService.Domain/Entities/LlmSettingsEntry.cs
+++ b/services/AiService/src/AiService.Api/Domain/Entities/LlmSettingsEntry.cs
@@ -1,6 +1,4 @@
-namespace AiService.Domain.Entities;
-
-using AiService.Domain;
+namespace AiService.Api.Domain.Entities;
public sealed class LlmSettingsEntry
{
diff --git a/services/AiService/src/AiService.Domain/Entities/McpSettingsEntry.cs b/services/AiService/src/AiService.Api/Domain/Entities/McpSettingsEntry.cs
similarity index 92%
rename from services/AiService/src/AiService.Domain/Entities/McpSettingsEntry.cs
rename to services/AiService/src/AiService.Api/Domain/Entities/McpSettingsEntry.cs
index 857a208c..3a5ddc50 100644
--- a/services/AiService/src/AiService.Domain/Entities/McpSettingsEntry.cs
+++ b/services/AiService/src/AiService.Api/Domain/Entities/McpSettingsEntry.cs
@@ -1,4 +1,4 @@
-namespace AiService.Domain.Entities;
+namespace AiService.Api.Domain.Entities;
public sealed class McpSettingsEntry
{
diff --git a/services/AiService/src/AiService.Domain/Entities/ReportPayload.cs b/services/AiService/src/AiService.Api/Domain/Entities/ReportPayload.cs
similarity index 90%
rename from services/AiService/src/AiService.Domain/Entities/ReportPayload.cs
rename to services/AiService/src/AiService.Api/Domain/Entities/ReportPayload.cs
index 9fcb8b1d..b9a9d030 100644
--- a/services/AiService/src/AiService.Domain/Entities/ReportPayload.cs
+++ b/services/AiService/src/AiService.Api/Domain/Entities/ReportPayload.cs
@@ -1,4 +1,4 @@
-namespace AiService.Domain.Entities;
+namespace AiService.Api.Domain.Entities;
/// Read/write mapping of the report_payload table (schema owned by services/Schema).
public sealed class ReportPayload
diff --git a/services/AiService/src/AiService.Domain/LlmProviders.cs b/services/AiService/src/AiService.Api/Domain/LlmProviders.cs
similarity index 96%
rename from services/AiService/src/AiService.Domain/LlmProviders.cs
rename to services/AiService/src/AiService.Api/Domain/LlmProviders.cs
index 93d38cd5..a47d3ba7 100644
--- a/services/AiService/src/AiService.Domain/LlmProviders.cs
+++ b/services/AiService/src/AiService.Api/Domain/LlmProviders.cs
@@ -1,4 +1,4 @@
-namespace AiService.Domain;
+namespace AiService.Api.Domain;
public static class LlmProviders
{
diff --git a/services/AiService/src/AiService.Domain/Models/DashboardAiGenerateRequest.cs b/services/AiService/src/AiService.Api/Domain/Models/DashboardAiGenerateRequest.cs
similarity index 96%
rename from services/AiService/src/AiService.Domain/Models/DashboardAiGenerateRequest.cs
rename to services/AiService/src/AiService.Api/Domain/Models/DashboardAiGenerateRequest.cs
index 8edc4379..a7912b7e 100644
--- a/services/AiService/src/AiService.Domain/Models/DashboardAiGenerateRequest.cs
+++ b/services/AiService/src/AiService.Api/Domain/Models/DashboardAiGenerateRequest.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-namespace AiService.Domain.Models;
+namespace AiService.Api.Domain.Models;
public sealed class DashboardAiGenerateRequest
{
diff --git a/services/AiService/src/AiService.Domain/Models/DashboardAiGenerateResponse.cs b/services/AiService/src/AiService.Api/Domain/Models/DashboardAiGenerateResponse.cs
similarity index 92%
rename from services/AiService/src/AiService.Domain/Models/DashboardAiGenerateResponse.cs
rename to services/AiService/src/AiService.Api/Domain/Models/DashboardAiGenerateResponse.cs
index f658997d..62d21dc8 100644
--- a/services/AiService/src/AiService.Domain/Models/DashboardAiGenerateResponse.cs
+++ b/services/AiService/src/AiService.Api/Domain/Models/DashboardAiGenerateResponse.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-namespace AiService.Domain.Models;
+namespace AiService.Api.Domain.Models;
public sealed class DashboardAiGenerateResponse
{
diff --git a/services/AiService/src/AiService.Domain/Models/LlmSettings.cs b/services/AiService/src/AiService.Api/Domain/Models/LlmSettings.cs
similarity index 98%
rename from services/AiService/src/AiService.Domain/Models/LlmSettings.cs
rename to services/AiService/src/AiService.Api/Domain/Models/LlmSettings.cs
index d9cfb61c..52f9fd71 100644
--- a/services/AiService/src/AiService.Domain/Models/LlmSettings.cs
+++ b/services/AiService/src/AiService.Api/Domain/Models/LlmSettings.cs
@@ -1,6 +1,4 @@
-namespace AiService.Domain.Models;
-
-using AiService.Domain;
+namespace AiService.Api.Domain.Models;
/// Singleton llm_settings row plus llm_provider_profiles.
public sealed class LlmSettings
diff --git a/services/AiService/src/AiService.Domain/Models/TypedPipelineConfig.cs b/services/AiService/src/AiService.Api/Domain/Models/TypedPipelineConfig.cs
similarity index 98%
rename from services/AiService/src/AiService.Domain/Models/TypedPipelineConfig.cs
rename to services/AiService/src/AiService.Api/Domain/Models/TypedPipelineConfig.cs
index 9bcf0f59..30f63515 100644
--- a/services/AiService/src/AiService.Domain/Models/TypedPipelineConfig.cs
+++ b/services/AiService/src/AiService.Api/Domain/Models/TypedPipelineConfig.cs
@@ -1,4 +1,4 @@
-namespace AiService.Domain.Models;
+namespace AiService.Api.Domain.Models;
public sealed class IntegrationSecrets
{
diff --git a/services/AiService/src/AiService.Domain/OllamaDefaults.cs b/services/AiService/src/AiService.Api/Domain/OllamaDefaults.cs
similarity index 75%
rename from services/AiService/src/AiService.Domain/OllamaDefaults.cs
rename to services/AiService/src/AiService.Api/Domain/OllamaDefaults.cs
index 5c24be95..fd2112cf 100644
--- a/services/AiService/src/AiService.Domain/OllamaDefaults.cs
+++ b/services/AiService/src/AiService.Api/Domain/OllamaDefaults.cs
@@ -1,4 +1,4 @@
-namespace AiService.Domain;
+namespace AiService.Api.Domain;
public static class OllamaDefaults
{
diff --git a/services/AiService/src/AiService.Domain/Repositories/IChatSessionRepository.cs b/services/AiService/src/AiService.Api/Domain/Repositories/IChatSessionRepository.cs
similarity index 93%
rename from services/AiService/src/AiService.Domain/Repositories/IChatSessionRepository.cs
rename to services/AiService/src/AiService.Api/Domain/Repositories/IChatSessionRepository.cs
index 817e39af..a4eb1dfa 100644
--- a/services/AiService/src/AiService.Domain/Repositories/IChatSessionRepository.cs
+++ b/services/AiService/src/AiService.Api/Domain/Repositories/IChatSessionRepository.cs
@@ -1,6 +1,6 @@
-using AiService.Domain.Entities;
+using AiService.Api.Domain.Entities;
-namespace AiService.Domain.Repositories;
+namespace AiService.Api.Domain.Repositories;
public interface IChatSessionRepository
{
diff --git a/services/AiService/src/AiService.Domain/Repositories/IGoogleAppSettingsRepository.cs b/services/AiService/src/AiService.Api/Domain/Repositories/IGoogleAppSettingsRepository.cs
similarity index 95%
rename from services/AiService/src/AiService.Domain/Repositories/IGoogleAppSettingsRepository.cs
rename to services/AiService/src/AiService.Api/Domain/Repositories/IGoogleAppSettingsRepository.cs
index 5910f724..a9cbd879 100644
--- a/services/AiService/src/AiService.Domain/Repositories/IGoogleAppSettingsRepository.cs
+++ b/services/AiService/src/AiService.Api/Domain/Repositories/IGoogleAppSettingsRepository.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-namespace AiService.Domain.Repositories;
+namespace AiService.Api.Domain.Repositories;
/// Singleton google_app_settings row (OAuth app credentials).
public interface IGoogleAppSettingsRepository
diff --git a/services/AiService/src/AiService.Domain/Repositories/ILlmCacheRepository.cs b/services/AiService/src/AiService.Api/Domain/Repositories/ILlmCacheRepository.cs
similarity index 89%
rename from services/AiService/src/AiService.Domain/Repositories/ILlmCacheRepository.cs
rename to services/AiService/src/AiService.Api/Domain/Repositories/ILlmCacheRepository.cs
index 431ec29a..359ea5ac 100644
--- a/services/AiService/src/AiService.Domain/Repositories/ILlmCacheRepository.cs
+++ b/services/AiService/src/AiService.Api/Domain/Repositories/ILlmCacheRepository.cs
@@ -1,4 +1,4 @@
-namespace AiService.Domain.Repositories;
+namespace AiService.Api.Domain.Repositories;
public interface ILlmCacheRepository
{
diff --git a/services/AiService/src/AiService.Domain/Repositories/ILlmSettingsRepository.cs b/services/AiService/src/AiService.Api/Domain/Repositories/ILlmSettingsRepository.cs
similarity index 84%
rename from services/AiService/src/AiService.Domain/Repositories/ILlmSettingsRepository.cs
rename to services/AiService/src/AiService.Api/Domain/Repositories/ILlmSettingsRepository.cs
index 9774d94f..c5ae7683 100644
--- a/services/AiService/src/AiService.Domain/Repositories/ILlmSettingsRepository.cs
+++ b/services/AiService/src/AiService.Api/Domain/Repositories/ILlmSettingsRepository.cs
@@ -1,6 +1,6 @@
-using AiService.Domain.Models;
+using AiService.Api.Domain.Models;
-namespace AiService.Domain.Repositories;
+namespace AiService.Api.Domain.Repositories;
public interface ILlmSettingsRepository
{
diff --git a/services/AiService/src/AiService.Domain/Repositories/ITypedConfigRepositories.cs b/services/AiService/src/AiService.Api/Domain/Repositories/ITypedConfigRepositories.cs
similarity index 89%
rename from services/AiService/src/AiService.Domain/Repositories/ITypedConfigRepositories.cs
rename to services/AiService/src/AiService.Api/Domain/Repositories/ITypedConfigRepositories.cs
index a250a84f..01bedb9d 100644
--- a/services/AiService/src/AiService.Domain/Repositories/ITypedConfigRepositories.cs
+++ b/services/AiService/src/AiService.Api/Domain/Repositories/ITypedConfigRepositories.cs
@@ -1,6 +1,6 @@
-using AiService.Domain.Models;
+using AiService.Api.Domain.Models;
-namespace AiService.Domain.Repositories;
+namespace AiService.Api.Domain.Repositories;
public interface IIntegrationSecretsRepository
{
diff --git a/services/AiService/src/AiService.Mcp/McpAuditTools.cs b/services/AiService/src/AiService.Api/Mcp/McpAuditTools.cs
similarity index 96%
rename from services/AiService/src/AiService.Mcp/McpAuditTools.cs
rename to services/AiService/src/AiService.Api/Mcp/McpAuditTools.cs
index 7128ae92..d3a89df4 100644
--- a/services/AiService/src/AiService.Mcp/McpAuditTools.cs
+++ b/services/AiService/src/AiService.Api/Mcp/McpAuditTools.cs
@@ -1,13 +1,13 @@
using System.ComponentModel;
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Domain;
-using AiService.Tools.Registry;
-using AiService.Tools.Selection;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Domain;
+using AiService.Api.Tools.Registry;
+using AiService.Api.Tools.Selection;
using ModelContextProtocol.Server;
-namespace AiService.Mcp;
+namespace AiService.Api.Mcp;
///
/// MCP audit tools that delegate to .
diff --git a/services/AiService/src/AiService.Mcp/McpBearerAuthFilter.cs b/services/AiService/src/AiService.Api/Mcp/McpBearerAuthFilter.cs
similarity index 92%
rename from services/AiService/src/AiService.Mcp/McpBearerAuthFilter.cs
rename to services/AiService/src/AiService.Api/Mcp/McpBearerAuthFilter.cs
index 57ac9700..9332fac5 100644
--- a/services/AiService/src/AiService.Mcp/McpBearerAuthFilter.cs
+++ b/services/AiService/src/AiService.Api/Mcp/McpBearerAuthFilter.cs
@@ -1,13 +1,10 @@
using System.Security.Cryptography;
using System.Text;
-using AiService.Application.Mcp;
-using AiService.Domain.Repositories;
-using Microsoft.AspNetCore.Http;
+using AiService.Api.Application.Mcp;
+using AiService.Api.Domain.Repositories;
using Microsoft.Extensions.Caching.Memory;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-namespace AiService.Mcp;
+namespace AiService.Api.Mcp;
///
/// Enforces McpSettingsEntry.BearerToken (Risk Settings > MCP) on the MCP Streamable HTTP
diff --git a/services/AiService/src/AiService.Mcp/McpDependencyInjection.cs b/services/AiService/src/AiService.Api/Mcp/McpDependencyInjection.cs
similarity index 78%
rename from services/AiService/src/AiService.Mcp/McpDependencyInjection.cs
rename to services/AiService/src/AiService.Api/Mcp/McpDependencyInjection.cs
index db9e3b71..9a2f314f 100644
--- a/services/AiService/src/AiService.Mcp/McpDependencyInjection.cs
+++ b/services/AiService/src/AiService.Api/Mcp/McpDependencyInjection.cs
@@ -1,7 +1,6 @@
-using AiService.Tools.Registry;
-using Microsoft.Extensions.DependencyInjection;
+using AiService.Api.Tools.Registry;
-namespace AiService.Mcp;
+namespace AiService.Api.Mcp;
public static class McpDependencyInjection
{
diff --git a/services/AiService/src/AiService.Mcp/McpServerExtensions.cs b/services/AiService/src/AiService.Api/Mcp/McpServerExtensions.cs
similarity index 94%
rename from services/AiService/src/AiService.Mcp/McpServerExtensions.cs
rename to services/AiService/src/AiService.Api/Mcp/McpServerExtensions.cs
index 74b8b369..63ad2f4a 100644
--- a/services/AiService/src/AiService.Mcp/McpServerExtensions.cs
+++ b/services/AiService/src/AiService.Api/Mcp/McpServerExtensions.cs
@@ -1,19 +1,13 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Application;
-using AiService.Tools.Domain;
-using AiService.Tools.Registry;
-using AiService.Tools.Selection;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Routing;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
+using AiService.Api.Application;
+using AiService.Api.Tools.Domain;
+using AiService.Api.Tools.Registry;
+using AiService.Api.Tools.Selection;
using ModelContextProtocol;
using ModelContextProtocol.Protocol;
-using ModelContextProtocol.Server;
-namespace AiService.Mcp;
+namespace AiService.Api.Mcp;
public static class McpServerExtensions
{
diff --git a/services/AiService/src/AiService.Mcp/McpToolCatalogService.cs b/services/AiService/src/AiService.Api/Mcp/McpToolCatalogService.cs
similarity index 94%
rename from services/AiService/src/AiService.Mcp/McpToolCatalogService.cs
rename to services/AiService/src/AiService.Api/Mcp/McpToolCatalogService.cs
index 5b5fe1dd..583fc87b 100644
--- a/services/AiService/src/AiService.Mcp/McpToolCatalogService.cs
+++ b/services/AiService/src/AiService.Api/Mcp/McpToolCatalogService.cs
@@ -1,9 +1,9 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Domain;
-using AiService.Tools.Registry;
-using AiService.Tools.Selection;
+using AiService.Api.Tools.Domain;
+using AiService.Api.Tools.Registry;
+using AiService.Api.Tools.Selection;
-namespace AiService.Mcp;
+namespace AiService.Api.Mcp;
///
/// Presents the audit tool catalog for GET /api/mcp-tools (mirrors Python MCP router).
diff --git a/services/AiService/src/AiService.Api/Program.cs b/services/AiService/src/AiService.Api/Program.cs
index 3cbd06c4..36c012ac 100644
--- a/services/AiService/src/AiService.Api/Program.cs
+++ b/services/AiService/src/AiService.Api/Program.cs
@@ -1,5 +1,5 @@
using AiService.Api;
-using AiService.Mcp;
+using AiService.Api.Mcp;
using WebsiteProfiling.Hosting;
var builder = WebApplication.CreateBuilder(args);
@@ -36,4 +36,7 @@
app.Run();
-public partial class Program;
+namespace AiService.Api
+{
+ public partial class Program;
+}
diff --git a/services/AiService/src/AiService.Providers/Chat/AnthropicChatClient.cs b/services/AiService/src/AiService.Api/Providers/Chat/AnthropicChatClient.cs
similarity index 99%
rename from services/AiService/src/AiService.Providers/Chat/AnthropicChatClient.cs
rename to services/AiService/src/AiService.Api/Providers/Chat/AnthropicChatClient.cs
index 4776fdc8..e4e2fc5a 100644
--- a/services/AiService/src/AiService.Providers/Chat/AnthropicChatClient.cs
+++ b/services/AiService/src/AiService.Api/Providers/Chat/AnthropicChatClient.cs
@@ -1,12 +1,11 @@
using System.Net.Http.Headers;
-using System.Net.Http.Json;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Domain;
+using AiService.Api.Domain;
using Microsoft.Extensions.AI;
-namespace AiService.Providers.Chat;
+namespace AiService.Api.Providers.Chat;
/// MEAI adapter over the Anthropic Messages HTTP API.
internal sealed class AnthropicChatClient(string apiKey, string model, TimeSpan timeout) : IChatClient
diff --git a/services/AiService/src/AiService.Providers/Chat/ChatClientFactory.cs b/services/AiService/src/AiService.Api/Providers/Chat/ChatClientFactory.cs
similarity index 95%
rename from services/AiService/src/AiService.Providers/Chat/ChatClientFactory.cs
rename to services/AiService/src/AiService.Api/Providers/Chat/ChatClientFactory.cs
index 320e65ee..60763d39 100644
--- a/services/AiService/src/AiService.Providers/Chat/ChatClientFactory.cs
+++ b/services/AiService/src/AiService.Api/Providers/Chat/ChatClientFactory.cs
@@ -1,12 +1,11 @@
using System.ClientModel;
-using AiService.Domain;
-using AiService.Domain.Models;
-using AiService.Domain.Repositories;
-using AiService.Providers.Chat;
+using AiService.Api.Domain;
+using AiService.Api.Domain.Models;
+using AiService.Api.Domain.Repositories;
using Microsoft.Extensions.AI;
using OpenAI;
-namespace AiService.Providers.Chat;
+namespace AiService.Api.Providers.Chat;
public sealed class ChatClientFactory(ILlmSettingsRepository configRepository) : IChatClientFactory
{
diff --git a/services/AiService/src/AiService.Providers/Chat/IChatClientFactory.cs b/services/AiService/src/AiService.Api/Providers/Chat/IChatClientFactory.cs
similarity index 74%
rename from services/AiService/src/AiService.Providers/Chat/IChatClientFactory.cs
rename to services/AiService/src/AiService.Api/Providers/Chat/IChatClientFactory.cs
index 6ca4de77..4ea8b7c8 100644
--- a/services/AiService/src/AiService.Providers/Chat/IChatClientFactory.cs
+++ b/services/AiService/src/AiService.Api/Providers/Chat/IChatClientFactory.cs
@@ -1,7 +1,7 @@
-using AiService.Domain.Models;
+using AiService.Api.Domain.Models;
using Microsoft.Extensions.AI;
-namespace AiService.Providers.Chat;
+namespace AiService.Api.Providers.Chat;
public interface IChatClientFactory
{
diff --git a/services/AiService/src/AiService.Providers/Chat/JsonResponseParser.cs b/services/AiService/src/AiService.Api/Providers/Chat/JsonResponseParser.cs
similarity index 97%
rename from services/AiService/src/AiService.Providers/Chat/JsonResponseParser.cs
rename to services/AiService/src/AiService.Api/Providers/Chat/JsonResponseParser.cs
index 905d6b3e..b01baa3f 100644
--- a/services/AiService/src/AiService.Providers/Chat/JsonResponseParser.cs
+++ b/services/AiService/src/AiService.Api/Providers/Chat/JsonResponseParser.cs
@@ -2,7 +2,7 @@
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
-namespace AiService.Providers.Chat;
+namespace AiService.Api.Providers.Chat;
public static partial class JsonResponseParser
{
diff --git a/services/AiService/src/AiService.Providers/Chat/LlmConfigHelpers.cs b/services/AiService/src/AiService.Api/Providers/Chat/LlmConfigHelpers.cs
similarity index 96%
rename from services/AiService/src/AiService.Providers/Chat/LlmConfigHelpers.cs
rename to services/AiService/src/AiService.Api/Providers/Chat/LlmConfigHelpers.cs
index 4e835d69..d0ee9a14 100644
--- a/services/AiService/src/AiService.Providers/Chat/LlmConfigHelpers.cs
+++ b/services/AiService/src/AiService.Api/Providers/Chat/LlmConfigHelpers.cs
@@ -1,7 +1,7 @@
-using AiService.Domain;
-using AiService.Domain.Models;
+using AiService.Api.Domain;
+using AiService.Api.Domain.Models;
-namespace AiService.Providers.Chat;
+namespace AiService.Api.Providers.Chat;
public static class LlmConfigHelpers
{
diff --git a/services/AiService/src/AiService.Providers/Chat/LlmTransportFailures.cs b/services/AiService/src/AiService.Api/Providers/Chat/LlmTransportFailures.cs
similarity index 94%
rename from services/AiService/src/AiService.Providers/Chat/LlmTransportFailures.cs
rename to services/AiService/src/AiService.Api/Providers/Chat/LlmTransportFailures.cs
index b8316b29..095a27d9 100644
--- a/services/AiService/src/AiService.Providers/Chat/LlmTransportFailures.cs
+++ b/services/AiService/src/AiService.Api/Providers/Chat/LlmTransportFailures.cs
@@ -1,7 +1,6 @@
-using System.Net.Http;
using System.Net.Sockets;
-namespace AiService.Providers.Chat;
+namespace AiService.Api.Providers.Chat;
/// Detect transport-level LLM failures (daemon down, DNS, timeout) vs parse/logic errors.
public static class LlmTransportFailures
diff --git a/services/AiService/src/AiService.Providers/Chat/StructuredCompletionService.cs b/services/AiService/src/AiService.Api/Providers/Chat/StructuredCompletionService.cs
similarity index 96%
rename from services/AiService/src/AiService.Providers/Chat/StructuredCompletionService.cs
rename to services/AiService/src/AiService.Api/Providers/Chat/StructuredCompletionService.cs
index 37b2b544..a0055bdc 100644
--- a/services/AiService/src/AiService.Providers/Chat/StructuredCompletionService.cs
+++ b/services/AiService/src/AiService.Api/Providers/Chat/StructuredCompletionService.cs
@@ -1,10 +1,9 @@
using System.Text;
using System.Text.Json.Nodes;
-using AiService.Domain.Models;
+using AiService.Api.Domain.Models;
using Microsoft.Extensions.AI;
-using Microsoft.Extensions.Logging;
-namespace AiService.Providers.Chat;
+namespace AiService.Api.Providers.Chat;
/// Structured JSON completions via .
public sealed class StructuredCompletionService(IChatClientFactory chatClientFactory, ILogger logger)
diff --git a/services/AiService/src/AiService.Providers/DependencyInjection.cs b/services/AiService/src/AiService.Api/Providers/DependencyInjection.cs
similarity index 73%
rename from services/AiService/src/AiService.Providers/DependencyInjection.cs
rename to services/AiService/src/AiService.Api/Providers/DependencyInjection.cs
index 076d8478..00bb92ea 100644
--- a/services/AiService/src/AiService.Providers/DependencyInjection.cs
+++ b/services/AiService/src/AiService.Api/Providers/DependencyInjection.cs
@@ -1,7 +1,6 @@
-using AiService.Providers.Chat;
-using Microsoft.Extensions.DependencyInjection;
+using AiService.Api.Providers.Chat;
-namespace AiService.Providers;
+namespace AiService.Api.Providers;
public static class DependencyInjection
{
diff --git a/services/AiService/src/AiService.Tools/Artifacts/ArtifactStore.cs b/services/AiService/src/AiService.Api/Tools/Artifacts/ArtifactStore.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Artifacts/ArtifactStore.cs
rename to services/AiService/src/AiService.Api/Tools/Artifacts/ArtifactStore.cs
index 756ff54b..cba6aa54 100644
--- a/services/AiService/src/AiService.Tools/Artifacts/ArtifactStore.cs
+++ b/services/AiService/src/AiService.Api/Tools/Artifacts/ArtifactStore.cs
@@ -3,7 +3,7 @@
using System.Text.RegularExpressions;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Tools.Artifacts;
+namespace AiService.Api.Tools.Artifacts;
///
/// Temporary export artifact store (DATA_DIR/exports) with TTL. Ports Python
diff --git a/services/AiService/src/AiService.Tools/Bridge/DataServiceClient.cs b/services/AiService/src/AiService.Api/Tools/Bridge/DataServiceClient.cs
similarity index 97%
rename from services/AiService/src/AiService.Tools/Bridge/DataServiceClient.cs
rename to services/AiService/src/AiService.Api/Tools/Bridge/DataServiceClient.cs
index 361e272e..9fb7951b 100644
--- a/services/AiService/src/AiService.Tools/Bridge/DataServiceClient.cs
+++ b/services/AiService/src/AiService.Api/Tools/Bridge/DataServiceClient.cs
@@ -1,6 +1,6 @@
using WebsiteProfiling.Contracts.Report;
-namespace AiService.Tools.Bridge;
+namespace AiService.Api.Tools.Bridge;
///
/// HTTP client for the .NET Data service's report export deliverables
diff --git a/services/AiService/src/AiService.Tools/Bridge/PythonBridgeMetrics.cs b/services/AiService/src/AiService.Api/Tools/Bridge/PythonBridgeMetrics.cs
similarity index 93%
rename from services/AiService/src/AiService.Tools/Bridge/PythonBridgeMetrics.cs
rename to services/AiService/src/AiService.Api/Tools/Bridge/PythonBridgeMetrics.cs
index 4b59d743..8cbcd970 100644
--- a/services/AiService/src/AiService.Tools/Bridge/PythonBridgeMetrics.cs
+++ b/services/AiService/src/AiService.Api/Tools/Bridge/PythonBridgeMetrics.cs
@@ -1,4 +1,4 @@
-namespace AiService.Tools.Bridge;
+namespace AiService.Api.Tools.Bridge;
///
/// Tracks Python audit-tool bridge usage. When reaches zero
diff --git a/services/AiService/src/AiService.Tools/Bridge/PythonToolBridgeClient.cs b/services/AiService/src/AiService.Api/Tools/Bridge/PythonToolBridgeClient.cs
similarity index 93%
rename from services/AiService/src/AiService.Tools/Bridge/PythonToolBridgeClient.cs
rename to services/AiService/src/AiService.Api/Tools/Bridge/PythonToolBridgeClient.cs
index a0200d8d..a71215bd 100644
--- a/services/AiService/src/AiService.Tools/Bridge/PythonToolBridgeClient.cs
+++ b/services/AiService/src/AiService.Api/Tools/Bridge/PythonToolBridgeClient.cs
@@ -1,9 +1,8 @@
-using System.Net.Http.Json;
using System.Text.Json.Nodes;
-using AiService.Tools.Options;
+using AiService.Api.Tools.Options;
using Microsoft.Extensions.Options;
-namespace AiService.Tools.Bridge;
+namespace AiService.Api.Tools.Bridge;
///
/// HTTP bridge to Python audit tools via POST {FASTAPI_URL}/api/report/audit-tool.
diff --git a/services/AiService/src/AiService.Tools/Compare/CompareHelpers.cs b/services/AiService/src/AiService.Api/Tools/Compare/CompareHelpers.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Compare/CompareHelpers.cs
rename to services/AiService/src/AiService.Api/Tools/Compare/CompareHelpers.cs
index 91d974cf..b1cbd47d 100644
--- a/services/AiService/src/AiService.Tools/Compare/CompareHelpers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Compare/CompareHelpers.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Nodes;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Tools.Compare;
+namespace AiService.Api.Tools.Compare;
///
/// Report payload comparison — ports Python reporting/compare_payload.py (parity with web
diff --git a/services/AiService/src/AiService.Tools/Context/AuditReportResolver.cs b/services/AiService/src/AiService.Api/Tools/Context/AuditReportResolver.cs
similarity index 98%
rename from services/AiService/src/AiService.Tools/Context/AuditReportResolver.cs
rename to services/AiService/src/AiService.Api/Tools/Context/AuditReportResolver.cs
index ee390e27..f57424c8 100644
--- a/services/AiService/src/AiService.Tools/Context/AuditReportResolver.cs
+++ b/services/AiService/src/AiService.Api/Tools/Context/AuditReportResolver.cs
@@ -1,8 +1,8 @@
using System.Text.RegularExpressions;
-using AiService.Tools.Persistence;
+using AiService.Api.Tools.Persistence;
using Microsoft.EntityFrameworkCore;
-namespace AiService.Tools.Context;
+namespace AiService.Api.Tools.Context;
///
/// Property-scoped report resolution for audit tools. Mirrors Data domain matching plus
diff --git a/services/AiService/src/AiService.Tools/Context/AuditToolContext.cs b/services/AiService/src/AiService.Api/Tools/Context/AuditToolContext.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Context/AuditToolContext.cs
rename to services/AiService/src/AiService.Api/Tools/Context/AuditToolContext.cs
index d1146ac6..7aac2968 100644
--- a/services/AiService/src/AiService.Tools/Context/AuditToolContext.cs
+++ b/services/AiService/src/AiService.Api/Tools/Context/AuditToolContext.cs
@@ -1,10 +1,9 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Tools.Persistence;
+using AiService.Api.Tools.Persistence;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Logging;
-namespace AiService.Tools.Context;
+namespace AiService.Api.Tools.Context;
///
/// Execution context for audit tools (property + report scope). Mirrors Python
diff --git a/services/AiService/src/AiService.Tools/DependencyInjection.cs b/services/AiService/src/AiService.Api/Tools/DependencyInjection.cs
similarity index 85%
rename from services/AiService/src/AiService.Tools/DependencyInjection.cs
rename to services/AiService/src/AiService.Api/Tools/DependencyInjection.cs
index ee59313a..4377cb12 100644
--- a/services/AiService/src/AiService.Tools/DependencyInjection.cs
+++ b/services/AiService/src/AiService.Api/Tools/DependencyInjection.cs
@@ -1,15 +1,13 @@
-using AiService.Tools.Bridge;
-using AiService.Tools.Options;
-using AiService.Tools.Persistence;
-using AiService.Tools.Registry;
-using AiService.Tools.Selection;
-using AiService.Tools.Services.Citations;
-using Microsoft.Extensions.DependencyInjection;
+using AiService.Api.Tools.Bridge;
+using AiService.Api.Tools.Options;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Registry;
+using AiService.Api.Tools.Selection;
+using AiService.Api.Tools.Services.Citations;
using Microsoft.Extensions.Options;
using WebsiteProfiling.Data;
-using WebsiteProfiling.Data.EntityFrameworkCore;
-namespace AiService.Tools;
+namespace AiService.Api.Tools;
public static class DependencyInjection
{
@@ -37,6 +35,11 @@ public static IServiceCollection AddAiServiceTools(this IServiceCollection servi
.BindConfiguration(DataServiceOptions.SectionName)
.PostConfigure(o =>
{
+ var core = Environment.GetEnvironmentVariable("CORE_SERVICE_URL");
+ if (!string.IsNullOrWhiteSpace(core))
+ {
+ o.BaseUrl = core.Trim();
+ }
var dataService = Environment.GetEnvironmentVariable("DATA_SERVICE_URL");
if (!string.IsNullOrWhiteSpace(dataService))
{
diff --git a/services/AiService/src/AiService.Tools/Domain/AuditToolDomains.cs b/services/AiService/src/AiService.Api/Tools/Domain/AuditToolDomains.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Domain/AuditToolDomains.cs
rename to services/AiService/src/AiService.Api/Tools/Domain/AuditToolDomains.cs
index 87726d98..602f2fab 100644
--- a/services/AiService/src/AiService.Tools/Domain/AuditToolDomains.cs
+++ b/services/AiService/src/AiService.Api/Tools/Domain/AuditToolDomains.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Registry;
+using AiService.Api.Tools.Registry;
-namespace AiService.Tools.Domain;
+namespace AiService.Api.Tools.Domain;
///
/// MCP domain bundles and classification. Ports Python
diff --git a/services/AiService/src/AiService.Tools/Handlers/Backlinks/BacklinksToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Backlinks/BacklinksToolHandlers.cs
similarity index 98%
rename from services/AiService/src/AiService.Tools/Handlers/Backlinks/BacklinksToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Backlinks/BacklinksToolHandlers.cs
index 77147d97..5181283d 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Backlinks/BacklinksToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Backlinks/BacklinksToolHandlers.cs
@@ -1,13 +1,12 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Slice;
-using AiService.Tools.Persistence;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Slice;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Logging;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Tools.Handlers.Backlinks;
+namespace AiService.Api.Tools.Handlers.Backlinks;
/// Backlinks and GSC links tools — ports Python backlinks/backlinks.py.
public static class BacklinksToolHandlers
diff --git a/services/AiService/src/AiService.Tools/Handlers/Core/CoreToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Core/CoreToolHandlers.cs
similarity index 96%
rename from services/AiService/src/AiService.Tools/Handlers/Core/CoreToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Core/CoreToolHandlers.cs
index 9a74dc18..943f2c26 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Core/CoreToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Core/CoreToolHandlers.cs
@@ -1,15 +1,14 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Domain;
-using AiService.Tools.Persistence;
-using AiService.Tools.Registry;
-using AiService.Tools.Selection;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Domain;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Registry;
+using AiService.Api.Tools.Selection;
+using AiService.Api.Tools.Slice;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.DependencyInjection;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Tools.Handlers.Core;
+namespace AiService.Api.Tools.Handlers.Core;
public static class CoreToolHandlers
{
diff --git a/services/AiService/src/AiService.Tools/Handlers/Core/PayloadExtrasToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Core/PayloadExtrasToolHandlers.cs
similarity index 97%
rename from services/AiService/src/AiService.Tools/Handlers/Core/PayloadExtrasToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Core/PayloadExtrasToolHandlers.cs
index e3277cc1..05bd1836 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Core/PayloadExtrasToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Core/PayloadExtrasToolHandlers.cs
@@ -1,10 +1,10 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Json;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Handlers.Core;
+namespace AiService.Api.Tools.Handlers.Core;
/// Extra payload slice tools — ports Python core/payload_extras.py.
public static class PayloadExtrasToolHandlers
diff --git a/services/AiService/src/AiService.Tools/Handlers/Core/WorkflowToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Core/WorkflowToolHandlers.cs
similarity index 96%
rename from services/AiService/src/AiService.Tools/Handlers/Core/WorkflowToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Core/WorkflowToolHandlers.cs
index dfab2ad5..8c4102a6 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Core/WorkflowToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Core/WorkflowToolHandlers.cs
@@ -1,14 +1,13 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Domain;
-using AiService.Tools.Registry;
-using AiService.Tools.Selection;
-using AiService.Tools.Slice;
-using Microsoft.Extensions.DependencyInjection;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Domain;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Registry;
+using AiService.Api.Tools.Selection;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Json;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Handlers.Core;
+namespace AiService.Api.Tools.Handlers.Core;
/// Tier-0 workflow orchestrators — ports Python core/router_tools.py.
public static class WorkflowToolHandlers
diff --git a/services/AiService/src/AiService.Tools/Handlers/Drift/DriftToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Drift/DriftToolHandlers.cs
similarity index 98%
rename from services/AiService/src/AiService.Tools/Handlers/Drift/DriftToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Drift/DriftToolHandlers.cs
index 82c424b0..30926ca3 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Drift/DriftToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Drift/DriftToolHandlers.cs
@@ -1,13 +1,13 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Compare;
-using AiService.Tools.Context;
-using AiService.Tools.Handlers.Google;
-using AiService.Tools.Persistence;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Compare;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Handlers.Google;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Slice;
using Microsoft.EntityFrameworkCore;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Tools.Handlers.Drift;
+namespace AiService.Api.Tools.Handlers.Drift;
///
/// Report compare/drift tools — ports Python compare/compare_slices.py, compare/compare.py,
diff --git a/services/AiService/src/AiService.Tools/Handlers/Export/ExportToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Export/ExportToolHandlers.cs
similarity index 98%
rename from services/AiService/src/AiService.Tools/Handlers/Export/ExportToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Export/ExportToolHandlers.cs
index b0373d24..7873ead9 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Export/ExportToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Export/ExportToolHandlers.cs
@@ -1,15 +1,15 @@
using System.Text;
using System.Text.Json.Nodes;
-using AiService.Tools.Artifacts;
-using AiService.Tools.Bridge;
-using AiService.Tools.Context;
-using AiService.Tools.Registry;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Artifacts;
+using AiService.Api.Tools.Bridge;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Registry;
+using AiService.Api.Tools.Slice;
using Microsoft.EntityFrameworkCore;
using WebsiteProfiling.Contracts.Json;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Handlers.Export;
+namespace AiService.Api.Tools.Handlers.Export;
/// Export and deliverable tools — ports Python export/export_tools.py and
/// export/export_extras.py.
@@ -435,7 +435,7 @@ public static Task ListExportFormatsAsync(
"Export broken links as CSV",
"Compare this report to report 38 as CSV"),
["notes"] = new JsonArray(
- "PDF requires the Data service (DATA_SERVICE_URL; see services/Data/)",
+ "PDF requires CoreService (CORE_SERVICE_URL or DATA_SERVICE_URL; see services/CoreService/)",
"Artifacts expire after 24 hours",
"Chat UI shows download buttons after export tools run"),
};
diff --git a/services/AiService/src/AiService.Tools/Handlers/Geo/GeoAuditHelpers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoAuditHelpers.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Handlers/Geo/GeoAuditHelpers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoAuditHelpers.cs
index fd3ca0ae..0bdb2008 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Geo/GeoAuditHelpers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoAuditHelpers.cs
@@ -1,9 +1,8 @@
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
-using AiService.Tools.Slice;
-using WebsiteProfiling.Contracts.Json;
+using AiService.Api.Tools.Slice;
-namespace AiService.Tools.Handlers.Geo;
+namespace AiService.Api.Tools.Handlers.Geo;
/// Shared GEO/AEO audit helpers — ports Python geo/geo_tools.py and geo/geo_list_tools.py.
public static class GeoAuditHelpers
diff --git a/services/AiService/src/AiService.Tools/Handlers/Geo/GeoCitabilityToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoCitabilityToolHandlers.cs
similarity index 98%
rename from services/AiService/src/AiService.Tools/Handlers/Geo/GeoCitabilityToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoCitabilityToolHandlers.cs
index 0e0afce5..c2000846 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Geo/GeoCitabilityToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoCitabilityToolHandlers.cs
@@ -1,11 +1,11 @@
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
-using AiService.Tools.Context;
-using AiService.Tools.Persistence;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Tools.Handlers.Geo;
+namespace AiService.Api.Tools.Handlers.Geo;
///
/// Research-backed citability score (0-100) for GEO/AEO — ports Python geo/geo_citability.py.
diff --git a/services/AiService/src/AiService.Tools/Handlers/Geo/GeoDetectorsToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoDetectorsToolHandlers.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Handlers/Geo/GeoDetectorsToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoDetectorsToolHandlers.cs
index 3472884e..3d5a801c 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Geo/GeoDetectorsToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoDetectorsToolHandlers.cs
@@ -1,11 +1,11 @@
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
-using AiService.Tools.Context;
-using AiService.Tools.Persistence;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Tools.Handlers.Geo;
+namespace AiService.Api.Tools.Handlers.Geo;
///
/// Advanced GEO/AEO detectors — ports Python geo/geo_detectors.py: negative signals, prompt
diff --git a/services/AiService/src/AiService.Tools/Handlers/Geo/GeoGenerationToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoGenerationToolHandlers.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Handlers/Geo/GeoGenerationToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoGenerationToolHandlers.cs
index 3f7ff0a5..9d206c94 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Geo/GeoGenerationToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoGenerationToolHandlers.cs
@@ -1,10 +1,10 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
using WebsiteProfiling.Contracts.Json;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Handlers.Geo;
+namespace AiService.Api.Tools.Handlers.Geo;
/// GEO file generators — ports Python integrations/llm_tools.py schema/robots/meta tools.
public static class GeoGenerationToolHandlers
diff --git a/services/AiService/src/AiService.Tools/Handlers/Geo/GeoListToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoListToolHandlers.cs
similarity index 98%
rename from services/AiService/src/AiService.Tools/Handlers/Geo/GeoListToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoListToolHandlers.cs
index c6f378ac..4b8cabfe 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Geo/GeoListToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoListToolHandlers.cs
@@ -1,11 +1,11 @@
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
-using AiService.Tools.Context;
-using AiService.Tools.Persistence;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Tools.Handlers.Geo;
+namespace AiService.Api.Tools.Handlers.Geo;
///
/// GEO/AEO page-level list tools + robots AI-bot tier scoring — ports Python geo/geo_list_tools.py.
diff --git a/services/AiService/src/AiService.Tools/Handlers/Geo/GeoToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoToolHandlers.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Handlers/Geo/GeoToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoToolHandlers.cs
index 98d627bc..0bb52581 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Geo/GeoToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Geo/GeoToolHandlers.cs
@@ -1,11 +1,11 @@
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
-using AiService.Tools.Context;
-using AiService.Tools.Persistence;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Tools.Handlers.Geo;
+namespace AiService.Api.Tools.Handlers.Geo;
/// GEO/AEO audit read tools — ports Python geo/geo_tools.py.
public static class GeoToolHandlers
diff --git a/services/AiService/src/AiService.Tools/Handlers/Geo/ReadingLevel.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Geo/ReadingLevel.cs
similarity index 97%
rename from services/AiService/src/AiService.Tools/Handlers/Geo/ReadingLevel.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Geo/ReadingLevel.cs
index f453e32b..9584d91d 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Geo/ReadingLevel.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Geo/ReadingLevel.cs
@@ -1,6 +1,6 @@
using System.Text.RegularExpressions;
-namespace AiService.Tools.Handlers.Geo;
+namespace AiService.Api.Tools.Handlers.Geo;
/// Ports Python content_analysis/reading_level.py.
public static partial class ReadingLevel
diff --git a/services/AiService/src/AiService.Tools/Handlers/Google/GoogleToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Google/GoogleToolHandlers.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Handlers/Google/GoogleToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Google/GoogleToolHandlers.cs
index 8b2a903d..5f8ce536 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Google/GoogleToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Google/GoogleToolHandlers.cs
@@ -1,10 +1,10 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Json;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Handlers.Google;
+namespace AiService.Api.Tools.Handlers.Google;
public static class GoogleToolHandlers
{
diff --git a/services/AiService/src/AiService.Tools/Handlers/Indexation/IndexationToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Indexation/IndexationToolHandlers.cs
similarity index 96%
rename from services/AiService/src/AiService.Tools/Handlers/Indexation/IndexationToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Indexation/IndexationToolHandlers.cs
index 5645711d..61e9be1d 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Indexation/IndexationToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Indexation/IndexationToolHandlers.cs
@@ -1,10 +1,10 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Json;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Handlers.Indexation;
+namespace AiService.Api.Tools.Handlers.Indexation;
/// Indexation coverage tools — ports Python indexation/indexation_tools.py.
public static class IndexationToolHandlers
diff --git a/services/AiService/src/AiService.Tools/Handlers/Insight/InsightLogic.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Insight/InsightLogic.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Handlers/Insight/InsightLogic.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Insight/InsightLogic.cs
index 724dd9e1..ffd18f23 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Insight/InsightLogic.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Insight/InsightLogic.cs
@@ -1,11 +1,10 @@
-using System.Globalization;
using System.Text.Json.Nodes;
-using AiService.Tools.Models.Insight;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Models.Insight;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Google;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Tools.Handlers.Insight;
+namespace AiService.Api.Tools.Handlers.Insight;
///
/// Pure cross-platform insight math — faithful port of Python
diff --git a/services/AiService/src/AiService.Tools/Handlers/Insight/InsightToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Insight/InsightToolHandlers.cs
similarity index 96%
rename from services/AiService/src/AiService.Tools/Handlers/Insight/InsightToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Insight/InsightToolHandlers.cs
index d48ac505..712d8064 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Insight/InsightToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Insight/InsightToolHandlers.cs
@@ -1,12 +1,12 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Mapping;
-using AiService.Tools.Models.Insight;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Handlers.Report;
+using AiService.Api.Tools.Mapping;
+using AiService.Api.Tools.Models.Insight;
+using AiService.Api.Tools.Persistence;
using WebsiteProfiling.Contracts.Json;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Handlers.Insight;
+namespace AiService.Api.Tools.Handlers.Insight;
///
/// Native cross-platform insight tools (GSC + GA4 blending). Faithful port of Python
@@ -193,7 +193,7 @@ public static async Task GetIssueToTrafficMapAsync(
{
var withSort = args.DeepClone() as JsonObject ?? [];
withSort["sort"] = "impact";
- var result = await Handlers.Report.ReportToolHandlers.ListIssuesAsync(db, ctx, withSort, cancellationToken);
+ var result = await ReportToolHandlers.ListIssuesAsync(db, ctx, withSort, cancellationToken);
if (result.TryGetPropertyValue("error", out _))
{
return result;
diff --git a/services/AiService/src/AiService.Tools/Handlers/Integrations/IntegrationToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Integrations/IntegrationToolHandlers.cs
similarity index 94%
rename from services/AiService/src/AiService.Tools/Handlers/Integrations/IntegrationToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Integrations/IntegrationToolHandlers.cs
index a475d52d..e200df1d 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Integrations/IntegrationToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Integrations/IntegrationToolHandlers.cs
@@ -1,14 +1,11 @@
-using System.Net.Http.Headers;
-using System.Net.Http.Json;
using System.Text.Json.Nodes;
-using AiService.Domain;
-using AiService.Tools.Services.Citations;
-using AiService.Tools.Context;
-using AiService.Tools.Slice;
+using AiService.Api.Domain;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Services.Citations;
using WebsiteProfiling.Contracts.Json;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Handlers.Integrations;
+namespace AiService.Api.Tools.Handlers.Integrations;
public static class IntegrationToolHandlers
{
diff --git a/services/AiService/src/AiService.Tools/Handlers/Issues/IssuesToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Issues/IssuesToolHandlers.cs
similarity index 94%
rename from services/AiService/src/AiService.Tools/Handlers/Issues/IssuesToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Issues/IssuesToolHandlers.cs
index d0ddb6f5..5f80d9f5 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Issues/IssuesToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Issues/IssuesToolHandlers.cs
@@ -1,10 +1,10 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Handlers.Report;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Handlers.Report;
+using AiService.Api.Tools.Persistence;
using WebsiteProfiling.Contracts.Json;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Handlers.Issues;
+namespace AiService.Api.Tools.Handlers.Issues;
/// Category-scoped issue tools — ports Python issues/issues.py.
public static class IssuesToolHandlers
diff --git a/services/AiService/src/AiService.Tools/Handlers/Keywords/KeywordsToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Keywords/KeywordsToolHandlers.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Handlers/Keywords/KeywordsToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Keywords/KeywordsToolHandlers.cs
index aa6a45cc..f5aee45b 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Keywords/KeywordsToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Keywords/KeywordsToolHandlers.cs
@@ -1,10 +1,10 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Json;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Handlers.Keywords;
+namespace AiService.Api.Tools.Handlers.Keywords;
///
/// Keyword query/list tools — ports Python keywords/keywords.py and
diff --git a/services/AiService/src/AiService.Tools/Handlers/Links/LinksToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Links/LinksToolHandlers.cs
similarity index 98%
rename from services/AiService/src/AiService.Tools/Handlers/Links/LinksToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Links/LinksToolHandlers.cs
index 435c37af..243b58a3 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Links/LinksToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Links/LinksToolHandlers.cs
@@ -1,10 +1,10 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Json;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Handlers.Links;
+namespace AiService.Api.Tools.Handlers.Links;
/// Internal linking tools — ports Python links/links.py.
public static class LinksToolHandlers
diff --git a/services/AiService/src/AiService.Tools/Handlers/Performance/PerformanceToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Performance/PerformanceToolHandlers.cs
similarity index 98%
rename from services/AiService/src/AiService.Tools/Handlers/Performance/PerformanceToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Performance/PerformanceToolHandlers.cs
index c738aa52..666037d5 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Performance/PerformanceToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Performance/PerformanceToolHandlers.cs
@@ -1,10 +1,10 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Json;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Handlers.Performance;
+namespace AiService.Api.Tools.Handlers.Performance;
/// Lighthouse performance tools — ports Python performance/lighthouse.py (payload-only paths).
public static class PerformanceToolHandlers
diff --git a/services/AiService/src/AiService.Tools/Handlers/Portfolio/PortfolioToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Portfolio/PortfolioToolHandlers.cs
similarity index 96%
rename from services/AiService/src/AiService.Tools/Handlers/Portfolio/PortfolioToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Portfolio/PortfolioToolHandlers.cs
index cf47358d..3716d43e 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Portfolio/PortfolioToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Portfolio/PortfolioToolHandlers.cs
@@ -1,14 +1,12 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Handlers.Report;
-using AiService.Tools.Persistence;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Handlers.Report;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Slice;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Logging;
-using WebsiteProfiling.Contracts.Json;
-namespace AiService.Tools.Handlers.Portfolio;
+namespace AiService.Api.Tools.Handlers.Portfolio;
/// Portfolio and chart aggregate tools — ports Python portfolio modules.
public static class PortfolioToolHandlers
diff --git a/services/AiService/src/AiService.Tools/Handlers/Report/ReportToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Report/ReportToolHandlers.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Handlers/Report/ReportToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Report/ReportToolHandlers.cs
index 027b5ec7..c73bff9a 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Report/ReportToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Report/ReportToolHandlers.cs
@@ -1,10 +1,10 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-
-using AiService.Tools.Persistence;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
using WebsiteProfiling.Contracts.Report;
-namespace AiService.Tools.Handlers.Report;
+
+namespace AiService.Api.Tools.Handlers.Report;
///
/// Report summary and issue query tools. Ports Python
diff --git a/services/AiService/src/AiService.Tools/Handlers/Schema/SchemaToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Schema/SchemaToolHandlers.cs
similarity index 97%
rename from services/AiService/src/AiService.Tools/Handlers/Schema/SchemaToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Schema/SchemaToolHandlers.cs
index 3da4510c..13e4f225 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Schema/SchemaToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Schema/SchemaToolHandlers.cs
@@ -1,10 +1,10 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Json;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Handlers.Schema;
+namespace AiService.Api.Tools.Handlers.Schema;
/// Schema markup audit tools — ports Python schema/schema.py.
public static class SchemaToolHandlers
diff --git a/services/AiService/src/AiService.Tools/Handlers/Security/SecurityToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Security/SecurityToolHandlers.cs
similarity index 96%
rename from services/AiService/src/AiService.Tools/Handlers/Security/SecurityToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Security/SecurityToolHandlers.cs
index 66e36895..f723be62 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Security/SecurityToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Security/SecurityToolHandlers.cs
@@ -1,10 +1,10 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Json;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Handlers.Security;
+namespace AiService.Api.Tools.Handlers.Security;
/// Security findings tools — ports Python security/security.py.
public static class SecurityToolHandlers
diff --git a/services/AiService/src/AiService.Tools/Handlers/Slice/PayloadSliceToolHandlers.cs b/services/AiService/src/AiService.Api/Tools/Handlers/Slice/PayloadSliceToolHandlers.cs
similarity index 93%
rename from services/AiService/src/AiService.Tools/Handlers/Slice/PayloadSliceToolHandlers.cs
rename to services/AiService/src/AiService.Api/Tools/Handlers/Slice/PayloadSliceToolHandlers.cs
index e508ca0c..052f3a88 100644
--- a/services/AiService/src/AiService.Tools/Handlers/Slice/PayloadSliceToolHandlers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Handlers/Slice/PayloadSliceToolHandlers.cs
@@ -1,10 +1,10 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Registry;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Registry;
+using AiService.Api.Tools.Slice;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Handlers.Slice;
+namespace AiService.Api.Tools.Handlers.Slice;
///
/// Bulk payload slice reads — ports simple Python tools using payload_dict_slice / payload_field.
diff --git a/services/AiService/src/AiService.Tools/Mapping/CrawlRowMapper.cs b/services/AiService/src/AiService.Api/Tools/Mapping/CrawlRowMapper.cs
similarity index 96%
rename from services/AiService/src/AiService.Tools/Mapping/CrawlRowMapper.cs
rename to services/AiService/src/AiService.Api/Tools/Mapping/CrawlRowMapper.cs
index 5b8b0710..2fcec960 100644
--- a/services/AiService/src/AiService.Tools/Mapping/CrawlRowMapper.cs
+++ b/services/AiService/src/AiService.Api/Tools/Mapping/CrawlRowMapper.cs
@@ -1,8 +1,8 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Slice;
using WebsiteProfiling.Contracts.Crawl;
-namespace AiService.Tools.Mapping;
+namespace AiService.Api.Tools.Mapping;
public static class CrawlRowMapper
{
diff --git a/services/AiService/src/AiService.Tools/Mapping/PayloadSliceMapper.cs b/services/AiService/src/AiService.Api/Tools/Mapping/PayloadSliceMapper.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Mapping/PayloadSliceMapper.cs
rename to services/AiService/src/AiService.Api/Tools/Mapping/PayloadSliceMapper.cs
index 371a3540..7a655119 100644
--- a/services/AiService/src/AiService.Tools/Mapping/PayloadSliceMapper.cs
+++ b/services/AiService/src/AiService.Api/Tools/Mapping/PayloadSliceMapper.cs
@@ -4,7 +4,7 @@
using WebsiteProfiling.Contracts.Json;
using WebsiteProfiling.Contracts.Report;
-namespace AiService.Tools.Mapping;
+namespace AiService.Api.Tools.Mapping;
public static class PayloadSliceMapper
{
diff --git a/services/AiService/src/AiService.Tools/Mapping/ToolArgsMapper.cs b/services/AiService/src/AiService.Api/Tools/Mapping/ToolArgsMapper.cs
similarity index 92%
rename from services/AiService/src/AiService.Tools/Mapping/ToolArgsMapper.cs
rename to services/AiService/src/AiService.Api/Tools/Mapping/ToolArgsMapper.cs
index aadcc744..7237737d 100644
--- a/services/AiService/src/AiService.Tools/Mapping/ToolArgsMapper.cs
+++ b/services/AiService/src/AiService.Api/Tools/Mapping/ToolArgsMapper.cs
@@ -2,7 +2,7 @@
using System.Text.Json.Nodes;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Tools.Mapping;
+namespace AiService.Api.Tools.Mapping;
public static class ToolArgsMapper
{
diff --git a/services/AiService/src/AiService.Tools/Mapping/ToolResultMapper.cs b/services/AiService/src/AiService.Api/Tools/Mapping/ToolResultMapper.cs
similarity index 89%
rename from services/AiService/src/AiService.Tools/Mapping/ToolResultMapper.cs
rename to services/AiService/src/AiService.Api/Tools/Mapping/ToolResultMapper.cs
index b0a35ee9..047ffaf0 100644
--- a/services/AiService/src/AiService.Tools/Mapping/ToolResultMapper.cs
+++ b/services/AiService/src/AiService.Api/Tools/Mapping/ToolResultMapper.cs
@@ -2,7 +2,7 @@
using System.Text.Json.Nodes;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Tools.Mapping;
+namespace AiService.Api.Tools.Mapping;
public static class ToolResultMapper
{
diff --git a/services/AiService/src/AiService.Tools/Models/Core/Tier0ToolModels.cs b/services/AiService/src/AiService.Api/Tools/Models/Core/Tier0ToolModels.cs
similarity index 95%
rename from services/AiService/src/AiService.Tools/Models/Core/Tier0ToolModels.cs
rename to services/AiService/src/AiService.Api/Tools/Models/Core/Tier0ToolModels.cs
index ab4899eb..c74f6271 100644
--- a/services/AiService/src/AiService.Tools/Models/Core/Tier0ToolModels.cs
+++ b/services/AiService/src/AiService.Api/Tools/Models/Core/Tier0ToolModels.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace AiService.Tools.Models.Core;
+namespace AiService.Api.Tools.Models.Core;
/// Args for Tier-0 router/SQL tools (batch 3 migration).
public sealed record RunSqlQueryArgs
diff --git a/services/AiService/src/AiService.Tools/Models/Insight/InsightToolModels.cs b/services/AiService/src/AiService.Api/Tools/Models/Insight/InsightToolModels.cs
similarity index 98%
rename from services/AiService/src/AiService.Tools/Models/Insight/InsightToolModels.cs
rename to services/AiService/src/AiService.Api/Tools/Models/Insight/InsightToolModels.cs
index 004e99f8..e4d69f77 100644
--- a/services/AiService/src/AiService.Tools/Models/Insight/InsightToolModels.cs
+++ b/services/AiService/src/AiService.Api/Tools/Models/Insight/InsightToolModels.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Serialization;
using WebsiteProfiling.Contracts.Google;
-namespace AiService.Tools.Models.Insight;
+namespace AiService.Api.Tools.Models.Insight;
public sealed record BlendedTableArgs
{
diff --git a/services/AiService/src/AiService.Tools/Modules/ToolHandlerModules.cs b/services/AiService/src/AiService.Api/Tools/Modules/ToolHandlerModules.cs
similarity index 96%
rename from services/AiService/src/AiService.Tools/Modules/ToolHandlerModules.cs
rename to services/AiService/src/AiService.Api/Tools/Modules/ToolHandlerModules.cs
index 6e47808f..fe539d3b 100644
--- a/services/AiService/src/AiService.Tools/Modules/ToolHandlerModules.cs
+++ b/services/AiService/src/AiService.Api/Tools/Modules/ToolHandlerModules.cs
@@ -1,27 +1,26 @@
-using AiService.Tools.Services.Citations;
-using AiService.Tools.Bridge;
-using AiService.Tools.Handlers.Backlinks;
-using AiService.Tools.Handlers.Core;
-using AiService.Tools.Handlers.Export;
-using AiService.Tools.Handlers.Geo;
-using AiService.Tools.Handlers.Google;
-using AiService.Tools.Handlers.Indexation;
-using AiService.Tools.Handlers.Insight;
-using AiService.Tools.Handlers.Integrations;
-using AiService.Tools.Handlers.Issues;
-using AiService.Tools.Handlers.Drift;
-using AiService.Tools.Handlers.Keywords;
-using AiService.Tools.Handlers.Links;
-using AiService.Tools.Handlers.Performance;
-using AiService.Tools.Handlers.Portfolio;
-using AiService.Tools.Handlers.Report;
-using AiService.Tools.Handlers.Schema;
-using AiService.Tools.Handlers.Security;
-using AiService.Tools.Handlers.Slice;
-using AiService.Tools.Registry;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace AiService.Tools.Modules;
+using AiService.Api.Tools.Bridge;
+using AiService.Api.Tools.Handlers.Backlinks;
+using AiService.Api.Tools.Handlers.Core;
+using AiService.Api.Tools.Handlers.Drift;
+using AiService.Api.Tools.Handlers.Export;
+using AiService.Api.Tools.Handlers.Geo;
+using AiService.Api.Tools.Handlers.Google;
+using AiService.Api.Tools.Handlers.Indexation;
+using AiService.Api.Tools.Handlers.Insight;
+using AiService.Api.Tools.Handlers.Integrations;
+using AiService.Api.Tools.Handlers.Issues;
+using AiService.Api.Tools.Handlers.Keywords;
+using AiService.Api.Tools.Handlers.Links;
+using AiService.Api.Tools.Handlers.Performance;
+using AiService.Api.Tools.Handlers.Portfolio;
+using AiService.Api.Tools.Handlers.Report;
+using AiService.Api.Tools.Handlers.Schema;
+using AiService.Api.Tools.Handlers.Security;
+using AiService.Api.Tools.Handlers.Slice;
+using AiService.Api.Tools.Registry;
+using AiService.Api.Tools.Services.Citations;
+
+namespace AiService.Api.Tools.Modules;
///
/// Registers native C# audit tool handlers by domain. Extend one module at a time as tools are ported from Python.
diff --git a/services/AiService/src/AiService.Tools/Options/DataServiceOptions.cs b/services/AiService/src/AiService.Api/Tools/Options/DataServiceOptions.cs
similarity index 58%
rename from services/AiService/src/AiService.Tools/Options/DataServiceOptions.cs
rename to services/AiService/src/AiService.Api/Tools/Options/DataServiceOptions.cs
index 487b43a0..3237df0d 100644
--- a/services/AiService/src/AiService.Tools/Options/DataServiceOptions.cs
+++ b/services/AiService/src/AiService.Api/Tools/Options/DataServiceOptions.cs
@@ -1,4 +1,4 @@
-namespace AiService.Tools.Options;
+namespace AiService.Api.Tools.Options;
///
/// Data service upstream used by for report PDF/CSV/JSON
@@ -8,6 +8,6 @@ public sealed class DataServiceOptions
{
public const string SectionName = "DataService";
- /// Data service base URL. Default matches local compose / BFF upstream.
- public string BaseUrl { get; set; } = "http://127.0.0.1:8091";
+ /// Core/Data service base URL. Default matches local compose / BFF upstream.
+ public string BaseUrl { get; set; } = "http://127.0.0.1:8094";
}
diff --git a/services/AiService/src/AiService.Tools/Options/FastApiOptions.cs b/services/AiService/src/AiService.Api/Tools/Options/FastApiOptions.cs
similarity index 91%
rename from services/AiService/src/AiService.Tools/Options/FastApiOptions.cs
rename to services/AiService/src/AiService.Api/Tools/Options/FastApiOptions.cs
index 9872ba84..3e3f4830 100644
--- a/services/AiService/src/AiService.Tools/Options/FastApiOptions.cs
+++ b/services/AiService/src/AiService.Api/Tools/Options/FastApiOptions.cs
@@ -1,4 +1,4 @@
-namespace AiService.Tools.Options;
+namespace AiService.Api.Tools.Options;
///
/// FastAPI upstream used by for tools not yet ported to C#.
diff --git a/services/AiService/src/AiService.Tools/Persistence/AuditToolsDbContext.cs b/services/AiService/src/AiService.Api/Tools/Persistence/AuditToolsDbContext.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Persistence/AuditToolsDbContext.cs
rename to services/AiService/src/AiService.Api/Tools/Persistence/AuditToolsDbContext.cs
index b1e3b2b9..3b033bb1 100644
--- a/services/AiService/src/AiService.Tools/Persistence/AuditToolsDbContext.cs
+++ b/services/AiService/src/AiService.Api/Tools/Persistence/AuditToolsDbContext.cs
@@ -1,7 +1,6 @@
using Microsoft.EntityFrameworkCore;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Persistence;
+namespace AiService.Api.Tools.Persistence;
public sealed class ReportPayloadRow
{
diff --git a/services/AiService/src/AiService.Tools/Registry/DelegatingToolHandler.cs b/services/AiService/src/AiService.Api/Tools/Registry/DelegatingToolHandler.cs
similarity index 81%
rename from services/AiService/src/AiService.Tools/Registry/DelegatingToolHandler.cs
rename to services/AiService/src/AiService.Api/Tools/Registry/DelegatingToolHandler.cs
index 462d73fc..5c7a1e94 100644
--- a/services/AiService/src/AiService.Tools/Registry/DelegatingToolHandler.cs
+++ b/services/AiService/src/AiService.Api/Tools/Registry/DelegatingToolHandler.cs
@@ -1,8 +1,8 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Persistence;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
-namespace AiService.Tools.Registry;
+namespace AiService.Api.Tools.Registry;
public sealed class DelegatingToolHandler(
string toolName,
diff --git a/services/AiService/src/AiService.Tools/Registry/IToolHandler.cs b/services/AiService/src/AiService.Api/Tools/Registry/IToolHandler.cs
similarity index 75%
rename from services/AiService/src/AiService.Tools/Registry/IToolHandler.cs
rename to services/AiService/src/AiService.Api/Tools/Registry/IToolHandler.cs
index 54abd540..a5286d74 100644
--- a/services/AiService/src/AiService.Tools/Registry/IToolHandler.cs
+++ b/services/AiService/src/AiService.Api/Tools/Registry/IToolHandler.cs
@@ -1,8 +1,8 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Persistence;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
-namespace AiService.Tools.Registry;
+namespace AiService.Api.Tools.Registry;
/// Single audit tool handler — mirrors Python registry call signature.
public interface IToolHandler
diff --git a/services/AiService/src/AiService.Tools/Registry/ToolCatalog.cs b/services/AiService/src/AiService.Api/Tools/Registry/ToolCatalog.cs
similarity index 98%
rename from services/AiService/src/AiService.Tools/Registry/ToolCatalog.cs
rename to services/AiService/src/AiService.Api/Tools/Registry/ToolCatalog.cs
index 315b43da..c5678a00 100644
--- a/services/AiService/src/AiService.Tools/Registry/ToolCatalog.cs
+++ b/services/AiService/src/AiService.Api/Tools/Registry/ToolCatalog.cs
@@ -2,7 +2,7 @@
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
-namespace AiService.Tools.Registry;
+namespace AiService.Api.Tools.Registry;
///
/// Loads the embedded tool_catalog.json and exposes OpenAI-compatible function definitions.
diff --git a/services/AiService/src/AiService.Tools/Registry/ToolCatalogEntryLookup.cs b/services/AiService/src/AiService.Api/Tools/Registry/ToolCatalogEntryLookup.cs
similarity index 92%
rename from services/AiService/src/AiService.Tools/Registry/ToolCatalogEntryLookup.cs
rename to services/AiService/src/AiService.Api/Tools/Registry/ToolCatalogEntryLookup.cs
index 57ae2d28..0d6ccf93 100644
--- a/services/AiService/src/AiService.Tools/Registry/ToolCatalogEntryLookup.cs
+++ b/services/AiService/src/AiService.Api/Tools/Registry/ToolCatalogEntryLookup.cs
@@ -1,7 +1,6 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Registry;
-namespace AiService.Tools.Registry;
+namespace AiService.Api.Tools.Registry;
/// Lightweight catalog entry lookup for MCP list_tools responses.
public sealed class ToolCatalogEntryLookup(ToolCatalog catalog)
diff --git a/services/AiService/src/AiService.Tools/Registry/ToolDispatcher.cs b/services/AiService/src/AiService.Api/Tools/Registry/ToolDispatcher.cs
similarity index 93%
rename from services/AiService/src/AiService.Tools/Registry/ToolDispatcher.cs
rename to services/AiService/src/AiService.Api/Tools/Registry/ToolDispatcher.cs
index 11b95ded..c7085fcc 100644
--- a/services/AiService/src/AiService.Tools/Registry/ToolDispatcher.cs
+++ b/services/AiService/src/AiService.Api/Tools/Registry/ToolDispatcher.cs
@@ -1,12 +1,11 @@
using System.Diagnostics;
using System.Text.Json.Nodes;
-using AiService.Tools.Bridge;
-using AiService.Tools.Context;
-using AiService.Tools.Persistence;
+using AiService.Api.Tools.Bridge;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Logging;
-namespace AiService.Tools.Registry;
+namespace AiService.Api.Tools.Registry;
///
/// Dispatches a tool call using EF Core. Native C# handlers take precedence;
diff --git a/services/AiService/src/AiService.Tools/Registry/ToolRegistry.cs b/services/AiService/src/AiService.Api/Tools/Registry/ToolRegistry.cs
similarity index 96%
rename from services/AiService/src/AiService.Tools/Registry/ToolRegistry.cs
rename to services/AiService/src/AiService.Api/Tools/Registry/ToolRegistry.cs
index dddfb465..134e12c2 100644
--- a/services/AiService/src/AiService.Tools/Registry/ToolRegistry.cs
+++ b/services/AiService/src/AiService.Api/Tools/Registry/ToolRegistry.cs
@@ -1,4 +1,4 @@
-namespace AiService.Tools.Registry;
+namespace AiService.Api.Tools.Registry;
/// Maps tool names to C# handlers registered at startup.
public sealed class ToolRegistry
diff --git a/services/AiService/src/AiService.Tools/Selection/AuditToolSelection.cs b/services/AiService/src/AiService.Api/Tools/Selection/AuditToolSelection.cs
similarity index 97%
rename from services/AiService/src/AiService.Tools/Selection/AuditToolSelection.cs
rename to services/AiService/src/AiService.Api/Tools/Selection/AuditToolSelection.cs
index d266273d..05bdc5e8 100644
--- a/services/AiService/src/AiService.Tools/Selection/AuditToolSelection.cs
+++ b/services/AiService/src/AiService.Api/Tools/Selection/AuditToolSelection.cs
@@ -1,12 +1,11 @@
using System.Text.Json;
-using AiService.Domain.Models;
-using AiService.Domain.Repositories;
-using AiService.Tools.Domain;
-using AiService.Tools.Registry;
+using AiService.Api.Domain.Models;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Tools.Domain;
+using AiService.Api.Tools.Registry;
using Microsoft.Extensions.Caching.Memory;
-using Microsoft.Extensions.DependencyInjection;
-namespace AiService.Tools.Selection;
+namespace AiService.Api.Tools.Selection;
///
/// Resolves which audit tools are enabled from MCP settings, env, and per-tool opt-outs.
diff --git a/services/AiService/src/AiService.Tools/Selection/ChatToolSelector.cs b/services/AiService/src/AiService.Api/Tools/Selection/ChatToolSelector.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Selection/ChatToolSelector.cs
rename to services/AiService/src/AiService.Api/Tools/Selection/ChatToolSelector.cs
index 42fc563c..034e00b3 100644
--- a/services/AiService/src/AiService.Tools/Selection/ChatToolSelector.cs
+++ b/services/AiService/src/AiService.Api/Tools/Selection/ChatToolSelector.cs
@@ -1,8 +1,7 @@
using System.Text.RegularExpressions;
-using AiService.Tools.Domain;
-using AiService.Tools.Registry;
+using AiService.Api.Tools.Domain;
-namespace AiService.Tools.Selection;
+namespace AiService.Api.Tools.Selection;
///
/// Dynamic per-turn tool selection for chat (ports Python tool_selector.py).
diff --git a/services/AiService/src/AiService.Tools/Selection/ToolCatalogSearch.cs b/services/AiService/src/AiService.Api/Tools/Selection/ToolCatalogSearch.cs
similarity index 95%
rename from services/AiService/src/AiService.Tools/Selection/ToolCatalogSearch.cs
rename to services/AiService/src/AiService.Api/Tools/Selection/ToolCatalogSearch.cs
index ee376490..5a33fc2f 100644
--- a/services/AiService/src/AiService.Tools/Selection/ToolCatalogSearch.cs
+++ b/services/AiService/src/AiService.Api/Tools/Selection/ToolCatalogSearch.cs
@@ -1,8 +1,8 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Domain;
-using AiService.Tools.Registry;
+using AiService.Api.Tools.Domain;
+using AiService.Api.Tools.Registry;
-namespace AiService.Tools.Selection;
+namespace AiService.Api.Tools.Selection;
/// Keyword search over tool catalog — ports Python registry.search_tools.
public static class ToolCatalogSearch
diff --git a/services/AiService/src/AiService.Tools/Services/Citations/CitationCheckService.cs b/services/AiService/src/AiService.Api/Tools/Services/Citations/CitationCheckService.cs
similarity index 98%
rename from services/AiService/src/AiService.Tools/Services/Citations/CitationCheckService.cs
rename to services/AiService/src/AiService.Api/Tools/Services/Citations/CitationCheckService.cs
index 15e784d5..f3649599 100644
--- a/services/AiService/src/AiService.Tools/Services/Citations/CitationCheckService.cs
+++ b/services/AiService/src/AiService.Api/Tools/Services/Citations/CitationCheckService.cs
@@ -1,12 +1,11 @@
using System.Net.Http.Headers;
-using System.Net.Http.Json;
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
-using AiService.Domain;
-using AiService.Domain.Models;
-using AiService.Domain.Repositories;
+using AiService.Api.Domain;
+using AiService.Api.Domain.Models;
+using AiService.Api.Domain.Repositories;
-namespace AiService.Tools.Services.Citations;
+namespace AiService.Api.Tools.Services.Citations;
///
/// Live AI citation checks — ports Python integrations/ai_citations.
diff --git a/services/AiService/src/AiService.Tools/Services/Citations/CitationModels.cs b/services/AiService/src/AiService.Api/Tools/Services/Citations/CitationModels.cs
similarity index 85%
rename from services/AiService/src/AiService.Tools/Services/Citations/CitationModels.cs
rename to services/AiService/src/AiService.Api/Tools/Services/Citations/CitationModels.cs
index 3133d2cd..a0148c68 100644
--- a/services/AiService/src/AiService.Tools/Services/Citations/CitationModels.cs
+++ b/services/AiService/src/AiService.Api/Tools/Services/Citations/CitationModels.cs
@@ -1,6 +1,6 @@
-using AiService.Domain;
+using AiService.Api.Domain;
-namespace AiService.Tools.Services.Citations;
+namespace AiService.Api.Tools.Services.Citations;
public sealed record CitationResult(
string Query,
diff --git a/services/AiService/src/AiService.Tools/Slice/CrawlFilter.cs b/services/AiService/src/AiService.Api/Tools/Slice/CrawlFilter.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Slice/CrawlFilter.cs
rename to services/AiService/src/AiService.Api/Tools/Slice/CrawlFilter.cs
index 9bb6f721..9fae293c 100644
--- a/services/AiService/src/AiService.Tools/Slice/CrawlFilter.cs
+++ b/services/AiService/src/AiService.Api/Tools/Slice/CrawlFilter.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Nodes;
using WebsiteProfiling.Contracts.Crawl;
-namespace AiService.Tools.Slice;
+namespace AiService.Api.Tools.Slice;
///
/// Crawl row filtering helpers — faithful port of Python
diff --git a/services/AiService/src/AiService.Tools/Slice/CrawlSliceHelpers.cs b/services/AiService/src/AiService.Api/Tools/Slice/CrawlSliceHelpers.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Slice/CrawlSliceHelpers.cs
rename to services/AiService/src/AiService.Api/Tools/Slice/CrawlSliceHelpers.cs
index 16a105b7..d77456b4 100644
--- a/services/AiService/src/AiService.Tools/Slice/CrawlSliceHelpers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Slice/CrawlSliceHelpers.cs
@@ -2,7 +2,7 @@
using System.Text.Json.Nodes;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Tools.Slice;
+namespace AiService.Api.Tools.Slice;
/// Crawl dataframe filters — mirrors Python _slice.crawl_filter.
public static class CrawlSliceHelpers
diff --git a/services/AiService/src/AiService.Tools/Slice/GoogleUrl.cs b/services/AiService/src/AiService.Api/Tools/Slice/GoogleUrl.cs
similarity index 98%
rename from services/AiService/src/AiService.Tools/Slice/GoogleUrl.cs
rename to services/AiService/src/AiService.Api/Tools/Slice/GoogleUrl.cs
index f24f5231..9c5c5940 100644
--- a/services/AiService/src/AiService.Tools/Slice/GoogleUrl.cs
+++ b/services/AiService/src/AiService.Api/Tools/Slice/GoogleUrl.cs
@@ -1,4 +1,4 @@
-namespace AiService.Tools.Slice;
+namespace AiService.Api.Tools.Slice;
///
/// URL normalization for joining crawl URLs with GSC pages and GA4 paths. Faithful port of
diff --git a/services/AiService/src/AiService.Tools/Slice/LinkSliceHelpers.cs b/services/AiService/src/AiService.Api/Tools/Slice/LinkSliceHelpers.cs
similarity index 97%
rename from services/AiService/src/AiService.Tools/Slice/LinkSliceHelpers.cs
rename to services/AiService/src/AiService.Api/Tools/Slice/LinkSliceHelpers.cs
index 07528358..ed82e434 100644
--- a/services/AiService/src/AiService.Tools/Slice/LinkSliceHelpers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Slice/LinkSliceHelpers.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Nodes;
using WebsiteProfiling.Contracts.Json;
-namespace AiService.Tools.Slice;
+namespace AiService.Api.Tools.Slice;
/// Link edge summaries — mirrors Python link_edges_report.summarize_link_rel.
public static class LinkSliceHelpers
diff --git a/services/AiService/src/AiService.Tools/Slice/PayloadArrayHelpers.cs b/services/AiService/src/AiService.Api/Tools/Slice/PayloadArrayHelpers.cs
similarity index 93%
rename from services/AiService/src/AiService.Tools/Slice/PayloadArrayHelpers.cs
rename to services/AiService/src/AiService.Api/Tools/Slice/PayloadArrayHelpers.cs
index 4ad36554..8f6139f9 100644
--- a/services/AiService/src/AiService.Tools/Slice/PayloadArrayHelpers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Slice/PayloadArrayHelpers.cs
@@ -1,8 +1,8 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
-using AiService.Tools.Persistence;
-namespace AiService.Tools.Slice;
+namespace AiService.Api.Tools.Slice;
/// Common capped payload array reads.
public static class PayloadArrayHelpers
diff --git a/services/AiService/src/AiService.Tools/Slice/PayloadSliceHelpers.cs b/services/AiService/src/AiService.Api/Tools/Slice/PayloadSliceHelpers.cs
similarity index 99%
rename from services/AiService/src/AiService.Tools/Slice/PayloadSliceHelpers.cs
rename to services/AiService/src/AiService.Api/Tools/Slice/PayloadSliceHelpers.cs
index d56d219f..dca3e80c 100644
--- a/services/AiService/src/AiService.Tools/Slice/PayloadSliceHelpers.cs
+++ b/services/AiService/src/AiService.Api/Tools/Slice/PayloadSliceHelpers.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-namespace AiService.Tools.Slice;
+namespace AiService.Api.Tools.Slice;
///
/// Shared list slicing and payload field helpers for audit tools. Mirrors Python
diff --git a/services/AiService/src/AiService.Tools/tool_catalog.json b/services/AiService/src/AiService.Api/Tools/tool_catalog.json
similarity index 100%
rename from services/AiService/src/AiService.Tools/tool_catalog.json
rename to services/AiService/src/AiService.Api/Tools/tool_catalog.json
diff --git a/services/AiService/src/AiService.Application/AiService.Application.csproj b/services/AiService/src/AiService.Application/AiService.Application.csproj
deleted file mode 100644
index 29b15f03..00000000
--- a/services/AiService/src/AiService.Application/AiService.Application.csproj
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
- net10.0
- enable
- enable
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/services/AiService/src/AiService.Domain/AiService.Domain.csproj b/services/AiService/src/AiService.Domain/AiService.Domain.csproj
deleted file mode 100644
index b7601447..00000000
--- a/services/AiService/src/AiService.Domain/AiService.Domain.csproj
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- net10.0
- enable
- enable
-
-
-
diff --git a/services/AiService/src/AiService.Mcp/AiService.Mcp.csproj b/services/AiService/src/AiService.Mcp/AiService.Mcp.csproj
deleted file mode 100644
index a9174e10..00000000
--- a/services/AiService/src/AiService.Mcp/AiService.Mcp.csproj
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- net10.0
- enable
- enable
- AiService.Mcp
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/services/AiService/src/AiService.Providers/AiService.Providers.csproj b/services/AiService/src/AiService.Providers/AiService.Providers.csproj
deleted file mode 100644
index 64fc68f8..00000000
--- a/services/AiService/src/AiService.Providers/AiService.Providers.csproj
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
- net10.0
- enable
- enable
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/services/AiService/src/AiService.Tools/AiService.Tools.csproj b/services/AiService/src/AiService.Tools/AiService.Tools.csproj
deleted file mode 100644
index ec44b582..00000000
--- a/services/AiService/src/AiService.Tools/AiService.Tools.csproj
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
- net10.0
- enable
- enable
- AiService.Tools
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/services/AiService/tests/AiService.Tests/AiService.Tests.csproj b/services/AiService/tests/AiService.Tests/AiService.Tests.csproj
index 0a7c746e..860eaf6f 100644
--- a/services/AiService/tests/AiService.Tests/AiService.Tests.csproj
+++ b/services/AiService/tests/AiService.Tests/AiService.Tests.csproj
@@ -1,4 +1,4 @@
-
+
net10.0
@@ -23,9 +23,6 @@
-
-
-
diff --git a/services/AiService/tests/AiService.Tests/AuditToolContextScopingTests.cs b/services/AiService/tests/AiService.Tests/AuditToolContextScopingTests.cs
index 3950506b..df2c4283 100644
--- a/services/AiService/tests/AiService.Tests/AuditToolContextScopingTests.cs
+++ b/services/AiService/tests/AiService.Tests/AuditToolContextScopingTests.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Persistence;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
using Microsoft.EntityFrameworkCore;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/AuditToolSelectionTests.cs b/services/AiService/tests/AiService.Tests/AuditToolSelectionTests.cs
index a1bbc4c3..0e7c0edc 100644
--- a/services/AiService/tests/AiService.Tests/AuditToolSelectionTests.cs
+++ b/services/AiService/tests/AiService.Tests/AuditToolSelectionTests.cs
@@ -1,7 +1,7 @@
-using AiService.Domain.Models;
-using AiService.Tools.Domain;
-using AiService.Tools.Registry;
-using AiService.Tools.Selection;
+using AiService.Api.Domain.Models;
+using AiService.Api.Tools.Domain;
+using AiService.Api.Tools.Registry;
+using AiService.Api.Tools.Selection;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/ChatAgentParityTests.cs b/services/AiService/tests/AiService.Tests/ChatAgentParityTests.cs
index 92b8a686..71fd4fcf 100644
--- a/services/AiService/tests/AiService.Tests/ChatAgentParityTests.cs
+++ b/services/AiService/tests/AiService.Tests/ChatAgentParityTests.cs
@@ -1,9 +1,9 @@
using System.Text.Json.Nodes;
-using AiService.Application.Chat;
-using AiService.Application.Prompts;
-using AiService.Domain.Models;
-using AiService.Tools.Domain;
-using AiService.Tools.Selection;
+using AiService.Api.Application.Chat;
+using AiService.Api.Application.Prompts;
+using AiService.Api.Domain.Models;
+using AiService.Api.Tools.Domain;
+using AiService.Api.Tools.Selection;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/ChatControllerPersistenceTests.cs b/services/AiService/tests/AiService.Tests/ChatControllerPersistenceTests.cs
index de1f7c74..c945e160 100644
--- a/services/AiService/tests/AiService.Tests/ChatControllerPersistenceTests.cs
+++ b/services/AiService/tests/AiService.Tests/ChatControllerPersistenceTests.cs
@@ -1,7 +1,7 @@
-using AiService.Application.Chat;
-using AiService.Domain;
-using AiService.Domain.Entities;
-using AiService.Domain.Repositories;
+using AiService.Api.Application.Chat;
+using AiService.Api.Domain;
+using AiService.Api.Domain.Entities;
+using AiService.Api.Domain.Repositories;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/ChatNarrativeFallbackTests.cs b/services/AiService/tests/AiService.Tests/ChatNarrativeFallbackTests.cs
index d66983a3..6361d475 100644
--- a/services/AiService/tests/AiService.Tests/ChatNarrativeFallbackTests.cs
+++ b/services/AiService/tests/AiService.Tests/ChatNarrativeFallbackTests.cs
@@ -1,4 +1,4 @@
-using AiService.Application.Chat;
+using AiService.Api.Application.Chat;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/ChatNarrativeParserTests.cs b/services/AiService/tests/AiService.Tests/ChatNarrativeParserTests.cs
index d7877a6b..4a06074a 100644
--- a/services/AiService/tests/AiService.Tests/ChatNarrativeParserTests.cs
+++ b/services/AiService/tests/AiService.Tests/ChatNarrativeParserTests.cs
@@ -1,4 +1,4 @@
-using AiService.Application.Chat;
+using AiService.Api.Application.Chat;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/ChatPersistenceMapperTests.cs b/services/AiService/tests/AiService.Tests/ChatPersistenceMapperTests.cs
index cf01f6bd..b4febabd 100644
--- a/services/AiService/tests/AiService.Tests/ChatPersistenceMapperTests.cs
+++ b/services/AiService/tests/AiService.Tests/ChatPersistenceMapperTests.cs
@@ -1,4 +1,4 @@
-using AiService.Application.Chat;
+using AiService.Api.Application.Chat;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/ChatSseSerializerTests.cs b/services/AiService/tests/AiService.Tests/ChatSseSerializerTests.cs
index a7be462e..a5faeaee 100644
--- a/services/AiService/tests/AiService.Tests/ChatSseSerializerTests.cs
+++ b/services/AiService/tests/AiService.Tests/ChatSseSerializerTests.cs
@@ -1,5 +1,5 @@
using System.Text.Json.Nodes;
-using AiService.Application.Chat;
+using AiService.Api.Application.Chat;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/CitationCheckServiceTests.cs b/services/AiService/tests/AiService.Tests/CitationCheckServiceTests.cs
index e2ee0f58..00d78b4d 100644
--- a/services/AiService/tests/AiService.Tests/CitationCheckServiceTests.cs
+++ b/services/AiService/tests/AiService.Tests/CitationCheckServiceTests.cs
@@ -1,6 +1,7 @@
-using AiService.Domain.Models;
-using AiService.Domain.Repositories;
-using AiService.Tools.Services.Citations;
+using AiService.Api.Domain.Models;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Tools.Services.Citations;
+using CitationCheckService = AiService.Api.Tools.Services.Citations.CitationCheckService;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/CompareHelpersTests.cs b/services/AiService/tests/AiService.Tests/CompareHelpersTests.cs
index 04e60eeb..8a7af0af 100644
--- a/services/AiService/tests/AiService.Tests/CompareHelpersTests.cs
+++ b/services/AiService/tests/AiService.Tests/CompareHelpersTests.cs
@@ -1,5 +1,5 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Compare;
+using AiService.Api.Tools.Compare;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/CrawlFilterTests.cs b/services/AiService/tests/AiService.Tests/CrawlFilterTests.cs
index fdce3cb6..f686683d 100644
--- a/services/AiService/tests/AiService.Tests/CrawlFilterTests.cs
+++ b/services/AiService/tests/AiService.Tests/CrawlFilterTests.cs
@@ -1,5 +1,5 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Slice;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/GeoAuditHelpersTests.cs b/services/AiService/tests/AiService.Tests/GeoAuditHelpersTests.cs
index f21fb066..74f19d55 100644
--- a/services/AiService/tests/AiService.Tests/GeoAuditHelpersTests.cs
+++ b/services/AiService/tests/AiService.Tests/GeoAuditHelpersTests.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Handlers.Geo;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Handlers.Geo;
+using AiService.Api.Tools.Slice;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/Handlers/ArtifactStoreTests.cs b/services/AiService/tests/AiService.Tests/Handlers/ArtifactStoreTests.cs
index 9bf70f05..f4c3171f 100644
--- a/services/AiService/tests/AiService.Tests/Handlers/ArtifactStoreTests.cs
+++ b/services/AiService/tests/AiService.Tests/Handlers/ArtifactStoreTests.cs
@@ -1,5 +1,5 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Artifacts;
+using ArtifactStore = AiService.Api.Tools.Artifacts.ArtifactStore;
namespace AiService.Tests.Handlers;
diff --git a/services/AiService/tests/AiService.Tests/Handlers/DriftToolHandlerTests.cs b/services/AiService/tests/AiService.Tests/Handlers/DriftToolHandlerTests.cs
index 8450b88d..88c83a65 100644
--- a/services/AiService/tests/AiService.Tests/Handlers/DriftToolHandlerTests.cs
+++ b/services/AiService/tests/AiService.Tests/Handlers/DriftToolHandlerTests.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Handlers.Drift;
-using AiService.Tools.Persistence;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Handlers.Drift;
+using AiService.Api.Tools.Persistence;
using Microsoft.EntityFrameworkCore;
namespace AiService.Tests.Handlers;
diff --git a/services/AiService/tests/AiService.Tests/Handlers/ExportToolHandlerTests.cs b/services/AiService/tests/AiService.Tests/Handlers/ExportToolHandlerTests.cs
index 8f8d0a7b..d866717a 100644
--- a/services/AiService/tests/AiService.Tests/Handlers/ExportToolHandlerTests.cs
+++ b/services/AiService/tests/AiService.Tests/Handlers/ExportToolHandlerTests.cs
@@ -1,15 +1,15 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Artifacts;
-using AiService.Tools.Bridge;
-using AiService.Tools.Context;
-using AiService.Tools.Handlers.Export;
-using AiService.Tools.Handlers.Security;
-using AiService.Tools.Options;
-using AiService.Tools.Persistence;
-using AiService.Tools.Registry;
+using AiService.Api.Tools.Bridge;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Handlers.Export;
+using AiService.Api.Tools.Handlers.Security;
+using AiService.Api.Tools.Options;
+using AiService.Api.Tools.Persistence;
+using AiService.Api.Tools.Registry;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
+using ArtifactStore = AiService.Api.Tools.Artifacts.ArtifactStore;
namespace AiService.Tests.Handlers;
diff --git a/services/AiService/tests/AiService.Tests/Handlers/GeoCitabilityToolHandlerTests.cs b/services/AiService/tests/AiService.Tests/Handlers/GeoCitabilityToolHandlerTests.cs
index ecb4b8bb..3731311f 100644
--- a/services/AiService/tests/AiService.Tests/Handlers/GeoCitabilityToolHandlerTests.cs
+++ b/services/AiService/tests/AiService.Tests/Handlers/GeoCitabilityToolHandlerTests.cs
@@ -1,8 +1,8 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Handlers.Geo;
-using AiService.Tools.Persistence;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
using Microsoft.EntityFrameworkCore;
+using GeoCitabilityToolHandlers = AiService.Api.Tools.Handlers.Geo.GeoCitabilityToolHandlers;
namespace AiService.Tests.Handlers;
diff --git a/services/AiService/tests/AiService.Tests/Handlers/GeoDetectorsToolHandlerTests.cs b/services/AiService/tests/AiService.Tests/Handlers/GeoDetectorsToolHandlerTests.cs
index 5655f97f..41cbb732 100644
--- a/services/AiService/tests/AiService.Tests/Handlers/GeoDetectorsToolHandlerTests.cs
+++ b/services/AiService/tests/AiService.Tests/Handlers/GeoDetectorsToolHandlerTests.cs
@@ -1,8 +1,8 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Handlers.Geo;
-using AiService.Tools.Persistence;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
using Microsoft.EntityFrameworkCore;
+using GeoDetectorsToolHandlers = AiService.Api.Tools.Handlers.Geo.GeoDetectorsToolHandlers;
namespace AiService.Tests.Handlers;
diff --git a/services/AiService/tests/AiService.Tests/Handlers/GeoListToolHandlerTests.cs b/services/AiService/tests/AiService.Tests/Handlers/GeoListToolHandlerTests.cs
index c201ebcc..78a67bdf 100644
--- a/services/AiService/tests/AiService.Tests/Handlers/GeoListToolHandlerTests.cs
+++ b/services/AiService/tests/AiService.Tests/Handlers/GeoListToolHandlerTests.cs
@@ -1,9 +1,9 @@
using System.Net;
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Handlers.Geo;
-using AiService.Tools.Persistence;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Persistence;
using Microsoft.EntityFrameworkCore;
+using GeoListToolHandlers = AiService.Api.Tools.Handlers.Geo.GeoListToolHandlers;
namespace AiService.Tests.Handlers;
diff --git a/services/AiService/tests/AiService.Tests/Handlers/GeoToolHandlersCompareTests.cs b/services/AiService/tests/AiService.Tests/Handlers/GeoToolHandlersCompareTests.cs
index 5f338537..8ad4b3ff 100644
--- a/services/AiService/tests/AiService.Tests/Handlers/GeoToolHandlersCompareTests.cs
+++ b/services/AiService/tests/AiService.Tests/Handlers/GeoToolHandlersCompareTests.cs
@@ -1,8 +1,8 @@
using System.Net;
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Handlers.Geo;
-using AiService.Tools.Persistence;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Handlers.Geo;
+using AiService.Api.Tools.Persistence;
using Microsoft.EntityFrameworkCore;
namespace AiService.Tests.Handlers;
diff --git a/services/AiService/tests/AiService.Tests/Handlers/KeywordsToolHandlerTests.cs b/services/AiService/tests/AiService.Tests/Handlers/KeywordsToolHandlerTests.cs
index c890328d..31bf0dcd 100644
--- a/services/AiService/tests/AiService.Tests/Handlers/KeywordsToolHandlerTests.cs
+++ b/services/AiService/tests/AiService.Tests/Handlers/KeywordsToolHandlerTests.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Handlers.Keywords;
-using AiService.Tools.Persistence;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Handlers.Keywords;
+using AiService.Api.Tools.Persistence;
using Microsoft.EntityFrameworkCore;
namespace AiService.Tests.Handlers;
diff --git a/services/AiService/tests/AiService.Tests/Handlers/SchemaToolHandlerTests.cs b/services/AiService/tests/AiService.Tests/Handlers/SchemaToolHandlerTests.cs
index fb54615b..cfaa2123 100644
--- a/services/AiService/tests/AiService.Tests/Handlers/SchemaToolHandlerTests.cs
+++ b/services/AiService/tests/AiService.Tests/Handlers/SchemaToolHandlerTests.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Context;
-using AiService.Tools.Handlers.Schema;
-using AiService.Tools.Persistence;
+using AiService.Api.Tools.Context;
+using AiService.Api.Tools.Handlers.Schema;
+using AiService.Api.Tools.Persistence;
using Microsoft.EntityFrameworkCore;
namespace AiService.Tests.Handlers;
diff --git a/services/AiService/tests/AiService.Tests/InsightLogicTests.cs b/services/AiService/tests/AiService.Tests/InsightLogicTests.cs
index 3d5570d3..94b0515d 100644
--- a/services/AiService/tests/AiService.Tests/InsightLogicTests.cs
+++ b/services/AiService/tests/AiService.Tests/InsightLogicTests.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-using AiService.Tools.Handlers.Insight;
-using AiService.Tools.Slice;
+using AiService.Api.Tools.Handlers.Insight;
+using AiService.Api.Tools.Slice;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/JsonNodeCopyTests.cs b/services/AiService/tests/AiService.Tests/JsonNodeCopyTests.cs
index e9de9162..4934f4e8 100644
--- a/services/AiService/tests/AiService.Tests/JsonNodeCopyTests.cs
+++ b/services/AiService/tests/AiService.Tests/JsonNodeCopyTests.cs
@@ -1,5 +1,5 @@
using System.Text.Json.Nodes;
-using AiService.Application.Json;
+using AiService.Api.Application.Json;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/LlmSettingsRepositoryTests.cs b/services/AiService/tests/AiService.Tests/LlmSettingsRepositoryTests.cs
index 4a290650..b3043d36 100644
--- a/services/AiService/tests/AiService.Tests/LlmSettingsRepositoryTests.cs
+++ b/services/AiService/tests/AiService.Tests/LlmSettingsRepositoryTests.cs
@@ -1,4 +1,4 @@
-using AiService.Application.Repositories;
+using AiService.Api.Application.Repositories;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/LlmTransportFailuresTests.cs b/services/AiService/tests/AiService.Tests/LlmTransportFailuresTests.cs
index ec38342d..4fd6d99f 100644
--- a/services/AiService/tests/AiService.Tests/LlmTransportFailuresTests.cs
+++ b/services/AiService/tests/AiService.Tests/LlmTransportFailuresTests.cs
@@ -1,6 +1,6 @@
using System.Net.Http;
using System.Net.Sockets;
-using AiService.Providers.Chat;
+using AiService.Api.Providers.Chat;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/McpBearerAuthFilterTests.cs b/services/AiService/tests/AiService.Tests/McpBearerAuthFilterTests.cs
index ff418bc3..02552d5f 100644
--- a/services/AiService/tests/AiService.Tests/McpBearerAuthFilterTests.cs
+++ b/services/AiService/tests/AiService.Tests/McpBearerAuthFilterTests.cs
@@ -1,6 +1,6 @@
-using AiService.Domain.Models;
-using AiService.Domain.Repositories;
-using AiService.Mcp;
+using AiService.Api.Domain.Models;
+using AiService.Api.Domain.Repositories;
+using AiService.Api.Mcp;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.Extensions.Caching.Memory;
diff --git a/services/AiService/tests/AiService.Tests/McpSettingsRepositoryTests.cs b/services/AiService/tests/AiService.Tests/McpSettingsRepositoryTests.cs
index 08191b1f..b0b4696a 100644
--- a/services/AiService/tests/AiService.Tests/McpSettingsRepositoryTests.cs
+++ b/services/AiService/tests/AiService.Tests/McpSettingsRepositoryTests.cs
@@ -1,8 +1,8 @@
-using AiService.Application.Mcp;
-using AiService.Application.Persistence;
-using AiService.Application.Repositories;
-using AiService.Domain.Entities;
-using AiService.Domain.Models;
+using AiService.Api.Application.Mcp;
+using AiService.Api.Application.Persistence;
+using AiService.Api.Application.Repositories;
+using AiService.Api.Domain.Entities;
+using AiService.Api.Domain.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
diff --git a/services/AiService/tests/AiService.Tests/McpToolsControllerTests.cs b/services/AiService/tests/AiService.Tests/McpToolsControllerTests.cs
index 2e1a8d3d..a0372490 100644
--- a/services/AiService/tests/AiService.Tests/McpToolsControllerTests.cs
+++ b/services/AiService/tests/AiService.Tests/McpToolsControllerTests.cs
@@ -14,7 +14,7 @@ public async Task Get_mcp_tools_returns_catalog_json()
using var env = ServiceRegistrationTestEnvironment.Push();
env.SetDefaultsForPostgresServices();
- await using var factory = new WebApplicationFactory().WithWebHostBuilder(builder =>
+ await using var factory = new WebApplicationFactory().WithWebHostBuilder(builder =>
{
builder.UseEnvironment("Development");
});
diff --git a/services/AiService/tests/AiService.Tests/NativeToolHandlerTests.cs b/services/AiService/tests/AiService.Tests/NativeToolHandlerTests.cs
index 33949d0e..0048e803 100644
--- a/services/AiService/tests/AiService.Tests/NativeToolHandlerTests.cs
+++ b/services/AiService/tests/AiService.Tests/NativeToolHandlerTests.cs
@@ -1,7 +1,5 @@
-using AiService.Application;
-using AiService.Application.Handlers;
-using AiService.Tools;
-using AiService.Tools.Modules;
+using AiService.Api.Application;
+using AiService.Api.Tools;
using Microsoft.Extensions.DependencyInjection;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/OllamaCatalogServiceTests.cs b/services/AiService/tests/AiService.Tests/OllamaCatalogServiceTests.cs
index 60e197cd..debbc73c 100644
--- a/services/AiService/tests/AiService.Tests/OllamaCatalogServiceTests.cs
+++ b/services/AiService/tests/AiService.Tests/OllamaCatalogServiceTests.cs
@@ -1,7 +1,7 @@
using System.Net;
using System.Text;
using System.Text.Json.Nodes;
-using AiService.Application.Services;
+using AiService.Api.Application.Services;
using Microsoft.Extensions.Logging.Abstractions;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/OllamaConnectionHealthTests.cs b/services/AiService/tests/AiService.Tests/OllamaConnectionHealthTests.cs
index 63c87a27..9fe566eb 100644
--- a/services/AiService/tests/AiService.Tests/OllamaConnectionHealthTests.cs
+++ b/services/AiService/tests/AiService.Tests/OllamaConnectionHealthTests.cs
@@ -1,4 +1,4 @@
-using AiService.Application.Services;
+using AiService.Api.Application.Services;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/SecretsKeyCatalogTests.cs b/services/AiService/tests/AiService.Tests/SecretsKeyCatalogTests.cs
index 37be51c9..6755acfb 100644
--- a/services/AiService/tests/AiService.Tests/SecretsKeyCatalogTests.cs
+++ b/services/AiService/tests/AiService.Tests/SecretsKeyCatalogTests.cs
@@ -1,4 +1,4 @@
-using AiService.Application.Services;
+using AiService.Api.Application.Services;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/SecretsServiceTests.cs b/services/AiService/tests/AiService.Tests/SecretsServiceTests.cs
index a3ccd726..4d7f592e 100644
--- a/services/AiService/tests/AiService.Tests/SecretsServiceTests.cs
+++ b/services/AiService/tests/AiService.Tests/SecretsServiceTests.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Nodes;
-using AiService.Application.Services;
-using AiService.Domain.Models;
-using AiService.Domain.Repositories;
+using AiService.Api.Application.Services;
+using AiService.Api.Domain.Models;
+using AiService.Api.Domain.Repositories;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/ServiceRegistrationValidationTests.cs b/services/AiService/tests/AiService.Tests/ServiceRegistrationValidationTests.cs
index a85e0cc1..a30dc695 100644
--- a/services/AiService/tests/AiService.Tests/ServiceRegistrationValidationTests.cs
+++ b/services/AiService/tests/AiService.Tests/ServiceRegistrationValidationTests.cs
@@ -1,6 +1,6 @@
-using AiService.Application.Services;
-using AiService.Mcp;
-using AiService.Tools.Selection;
+using AiService.Api.Application.Services;
+using AiService.Api.Mcp;
+using AiService.Api.Tools.Selection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
@@ -24,7 +24,7 @@ public void Web_host_resolves_core_services(bool enableMcpHttp)
env.SetDefaultsForPostgresServices();
env.Set("WP_MCP_HTTP", enableMcpHttp ? "1" : null);
- using var factory = new WebApplicationFactory().WithWebHostBuilder(builder =>
+ using var factory = new WebApplicationFactory().WithWebHostBuilder(builder =>
{
builder.UseEnvironment("Development");
});
diff --git a/services/AiService/tests/AiService.Tests/StreamingNarrativeExtractorTests.cs b/services/AiService/tests/AiService.Tests/StreamingNarrativeExtractorTests.cs
index 492f4d21..eb388035 100644
--- a/services/AiService/tests/AiService.Tests/StreamingNarrativeExtractorTests.cs
+++ b/services/AiService/tests/AiService.Tests/StreamingNarrativeExtractorTests.cs
@@ -1,4 +1,4 @@
-using AiService.Application.Chat;
+using AiService.Api.Application.Chat;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/StructuredCompletionStreamingTests.cs b/services/AiService/tests/AiService.Tests/StructuredCompletionStreamingTests.cs
index 733fbed0..71eaa523 100644
--- a/services/AiService/tests/AiService.Tests/StructuredCompletionStreamingTests.cs
+++ b/services/AiService/tests/AiService.Tests/StructuredCompletionStreamingTests.cs
@@ -2,8 +2,8 @@
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Text.Json.Nodes;
-using AiService.Domain.Models;
-using AiService.Providers.Chat;
+using AiService.Api.Domain.Models;
+using AiService.Api.Providers.Chat;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Logging.Abstractions;
diff --git a/services/AiService/tests/AiService.Tests/ToolCatalogTests.cs b/services/AiService/tests/AiService.Tests/ToolCatalogTests.cs
index 6f206834..9bf713d0 100644
--- a/services/AiService/tests/AiService.Tests/ToolCatalogTests.cs
+++ b/services/AiService/tests/AiService.Tests/ToolCatalogTests.cs
@@ -1,4 +1,4 @@
-using AiService.Tools.Registry;
+using AiService.Api.Tools.Registry;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/ToolConcurrencyTests.cs b/services/AiService/tests/AiService.Tests/ToolConcurrencyTests.cs
index b176e21e..d22765fb 100644
--- a/services/AiService/tests/AiService.Tests/ToolConcurrencyTests.cs
+++ b/services/AiService/tests/AiService.Tests/ToolConcurrencyTests.cs
@@ -1,5 +1,5 @@
using System.Text.Json.Nodes;
-using AiService.Application.Chat;
+using AiService.Api.Application.Chat;
namespace AiService.Tests;
diff --git a/services/AiService/tests/AiService.Tests/ToolResultCompactorTests.cs b/services/AiService/tests/AiService.Tests/ToolResultCompactorTests.cs
index aec8edaf..71ec6be3 100644
--- a/services/AiService/tests/AiService.Tests/ToolResultCompactorTests.cs
+++ b/services/AiService/tests/AiService.Tests/ToolResultCompactorTests.cs
@@ -1,5 +1,5 @@
using System.Text.Json.Nodes;
-using AiService.Application.Chat;
+using AiService.Api.Application.Chat;
namespace AiService.Tests;
diff --git a/services/Bff/Dockerfile b/services/Bff/Dockerfile
index b742168c..076ae254 100644
--- a/services/Bff/Dockerfile
+++ b/services/Bff/Dockerfile
@@ -1,13 +1,9 @@
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
-COPY services/Shared/WebsiteProfiling.Hosting/WebsiteProfiling.Hosting.csproj services/Shared/WebsiteProfiling.Hosting/
-COPY services/Shared/WebsiteProfiling.Contracts/WebsiteProfiling.Contracts.csproj services/Shared/WebsiteProfiling.Contracts/
-COPY services/Bff/src/Bff.Domain/Bff.Domain.csproj services/Bff/src/Bff.Domain/
-COPY services/Bff/src/Bff.Application/Bff.Application.csproj services/Bff/src/Bff.Application/
+COPY services/Shared/WebsiteProfiling.Shared/WebsiteProfiling.Shared.csproj services/Shared/WebsiteProfiling.Shared/
COPY services/Bff/src/Bff.Api/Bff.Api.csproj services/Bff/src/Bff.Api/
RUN dotnet restore services/Bff/src/Bff.Api/Bff.Api.csproj
-COPY services/Shared/WebsiteProfiling.Hosting/ services/Shared/WebsiteProfiling.Hosting/
-COPY services/Shared/WebsiteProfiling.Contracts/ services/Shared/WebsiteProfiling.Contracts/
+COPY services/Shared/WebsiteProfiling.Shared/ services/Shared/WebsiteProfiling.Shared/
COPY services/Bff/src/ services/Bff/src/
RUN dotnet publish services/Bff/src/Bff.Api/Bff.Api.csproj -c Release -o /app/publish --no-restore
diff --git a/services/Bff/generate-client.sh b/services/Bff/generate-client.sh
index 8937623a..f93f39af 100755
--- a/services/Bff/generate-client.sh
+++ b/services/Bff/generate-client.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Regenerate the typed FastAPI client (src/Bff.Application/Generated/FastApiClient.g.cs)
+# Regenerate the typed FastAPI client (src/Bff.Api/Application/Generated/FastApiClient.g.cs)
# from the committed OpenAPI spec (web/openapi.json).
#
# Prerequisite (one-time): dotnet tool install -g NSwag.ConsoleCore
@@ -7,4 +7,4 @@
set -e
cd "$(dirname "$0")"
nswag run nswag.json
-echo "Generated src/Bff.Application/Generated/FastApiClient.g.cs"
+echo "Generated src/Bff.Api/Application/Generated/FastApiClient.g.cs"
diff --git a/services/Bff/nswag.json b/services/Bff/nswag.json
index 0cc862c8..53468032 100644
--- a/services/Bff/nswag.json
+++ b/services/Bff/nswag.json
@@ -26,7 +26,7 @@
"exceptionClass": "FastApiClientException",
"useBaseUrl": false,
"generateNullableReferenceTypes": true,
- "output": "src/Bff.Application/Generated/FastApiClient.g.cs"
+ "output": "src/Bff.Api/Application/Generated/FastApiClient.g.cs"
}
}
}
diff --git a/services/Bff/src/Bff.Application/Auth/WpSessionTokens.cs b/services/Bff/src/Bff.Api/Application/Auth/WpSessionTokens.cs
similarity index 99%
rename from services/Bff/src/Bff.Application/Auth/WpSessionTokens.cs
rename to services/Bff/src/Bff.Api/Application/Auth/WpSessionTokens.cs
index cade4c33..c662b432 100644
--- a/services/Bff/src/Bff.Application/Auth/WpSessionTokens.cs
+++ b/services/Bff/src/Bff.Api/Application/Auth/WpSessionTokens.cs
@@ -2,7 +2,7 @@
using System.Security.Cryptography;
using System.Text;
-namespace Bff.Application.Auth;
+namespace Bff.Api.Application.Auth;
///
/// Create/verify the wp_session token, byte-for-byte compatible with the TypeScript
diff --git a/services/Bff/src/Bff.Application/DependencyInjection.cs b/services/Bff/src/Bff.Api/Application/DependencyInjection.cs
similarity index 94%
rename from services/Bff/src/Bff.Application/DependencyInjection.cs
rename to services/Bff/src/Bff.Api/Application/DependencyInjection.cs
index 3ec03730..5f6a9306 100644
--- a/services/Bff/src/Bff.Application/DependencyInjection.cs
+++ b/services/Bff/src/Bff.Api/Application/DependencyInjection.cs
@@ -1,8 +1,7 @@
-using Bff.Application.Http;
-using Bff.Application.Options;
-using Microsoft.Extensions.DependencyInjection;
+using Bff.Api.Application.Http;
+using Bff.Api.Application.Options;
-namespace Bff.Application;
+namespace Bff.Api.Application;
public static class DependencyInjection
{
@@ -38,6 +37,13 @@ public static IServiceCollection AddBffApplication(this IServiceCollection servi
{
o.FastApiBaseUrl = fastapi.Trim();
}
+ var core = Environment.GetEnvironmentVariable("CORE_SERVICE_URL");
+ if (!string.IsNullOrWhiteSpace(core))
+ {
+ o.DataBaseUrl = core.Trim();
+ o.IntegrationsBaseUrl = core.Trim();
+ o.ReportBaseUrl = core.Trim();
+ }
var data = Environment.GetEnvironmentVariable("DATA_SERVICE_URL");
if (!string.IsNullOrWhiteSpace(data))
{
@@ -204,7 +210,7 @@ public static IServiceCollection AddBffApplication(this IServiceCollection servi
// Typed FastAPI client generated from web/openapi.json (NSwag). The bulk of the gateway
// proxies opaque payloads via the generic forwarder; this typed client is available for
// aggregation/composition endpoints that need to read upstream responses by shape.
- services.AddHttpClient()
+ services.AddHttpClient()
.ConfigureHttpClient((sp, client) =>
{
var opts = GetUpstream(sp);
diff --git a/services/Bff/src/Bff.Application/Generated/FastApiClient.g.cs b/services/Bff/src/Bff.Api/Application/Generated/FastApiClient.g.cs
similarity index 100%
rename from services/Bff/src/Bff.Application/Generated/FastApiClient.g.cs
rename to services/Bff/src/Bff.Api/Application/Generated/FastApiClient.g.cs
diff --git a/services/Bff/src/Bff.Application/Http/HttpRequestMessageCloner.cs b/services/Bff/src/Bff.Api/Application/Http/HttpRequestMessageCloner.cs
similarity index 90%
rename from services/Bff/src/Bff.Application/Http/HttpRequestMessageCloner.cs
rename to services/Bff/src/Bff.Api/Application/Http/HttpRequestMessageCloner.cs
index 09ebd8d9..94703b76 100644
--- a/services/Bff/src/Bff.Application/Http/HttpRequestMessageCloner.cs
+++ b/services/Bff/src/Bff.Api/Application/Http/HttpRequestMessageCloner.cs
@@ -1,6 +1,4 @@
-using System.Net;
-
-namespace Bff.Application.Http;
+namespace Bff.Api.Application.Http;
internal static class HttpRequestMessageCloner
{
diff --git a/services/Bff/src/Bff.Application/Http/IdempotentRetryHandler.cs b/services/Bff/src/Bff.Api/Application/Http/IdempotentRetryHandler.cs
similarity index 98%
rename from services/Bff/src/Bff.Application/Http/IdempotentRetryHandler.cs
rename to services/Bff/src/Bff.Api/Application/Http/IdempotentRetryHandler.cs
index a80a8858..263c0905 100644
--- a/services/Bff/src/Bff.Application/Http/IdempotentRetryHandler.cs
+++ b/services/Bff/src/Bff.Api/Application/Http/IdempotentRetryHandler.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Bff.Application.Http;
+namespace Bff.Api.Application.Http;
///
/// Minimal, dependency-free resilience: retries transient failures for idempotent
diff --git a/services/Bff/src/Bff.Application/Options/AuthOptions.cs b/services/Bff/src/Bff.Api/Application/Options/AuthOptions.cs
similarity index 96%
rename from services/Bff/src/Bff.Application/Options/AuthOptions.cs
rename to services/Bff/src/Bff.Api/Application/Options/AuthOptions.cs
index b5b70806..6e06354b 100644
--- a/services/Bff/src/Bff.Application/Options/AuthOptions.cs
+++ b/services/Bff/src/Bff.Api/Application/Options/AuthOptions.cs
@@ -1,6 +1,6 @@
-using Bff.Domain;
+using Bff.Api.Domain;
-namespace Bff.Application.Options;
+namespace Bff.Api.Application.Options;
///
/// Auth configuration mirroring the TS env contract (web/src/server/auth.ts):
diff --git a/services/Bff/src/Bff.Application/Options/BffCorsOptions.cs b/services/Bff/src/Bff.Api/Application/Options/BffCorsOptions.cs
similarity index 91%
rename from services/Bff/src/Bff.Application/Options/BffCorsOptions.cs
rename to services/Bff/src/Bff.Api/Application/Options/BffCorsOptions.cs
index 3de42727..10a4e5f7 100644
--- a/services/Bff/src/Bff.Application/Options/BffCorsOptions.cs
+++ b/services/Bff/src/Bff.Api/Application/Options/BffCorsOptions.cs
@@ -1,4 +1,4 @@
-namespace Bff.Application.Options;
+namespace Bff.Api.Application.Options;
///
/// Credentialed-CORS configuration. The browser calls the BFF cross-origin, so we must
diff --git a/services/Bff/src/Bff.Application/Options/UpstreamOptions.cs b/services/Bff/src/Bff.Api/Application/Options/UpstreamOptions.cs
similarity index 93%
rename from services/Bff/src/Bff.Application/Options/UpstreamOptions.cs
rename to services/Bff/src/Bff.Api/Application/Options/UpstreamOptions.cs
index 3ac11f4f..166b6310 100644
--- a/services/Bff/src/Bff.Application/Options/UpstreamOptions.cs
+++ b/services/Bff/src/Bff.Api/Application/Options/UpstreamOptions.cs
@@ -1,4 +1,4 @@
-namespace Bff.Application.Options;
+namespace Bff.Api.Application.Options;
///
/// Base URLs + timeouts for the services the BFF fronts. Both upstreams are
@@ -14,11 +14,11 @@ public sealed class UpstreamOptions
/// Timeout for normal (non-streaming) upstream calls. Parity with the TS proxy (120s).
public int TimeoutSeconds { get; set; } = 120;
- /// Data service base URL (env override: DATA_SERVICE_URL). Internal .NET read service.
- public string DataBaseUrl { get; set; } = "http://127.0.0.1:8091";
+ /// Data service base URL (env override: DATA_SERVICE_URL or CORE_SERVICE_URL). Core .NET service.
+ public string DataBaseUrl { get; set; } = "http://127.0.0.1:8094";
- /// Integrations service base URL (env override: INTEGRATIONS_SERVICE_URL).
- public string IntegrationsBaseUrl { get; set; } = "http://127.0.0.1:8093";
+ /// Integrations service base URL (env override: INTEGRATIONS_SERVICE_URL or CORE_SERVICE_URL).
+ public string IntegrationsBaseUrl { get; set; } = "http://127.0.0.1:8094";
/// AiService base URL (env override: AI_SERVICE_URL). Internal .NET AI/LLM service.
public string AiBaseUrl { get; set; } = "http://127.0.0.1:8092";
diff --git a/services/Bff/src/Bff.Api/Auth/AccessControlMiddleware.cs b/services/Bff/src/Bff.Api/Auth/AccessControlMiddleware.cs
index 985719e9..43f87dbe 100644
--- a/services/Bff/src/Bff.Api/Auth/AccessControlMiddleware.cs
+++ b/services/Bff/src/Bff.Api/Auth/AccessControlMiddleware.cs
@@ -1,6 +1,6 @@
using System.Security.Claims;
-using Bff.Application.Options;
-using Bff.Domain;
+using Bff.Api.Application.Options;
+using Bff.Api.Domain;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
diff --git a/services/Bff/src/Bff.Api/Auth/WpSessionAuthenticationHandler.cs b/services/Bff/src/Bff.Api/Auth/WpSessionAuthenticationHandler.cs
index 86746aec..6f0bd2fa 100644
--- a/services/Bff/src/Bff.Api/Auth/WpSessionAuthenticationHandler.cs
+++ b/services/Bff/src/Bff.Api/Auth/WpSessionAuthenticationHandler.cs
@@ -1,8 +1,7 @@
using System.Security.Claims;
using System.Text.Encodings.Web;
-using Bff.Application.Auth;
-using Bff.Application.Options;
-using Bff.Domain;
+using Bff.Api.Application.Auth;
+using Bff.Api.Application.Options;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options;
diff --git a/services/Bff/src/Bff.Api/Bff.Api.csproj b/services/Bff/src/Bff.Api/Bff.Api.csproj
index 21e02db7..6796f80a 100644
--- a/services/Bff/src/Bff.Api/Bff.Api.csproj
+++ b/services/Bff/src/Bff.Api/Bff.Api.csproj
@@ -1,10 +1,7 @@
-
-
-
-
+
diff --git a/services/Bff/src/Bff.Domain/Roles.cs b/services/Bff/src/Bff.Api/Domain/Roles.cs
similarity index 98%
rename from services/Bff/src/Bff.Domain/Roles.cs
rename to services/Bff/src/Bff.Api/Domain/Roles.cs
index 1f0ee891..4865abb5 100644
--- a/services/Bff/src/Bff.Domain/Roles.cs
+++ b/services/Bff/src/Bff.Api/Domain/Roles.cs
@@ -1,4 +1,4 @@
-namespace Bff.Domain;
+namespace Bff.Api.Domain;
///
/// Role model, kept byte-compatible with the TypeScript auth layer
diff --git a/services/Bff/src/Bff.Api/Endpoints/AuthEndpoints.cs b/services/Bff/src/Bff.Api/Endpoints/AuthEndpoints.cs
index e49e6e4e..b186fbaa 100644
--- a/services/Bff/src/Bff.Api/Endpoints/AuthEndpoints.cs
+++ b/services/Bff/src/Bff.Api/Endpoints/AuthEndpoints.cs
@@ -1,8 +1,8 @@
using System.Security.Cryptography;
using System.Text;
-using Bff.Application.Auth;
-using Bff.Application.Options;
-using Bff.Domain;
+using Bff.Api.Application.Auth;
+using Bff.Api.Application.Options;
+using Bff.Api.Domain;
using Microsoft.Extensions.Options;
namespace Bff.Api.Endpoints;
diff --git a/services/Bff/src/Bff.Api/Endpoints/ProxyEndpoints.cs b/services/Bff/src/Bff.Api/Endpoints/ProxyEndpoints.cs
index 5bff467c..2dd98606 100644
--- a/services/Bff/src/Bff.Api/Endpoints/ProxyEndpoints.cs
+++ b/services/Bff/src/Bff.Api/Endpoints/ProxyEndpoints.cs
@@ -1,6 +1,7 @@
+using Bff.Api.Application;
+using Bff.Api.Application.Options;
using Bff.Api.Forwarding;
using Bff.Application;
-using Bff.Application.Options;
using Microsoft.Extensions.Options;
using WebsiteProfiling.Contracts.Report;
diff --git a/services/Bff/src/Bff.Api/Program.cs b/services/Bff/src/Bff.Api/Program.cs
index afedc7d3..23e6f388 100644
--- a/services/Bff/src/Bff.Api/Program.cs
+++ b/services/Bff/src/Bff.Api/Program.cs
@@ -1,8 +1,8 @@
+using Bff.Api.Application;
using Bff.Api.Auth;
using Bff.Api.Endpoints;
using Bff.Api.Forwarding;
using Bff.Api.Infrastructure;
-using Bff.Application;
using Microsoft.AspNetCore.Authentication;
using WebsiteProfiling.Hosting;
@@ -71,4 +71,7 @@ static string[] ResolveCorsOrigins(IConfiguration config)
return ["http://localhost:3000"];
}
-public partial class Program;
+namespace Bff.Api
+{
+ public partial class Program;
+}
diff --git a/services/Bff/src/Bff.Application/Bff.Application.csproj b/services/Bff/src/Bff.Application/Bff.Application.csproj
deleted file mode 100644
index de38ac1e..00000000
--- a/services/Bff/src/Bff.Application/Bff.Application.csproj
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- net10.0
- enable
- enable
-
-
-
diff --git a/services/Bff/src/Bff.Domain/Bff.Domain.csproj b/services/Bff/src/Bff.Domain/Bff.Domain.csproj
deleted file mode 100644
index 9ed914b5..00000000
--- a/services/Bff/src/Bff.Domain/Bff.Domain.csproj
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- net10.0
- enable
- enable
-
-
-
diff --git a/services/Bff/tests/Bff.Tests/Bff.Tests.csproj b/services/Bff/tests/Bff.Tests/Bff.Tests.csproj
index c7ee93a8..cb73641f 100644
--- a/services/Bff/tests/Bff.Tests/Bff.Tests.csproj
+++ b/services/Bff/tests/Bff.Tests/Bff.Tests.csproj
@@ -22,8 +22,6 @@
-
-
diff --git a/services/Bff/tests/Bff.Tests/GatewayTests.cs b/services/Bff/tests/Bff.Tests/GatewayTests.cs
index 482d7c13..84c82e4a 100644
--- a/services/Bff/tests/Bff.Tests/GatewayTests.cs
+++ b/services/Bff/tests/Bff.Tests/GatewayTests.cs
@@ -2,8 +2,10 @@
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
+using Bff.Api;
+using Bff.Api.Application;
+using Bff.Api.Application.Auth;
using Bff.Application;
-using Bff.Application.Auth;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Configuration;
diff --git a/services/Bff/tests/Bff.Tests/IdempotentRetryHandlerTests.cs b/services/Bff/tests/Bff.Tests/IdempotentRetryHandlerTests.cs
index 78af9136..c3ec3780 100644
--- a/services/Bff/tests/Bff.Tests/IdempotentRetryHandlerTests.cs
+++ b/services/Bff/tests/Bff.Tests/IdempotentRetryHandlerTests.cs
@@ -1,5 +1,5 @@
using System.Net;
-using Bff.Application.Http;
+using Bff.Api.Application.Http;
namespace Bff.Tests;
diff --git a/services/Bff/tests/Bff.Tests/ServiceRegistrationValidationTests.cs b/services/Bff/tests/Bff.Tests/ServiceRegistrationValidationTests.cs
index dd0cff0e..9b282e33 100644
--- a/services/Bff/tests/Bff.Tests/ServiceRegistrationValidationTests.cs
+++ b/services/Bff/tests/Bff.Tests/ServiceRegistrationValidationTests.cs
@@ -1,3 +1,4 @@
+using Bff.Api;
using Bff.Api.Forwarding;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
diff --git a/services/Bff/tests/Bff.Tests/WpSessionTokensTests.cs b/services/Bff/tests/Bff.Tests/WpSessionTokensTests.cs
index 4316df4a..f01dda02 100644
--- a/services/Bff/tests/Bff.Tests/WpSessionTokensTests.cs
+++ b/services/Bff/tests/Bff.Tests/WpSessionTokensTests.cs
@@ -1,4 +1,4 @@
-using Bff.Application.Auth;
+using Bff.Api.Application.Auth;
namespace Bff.Tests;
diff --git a/services/CoreService/Dockerfile b/services/CoreService/Dockerfile
new file mode 100644
index 00000000..e79a726e
--- /dev/null
+++ b/services/CoreService/Dockerfile
@@ -0,0 +1,21 @@
+FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
+WORKDIR /src
+COPY services/Shared/WebsiteProfiling.Shared/WebsiteProfiling.Shared.csproj services/Shared/WebsiteProfiling.Shared/
+COPY services/CoreService/src/CoreService.Api/CoreService.Api.csproj services/CoreService/src/CoreService.Api/
+RUN dotnet restore services/CoreService/src/CoreService.Api/CoreService.Api.csproj
+COPY services/Shared/WebsiteProfiling.Shared/ services/Shared/WebsiteProfiling.Shared/
+COPY config/typed_config_manifest.json config/typed_config_manifest.json
+COPY services/CoreService/src/ services/CoreService/src/
+RUN dotnet publish services/CoreService/src/CoreService.Api/CoreService.Api.csproj -c Release -o /app/publish --no-restore
+
+FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
+WORKDIR /app
+# curl is used by the compose healthcheck; libgssapi-krb5-2 silences Npgsql's harmless
+# GSSAPI probe warning on connect. Neither ships in the aspnet image.
+RUN apt-get update \
+ && apt-get install -y --no-install-recommends curl libgssapi-krb5-2 \
+ && rm -rf /var/lib/apt/lists/*
+ENV ASPNETCORE_URLS=http://+:8094
+EXPOSE 8094
+COPY --from=build /app/publish .
+ENTRYPOINT ["dotnet", "CoreService.Api.dll"]
diff --git a/services/CoreService/README.md b/services/CoreService/README.md
new file mode 100644
index 00000000..640a507d
--- /dev/null
+++ b/services/CoreService/README.md
@@ -0,0 +1,61 @@
+# CoreService
+
+Unified .NET microservice combining **Report build & orchestration**, **Data reads & exports**, and **Google/Bing integrations** for Site Audit.
+
+CoreService was formed by consolidating `Data`, `ReportService`, and `IntegrationsService` into a single cohesive service, reducing infrastructure operational overhead and project proliferation while preserving bounded context modularity.
+
+## Bounded Contexts
+
+Inside `services/CoreService/src/CoreService.Api/`:
+
+1. **Report & Pipeline Orchestration** (`Application/Build`, `Application/Pipeline`, `Domain/Report`):
+ - Report generation and native metric assembler
+ - Crawl orchestration and pipeline worker
+ - Compare and dashboard analytics
+ - Health score calculation
+
+2. **Data Reads & Exports** (`DataApplication`, `Domain/Data`, `Rendering`):
+ - Direct Postgres read operations (portfolio, crawl payloads, issue status, filters)
+ - PDF export (QuestPDF) and Excel workbook export (ClosedXML)
+ - CSV, JSON, and sitemap exports
+ - Content studio scores and drafts
+
+3. **External Integrations** (`IntegrationsApplication`, `Domain/Integrations`, `Providers/Google`):
+ - Google Search Console (GSC) and Google Analytics 4 (GA4) data fetching
+ - Google OAuth token exchange and callback lifecycle
+ - Live URL inspection and indexation status
+ - Keyword enrichment and rank tracking
+
+## Run locally
+
+```bash
+cd services/CoreService
+export DATABASE_URL=postgres://profiling:profiling@127.0.0.1:5432/website_profiling
+export FASTAPI_URL=http://127.0.0.1:8096
+export AI_SERVICE_URL=http://127.0.0.1:8092
+dotnet run --project src/CoreService.Api
+```
+
+Service listens on **http://localhost:8094**. Swagger UI in Development: **http://localhost:8094/docs**.
+
+`./local-run` starts CoreService automatically. The BFF proxies client requests to CoreService via `CORE_SERVICE_URL` (with `DATA_SERVICE_URL`, `INTEGRATIONS_SERVICE_URL`, and `REPORT_SERVICE_URL` aliased).
+
+## Key Environment Variables
+
+| Variable | Default | Description |
+|----------|---------|-------------|
+| `CORE_SERVICE_URL` | `http://127.0.0.1:8094` | Base URL of CoreService |
+| `DATABASE_URL` | (required) | PostgreSQL connection string |
+| `FASTAPI_URL` | `http://127.0.0.1:8096` | Internal Python FastAPI bridge URL |
+| `AI_SERVICE_URL` | `http://127.0.0.1:8092` | Internal AiService URL |
+| `AUTH_SECRET` | — | Secret key for signing OAuth session states |
+| `GOOGLE_REDIRECT_URI` | `http://localhost:8090/api/integrations/google/callback` | OAuth redirect URI |
+| `REPORT_SERVICE_WORKER_ENABLED` | `1` | Enable background C# pipeline job runner |
+| `REPORT_SERVICE_VALIDATE_NATIVE` | `1` | Validate native C# report against Python bridge |
+
+## Testing
+
+```bash
+dotnet test services/CoreService/tests/CoreService.Tests/CoreService.Tests.csproj
+```
+All 262 unit and integration tests run in ~7-8 seconds against in-memory mocks and WebApplicationFactory.
diff --git a/services/ReportService/src/ReportService.Application/Bridge/FastApiPythonBridge.cs b/services/CoreService/src/CoreService.Api/Application/Bridge/FastApiPythonBridge.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Bridge/FastApiPythonBridge.cs
rename to services/CoreService/src/CoreService.Api/Application/Bridge/FastApiPythonBridge.cs
index 1b6420e2..f88e9a3d 100644
--- a/services/ReportService/src/ReportService.Application/Bridge/FastApiPythonBridge.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Bridge/FastApiPythonBridge.cs
@@ -1,10 +1,9 @@
-using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
+using CoreService.Api.Application.Options;
using Microsoft.Extensions.Options;
-using ReportService.Application.Options;
-namespace ReportService.Application.Bridge;
+namespace CoreService.Api.Application.Bridge;
///
/// Delegates report build to Python FastAPI when ReportService has no native builder (Docker / bridge mode).
diff --git a/services/ReportService/src/ReportService.Application/Build/BrowserDiagnosticsAggregator.cs b/services/CoreService/src/CoreService.Api/Application/Build/BrowserDiagnosticsAggregator.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/BrowserDiagnosticsAggregator.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/BrowserDiagnosticsAggregator.cs
index e8c10a55..6df630f5 100644
--- a/services/ReportService/src/ReportService.Application/Build/BrowserDiagnosticsAggregator.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/BrowserDiagnosticsAggregator.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
///
/// Port of Python browser_diagnostics.aggregate_browser_diagnostics_df for report_meta.crawl_scope.
diff --git a/services/ReportService/src/ReportService.Application/Build/BrowserDiagnosticsHelper.cs b/services/CoreService/src/CoreService.Api/Application/Build/BrowserDiagnosticsHelper.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/BrowserDiagnosticsHelper.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/BrowserDiagnosticsHelper.cs
index e7c98a5c..eca16aa7 100644
--- a/services/ReportService/src/ReportService.Application/Build/BrowserDiagnosticsHelper.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/BrowserDiagnosticsHelper.cs
@@ -1,6 +1,6 @@
using System.Text.Json;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python crawl/fetchers/browser_diagnostics.browser_summary_from_page_analysis.
public static class BrowserDiagnosticsHelper
diff --git a/services/ReportService/src/ReportService.Application/Build/Categories/CoreWebVitalsCategoryBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/Categories/CoreWebVitalsCategoryBuilder.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/Categories/CoreWebVitalsCategoryBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/Categories/CoreWebVitalsCategoryBuilder.cs
index 05e824db..3506e58d 100644
--- a/services/ReportService/src/ReportService.Application/Build/Categories/CoreWebVitalsCategoryBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/Categories/CoreWebVitalsCategoryBuilder.cs
@@ -1,6 +1,6 @@
using System.Text.Json;
-namespace ReportService.Application.Build.Categories;
+namespace CoreService.Api.Application.Build.Categories;
public static class CoreWebVitalsCategoryBuilder
{
diff --git a/services/ReportService/src/ReportService.Application/Build/Categories/HtmlAccessibilityCategoryBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/Categories/HtmlAccessibilityCategoryBuilder.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/Categories/HtmlAccessibilityCategoryBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/Categories/HtmlAccessibilityCategoryBuilder.cs
index c147b939..5ba2136d 100644
--- a/services/ReportService/src/ReportService.Application/Build/Categories/HtmlAccessibilityCategoryBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/Categories/HtmlAccessibilityCategoryBuilder.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build.Categories;
+namespace CoreService.Api.Application.Build.Categories;
public static class HtmlAccessibilityCategoryBuilder
{
diff --git a/services/ReportService/src/ReportService.Application/Build/Categories/IntelligenceCategoryBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/Categories/IntelligenceCategoryBuilder.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/Categories/IntelligenceCategoryBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/Categories/IntelligenceCategoryBuilder.cs
index c1a8c4d7..19f7ae16 100644
--- a/services/ReportService/src/ReportService.Application/Build/Categories/IntelligenceCategoryBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/Categories/IntelligenceCategoryBuilder.cs
@@ -1,6 +1,6 @@
using System.Text.Json;
-namespace ReportService.Application.Build.Categories;
+namespace CoreService.Api.Application.Build.Categories;
public static class IntelligenceCategoryBuilder
{
diff --git a/services/ReportService/src/ReportService.Application/Build/Categories/LinkHealthCategoryBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/Categories/LinkHealthCategoryBuilder.cs
similarity index 97%
rename from services/ReportService/src/ReportService.Application/Build/Categories/LinkHealthCategoryBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/Categories/LinkHealthCategoryBuilder.cs
index 3dc3dcd0..84bfbcdb 100644
--- a/services/ReportService/src/ReportService.Application/Build/Categories/LinkHealthCategoryBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/Categories/LinkHealthCategoryBuilder.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build.Categories;
+namespace CoreService.Api.Application.Build.Categories;
public static class LinkHealthCategoryBuilder
{
diff --git a/services/ReportService/src/ReportService.Application/Build/Categories/MobileCategoryBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/Categories/MobileCategoryBuilder.cs
similarity index 97%
rename from services/ReportService/src/ReportService.Application/Build/Categories/MobileCategoryBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/Categories/MobileCategoryBuilder.cs
index 11f2c308..98727892 100644
--- a/services/ReportService/src/ReportService.Application/Build/Categories/MobileCategoryBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/Categories/MobileCategoryBuilder.cs
@@ -1,8 +1,8 @@
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build.Categories;
+namespace CoreService.Api.Application.Build.Categories;
public static class MobileCategoryBuilder
{
diff --git a/services/ReportService/src/ReportService.Application/Build/Categories/PerformanceCategoryBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/Categories/PerformanceCategoryBuilder.cs
similarity index 97%
rename from services/ReportService/src/ReportService.Application/Build/Categories/PerformanceCategoryBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/Categories/PerformanceCategoryBuilder.cs
index cd609ccf..f26ac864 100644
--- a/services/ReportService/src/ReportService.Application/Build/Categories/PerformanceCategoryBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/Categories/PerformanceCategoryBuilder.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build.Categories;
+namespace CoreService.Api.Application.Build.Categories;
public static class PerformanceCategoryBuilder
{
diff --git a/services/ReportService/src/ReportService.Application/Build/Categories/SearchPerformanceCategoryBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/Categories/SearchPerformanceCategoryBuilder.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/Categories/SearchPerformanceCategoryBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/Categories/SearchPerformanceCategoryBuilder.cs
index 92d428d2..55d835ac 100644
--- a/services/ReportService/src/ReportService.Application/Build/Categories/SearchPerformanceCategoryBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/Categories/SearchPerformanceCategoryBuilder.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Build.Categories;
+namespace CoreService.Api.Application.Build.Categories;
/// Port of Python reporting/categories/search_performance.py.
public static class SearchPerformanceCategoryBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/Categories/SecurityCategoryBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/Categories/SecurityCategoryBuilder.cs
similarity index 96%
rename from services/ReportService/src/ReportService.Application/Build/Categories/SecurityCategoryBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/Categories/SecurityCategoryBuilder.cs
index fae90ea1..39b15ff7 100644
--- a/services/ReportService/src/ReportService.Application/Build/Categories/SecurityCategoryBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/Categories/SecurityCategoryBuilder.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build.Categories;
+namespace CoreService.Api.Application.Build.Categories;
public static class SecurityCategoryBuilder
{
diff --git a/services/ReportService/src/ReportService.Application/Build/Categories/TechnicalSeoCategoryBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/Categories/TechnicalSeoCategoryBuilder.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/Categories/TechnicalSeoCategoryBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/Categories/TechnicalSeoCategoryBuilder.cs
index d8807e2b..c24593c1 100644
--- a/services/ReportService/src/ReportService.Application/Build/Categories/TechnicalSeoCategoryBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/Categories/TechnicalSeoCategoryBuilder.cs
@@ -1,8 +1,7 @@
using System.Text.Json;
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build.Categories;
+namespace CoreService.Api.Application.Build.Categories;
public static class TechnicalSeoCategoryBuilder
{
diff --git a/services/ReportService/src/ReportService.Application/Build/CategoryBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/CategoryBuilder.cs
similarity index 97%
rename from services/ReportService/src/ReportService.Application/Build/CategoryBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/CategoryBuilder.cs
index 556b8f9d..894556ae 100644
--- a/services/ReportService/src/ReportService.Application/Build/CategoryBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/CategoryBuilder.cs
@@ -1,9 +1,9 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using ReportService.Application.Build.Categories;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build.Categories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
///
/// Issue category assembly for report payloads. Incremental port from Python reporting/categories/*.
diff --git a/services/ReportService/src/ReportService.Application/Build/CategoryHelpers.cs b/services/CoreService/src/CoreService.Api/Application/Build/CategoryHelpers.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/CategoryHelpers.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/CategoryHelpers.cs
index aeaff52c..4fecc860 100644
--- a/services/ReportService/src/ReportService.Application/Build/CategoryHelpers.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/CategoryHelpers.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
using System.Text.RegularExpressions;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Shared helpers ported from Python reporting/categories/_helpers.py.
public static partial class CategoryHelpers
diff --git a/services/ReportService/src/ReportService.Application/Build/CategoryIssue.cs b/services/CoreService/src/CoreService.Api/Application/Build/CategoryIssue.cs
similarity index 91%
rename from services/ReportService/src/ReportService.Application/Build/CategoryIssue.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/CategoryIssue.cs
index 9afd6eac..41f04ab4 100644
--- a/services/ReportService/src/ReportService.Application/Build/CategoryIssue.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/CategoryIssue.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
public sealed record CategoryIssue(
string Message,
diff --git a/services/ReportService/src/ReportService.Application/Build/CategoryPayloadSerializer.cs b/services/CoreService/src/CoreService.Api/Application/Build/CategoryPayloadSerializer.cs
similarity index 97%
rename from services/ReportService/src/ReportService.Application/Build/CategoryPayloadSerializer.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/CategoryPayloadSerializer.cs
index a26d05ab..0a2b12ba 100644
--- a/services/ReportService/src/ReportService.Application/Build/CategoryPayloadSerializer.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/CategoryPayloadSerializer.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
public static class CategoryPayloadSerializer
{
diff --git a/services/ReportService/src/ReportService.Application/Build/CompetitorLinkGapBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/CompetitorLinkGapBuilder.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/CompetitorLinkGapBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/CompetitorLinkGapBuilder.cs
index b985a3a0..ead57efb 100644
--- a/services/ReportService/src/ReportService.Application/Build/CompetitorLinkGapBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/CompetitorLinkGapBuilder.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python integrations/google/competitor_links.build_competitor_link_gap.
public static class CompetitorLinkGapBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/ContactIntelligenceBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/ContactIntelligenceBuilder.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/ContactIntelligenceBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/ContactIntelligenceBuilder.cs
index 1114521a..52def473 100644
--- a/services/ReportService/src/ReportService.Application/Build/ContactIntelligenceBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/ContactIntelligenceBuilder.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
using System.Text.RegularExpressions;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python reporting/contact_intelligence.py.
public static partial class ContactIntelligenceBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/ContentAnalyticsBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/ContentAnalyticsBuilder.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/ContentAnalyticsBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/ContentAnalyticsBuilder.cs
index 5e8eafea..24448698 100644
--- a/services/ReportService/src/ReportService.Application/Build/ContentAnalyticsBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/ContentAnalyticsBuilder.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python reporting/content_analytics.py core analytics helpers.
public static class ContentAnalyticsBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/ContentUrlListsBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/ContentUrlListsBuilder.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/ContentUrlListsBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/ContentUrlListsBuilder.cs
index 0d188209..58494de6 100644
--- a/services/ReportService/src/ReportService.Application/Build/ContentUrlListsBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/ContentUrlListsBuilder.cs
@@ -1,7 +1,6 @@
-using System.Text.Json;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python reporting/builder_sections/content_urls.build_content_url_lists.
public static class ContentUrlListsBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/CrawlSegmentsBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/CrawlSegmentsBuilder.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/CrawlSegmentsBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/CrawlSegmentsBuilder.cs
index f2a57457..4b31b7df 100644
--- a/services/ReportService/src/ReportService.Application/Build/CrawlSegmentsBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/CrawlSegmentsBuilder.cs
@@ -1,7 +1,7 @@
using System.Text.RegularExpressions;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python reporting/crawl_segments.py per path-prefix health scores.
public static partial class CrawlSegmentsBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/CtrCurve.cs b/services/CoreService/src/CoreService.Api/Application/Build/CtrCurve.cs
similarity index 96%
rename from services/ReportService/src/ReportService.Application/Build/CtrCurve.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/CtrCurve.cs
index 7290c32b..938c11f0 100644
--- a/services/ReportService/src/ReportService.Application/Build/CtrCurve.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/CtrCurve.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// AWR 2024 desktop organic CTR curve (ported from keyword_enrich.py).
public static class CtrCurve
diff --git a/services/ReportService/src/ReportService.Application/Build/EdgesBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/EdgesBuilder.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/EdgesBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/EdgesBuilder.cs
index 3148c490..6ff450f2 100644
--- a/services/ReportService/src/ReportService.Application/Build/EdgesBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/EdgesBuilder.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
///
/// Edge-list helpers for report build. Full edge extraction (HTTP fetch) remains in Python until ported.
diff --git a/services/ReportService/src/ReportService.Application/Build/FingerprintTextHelper.cs b/services/CoreService/src/CoreService.Api/Application/Build/FingerprintTextHelper.cs
similarity index 96%
rename from services/ReportService/src/ReportService.Application/Build/FingerprintTextHelper.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/FingerprintTextHelper.cs
index 8258ab40..ae83b3d3 100644
--- a/services/ReportService/src/ReportService.Application/Build/FingerprintTextHelper.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/FingerprintTextHelper.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
using System.Text.RegularExpressions;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python analysis/text.py normalize_fingerprint_text and top_keywords_as_text.
public static partial class FingerprintTextHelper
diff --git a/services/ReportService/src/ReportService.Application/Build/HreflangIssueUrlsBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/HreflangIssueUrlsBuilder.cs
similarity index 82%
rename from services/ReportService/src/ReportService.Application/Build/HreflangIssueUrlsBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/HreflangIssueUrlsBuilder.cs
index 9e6e4d15..6ba3b55f 100644
--- a/services/ReportService/src/ReportService.Application/Build/HreflangIssueUrlsBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/HreflangIssueUrlsBuilder.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
public static class HreflangIssueUrlsBuilder
{
diff --git a/services/ReportService/src/ReportService.Application/Build/ImageInventoryBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/ImageInventoryBuilder.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/ImageInventoryBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/ImageInventoryBuilder.cs
index c66e7a27..0980a949 100644
--- a/services/ReportService/src/ReportService.Application/Build/ImageInventoryBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/ImageInventoryBuilder.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Aggregate image inventory from crawl row JSONB (page_analysis + social images).
public static class ImageInventoryBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/IndexationCoverageBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/IndexationCoverageBuilder.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/IndexationCoverageBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/IndexationCoverageBuilder.cs
index 84f70b83..b06d8358 100644
--- a/services/ReportService/src/ReportService.Application/Build/IndexationCoverageBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/IndexationCoverageBuilder.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python reporting/indexation.build_indexation_coverage.
public static class IndexationCoverageBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/IssueImpactEnricher.cs b/services/CoreService/src/CoreService.Api/Application/Build/IssueImpactEnricher.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/IssueImpactEnricher.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/IssueImpactEnricher.cs
index 5fd879eb..97f0cf28 100644
--- a/services/ReportService/src/ReportService.Application/Build/IssueImpactEnricher.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/IssueImpactEnricher.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python reporting/issue_impact.py — GSC/GA4 traffic on category issues.
public static class IssueImpactEnricher
diff --git a/services/ReportService/src/ReportService.Application/Build/JsonObjectParser.cs b/services/CoreService/src/CoreService.Api/Application/Build/JsonObjectParser.cs
similarity index 96%
rename from services/ReportService/src/ReportService.Application/Build/JsonObjectParser.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/JsonObjectParser.cs
index 8fcd65ea..a8f600b3 100644
--- a/services/ReportService/src/ReportService.Application/Build/JsonObjectParser.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/JsonObjectParser.cs
@@ -1,6 +1,6 @@
using System.Text.Json;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
internal static class JsonObjectParser
{
diff --git a/services/ReportService/src/ReportService.Application/Build/KeywordOpportunitiesBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/KeywordOpportunitiesBuilder.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/KeywordOpportunitiesBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/KeywordOpportunitiesBuilder.cs
index b8bce766..38365ce2 100644
--- a/services/ReportService/src/ReportService.Application/Build/KeywordOpportunitiesBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/KeywordOpportunitiesBuilder.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
using System.Text.RegularExpressions;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python tools/keywords.py + content_analytics._build_keyword_opportunities.
public static class KeywordOpportunitiesBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/LighthouseFailureUrlsBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/LighthouseFailureUrlsBuilder.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/LighthouseFailureUrlsBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/LighthouseFailureUrlsBuilder.cs
index c0b2a943..733f372b 100644
--- a/services/ReportService/src/ReportService.Application/Build/LighthouseFailureUrlsBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/LighthouseFailureUrlsBuilder.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python reporting/builder.py lighthouse_failure_urls bucketing.
public static class LighthouseFailureUrlsBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/LighthouseJsonHelper.cs b/services/CoreService/src/CoreService.Api/Application/Build/LighthouseJsonHelper.cs
similarity index 95%
rename from services/ReportService/src/ReportService.Application/Build/LighthouseJsonHelper.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/LighthouseJsonHelper.cs
index 09c73ceb..0573efca 100644
--- a/services/ReportService/src/ReportService.Application/Build/LighthouseJsonHelper.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/LighthouseJsonHelper.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
internal static class LighthouseJsonHelper
{
diff --git a/services/ReportService/src/ReportService.Application/Build/LighthouseReportAssembler.cs b/services/CoreService/src/CoreService.Api/Application/Build/LighthouseReportAssembler.cs
similarity index 93%
rename from services/ReportService/src/ReportService.Application/Build/LighthouseReportAssembler.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/LighthouseReportAssembler.cs
index 851edc0b..939897ab 100644
--- a/services/ReportService/src/ReportService.Application/Build/LighthouseReportAssembler.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/LighthouseReportAssembler.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Nodes;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
///
/// Assembles per-URL Lighthouse data from DB rows (Python build_lighthouse_by_url parity).
diff --git a/services/ReportService/src/ReportService.Application/Build/LighthouseReportMerge.cs b/services/CoreService/src/CoreService.Api/Application/Build/LighthouseReportMerge.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/LighthouseReportMerge.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/LighthouseReportMerge.cs
index af612600..04e5aed8 100644
--- a/services/ReportService/src/ReportService.Application/Build/LighthouseReportMerge.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/LighthouseReportMerge.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
///
/// Pure Lighthouse merge helpers ported from Python reporting/lighthouse_report.py.
diff --git a/services/ReportService/src/ReportService.Application/Build/LinkEdgesReportBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/LinkEdgesReportBuilder.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/LinkEdgesReportBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/LinkEdgesReportBuilder.cs
index 618f1dcc..6de80c71 100644
--- a/services/ReportService/src/ReportService.Application/Build/LinkEdgesReportBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/LinkEdgesReportBuilder.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python reporting/link_edges_report.py.
public static class LinkEdgesReportBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/LinksListBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/LinksListBuilder.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/LinksListBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/LinksListBuilder.cs
index eecc4b72..fe42fefc 100644
--- a/services/ReportService/src/ReportService.Application/Build/LinksListBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/LinksListBuilder.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python reporting/builder_sections/links.build_links_list.
public static class LinksListBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/LocalEnrichmentBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/LocalEnrichmentBuilder.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/LocalEnrichmentBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/LocalEnrichmentBuilder.cs
index 445d12d7..b39384a6 100644
--- a/services/ReportService/src/ReportService.Application/Build/LocalEnrichmentBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/LocalEnrichmentBuilder.cs
@@ -1,12 +1,11 @@
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
+using CoreService.Api.Application.Repositories;
using FuzzySharp;
using LanguageIdentification;
-using Microsoft.Extensions.Logging;
-using ReportService.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python analysis/local.py — deterministic duplicate and language detection.
public static class LocalEnrichmentBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/MlBundleExtractor.cs b/services/CoreService/src/CoreService.Api/Application/Build/MlBundleExtractor.cs
similarity index 96%
rename from services/ReportService/src/ReportService.Application/Build/MlBundleExtractor.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/MlBundleExtractor.cs
index 4f13cb31..6c04f3b4 100644
--- a/services/ReportService/src/ReportService.Application/Build/MlBundleExtractor.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/MlBundleExtractor.cs
@@ -1,6 +1,6 @@
using System.Text.Json;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
internal static class MlBundleExtractor
{
diff --git a/services/ReportService/src/ReportService.Application/Build/MlBundleMaps.cs b/services/CoreService/src/CoreService.Api/Application/Build/MlBundleMaps.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/MlBundleMaps.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/MlBundleMaps.cs
index 61a64ca5..7131f584 100644
--- a/services/ReportService/src/ReportService.Application/Build/MlBundleMaps.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/MlBundleMaps.cs
@@ -1,6 +1,6 @@
using System.Text.Json;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
internal static class MlBundleMaps
{
diff --git a/services/ReportService/src/ReportService.Application/Build/NativeReportBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/NativeReportBuilder.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/NativeReportBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/NativeReportBuilder.cs
index 4fce45bc..08704083 100644
--- a/services/ReportService/src/ReportService.Application/Build/NativeReportBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/NativeReportBuilder.cs
@@ -1,12 +1,11 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using ReportService.Application.Bridge;
-using ReportService.Application.Build.Categories;
-using ReportService.Application.Integrations;
-using ReportService.Application.Repositories;
-using Microsoft.Extensions.Logging;
+using CoreService.Api.Application.Bridge;
+using CoreService.Api.Application.Build.Categories;
+using CoreService.Api.Application.Integrations;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Native report build orchestration. Core sections are native; enrichments (Google, security scan) remain optional stubs.
public sealed class NativeReportBuilder(
diff --git a/services/ReportService/src/ReportService.Application/Build/NativeReportPayloadAssembler.cs b/services/CoreService/src/CoreService.Api/Application/Build/NativeReportPayloadAssembler.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/NativeReportPayloadAssembler.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/NativeReportPayloadAssembler.cs
index 586e7c24..9364e938 100644
--- a/services/ReportService/src/ReportService.Application/Build/NativeReportPayloadAssembler.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/NativeReportPayloadAssembler.cs
@@ -1,8 +1,7 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using ReportService.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Assembles native report payload sections ported from Python reporting/builder.py.
public static class NativeReportPayloadAssembler
diff --git a/services/ReportService/src/ReportService.Application/Build/OptionalAuditUrlsBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/OptionalAuditUrlsBuilder.cs
similarity index 97%
rename from services/ReportService/src/ReportService.Application/Build/OptionalAuditUrlsBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/OptionalAuditUrlsBuilder.cs
index d85525c5..3ae20f34 100644
--- a/services/ReportService/src/ReportService.Application/Build/OptionalAuditUrlsBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/OptionalAuditUrlsBuilder.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Bucket category issues into optional_audit_urls lists (Python builder.py message heuristics).
public static class OptionalAuditUrlsBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/OptionalAuditsBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/OptionalAuditsBuilder.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/OptionalAuditsBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/OptionalAuditsBuilder.cs
index 1816c980..bc2dc31d 100644
--- a/services/ReportService/src/ReportService.Application/Build/OptionalAuditsBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/OptionalAuditsBuilder.cs
@@ -1,9 +1,8 @@
using System.Text.Json;
using System.Text.RegularExpressions;
-using Microsoft.Extensions.Logging;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python reporting/optional_audits.py — pagination, spell, HTML, AMP, Wayback, axe.
public static class OptionalAuditsBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/ReportBuildService.cs b/services/CoreService/src/CoreService.Api/Application/Build/ReportBuildService.cs
similarity index 96%
rename from services/ReportService/src/ReportService.Application/Build/ReportBuildService.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/ReportBuildService.cs
index 350e7317..439d006e 100644
--- a/services/ReportService/src/ReportService.Application/Build/ReportBuildService.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/ReportBuildService.cs
@@ -1,12 +1,10 @@
-using System.Net.Http.Json;
using System.Text.Json;
-using Microsoft.Extensions.Logging;
+using CoreService.Api.Application.Bridge;
+using CoreService.Api.Application.Options;
+using CoreService.Api.Application.Repositories;
using Microsoft.Extensions.Options;
-using ReportService.Application.Bridge;
-using ReportService.Application.Options;
-using ReportService.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
public sealed class ReportBuildService(
FastApiPythonBridge bridge,
diff --git a/services/ReportService/src/ReportService.Application/Build/ReportChartDataBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/ReportChartDataBuilder.cs
similarity index 97%
rename from services/ReportService/src/ReportService.Application/Build/ReportChartDataBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/ReportChartDataBuilder.cs
index f21909be..9a10bb1a 100644
--- a/services/ReportService/src/ReportService.Application/Build/ReportChartDataBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/ReportChartDataBuilder.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
public sealed record ReportChartData(
Dictionary StatusCounts,
diff --git a/services/ReportService/src/ReportService.Application/Build/ReportEdgeResolver.cs b/services/CoreService/src/CoreService.Api/Application/Build/ReportEdgeResolver.cs
similarity index 93%
rename from services/ReportService/src/ReportService.Application/Build/ReportEdgeResolver.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/ReportEdgeResolver.cs
index 8d5540bc..3be8fc69 100644
--- a/services/ReportService/src/ReportService.Application/Build/ReportEdgeResolver.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/ReportEdgeResolver.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Choose internal link pairs for graph/categories (DB plot edges first, then crawl columns).
public static class ReportEdgeResolver
diff --git a/services/ReportService/src/ReportService.Application/Build/ReportGraphBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/ReportGraphBuilder.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/ReportGraphBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/ReportGraphBuilder.cs
index 4673cfd0..d15e417a 100644
--- a/services/ReportService/src/ReportService.Application/Build/ReportGraphBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/ReportGraphBuilder.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
public sealed record ReportGraphResult(
List GraphNodes,
diff --git a/services/ReportService/src/ReportService.Application/Build/ReportMetadataBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/ReportMetadataBuilder.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/ReportMetadataBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/ReportMetadataBuilder.cs
index 9ac8f525..c22ce655 100644
--- a/services/ReportService/src/ReportService.Application/Build/ReportMetadataBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/ReportMetadataBuilder.cs
@@ -1,9 +1,9 @@
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
///
/// Port of Python reporting/report_metadata.py — provenance, crawl scope, fingerprints, hreflang.
diff --git a/services/ReportService/src/ReportService.Application/Build/ReportNativeValidator.cs b/services/CoreService/src/CoreService.Api/Application/Build/ReportNativeValidator.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/ReportNativeValidator.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/ReportNativeValidator.cs
index c80cc12c..407921ff 100644
--- a/services/ReportService/src/ReportService.Application/Build/ReportNativeValidator.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/ReportNativeValidator.cs
@@ -1,6 +1,6 @@
using System.Text.Json;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
///
/// Validates native slices against Python bridge payloads (Phase 2 parity checks).
diff --git a/services/ReportService/src/ReportService.Application/Build/SecurityScanBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/SecurityScanBuilder.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/SecurityScanBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/SecurityScanBuilder.cs
index 8e142033..a701918a 100644
--- a/services/ReportService/src/ReportService.Application/Build/SecurityScanBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/SecurityScanBuilder.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
///
/// Passive security findings from crawl data (Python security_scanner passive checks; no active probes).
diff --git a/services/ReportService/src/ReportService.Application/Build/SeoSummaryBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/SeoSummaryBuilder.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/SeoSummaryBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/SeoSummaryBuilder.cs
index 26a0a8d0..c0969b89 100644
--- a/services/ReportService/src/ReportService.Application/Build/SeoSummaryBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/SeoSummaryBuilder.cs
@@ -1,7 +1,7 @@
using System.Text.RegularExpressions;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
///
/// Port of Python reporting/seo_summary.py — crawl summary, SEO health, issues, recommendations.
diff --git a/services/ReportService/src/ReportService.Application/Build/SiteFileParser.cs b/services/CoreService/src/CoreService.Api/Application/Build/SiteFileParser.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/SiteFileParser.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/SiteFileParser.cs
index e16f1a13..d128f156 100644
--- a/services/ReportService/src/ReportService.Application/Build/SiteFileParser.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/SiteFileParser.cs
@@ -1,6 +1,6 @@
using System.Text.RegularExpressions;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python reporting/site_files.py parse helpers.
public static partial class SiteFileParser
diff --git a/services/ReportService/src/ReportService.Application/Build/SiteHealthScoreBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/SiteHealthScoreBuilder.cs
similarity index 96%
rename from services/ReportService/src/ReportService.Application/Build/SiteHealthScoreBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/SiteHealthScoreBuilder.cs
index cb0755c0..bfa0796c 100644
--- a/services/ReportService/src/ReportService.Application/Build/SiteHealthScoreBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/SiteHealthScoreBuilder.cs
@@ -1,6 +1,6 @@
using WebsiteProfiling.Contracts.Report;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// ReportService adapters over shared .
public static class SiteHealthScoreBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/SiteLevelBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/SiteLevelBuilder.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/SiteLevelBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/SiteLevelBuilder.cs
index c5303e12..9e1813d6 100644
--- a/services/ReportService/src/ReportService.Application/Build/SiteLevelBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/SiteLevelBuilder.cs
@@ -1,7 +1,7 @@
using System.Net.Http.Headers;
using System.Text.Json;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python reporting/site_level.py and site_files.py fetch helpers.
public sealed class SiteLevelBuilder(IHttpClientFactory httpClientFactory)
diff --git a/services/ReportService/src/ReportService.Application/Build/SitemapDiscoveryService.cs b/services/CoreService/src/CoreService.Api/Application/Build/SitemapDiscoveryService.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/SitemapDiscoveryService.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/SitemapDiscoveryService.cs
index 514eaba7..706cf38d 100644
--- a/services/ReportService/src/ReportService.Application/Build/SitemapDiscoveryService.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/SitemapDiscoveryService.cs
@@ -1,7 +1,7 @@
using System.Net.Http.Headers;
using System.Xml.Linq;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python crawl/sitemap.discover_sitemap_urls (same-origin page URLs).
public sealed class SitemapDiscoveryService(IHttpClientFactory httpClientFactory)
diff --git a/services/ReportService/src/ReportService.Application/Build/SpellCheckerFactory.cs b/services/CoreService/src/CoreService.Api/Application/Build/SpellCheckerFactory.cs
similarity index 91%
rename from services/ReportService/src/ReportService.Application/Build/SpellCheckerFactory.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/SpellCheckerFactory.cs
index 526c5a79..2330515b 100644
--- a/services/ReportService/src/ReportService.Application/Build/SpellCheckerFactory.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/SpellCheckerFactory.cs
@@ -1,10 +1,6 @@
-using System.Text.Json;
-using System.Text.RegularExpressions;
-using Microsoft.Extensions.Logging;
-using ReportService.Application.Repositories;
using WeCantSpell.Hunspell;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Optional Hunspell spell checker for optional audits (mirrors pyspellchecker path).
internal static class SpellCheckerFactory
diff --git a/services/ReportService/src/ReportService.Application/Build/SubdomainInventoryBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/SubdomainInventoryBuilder.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/SubdomainInventoryBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/SubdomainInventoryBuilder.cs
index dd32d4f1..2c7cbffe 100644
--- a/services/ReportService/src/ReportService.Application/Build/SubdomainInventoryBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/SubdomainInventoryBuilder.cs
@@ -1,8 +1,8 @@
using System.Net.Http.Headers;
using System.Text.Json;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python reporting/subdomains.py passive subdomain inventory.
public sealed class SubdomainInventoryBuilder(IHttpClientFactory httpClientFactory)
diff --git a/services/ReportService/src/ReportService.Application/Build/TextHygieneHelper.cs b/services/CoreService/src/CoreService.Api/Application/Build/TextHygieneHelper.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Build/TextHygieneHelper.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/TextHygieneHelper.cs
index e410ccfc..3888c5cc 100644
--- a/services/ReportService/src/ReportService.Application/Build/TextHygieneHelper.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/TextHygieneHelper.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Minimal port of Python analysis/text_hygiene.is_junk_semantic_term for keyword filtering.
public static class TextHygieneHelper
diff --git a/services/ReportService/src/ReportService.Application/Build/ThinContentHelper.cs b/services/CoreService/src/CoreService.Api/Application/Build/ThinContentHelper.cs
similarity index 88%
rename from services/ReportService/src/ReportService.Application/Build/ThinContentHelper.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/ThinContentHelper.cs
index d9e4ae94..b4513e3b 100644
--- a/services/ReportService/src/ReportService.Application/Build/ThinContentHelper.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/ThinContentHelper.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Shared thin-content detection (200 words; char fallback when word_count absent).
public static class ThinContentHelper
diff --git a/services/ReportService/src/ReportService.Application/Build/UrlJoinBuilder.cs b/services/CoreService/src/CoreService.Api/Application/Build/UrlJoinBuilder.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Build/UrlJoinBuilder.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/UrlJoinBuilder.cs
index 54e4c1b2..0fea3b3c 100644
--- a/services/ReportService/src/ReportService.Application/Build/UrlJoinBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/UrlJoinBuilder.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python compute_url_join.
public static class UrlJoinBuilder
diff --git a/services/ReportService/src/ReportService.Application/Build/UrlNormalizeHelper.cs b/services/CoreService/src/CoreService.Api/Application/Build/UrlNormalizeHelper.cs
similarity index 97%
rename from services/ReportService/src/ReportService.Application/Build/UrlNormalizeHelper.cs
rename to services/CoreService/src/CoreService.Api/Application/Build/UrlNormalizeHelper.cs
index 68622c89..31c888b9 100644
--- a/services/ReportService/src/ReportService.Application/Build/UrlNormalizeHelper.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Build/UrlNormalizeHelper.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Build;
+namespace CoreService.Api.Application.Build;
/// Port of Python integrations/google/normalize.py URL join keys.
public static class UrlNormalizeHelper
diff --git a/services/ReportService/src/ReportService.Application/Compare/CompareExportService.cs b/services/CoreService/src/CoreService.Api/Application/Compare/CompareExportService.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Compare/CompareExportService.cs
rename to services/CoreService/src/CoreService.Api/Application/Compare/CompareExportService.cs
index 58b9aaad..a6e67df3 100644
--- a/services/ReportService/src/ReportService.Application/Compare/CompareExportService.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Compare/CompareExportService.cs
@@ -2,7 +2,7 @@
using System.Text.Json;
using Npgsql;
-namespace ReportService.Application.Compare;
+namespace CoreService.Api.Application.Compare;
public sealed class CompareExportService(NpgsqlDataSource dataSource)
{
diff --git a/services/ReportService/src/ReportService.Application/Dashboard/DashboardRepository.cs b/services/CoreService/src/CoreService.Api/Application/Dashboard/DashboardRepository.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Dashboard/DashboardRepository.cs
rename to services/CoreService/src/CoreService.Api/Application/Dashboard/DashboardRepository.cs
index 86ac4069..390c60f8 100644
--- a/services/ReportService/src/ReportService.Application/Dashboard/DashboardRepository.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Dashboard/DashboardRepository.cs
@@ -3,7 +3,7 @@
using Npgsql;
using NpgsqlTypes;
-namespace ReportService.Application.Dashboard;
+namespace CoreService.Api.Application.Dashboard;
public sealed class DashboardRepository(NpgsqlDataSource dataSource)
{
diff --git a/services/ReportService/src/ReportService.Application/DependencyInjection.cs b/services/CoreService/src/CoreService.Api/Application/DependencyInjection.cs
similarity index 89%
rename from services/ReportService/src/ReportService.Application/DependencyInjection.cs
rename to services/CoreService/src/CoreService.Api/Application/DependencyInjection.cs
index 217bb8bf..5ae0c9a0 100644
--- a/services/ReportService/src/ReportService.Application/DependencyInjection.cs
+++ b/services/CoreService/src/CoreService.Api/Application/DependencyInjection.cs
@@ -1,20 +1,17 @@
+using CoreService.Api.Application.Bridge;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Compare;
+using CoreService.Api.Application.Dashboard;
+using CoreService.Api.Application.Integrations;
+using CoreService.Api.Application.Options;
+using CoreService.Api.Application.Orchestration;
+using CoreService.Api.Application.Persistence;
+using CoreService.Api.Application.Pipeline;
+using CoreService.Api.Application.Repositories;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using ReportService.Application.Bridge;
-using ReportService.Application.Build;
-using ReportService.Application.Compare;
-using ReportService.Application.Dashboard;
-using ReportService.Application.Integrations;
-using ReportService.Application.Orchestration;
-using ReportService.Application.Options;
-using ReportService.Application.Persistence;
-using ReportService.Application.Pipeline;
-using ReportService.Application.Repositories;
using WebsiteProfiling.Data;
-using WebsiteProfiling.Data.EntityFrameworkCore;
-namespace ReportService.Application;
+namespace CoreService.Api.Application;
public static class DependencyInjection
{
diff --git a/services/ReportService/src/ReportService.Application/Integrations/AiServiceEnrichmentClient.cs b/services/CoreService/src/CoreService.Api/Application/Integrations/AiServiceEnrichmentClient.cs
similarity index 95%
rename from services/ReportService/src/ReportService.Application/Integrations/AiServiceEnrichmentClient.cs
rename to services/CoreService/src/CoreService.Api/Application/Integrations/AiServiceEnrichmentClient.cs
index 9f7d609c..0b17fb1f 100644
--- a/services/ReportService/src/ReportService.Application/Integrations/AiServiceEnrichmentClient.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Integrations/AiServiceEnrichmentClient.cs
@@ -1,9 +1,8 @@
-using System.Net.Http.Json;
using System.Text.Json;
+using CoreService.Api.Application.Options;
using Microsoft.Extensions.Options;
-using ReportService.Application.Options;
-namespace ReportService.Application.Integrations;
+namespace CoreService.Api.Application.Integrations;
/// Calls AiService enrichment endpoints for native report build.
public sealed class AiServiceEnrichmentClient(
diff --git a/services/ReportService/src/ReportService.Application/Integrations/CruxOriginMetricsFetcher.cs b/services/CoreService/src/CoreService.Api/Application/Integrations/CruxOriginMetricsFetcher.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Integrations/CruxOriginMetricsFetcher.cs
rename to services/CoreService/src/CoreService.Api/Application/Integrations/CruxOriginMetricsFetcher.cs
index 74d87031..7b832760 100644
--- a/services/ReportService/src/ReportService.Application/Integrations/CruxOriginMetricsFetcher.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Integrations/CruxOriginMetricsFetcher.cs
@@ -1,7 +1,6 @@
-using System.Net.Http.Json;
using System.Text.Json;
-namespace ReportService.Application.Integrations;
+namespace CoreService.Api.Application.Integrations;
/// Port of Python integrations/crux/fetch.py — origin-level CrUX field metrics.
public static class CruxOriginMetricsFetcher
diff --git a/services/ReportService/src/ReportService.Application/Integrations/IntegrationsReportDataClient.cs b/services/CoreService/src/CoreService.Api/Application/Integrations/IntegrationsReportDataClient.cs
similarity index 95%
rename from services/ReportService/src/ReportService.Application/Integrations/IntegrationsReportDataClient.cs
rename to services/CoreService/src/CoreService.Api/Application/Integrations/IntegrationsReportDataClient.cs
index 069ce863..04de1670 100644
--- a/services/ReportService/src/ReportService.Application/Integrations/IntegrationsReportDataClient.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Integrations/IntegrationsReportDataClient.cs
@@ -1,9 +1,8 @@
-using System.Net.Http.Json;
using System.Text.Json;
+using CoreService.Api.Application.Options;
using Microsoft.Extensions.Options;
-using ReportService.Application.Options;
-namespace ReportService.Application.Integrations;
+namespace CoreService.Api.Application.Integrations;
///
/// Fetches Google/keyword/GSC link snapshots from IntegrationsService for native report build.
diff --git a/services/ReportService/src/ReportService.Application/Options/FastApiOptions.cs b/services/CoreService/src/CoreService.Api/Application/Options/FastApiOptions.cs
similarity index 81%
rename from services/ReportService/src/ReportService.Application/Options/FastApiOptions.cs
rename to services/CoreService/src/CoreService.Api/Application/Options/FastApiOptions.cs
index 71cac715..cc12e896 100644
--- a/services/ReportService/src/ReportService.Application/Options/FastApiOptions.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Options/FastApiOptions.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Options;
+namespace CoreService.Api.Application.Options;
public sealed class FastApiOptions
{
diff --git a/services/ReportService/src/ReportService.Application/Options/ReportServiceOptions.cs b/services/CoreService/src/CoreService.Api/Application/Options/ReportServiceOptions.cs
similarity index 92%
rename from services/ReportService/src/ReportService.Application/Options/ReportServiceOptions.cs
rename to services/CoreService/src/CoreService.Api/Application/Options/ReportServiceOptions.cs
index 1512340a..a054ecc1 100644
--- a/services/ReportService/src/ReportService.Application/Options/ReportServiceOptions.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Options/ReportServiceOptions.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Options;
+namespace CoreService.Api.Application.Options;
public sealed class ReportServiceOptions
{
diff --git a/services/ReportService/src/ReportService.Application/Options/WorkerOptions.cs b/services/CoreService/src/CoreService.Api/Application/Options/WorkerOptions.cs
similarity index 91%
rename from services/ReportService/src/ReportService.Application/Options/WorkerOptions.cs
rename to services/CoreService/src/CoreService.Api/Application/Options/WorkerOptions.cs
index fb669f60..0f059a71 100644
--- a/services/ReportService/src/ReportService.Application/Options/WorkerOptions.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Options/WorkerOptions.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Options;
+namespace CoreService.Api.Application.Options;
public sealed class WorkerOptions
{
diff --git a/services/ReportService/src/ReportService.Application/Orchestration/PipelineOrchestratorService.cs b/services/CoreService/src/CoreService.Api/Application/Orchestration/PipelineOrchestratorService.cs
similarity index 94%
rename from services/ReportService/src/ReportService.Application/Orchestration/PipelineOrchestratorService.cs
rename to services/CoreService/src/CoreService.Api/Application/Orchestration/PipelineOrchestratorService.cs
index 5e46cd2a..b969045d 100644
--- a/services/ReportService/src/ReportService.Application/Orchestration/PipelineOrchestratorService.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Orchestration/PipelineOrchestratorService.cs
@@ -1,8 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Bridge;
-using ReportService.Application.Pipeline;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Pipeline;
-namespace ReportService.Application.Orchestration;
+namespace CoreService.Api.Application.Orchestration;
///
/// Full-audit orchestrator: enqueue crawl+lighthouse on C# worker, poll job, then build report.
diff --git a/services/ReportService/src/ReportService.Application/Persistence/ReportDbContext.cs b/services/CoreService/src/CoreService.Api/Application/Persistence/ReportDbContext.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Persistence/ReportDbContext.cs
rename to services/CoreService/src/CoreService.Api/Application/Persistence/ReportDbContext.cs
index 42392b15..149297ca 100644
--- a/services/ReportService/src/ReportService.Application/Persistence/ReportDbContext.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Persistence/ReportDbContext.cs
@@ -1,7 +1,7 @@
+using CoreService.Api.Domain.Report.Entities;
using Microsoft.EntityFrameworkCore;
-using ReportService.Domain.Entities;
-namespace ReportService.Application.Persistence;
+namespace CoreService.Api.Application.Persistence;
///
/// EF Core context over the schema owned by services/Schema. No migrations here; tracking disabled globally for reads.
diff --git a/services/ReportService/src/ReportService.Application/Pipeline/Models/PipelineJobRecord.cs b/services/CoreService/src/CoreService.Api/Application/Pipeline/Models/PipelineJobRecord.cs
similarity index 93%
rename from services/ReportService/src/ReportService.Application/Pipeline/Models/PipelineJobRecord.cs
rename to services/CoreService/src/CoreService.Api/Application/Pipeline/Models/PipelineJobRecord.cs
index 7700229d..f0133f49 100644
--- a/services/ReportService/src/ReportService.Application/Pipeline/Models/PipelineJobRecord.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Pipeline/Models/PipelineJobRecord.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Pipeline.Models;
+namespace CoreService.Api.Application.Pipeline.Models;
public sealed record PipelineJobRecord
{
diff --git a/services/ReportService/src/ReportService.Application/Pipeline/PipelineConfigRepository.cs b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineConfigRepository.cs
similarity index 97%
rename from services/ReportService/src/ReportService.Application/Pipeline/PipelineConfigRepository.cs
rename to services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineConfigRepository.cs
index b0f3d3bb..660405d1 100644
--- a/services/ReportService/src/ReportService.Application/Pipeline/PipelineConfigRepository.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineConfigRepository.cs
@@ -1,7 +1,7 @@
using Npgsql;
using WebsiteProfiling.TypedConfig;
-namespace ReportService.Application.Pipeline;
+namespace CoreService.Api.Application.Pipeline;
/// Persists flat pipeline config keys to typed Postgres tables (manifest-driven).
public sealed class PipelineConfigRepository(NpgsqlDataSource dataSource)
diff --git a/services/ReportService/src/ReportService.Application/Pipeline/PipelineJobRepository.cs b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineJobRepository.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Pipeline/PipelineJobRepository.cs
rename to services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineJobRepository.cs
index 6cdee67c..1867f31f 100644
--- a/services/ReportService/src/ReportService.Application/Pipeline/PipelineJobRepository.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineJobRepository.cs
@@ -1,11 +1,11 @@
using System.Diagnostics;
+using CoreService.Api.Application.Persistence;
+using CoreService.Api.Application.Pipeline.Models;
+using CoreService.Api.Domain.Report.Entities;
using Microsoft.EntityFrameworkCore;
using Npgsql;
-using ReportService.Application.Persistence;
-using ReportService.Application.Pipeline.Models;
-using ReportService.Domain.Entities;
-namespace ReportService.Application.Pipeline;
+namespace CoreService.Api.Application.Pipeline;
public sealed class PipelineJobRepository(
IDbContextFactory dbFactory,
diff --git a/services/ReportService/src/ReportService.Application/Pipeline/PipelineJobRunner.cs b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineJobRunner.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Pipeline/PipelineJobRunner.cs
rename to services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineJobRunner.cs
index 20bf99cb..41da959a 100644
--- a/services/ReportService/src/ReportService.Application/Pipeline/PipelineJobRunner.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineJobRunner.cs
@@ -1,14 +1,12 @@
using System.Collections;
using System.Diagnostics;
-using System.Text;
-using Microsoft.Extensions.Logging;
+using CoreService.Api.Application.Bridge;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Options;
+using CoreService.Api.Application.Pipeline.Models;
using Microsoft.Extensions.Options;
-using ReportService.Application.Bridge;
-using ReportService.Application.Build;
-using ReportService.Application.Options;
-using ReportService.Application.Pipeline.Models;
-namespace ReportService.Application.Pipeline;
+namespace CoreService.Api.Application.Pipeline;
public sealed class PipelineJobRunner(
PipelineJobRepository jobs,
diff --git a/services/ReportService/src/ReportService.Application/Pipeline/PipelineProcessRegistry.cs b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineProcessRegistry.cs
similarity index 97%
rename from services/ReportService/src/ReportService.Application/Pipeline/PipelineProcessRegistry.cs
rename to services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineProcessRegistry.cs
index 877dedf7..5209184e 100644
--- a/services/ReportService/src/ReportService.Application/Pipeline/PipelineProcessRegistry.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineProcessRegistry.cs
@@ -1,7 +1,7 @@
using System.Collections.Concurrent;
using System.Diagnostics;
-namespace ReportService.Application.Pipeline;
+namespace CoreService.Api.Application.Pipeline;
///
/// Tracks live pipeline subprocess handles so cancel can kill Python even when the worker poll loop is stuck.
diff --git a/services/ReportService/src/ReportService.Application/Pipeline/PipelinePropertyRepository.cs b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelinePropertyRepository.cs
similarity index 96%
rename from services/ReportService/src/ReportService.Application/Pipeline/PipelinePropertyRepository.cs
rename to services/CoreService/src/CoreService.Api/Application/Pipeline/PipelinePropertyRepository.cs
index f501f23b..c2730007 100644
--- a/services/ReportService/src/ReportService.Application/Pipeline/PipelinePropertyRepository.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelinePropertyRepository.cs
@@ -1,9 +1,7 @@
-using System.Text.Json;
using System.Text.RegularExpressions;
-using Microsoft.Extensions.Logging;
using Npgsql;
-namespace ReportService.Application.Pipeline;
+namespace CoreService.Api.Application.Pipeline;
public sealed class PipelinePropertyRepository(NpgsqlDataSource dataSource)
{
diff --git a/services/ReportService/src/ReportService.Application/Pipeline/PipelineRunService.cs b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineRunService.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Pipeline/PipelineRunService.cs
rename to services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineRunService.cs
index a007c8e5..4cd9b4cf 100644
--- a/services/ReportService/src/ReportService.Application/Pipeline/PipelineRunService.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineRunService.cs
@@ -1,6 +1,4 @@
-using ReportService.Application.Pipeline.Models;
-
-namespace ReportService.Application.Pipeline;
+namespace CoreService.Api.Application.Pipeline;
public sealed class PipelineRunService(
PipelineJobRepository jobs,
diff --git a/services/ReportService/src/ReportService.Application/Pipeline/PipelineStateHelper.cs b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineStateHelper.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Application/Pipeline/PipelineStateHelper.cs
rename to services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineStateHelper.cs
index 64fee806..b16fe2a5 100644
--- a/services/ReportService/src/ReportService.Application/Pipeline/PipelineStateHelper.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineStateHelper.cs
@@ -1,6 +1,6 @@
using System.Globalization;
-namespace ReportService.Application.Pipeline;
+namespace CoreService.Api.Application.Pipeline;
public static class PipelineStateHelper
{
diff --git a/services/ReportService/src/ReportService.Application/Pipeline/PipelineWorkerBackgroundService.cs b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineWorkerBackgroundService.cs
similarity index 91%
rename from services/ReportService/src/ReportService.Application/Pipeline/PipelineWorkerBackgroundService.cs
rename to services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineWorkerBackgroundService.cs
index b6587ec9..d921b5e8 100644
--- a/services/ReportService/src/ReportService.Application/Pipeline/PipelineWorkerBackgroundService.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Pipeline/PipelineWorkerBackgroundService.cs
@@ -1,11 +1,8 @@
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
+using CoreService.Api.Application.Options;
+using CoreService.Api.Application.Pipeline.Models;
using Microsoft.Extensions.Options;
-using ReportService.Application.Options;
-using ReportService.Application.Pipeline.Models;
-namespace ReportService.Application.Pipeline;
+namespace CoreService.Api.Application.Pipeline;
public sealed class PipelineWorkerBackgroundService(
IServiceScopeFactory scopeFactory,
diff --git a/services/ReportService/src/ReportService.Application/Repositories/CrawlEdgesReader.cs b/services/CoreService/src/CoreService.Api/Application/Repositories/CrawlEdgesReader.cs
similarity index 90%
rename from services/ReportService/src/ReportService.Application/Repositories/CrawlEdgesReader.cs
rename to services/CoreService/src/CoreService.Api/Application/Repositories/CrawlEdgesReader.cs
index 319b3b90..99c8730b 100644
--- a/services/ReportService/src/ReportService.Application/Repositories/CrawlEdgesReader.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Repositories/CrawlEdgesReader.cs
@@ -1,7 +1,7 @@
+using CoreService.Api.Application.Persistence;
using Microsoft.EntityFrameworkCore;
-using ReportService.Application.Persistence;
-namespace ReportService.Application.Repositories;
+namespace CoreService.Api.Application.Repositories;
/// Reads plot/crawl internal link pairs from the edges table (Python read_edges parity).
public sealed class CrawlEdgesReader(ReportDbContext db)
diff --git a/services/ReportService/src/ReportService.Application/Repositories/CrawlPageHtmlReader.cs b/services/CoreService/src/CoreService.Api/Application/Repositories/CrawlPageHtmlReader.cs
similarity index 96%
rename from services/ReportService/src/ReportService.Application/Repositories/CrawlPageHtmlReader.cs
rename to services/CoreService/src/CoreService.Api/Application/Repositories/CrawlPageHtmlReader.cs
index 8aa5ec06..b735d8da 100644
--- a/services/ReportService/src/ReportService.Application/Repositories/CrawlPageHtmlReader.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Repositories/CrawlPageHtmlReader.cs
@@ -1,6 +1,6 @@
using Npgsql;
-namespace ReportService.Application.Repositories;
+namespace CoreService.Api.Application.Repositories;
/// Batch-read stored HTML from crawl_page_html for optional HTML validation audits.
public sealed class CrawlPageHtmlReader(NpgsqlDataSource dataSource)
diff --git a/services/ReportService/src/ReportService.Application/Repositories/CrawlRepository.cs b/services/CoreService/src/CoreService.Api/Application/Repositories/CrawlRepository.cs
similarity index 96%
rename from services/ReportService/src/ReportService.Application/Repositories/CrawlRepository.cs
rename to services/CoreService/src/CoreService.Api/Application/Repositories/CrawlRepository.cs
index 145ea4b1..78eeaa1d 100644
--- a/services/ReportService/src/ReportService.Application/Repositories/CrawlRepository.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Repositories/CrawlRepository.cs
@@ -1,7 +1,7 @@
+using CoreService.Api.Application.Persistence;
using Microsoft.EntityFrameworkCore;
-using ReportService.Application.Persistence;
-namespace ReportService.Application.Repositories;
+namespace CoreService.Api.Application.Repositories;
public sealed class CrawlRepository(ReportDbContext db)
{
diff --git a/services/ReportService/src/ReportService.Application/Repositories/CrawlRow.cs b/services/CoreService/src/CoreService.Api/Application/Repositories/CrawlRow.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Repositories/CrawlRow.cs
rename to services/CoreService/src/CoreService.Api/Application/Repositories/CrawlRow.cs
index 79534fab..55c82391 100644
--- a/services/ReportService/src/ReportService.Application/Repositories/CrawlRow.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Repositories/CrawlRow.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Repositories;
+namespace CoreService.Api.Application.Repositories;
///
/// One crawled URL row (merged crawl_results.url + JSON data column).
diff --git a/services/ReportService/src/ReportService.Application/Repositories/CrawlRowMapper.cs b/services/CoreService/src/CoreService.Api/Application/Repositories/CrawlRowMapper.cs
similarity index 98%
rename from services/ReportService/src/ReportService.Application/Repositories/CrawlRowMapper.cs
rename to services/CoreService/src/CoreService.Api/Application/Repositories/CrawlRowMapper.cs
index a197d738..1269e5b4 100644
--- a/services/ReportService/src/ReportService.Application/Repositories/CrawlRowMapper.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Repositories/CrawlRowMapper.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using ReportService.Domain.Entities;
+using CoreService.Api.Domain.Report.Entities;
-namespace ReportService.Application.Repositories;
+namespace CoreService.Api.Application.Repositories;
internal static class CrawlRowMapper
{
diff --git a/services/ReportService/src/ReportService.Application/Repositories/CrawlRunResolver.cs b/services/CoreService/src/CoreService.Api/Application/Repositories/CrawlRunResolver.cs
similarity index 96%
rename from services/ReportService/src/ReportService.Application/Repositories/CrawlRunResolver.cs
rename to services/CoreService/src/CoreService.Api/Application/Repositories/CrawlRunResolver.cs
index bc3532a7..4461400c 100644
--- a/services/ReportService/src/ReportService.Application/Repositories/CrawlRunResolver.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Repositories/CrawlRunResolver.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Application.Repositories;
+namespace CoreService.Api.Application.Repositories;
///
/// Resolves which crawl run to use for report/Lighthouse (Python resolve_crawl_run_id_for_cfg parity).
diff --git a/services/ReportService/src/ReportService.Application/Repositories/LighthouseDbReader.cs b/services/CoreService/src/CoreService.Api/Application/Repositories/LighthouseDbReader.cs
similarity index 94%
rename from services/ReportService/src/ReportService.Application/Repositories/LighthouseDbReader.cs
rename to services/CoreService/src/CoreService.Api/Application/Repositories/LighthouseDbReader.cs
index e00ee915..e750f26a 100644
--- a/services/ReportService/src/ReportService.Application/Repositories/LighthouseDbReader.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Repositories/LighthouseDbReader.cs
@@ -1,9 +1,9 @@
using System.Text.Json;
using System.Text.Json.Nodes;
+using CoreService.Api.Application.Persistence;
using Microsoft.EntityFrameworkCore;
-using ReportService.Application.Persistence;
-namespace ReportService.Application.Repositories;
+namespace CoreService.Api.Application.Repositories;
public sealed class LighthouseDbReader(ReportDbContext db)
{
diff --git a/services/ReportService/src/ReportService.Application/Repositories/LinkEdgesReader.cs b/services/CoreService/src/CoreService.Api/Application/Repositories/LinkEdgesReader.cs
similarity index 86%
rename from services/ReportService/src/ReportService.Application/Repositories/LinkEdgesReader.cs
rename to services/CoreService/src/CoreService.Api/Application/Repositories/LinkEdgesReader.cs
index 9e5f89cb..ac471d5a 100644
--- a/services/ReportService/src/ReportService.Application/Repositories/LinkEdgesReader.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Repositories/LinkEdgesReader.cs
@@ -1,9 +1,8 @@
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Persistence;
using Microsoft.EntityFrameworkCore;
-using ReportService.Application.Build;
-using ReportService.Application.Persistence;
-using ReportService.Domain.Entities;
-namespace ReportService.Application.Repositories;
+namespace CoreService.Api.Application.Repositories;
public sealed class LinkEdgesReader(ReportDbContext db)
{
diff --git a/services/ReportService/src/ReportService.Application/Repositories/ReportPayloadWriter.cs b/services/CoreService/src/CoreService.Api/Application/Repositories/ReportPayloadWriter.cs
similarity index 96%
rename from services/ReportService/src/ReportService.Application/Repositories/ReportPayloadWriter.cs
rename to services/CoreService/src/CoreService.Api/Application/Repositories/ReportPayloadWriter.cs
index 2d7c3a35..43ef731c 100644
--- a/services/ReportService/src/ReportService.Application/Repositories/ReportPayloadWriter.cs
+++ b/services/CoreService/src/CoreService.Api/Application/Repositories/ReportPayloadWriter.cs
@@ -1,9 +1,9 @@
using System.Text.Json;
-using ReportService.Application.Build;
-using ReportService.Application.Persistence;
-using ReportService.Domain.Entities;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Persistence;
+using CoreService.Api.Domain.Report.Entities;
-namespace ReportService.Application.Repositories;
+namespace CoreService.Api.Application.Repositories;
public sealed class ReportPayloadWriter(ReportDbContext db)
{
diff --git a/services/Data/src/Data.Api/BinaryFileActionResult.cs b/services/CoreService/src/CoreService.Api/BinaryFileActionResult.cs
similarity index 97%
rename from services/Data/src/Data.Api/BinaryFileActionResult.cs
rename to services/CoreService/src/CoreService.Api/BinaryFileActionResult.cs
index 1a94bc91..739f5a24 100644
--- a/services/Data/src/Data.Api/BinaryFileActionResult.cs
+++ b/services/CoreService/src/CoreService.Api/BinaryFileActionResult.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api;
+namespace CoreService.Api;
///
/// Writes raw bytes with an explicit content type and Content-Disposition header — ported from
diff --git a/services/Data/src/Data.Api/Controllers/AlertsController.cs b/services/CoreService/src/CoreService.Api/Controllers/AlertsController.cs
similarity index 90%
rename from services/Data/src/Data.Api/Controllers/AlertsController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/AlertsController.cs
index bb61b812..27892463 100644
--- a/services/Data/src/Data.Api/Controllers/AlertsController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/AlertsController.cs
@@ -1,7 +1,7 @@
-using Data.Application.Python;
+using CoreService.Api.DataApplication.Python;
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/alerts")]
diff --git a/services/Data/src/Data.Api/Controllers/BacklinksController.cs b/services/CoreService/src/CoreService.Api/Controllers/BacklinksController.cs
similarity index 86%
rename from services/Data/src/Data.Api/Controllers/BacklinksController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/BacklinksController.cs
index f5b89e3a..63817640 100644
--- a/services/Data/src/Data.Api/Controllers/BacklinksController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/BacklinksController.cs
@@ -1,7 +1,7 @@
-using Data.Application.Repositories;
+using CoreService.Api.DataApplication.Repositories;
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/backlinks")]
diff --git a/services/Data/src/Data.Api/Controllers/ClientPreferencesController.cs b/services/CoreService/src/CoreService.Api/Controllers/ClientPreferencesController.cs
similarity index 97%
rename from services/Data/src/Data.Api/Controllers/ClientPreferencesController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/ClientPreferencesController.cs
index 80200c75..b090fa9a 100644
--- a/services/Data/src/Data.Api/Controllers/ClientPreferencesController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/ClientPreferencesController.cs
@@ -1,7 +1,7 @@
-using Data.Application.Repositories;
+using CoreService.Api.DataApplication.Repositories;
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/client-preferences")]
diff --git a/services/ReportService/src/ReportService.Api/Controllers/CompareController.cs b/services/CoreService/src/CoreService.Api/Controllers/CompareController.cs
similarity index 92%
rename from services/ReportService/src/ReportService.Api/Controllers/CompareController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/CompareController.cs
index 9ffdab7a..4314f328 100644
--- a/services/ReportService/src/ReportService.Api/Controllers/CompareController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/CompareController.cs
@@ -1,7 +1,7 @@
+using CoreService.Api.Application.Compare;
using Microsoft.AspNetCore.Mvc;
-using ReportService.Application.Compare;
-namespace ReportService.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/compare")]
diff --git a/services/Data/src/Data.Api/Controllers/ContentDraftsController.cs b/services/CoreService/src/CoreService.Api/Controllers/ContentDraftsController.cs
similarity index 97%
rename from services/Data/src/Data.Api/Controllers/ContentDraftsController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/ContentDraftsController.cs
index 739eb65d..dacc7290 100644
--- a/services/Data/src/Data.Api/Controllers/ContentDraftsController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/ContentDraftsController.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
-using Data.Application.Repositories;
+using CoreService.Api.DataApplication.Repositories;
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/content-drafts")]
diff --git a/services/Data/src/Data.Api/Controllers/ContentScoreController.cs b/services/CoreService/src/CoreService.Api/Controllers/ContentScoreController.cs
similarity index 95%
rename from services/Data/src/Data.Api/Controllers/ContentScoreController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/ContentScoreController.cs
index 870ac06b..46a33a7f 100644
--- a/services/Data/src/Data.Api/Controllers/ContentScoreController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/ContentScoreController.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
-using Data.Application.Python;
+using CoreService.Api.DataApplication.Python;
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/content")]
diff --git a/services/ReportService/src/ReportService.Api/Controllers/CrawlController.cs b/services/CoreService/src/CoreService.Api/Controllers/CrawlController.cs
similarity index 99%
rename from services/ReportService/src/ReportService.Api/Controllers/CrawlController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/CrawlController.cs
index a988f5c7..ec83839f 100644
--- a/services/ReportService/src/ReportService.Api/Controllers/CrawlController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/CrawlController.cs
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Npgsql;
-namespace ReportService.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/crawl")]
diff --git a/services/ReportService/src/ReportService.Api/Controllers/DashboardsController.cs b/services/CoreService/src/CoreService.Api/Controllers/DashboardsController.cs
similarity index 97%
rename from services/ReportService/src/ReportService.Api/Controllers/DashboardsController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/DashboardsController.cs
index f1dae41e..4f8c0103 100644
--- a/services/ReportService/src/ReportService.Api/Controllers/DashboardsController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/DashboardsController.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
+using CoreService.Api.Application.Dashboard;
using Microsoft.AspNetCore.Mvc;
-using ReportService.Application.Dashboard;
-namespace ReportService.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/dashboards")]
diff --git a/services/Data/src/Data.Api/Controllers/FiltersController.cs b/services/CoreService/src/CoreService.Api/Controllers/FiltersController.cs
similarity index 95%
rename from services/Data/src/Data.Api/Controllers/FiltersController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/FiltersController.cs
index 3cea7053..21022575 100644
--- a/services/Data/src/Data.Api/Controllers/FiltersController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/FiltersController.cs
@@ -1,9 +1,9 @@
using System.Text.Json;
-using Data.Application.Dto.Filters;
-using Data.Application.Repositories;
+using CoreService.Api.DataApplication.Dto.Filters;
+using CoreService.Api.DataApplication.Repositories;
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
///
/// Saved crawl filter endpoints ported from FastAPI's /api/filters.
diff --git a/services/Data/src/Data.Api/Controllers/HealthController.cs b/services/CoreService/src/CoreService.Api/Controllers/HealthController.cs
similarity index 87%
rename from services/Data/src/Data.Api/Controllers/HealthController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/HealthController.cs
index 9e3e1dc0..abfae45d 100644
--- a/services/Data/src/Data.Api/Controllers/HealthController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/HealthController.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("")]
diff --git a/services/IntegrationsService/src/IntegrationsService.Api/Controllers/IntegrationsBingController.cs b/services/CoreService/src/CoreService.Api/Controllers/IntegrationsBingController.cs
similarity index 90%
rename from services/IntegrationsService/src/IntegrationsService.Api/Controllers/IntegrationsBingController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/IntegrationsBingController.cs
index 396723a4..d067d98d 100644
--- a/services/IntegrationsService/src/IntegrationsService.Api/Controllers/IntegrationsBingController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/IntegrationsBingController.cs
@@ -1,8 +1,8 @@
-using IntegrationsService.Application.Google;
-using IntegrationsService.Application.Repositories;
+using CoreService.Api.IntegrationsApplication.Google;
+using CoreService.Api.IntegrationsApplication.Repositories;
using Microsoft.AspNetCore.Mvc;
-namespace IntegrationsService.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/integrations/bing")]
diff --git a/services/IntegrationsService/src/IntegrationsService.Api/Controllers/IntegrationsGoogleController.cs b/services/CoreService/src/CoreService.Api/Controllers/IntegrationsGoogleController.cs
similarity index 99%
rename from services/IntegrationsService/src/IntegrationsService.Api/Controllers/IntegrationsGoogleController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/IntegrationsGoogleController.cs
index ec76c122..d1fdb2de 100644
--- a/services/IntegrationsService/src/IntegrationsService.Api/Controllers/IntegrationsGoogleController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/IntegrationsGoogleController.cs
@@ -1,9 +1,9 @@
using System.Text.Json;
-using IntegrationsService.Application.Google;
-using IntegrationsService.Application.Repositories;
+using CoreService.Api.IntegrationsApplication.Google;
+using CoreService.Api.IntegrationsApplication.Repositories;
using Microsoft.AspNetCore.Mvc;
-namespace IntegrationsService.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/integrations/google")]
diff --git a/services/IntegrationsService/src/IntegrationsService.Api/Controllers/Internal/GoogleFetchController.cs b/services/CoreService/src/CoreService.Api/Controllers/Internal/GoogleFetchController.cs
similarity index 93%
rename from services/IntegrationsService/src/IntegrationsService.Api/Controllers/Internal/GoogleFetchController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/Internal/GoogleFetchController.cs
index 00a9c0be..f3aba861 100644
--- a/services/IntegrationsService/src/IntegrationsService.Api/Controllers/Internal/GoogleFetchController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/Internal/GoogleFetchController.cs
@@ -1,8 +1,8 @@
-using IntegrationsService.Application.Google;
-using IntegrationsService.Application.Repositories;
+using CoreService.Api.IntegrationsApplication.Google;
+using CoreService.Api.IntegrationsApplication.Repositories;
using Microsoft.AspNetCore.Mvc;
-namespace IntegrationsService.Api.Controllers.Internal;
+namespace CoreService.Api.Controllers.Internal;
[ApiController]
[Route("internal/integrations/google")]
diff --git a/services/IntegrationsService/src/IntegrationsService.Api/Controllers/Internal/KeywordEnrichController.cs b/services/CoreService/src/CoreService.Api/Controllers/Internal/KeywordEnrichController.cs
similarity index 94%
rename from services/IntegrationsService/src/IntegrationsService.Api/Controllers/Internal/KeywordEnrichController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/Internal/KeywordEnrichController.cs
index be868d41..fae540b6 100644
--- a/services/IntegrationsService/src/IntegrationsService.Api/Controllers/Internal/KeywordEnrichController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/Internal/KeywordEnrichController.cs
@@ -1,7 +1,7 @@
-using IntegrationsService.Application.Google;
+using CoreService.Api.IntegrationsApplication.Google;
using Microsoft.AspNetCore.Mvc;
-namespace IntegrationsService.Api.Controllers.Internal;
+namespace CoreService.Api.Controllers.Internal;
[ApiController]
[Route("internal/integrations/keywords")]
diff --git a/services/ReportService/src/ReportService.Api/Controllers/Internal/PipelineOrchestratorController.cs b/services/CoreService/src/CoreService.Api/Controllers/Internal/PipelineOrchestratorController.cs
similarity index 94%
rename from services/ReportService/src/ReportService.Api/Controllers/Internal/PipelineOrchestratorController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/Internal/PipelineOrchestratorController.cs
index 24b38dbf..684a948a 100644
--- a/services/ReportService/src/ReportService.Api/Controllers/Internal/PipelineOrchestratorController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/Internal/PipelineOrchestratorController.cs
@@ -1,7 +1,7 @@
+using CoreService.Api.Application.Orchestration;
using Microsoft.AspNetCore.Mvc;
-using ReportService.Application.Orchestration;
-namespace ReportService.Api.Controllers.Internal;
+namespace CoreService.Api.Controllers.Internal;
[ApiController]
[Route("internal/pipeline")]
diff --git a/services/ReportService/src/ReportService.Api/Controllers/Internal/ReportBuildController.cs b/services/CoreService/src/CoreService.Api/Controllers/Internal/ReportBuildController.cs
similarity index 93%
rename from services/ReportService/src/ReportService.Api/Controllers/Internal/ReportBuildController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/Internal/ReportBuildController.cs
index e1b7035f..5e87d58a 100644
--- a/services/ReportService/src/ReportService.Api/Controllers/Internal/ReportBuildController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/Internal/ReportBuildController.cs
@@ -1,7 +1,7 @@
+using CoreService.Api.Application.Build;
using Microsoft.AspNetCore.Mvc;
-using ReportService.Application.Build;
-namespace ReportService.Api.Controllers.Internal;
+namespace CoreService.Api.Controllers.Internal;
[ApiController]
[Route("internal/report")]
diff --git a/services/IntegrationsService/src/IntegrationsService.Api/Controllers/Internal/ReportEnrichmentController.cs b/services/CoreService/src/CoreService.Api/Controllers/Internal/ReportEnrichmentController.cs
similarity index 89%
rename from services/IntegrationsService/src/IntegrationsService.Api/Controllers/Internal/ReportEnrichmentController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/Internal/ReportEnrichmentController.cs
index 1829a147..2bf76b02 100644
--- a/services/IntegrationsService/src/IntegrationsService.Api/Controllers/Internal/ReportEnrichmentController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/Internal/ReportEnrichmentController.cs
@@ -1,7 +1,7 @@
-using IntegrationsService.Application.Report;
+using CoreService.Api.IntegrationsApplication.Report;
using Microsoft.AspNetCore.Mvc;
-namespace IntegrationsService.Api.Controllers.Internal;
+namespace CoreService.Api.Controllers.Internal;
[ApiController]
[Route("internal/integrations/report")]
diff --git a/services/Data/src/Data.Api/Controllers/IssuesController.cs b/services/CoreService/src/CoreService.Api/Controllers/IssuesController.cs
similarity index 94%
rename from services/Data/src/Data.Api/Controllers/IssuesController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/IssuesController.cs
index b46c9a08..281d0ba0 100644
--- a/services/Data/src/Data.Api/Controllers/IssuesController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/IssuesController.cs
@@ -1,8 +1,8 @@
-using Data.Application.Dto.Issues;
-using Data.Application.Repositories;
+using CoreService.Api.DataApplication.Dto.Issues;
+using CoreService.Api.DataApplication.Repositories;
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
///
/// Issue workflow endpoints ported from FastAPI's /api/issues/* (status only; LLM routes stay on FastAPI).
diff --git a/services/Data/src/Data.Api/Controllers/KeywordsController.cs b/services/CoreService/src/CoreService.Api/Controllers/KeywordsController.cs
similarity index 89%
rename from services/Data/src/Data.Api/Controllers/KeywordsController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/KeywordsController.cs
index d563e48f..2744652f 100644
--- a/services/Data/src/Data.Api/Controllers/KeywordsController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/KeywordsController.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
-using Data.Application.Content;
+using CoreService.Api.DataApplication.Content;
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/keywords")]
diff --git a/services/Data/src/Data.Api/Controllers/LogsController.cs b/services/CoreService/src/CoreService.Api/Controllers/LogsController.cs
similarity index 94%
rename from services/Data/src/Data.Api/Controllers/LogsController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/LogsController.cs
index 1b5ecb60..6879b4c6 100644
--- a/services/Data/src/Data.Api/Controllers/LogsController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/LogsController.cs
@@ -1,7 +1,7 @@
-using Data.Application.Python;
+using CoreService.Api.DataApplication.Python;
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/logs")]
diff --git a/services/Data/src/Data.Api/Controllers/PageMarkdownController.cs b/services/CoreService/src/CoreService.Api/Controllers/PageMarkdownController.cs
similarity index 98%
rename from services/Data/src/Data.Api/Controllers/PageMarkdownController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/PageMarkdownController.cs
index f86f74aa..8f553cfd 100644
--- a/services/Data/src/Data.Api/Controllers/PageMarkdownController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/PageMarkdownController.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
-using Data.Application.Repositories;
+using CoreService.Api.DataApplication.Repositories;
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/page-markdown")]
diff --git a/services/ReportService/src/ReportService.Api/Controllers/PipelineJobsController.cs b/services/CoreService/src/CoreService.Api/Controllers/PipelineJobsController.cs
similarity index 97%
rename from services/ReportService/src/ReportService.Api/Controllers/PipelineJobsController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/PipelineJobsController.cs
index 722e96ad..4d06ee25 100644
--- a/services/ReportService/src/ReportService.Api/Controllers/PipelineJobsController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/PipelineJobsController.cs
@@ -1,9 +1,8 @@
-using Microsoft.AspNetCore.Http;
+using CoreService.Api.Application.Pipeline;
using Microsoft.AspNetCore.Mvc;
-using ReportService.Application.Pipeline;
using WebsiteProfiling.Contracts.Config;
-namespace ReportService.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api")]
diff --git a/services/ReportService/src/ReportService.Api/Controllers/PipelinePreviewController.cs b/services/CoreService/src/CoreService.Api/Controllers/PipelinePreviewController.cs
similarity index 93%
rename from services/ReportService/src/ReportService.Api/Controllers/PipelinePreviewController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/PipelinePreviewController.cs
index b7164e4f..ebbd729a 100644
--- a/services/ReportService/src/ReportService.Api/Controllers/PipelinePreviewController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/PipelinePreviewController.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
+using CoreService.Api.Application.Bridge;
using Microsoft.AspNetCore.Mvc;
-using ReportService.Application.Bridge;
-namespace ReportService.Api.Controllers;
+namespace CoreService.Api.Controllers;
/// Browser-facing pipeline preview — relays to Python's internal
/// /internal/pipeline/preview via the existing FastApiPythonBridge. Unlike
diff --git a/services/Data/src/Data.Api/Controllers/PipelineSettingsController.cs b/services/CoreService/src/CoreService.Api/Controllers/PipelineSettingsController.cs
similarity index 95%
rename from services/Data/src/Data.Api/Controllers/PipelineSettingsController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/PipelineSettingsController.cs
index d75b860b..c8ffb0a0 100644
--- a/services/Data/src/Data.Api/Controllers/PipelineSettingsController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/PipelineSettingsController.cs
@@ -1,7 +1,7 @@
-using Data.Application.Repositories;
+using CoreService.Api.DataApplication.Repositories;
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/pipeline-settings")]
diff --git a/services/Data/src/Data.Api/Controllers/PortfolioController.cs b/services/CoreService/src/CoreService.Api/Controllers/PortfolioController.cs
similarity index 89%
rename from services/Data/src/Data.Api/Controllers/PortfolioController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/PortfolioController.cs
index 2f92c72d..5925a5b2 100644
--- a/services/Data/src/Data.Api/Controllers/PortfolioController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/PortfolioController.cs
@@ -1,8 +1,8 @@
-using Data.Application.Dto.Portfolio;
-using Data.Application.Repositories;
+using CoreService.Api.DataApplication.Dto.Portfolio;
+using CoreService.Api.DataApplication.Repositories;
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
///
/// Portfolio mutations ported from FastAPI's /api/portfolio/*.
diff --git a/services/Data/src/Data.Api/Controllers/PropertiesController.cs b/services/CoreService/src/CoreService.Api/Controllers/PropertiesController.cs
similarity index 98%
rename from services/Data/src/Data.Api/Controllers/PropertiesController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/PropertiesController.cs
index 6683c6df..15ed2424 100644
--- a/services/Data/src/Data.Api/Controllers/PropertiesController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/PropertiesController.cs
@@ -1,7 +1,7 @@
-using Data.Application.Repositories;
+using CoreService.Api.DataApplication.Repositories;
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/properties")]
diff --git a/services/IntegrationsService/src/IntegrationsService.Api/Controllers/PropertyGoogleController.cs b/services/CoreService/src/CoreService.Api/Controllers/PropertyGoogleController.cs
similarity index 98%
rename from services/IntegrationsService/src/IntegrationsService.Api/Controllers/PropertyGoogleController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/PropertyGoogleController.cs
index 1670c1d1..e22cf24f 100644
--- a/services/IntegrationsService/src/IntegrationsService.Api/Controllers/PropertyGoogleController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/PropertyGoogleController.cs
@@ -1,10 +1,9 @@
using System.Text.Json;
-using IntegrationsService.Application.Google;
-using IntegrationsService.Application.Repositories;
+using CoreService.Api.IntegrationsApplication.Google;
+using CoreService.Api.IntegrationsApplication.Repositories;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Logging;
-namespace IntegrationsService.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/properties/{propertyId:long}/google")]
diff --git a/services/Data/src/Data.Api/Controllers/ReportController.cs b/services/CoreService/src/CoreService.Api/Controllers/ReportController.cs
similarity index 94%
rename from services/Data/src/Data.Api/Controllers/ReportController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/ReportController.cs
index df4c1486..bfb2ecfa 100644
--- a/services/Data/src/Data.Api/Controllers/ReportController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/ReportController.cs
@@ -1,13 +1,12 @@
-using System.Text.Json;
-using Data.Application.Dto.Meta;
-using Data.Application.Dto.Portfolio;
-using Data.Application.Dto.Report;
-using Data.Application.Portfolio;
-using Data.Application.Report;
-using Data.Application.Repositories;
+using CoreService.Api.DataApplication.Dto.Meta;
+using CoreService.Api.DataApplication.Dto.Portfolio;
+using CoreService.Api.DataApplication.Dto.Report;
+using CoreService.Api.DataApplication.Portfolio;
+using CoreService.Api.DataApplication.Report;
+using CoreService.Api.DataApplication.Repositories;
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
///
/// Read endpoints ported from FastAPI's /api/report/*. The BFF forwards the full path
diff --git a/services/Data/src/Data.Api/Controllers/ReportExportController.cs b/services/CoreService/src/CoreService.Api/Controllers/ReportExportController.cs
similarity index 98%
rename from services/Data/src/Data.Api/Controllers/ReportExportController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/ReportExportController.cs
index 45b53ef6..f24051c3 100644
--- a/services/Data/src/Data.Api/Controllers/ReportExportController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/ReportExportController.cs
@@ -1,11 +1,11 @@
using System.Text;
-using MediaTypeNames = System.Net.Mime.MediaTypeNames;
-using Data.Application.Services;
-using Data.Domain.Models;
+using CoreService.Api.DataApplication.Services;
+using CoreService.Api.Domain.Data.Models;
using Microsoft.AspNetCore.Mvc;
using WebsiteProfiling.Contracts.Report;
+using MediaTypeNames = System.Net.Mime.MediaTypeNames;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
///
/// PDF/Excel/CSV/JSON/sitemap report export — absorbed from the former FileService. Route prefix
diff --git a/services/Data/src/Data.Api/Controllers/ReportExportMimeTypes.cs b/services/CoreService/src/CoreService.Api/Controllers/ReportExportMimeTypes.cs
similarity index 85%
rename from services/Data/src/Data.Api/Controllers/ReportExportMimeTypes.cs
rename to services/CoreService/src/CoreService.Api/Controllers/ReportExportMimeTypes.cs
index 0a7907fe..98018ae5 100644
--- a/services/Data/src/Data.Api/Controllers/ReportExportMimeTypes.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/ReportExportMimeTypes.cs
@@ -1,4 +1,4 @@
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
/// MIME types not covered by System.Net.Mime.MediaTypeNames.
internal static class ReportExportMimeTypes
diff --git a/services/ReportService/src/ReportService.Api/Controllers/ScheduleController.cs b/services/CoreService/src/CoreService.Api/Controllers/ScheduleController.cs
similarity index 86%
rename from services/ReportService/src/ReportService.Api/Controllers/ScheduleController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/ScheduleController.cs
index 7e7a56a3..20ed68b7 100644
--- a/services/ReportService/src/ReportService.Api/Controllers/ScheduleController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/ScheduleController.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc;
-namespace ReportService.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api")]
diff --git a/services/Data/src/Data.Api/Controllers/UiPreferencesController.cs b/services/CoreService/src/CoreService.Api/Controllers/UiPreferencesController.cs
similarity index 96%
rename from services/Data/src/Data.Api/Controllers/UiPreferencesController.cs
rename to services/CoreService/src/CoreService.Api/Controllers/UiPreferencesController.cs
index c4726068..144deff5 100644
--- a/services/Data/src/Data.Api/Controllers/UiPreferencesController.cs
+++ b/services/CoreService/src/CoreService.Api/Controllers/UiPreferencesController.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
-using Data.Application.Repositories;
+using CoreService.Api.DataApplication.Repositories;
using Microsoft.AspNetCore.Mvc;
-namespace Data.Api.Controllers;
+namespace CoreService.Api.Controllers;
[ApiController]
[Route("api/ui-preferences")]
diff --git a/services/CoreService/src/CoreService.Api/CoreService.Api.csproj b/services/CoreService/src/CoreService.Api/CoreService.Api.csproj
new file mode 100644
index 00000000..46609cb7
--- /dev/null
+++ b/services/CoreService/src/CoreService.Api/CoreService.Api.csproj
@@ -0,0 +1,34 @@
+
+
+
+ net10.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/services/Data/src/Data.Application/Clients/AppSettingsClient.cs b/services/CoreService/src/CoreService.Api/DataApplication/Clients/AppSettingsClient.cs
similarity index 88%
rename from services/Data/src/Data.Application/Clients/AppSettingsClient.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Clients/AppSettingsClient.cs
index f23c021d..4c6c2284 100644
--- a/services/Data/src/Data.Application/Clients/AppSettingsClient.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Clients/AppSettingsClient.cs
@@ -1,9 +1,7 @@
-using System.Net.Http.Json;
-using Data.Application.Repositories;
-using Data.Domain.Models;
-using Microsoft.Extensions.Logging;
+using CoreService.Api.DataApplication.Repositories;
+using CoreService.Api.Domain.Data.Models;
-namespace Data.Application.Clients;
+namespace CoreService.Api.DataApplication.Clients;
public sealed class AppSettingsClient(
IUiPreferencesRepository uiPreferences,
diff --git a/services/Data/src/Data.Application/Clients/DbReportDataClient.cs b/services/CoreService/src/CoreService.Api/DataApplication/Clients/DbReportDataClient.cs
similarity index 91%
rename from services/Data/src/Data.Application/Clients/DbReportDataClient.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Clients/DbReportDataClient.cs
index 0ec994e3..c187cc5f 100644
--- a/services/Data/src/Data.Application/Clients/DbReportDataClient.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Clients/DbReportDataClient.cs
@@ -1,9 +1,9 @@
using System.Text.Json;
-using Data.Application.Persistence;
-using Data.Domain.Models;
+using CoreService.Api.DataApplication.Persistence;
+using CoreService.Api.Domain.Data.Models;
using Microsoft.EntityFrameworkCore;
-namespace Data.Application.Clients;
+namespace CoreService.Api.DataApplication.Clients;
///
/// Reads report payloads directly from Postgres via the shared .
diff --git a/services/Data/src/Data.Application/Clients/IAppSettingsClient.cs b/services/CoreService/src/CoreService.Api/DataApplication/Clients/IAppSettingsClient.cs
similarity index 74%
rename from services/Data/src/Data.Application/Clients/IAppSettingsClient.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Clients/IAppSettingsClient.cs
index 59db8426..e8014cbf 100644
--- a/services/Data/src/Data.Application/Clients/IAppSettingsClient.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Clients/IAppSettingsClient.cs
@@ -1,6 +1,6 @@
-using Data.Domain.Models;
+using CoreService.Api.Domain.Data.Models;
-namespace Data.Application.Clients;
+namespace CoreService.Api.DataApplication.Clients;
public interface IAppSettingsClient
{
diff --git a/services/Data/src/Data.Application/Clients/IReportDataClient.cs b/services/CoreService/src/CoreService.Api/DataApplication/Clients/IReportDataClient.cs
similarity index 74%
rename from services/Data/src/Data.Application/Clients/IReportDataClient.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Clients/IReportDataClient.cs
index 605efe02..7276eb8a 100644
--- a/services/Data/src/Data.Application/Clients/IReportDataClient.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Clients/IReportDataClient.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using Data.Domain.Models;
+using CoreService.Api.Domain.Data.Models;
-namespace Data.Application.Clients;
+namespace CoreService.Api.DataApplication.Clients;
public interface IReportDataClient
{
diff --git a/services/Data/src/Data.Application/Clients/LogoFetcher.cs b/services/CoreService/src/CoreService.Api/DataApplication/Clients/LogoFetcher.cs
similarity index 94%
rename from services/Data/src/Data.Application/Clients/LogoFetcher.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Clients/LogoFetcher.cs
index 5d6075fd..b4e4a3e1 100644
--- a/services/Data/src/Data.Application/Clients/LogoFetcher.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Clients/LogoFetcher.cs
@@ -1,6 +1,4 @@
-using Microsoft.Extensions.Logging;
-
-namespace Data.Application.Clients;
+namespace CoreService.Api.DataApplication.Clients;
public sealed class LogoFetcher(HttpClient http, ILogger logger) : ILogoFetcher
{
diff --git a/services/Data/src/Data.Application/Clients/OutboundUrlValidator.cs b/services/CoreService/src/CoreService.Api/DataApplication/Clients/OutboundUrlValidator.cs
similarity index 97%
rename from services/Data/src/Data.Application/Clients/OutboundUrlValidator.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Clients/OutboundUrlValidator.cs
index 01adcf04..cfc07ab0 100644
--- a/services/Data/src/Data.Application/Clients/OutboundUrlValidator.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Clients/OutboundUrlValidator.cs
@@ -1,7 +1,7 @@
using System.Net;
using System.Net.Sockets;
-namespace Data.Application.Clients;
+namespace CoreService.Api.DataApplication.Clients;
internal static class OutboundUrlValidator
{
diff --git a/services/Data/src/Data.Application/Content/ContentBriefBuilder.cs b/services/CoreService/src/CoreService.Api/DataApplication/Content/ContentBriefBuilder.cs
similarity index 98%
rename from services/Data/src/Data.Application/Content/ContentBriefBuilder.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Content/ContentBriefBuilder.cs
index 3c973699..b0443daf 100644
--- a/services/Data/src/Data.Application/Content/ContentBriefBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Content/ContentBriefBuilder.cs
@@ -1,6 +1,6 @@
using System.Text.Json;
-namespace Data.Application.Content;
+namespace CoreService.Api.DataApplication.Content;
/// Heuristic content brief — port of Python ai_service_client.generate_content_brief.
public static class ContentBriefBuilder
diff --git a/services/Data/src/Data.Application/DependencyInjection.cs b/services/CoreService/src/CoreService.Api/DataApplication/DependencyInjection.cs
similarity index 87%
rename from services/Data/src/Data.Application/DependencyInjection.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/DependencyInjection.cs
index 17fb452f..2257cb04 100644
--- a/services/Data/src/Data.Application/DependencyInjection.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/DependencyInjection.cs
@@ -1,18 +1,16 @@
-using Data.Application.Clients;
-using Data.Application.Options;
-using Data.Application.Persistence;
-using Data.Application.Portfolio;
-using Data.Application.Python;
-using Data.Application.Report;
-using Data.Application.Repositories;
-using Data.Application.Services;
-using Data.Rendering;
-using Data.Rendering.Exports;
-using Microsoft.Extensions.DependencyInjection;
+using CoreService.Api.DataApplication.Clients;
+using CoreService.Api.DataApplication.Options;
+using CoreService.Api.DataApplication.Persistence;
+using CoreService.Api.DataApplication.Portfolio;
+using CoreService.Api.DataApplication.Python;
+using CoreService.Api.DataApplication.Report;
+using CoreService.Api.DataApplication.Repositories;
+using CoreService.Api.DataApplication.Services;
+using CoreService.Api.Rendering;
+using CoreService.Api.Rendering.Exports;
using WebsiteProfiling.Data;
-using WebsiteProfiling.Data.EntityFrameworkCore;
-namespace Data.Application;
+namespace CoreService.Api.DataApplication;
public static class DependencyInjection
{
diff --git a/services/Data/src/Data.Application/Domain/DomainResolver.cs b/services/CoreService/src/CoreService.Api/DataApplication/Domain/DomainResolver.cs
similarity index 95%
rename from services/Data/src/Data.Application/Domain/DomainResolver.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Domain/DomainResolver.cs
index b6fb6c05..be857cf4 100644
--- a/services/Data/src/Data.Application/Domain/DomainResolver.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Domain/DomainResolver.cs
@@ -1,7 +1,7 @@
using System.Text.RegularExpressions;
-using Data.Domain.Models;
+using CoreService.Api.Domain.Data.Models;
-namespace Data.Application.Domain;
+namespace CoreService.Api.DataApplication.Domain;
public static partial class DomainResolver
{
diff --git a/services/Data/src/Data.Application/Dto/Filters/SavedFilterDtos.cs b/services/CoreService/src/CoreService.Api/DataApplication/Dto/Filters/SavedFilterDtos.cs
similarity index 95%
rename from services/Data/src/Data.Application/Dto/Filters/SavedFilterDtos.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Dto/Filters/SavedFilterDtos.cs
index 468741fe..5872868c 100644
--- a/services/Data/src/Data.Application/Dto/Filters/SavedFilterDtos.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Dto/Filters/SavedFilterDtos.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-namespace Data.Application.Dto.Filters;
+namespace CoreService.Api.DataApplication.Dto.Filters;
public sealed class SavedFilterRowDto
{
diff --git a/services/Data/src/Data.Application/Dto/Issues/IssueStatusDtos.cs b/services/CoreService/src/CoreService.Api/DataApplication/Dto/Issues/IssueStatusDtos.cs
similarity index 97%
rename from services/Data/src/Data.Application/Dto/Issues/IssueStatusDtos.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Dto/Issues/IssueStatusDtos.cs
index f675b01a..f3e58fbb 100644
--- a/services/Data/src/Data.Application/Dto/Issues/IssueStatusDtos.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Dto/Issues/IssueStatusDtos.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace Data.Application.Dto.Issues;
+namespace CoreService.Api.DataApplication.Dto.Issues;
public sealed class IssueStatusRowDto
{
diff --git a/services/Data/src/Data.Application/Dto/Meta/ReportMetaResponse.cs b/services/CoreService/src/CoreService.Api/DataApplication/Dto/Meta/ReportMetaResponse.cs
similarity index 97%
rename from services/Data/src/Data.Application/Dto/Meta/ReportMetaResponse.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Dto/Meta/ReportMetaResponse.cs
index 1336a3a1..5311b37c 100644
--- a/services/Data/src/Data.Application/Dto/Meta/ReportMetaResponse.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Dto/Meta/ReportMetaResponse.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace Data.Application.Dto.Meta;
+namespace CoreService.Api.DataApplication.Dto.Meta;
///
/// Response shape for GET /api/report/meta. Mirrors the FastAPI router which returns
diff --git a/services/Data/src/Data.Application/Dto/Portfolio/DeletePortfolioRequest.cs b/services/CoreService/src/CoreService.Api/DataApplication/Dto/Portfolio/DeletePortfolioRequest.cs
similarity index 80%
rename from services/Data/src/Data.Application/Dto/Portfolio/DeletePortfolioRequest.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Dto/Portfolio/DeletePortfolioRequest.cs
index f74812be..0776d3ef 100644
--- a/services/Data/src/Data.Application/Dto/Portfolio/DeletePortfolioRequest.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Dto/Portfolio/DeletePortfolioRequest.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace Data.Application.Dto.Portfolio;
+namespace CoreService.Api.DataApplication.Dto.Portfolio;
public sealed class DeletePortfolioRequest
{
diff --git a/services/Data/src/Data.Application/Dto/Portfolio/PortfolioDtos.cs b/services/CoreService/src/CoreService.Api/DataApplication/Dto/Portfolio/PortfolioDtos.cs
similarity index 99%
rename from services/Data/src/Data.Application/Dto/Portfolio/PortfolioDtos.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Dto/Portfolio/PortfolioDtos.cs
index 760e0495..1ce86843 100644
--- a/services/Data/src/Data.Application/Dto/Portfolio/PortfolioDtos.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Dto/Portfolio/PortfolioDtos.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
-namespace Data.Application.Dto.Portfolio;
+namespace CoreService.Api.DataApplication.Dto.Portfolio;
public sealed class PortfolioIssueCountsDto
{
diff --git a/services/Data/src/Data.Application/Dto/Report/AuditHistoryResponse.cs b/services/CoreService/src/CoreService.Api/DataApplication/Dto/Report/AuditHistoryResponse.cs
similarity index 95%
rename from services/Data/src/Data.Application/Dto/Report/AuditHistoryResponse.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Dto/Report/AuditHistoryResponse.cs
index fffefa1f..d68f4fa1 100644
--- a/services/Data/src/Data.Application/Dto/Report/AuditHistoryResponse.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Dto/Report/AuditHistoryResponse.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace Data.Application.Dto.Report;
+namespace CoreService.Api.DataApplication.Dto.Report;
/// Port of the items returned by list_audit_history in report_loader.py.
public sealed class AuditHistoryItem
diff --git a/services/Data/src/Data.Application/Dto/Report/MobileDeltaResponse.cs b/services/CoreService/src/CoreService.Api/DataApplication/Dto/Report/MobileDeltaResponse.cs
similarity index 95%
rename from services/Data/src/Data.Application/Dto/Report/MobileDeltaResponse.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Dto/Report/MobileDeltaResponse.cs
index 7f4d47b4..db35a4dc 100644
--- a/services/Data/src/Data.Application/Dto/Report/MobileDeltaResponse.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Dto/Report/MobileDeltaResponse.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace Data.Application.Dto.Report;
+namespace CoreService.Api.DataApplication.Dto.Report;
/// Per-URL desktop/mobile snapshot from get_mobile_desktop_delta.
public sealed class CrawlPageSnapshot
diff --git a/services/Data/src/Data.Application/Issues/IssueStatusFingerprint.cs b/services/CoreService/src/CoreService.Api/DataApplication/Issues/IssueStatusFingerprint.cs
similarity index 91%
rename from services/Data/src/Data.Application/Issues/IssueStatusFingerprint.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Issues/IssueStatusFingerprint.cs
index 7f669b49..f693d8d2 100644
--- a/services/Data/src/Data.Application/Issues/IssueStatusFingerprint.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Issues/IssueStatusFingerprint.cs
@@ -1,7 +1,7 @@
using System.Security.Cryptography;
using System.Text;
-namespace Data.Application.Issues;
+namespace CoreService.Api.DataApplication.Issues;
///
/// Port of issue_status_store.issue_fingerprint.
diff --git a/services/Data/src/Data.Application/Json/PyIso.cs b/services/CoreService/src/CoreService.Api/DataApplication/Json/PyIso.cs
similarity index 96%
rename from services/Data/src/Data.Application/Json/PyIso.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Json/PyIso.cs
index d0c38ba9..0178d8bc 100644
--- a/services/Data/src/Data.Application/Json/PyIso.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Json/PyIso.cs
@@ -1,6 +1,6 @@
using System.Globalization;
-namespace Data.Application.Json;
+namespace CoreService.Api.DataApplication.Json;
///
/// Formats timestamps to match Python's datetime.isoformat() on the UTC values returned by
diff --git a/services/Data/src/Data.Application/Mapping/AuditReportMapper.cs b/services/CoreService/src/CoreService.Api/DataApplication/Mapping/AuditReportMapper.cs
similarity index 99%
rename from services/Data/src/Data.Application/Mapping/AuditReportMapper.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Mapping/AuditReportMapper.cs
index 8b47c461..e09c14ec 100644
--- a/services/Data/src/Data.Application/Mapping/AuditReportMapper.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Mapping/AuditReportMapper.cs
@@ -1,10 +1,10 @@
using System.Globalization;
using System.Text.Json;
-using Data.Domain.Models;
+using CoreService.Api.Domain.Data.Models;
using WebsiteProfiling.Contracts.Json;
using WebsiteProfiling.Contracts.Report;
-namespace Data.Application.Mapping;
+namespace CoreService.Api.DataApplication.Mapping;
public static class AuditReportMapper
{
diff --git a/services/Data/src/Data.Application/Mapping/ChapterMappers.cs b/services/CoreService/src/CoreService.Api/DataApplication/Mapping/ChapterMappers.cs
similarity index 99%
rename from services/Data/src/Data.Application/Mapping/ChapterMappers.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Mapping/ChapterMappers.cs
index a0b0e20d..18d37722 100644
--- a/services/Data/src/Data.Application/Mapping/ChapterMappers.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Mapping/ChapterMappers.cs
@@ -1,9 +1,8 @@
-using System.Globalization;
using System.Text.Json;
-using Data.Domain.Models;
+using CoreService.Api.Domain.Data.Models;
using WebsiteProfiling.Contracts.Json;
-namespace Data.Application.Mapping;
+namespace CoreService.Api.DataApplication.Mapping;
public static class ChapterMappers
{
diff --git a/services/Data/src/Data.Application/Mapping/IssueNormalizer.cs b/services/CoreService/src/CoreService.Api/DataApplication/Mapping/IssueNormalizer.cs
similarity index 97%
rename from services/Data/src/Data.Application/Mapping/IssueNormalizer.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Mapping/IssueNormalizer.cs
index 12a1cda7..bb251e70 100644
--- a/services/Data/src/Data.Application/Mapping/IssueNormalizer.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Mapping/IssueNormalizer.cs
@@ -1,8 +1,7 @@
using System.Text.RegularExpressions;
-using Data.Domain.Models;
using WebsiteProfiling.Contracts.Report;
-namespace Data.Application.Mapping;
+namespace CoreService.Api.DataApplication.Mapping;
public static partial class IssueNormalizer
{
diff --git a/services/Data/src/Data.Application/Mapping/PayloadSliceMapper.cs b/services/CoreService/src/CoreService.Api/DataApplication/Mapping/PayloadSliceMapper.cs
similarity index 98%
rename from services/Data/src/Data.Application/Mapping/PayloadSliceMapper.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Mapping/PayloadSliceMapper.cs
index 48cc532a..0de35a99 100644
--- a/services/Data/src/Data.Application/Mapping/PayloadSliceMapper.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Mapping/PayloadSliceMapper.cs
@@ -5,7 +5,7 @@
using WebsiteProfiling.Contracts.Json;
using WebsiteProfiling.Contracts.Report;
-namespace Data.Application.Mapping;
+namespace CoreService.Api.DataApplication.Mapping;
public static class PayloadSliceMapper
{
diff --git a/services/Data/src/Data.Application/Options/ReportApiOptions.cs b/services/CoreService/src/CoreService.Api/DataApplication/Options/ReportApiOptions.cs
similarity index 90%
rename from services/Data/src/Data.Application/Options/ReportApiOptions.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Options/ReportApiOptions.cs
index 8da5e6e8..5164297c 100644
--- a/services/Data/src/Data.Application/Options/ReportApiOptions.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Options/ReportApiOptions.cs
@@ -1,4 +1,4 @@
-namespace Data.Application.Options;
+namespace CoreService.Api.DataApplication.Options;
///
/// HTTP base URL for the Site Audit app-settings / branding API (used by AppSettingsClient).
diff --git a/services/Data/src/Data.Application/Persistence/DataDbContext.cs b/services/CoreService/src/CoreService.Api/DataApplication/Persistence/DataDbContext.cs
similarity index 98%
rename from services/Data/src/Data.Application/Persistence/DataDbContext.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Persistence/DataDbContext.cs
index 7e41a910..129666a4 100644
--- a/services/Data/src/Data.Application/Persistence/DataDbContext.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Persistence/DataDbContext.cs
@@ -1,7 +1,7 @@
-using Data.Domain.Entities;
+using CoreService.Api.Domain.Data.Entities;
using Microsoft.EntityFrameworkCore;
-namespace Data.Application.Persistence;
+namespace CoreService.Api.DataApplication.Persistence;
///
/// EF Core context over the schema owned by services/Schema. It NEVER creates or migrates tables:
diff --git a/services/Data/src/Data.Application/Portfolio/PortfolioConstants.cs b/services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioConstants.cs
similarity index 94%
rename from services/Data/src/Data.Application/Portfolio/PortfolioConstants.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioConstants.cs
index be611b99..4bfb75fb 100644
--- a/services/Data/src/Data.Application/Portfolio/PortfolioConstants.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioConstants.cs
@@ -1,4 +1,4 @@
-namespace Data.Application.Portfolio;
+namespace CoreService.Api.DataApplication.Portfolio;
public static class PortfolioConstants
{
diff --git a/services/Data/src/Data.Application/Portfolio/PortfolioGrouping.cs b/services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioGrouping.cs
similarity index 99%
rename from services/Data/src/Data.Application/Portfolio/PortfolioGrouping.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioGrouping.cs
index c797224f..96361020 100644
--- a/services/Data/src/Data.Application/Portfolio/PortfolioGrouping.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioGrouping.cs
@@ -1,10 +1,9 @@
using System.Text.Json;
-using System.Text.Json.Nodes;
-using Data.Application.Dto.Portfolio;
-using Data.Application.Mapping;
+using CoreService.Api.DataApplication.Dto.Portfolio;
+using CoreService.Api.DataApplication.Mapping;
using WebsiteProfiling.Contracts.Report;
-namespace Data.Application.Portfolio;
+namespace CoreService.Api.DataApplication.Portfolio;
internal static class PortfolioGrouping
{
diff --git a/services/Data/src/Data.Application/Portfolio/PortfolioHelpers.cs b/services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioHelpers.cs
similarity index 99%
rename from services/Data/src/Data.Application/Portfolio/PortfolioHelpers.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioHelpers.cs
index 85cb56db..38e6452d 100644
--- a/services/Data/src/Data.Application/Portfolio/PortfolioHelpers.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioHelpers.cs
@@ -3,7 +3,7 @@
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
-namespace Data.Application.Portfolio;
+namespace CoreService.Api.DataApplication.Portfolio;
internal static partial class PortfolioHelpers
{
diff --git a/services/Data/src/Data.Application/Portfolio/PortfolioHistory.cs b/services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioHistory.cs
similarity index 92%
rename from services/Data/src/Data.Application/Portfolio/PortfolioHistory.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioHistory.cs
index 6d340677..0b5dedba 100644
--- a/services/Data/src/Data.Application/Portfolio/PortfolioHistory.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioHistory.cs
@@ -1,6 +1,6 @@
-using Data.Application.Dto.Portfolio;
+using CoreService.Api.DataApplication.Dto.Portfolio;
-namespace Data.Application.Portfolio;
+namespace CoreService.Api.DataApplication.Portfolio;
internal static class PortfolioHistory
{
diff --git a/services/Data/src/Data.Application/Portfolio/PortfolioMaps.cs b/services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioMaps.cs
similarity index 92%
rename from services/Data/src/Data.Application/Portfolio/PortfolioMaps.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioMaps.cs
index a3920857..f001c462 100644
--- a/services/Data/src/Data.Application/Portfolio/PortfolioMaps.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioMaps.cs
@@ -1,6 +1,6 @@
-using Data.Application.Dto.Portfolio;
+using CoreService.Api.DataApplication.Dto.Portfolio;
-namespace Data.Application.Portfolio;
+namespace CoreService.Api.DataApplication.Portfolio;
internal sealed class PortfolioMaps
{
diff --git a/services/Data/src/Data.Application/Portfolio/PortfolioService.cs b/services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioService.cs
similarity index 97%
rename from services/Data/src/Data.Application/Portfolio/PortfolioService.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioService.cs
index e09c77b9..89266ddd 100644
--- a/services/Data/src/Data.Application/Portfolio/PortfolioService.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Portfolio/PortfolioService.cs
@@ -1,9 +1,9 @@
using System.Text.Json;
-using Data.Application.Dto.Portfolio;
-using Data.Application.Repositories;
+using CoreService.Api.DataApplication.Dto.Portfolio;
+using CoreService.Api.DataApplication.Repositories;
using Microsoft.Extensions.Caching.Memory;
-namespace Data.Application.Portfolio;
+namespace CoreService.Api.DataApplication.Portfolio;
public interface IPortfolioService
{
diff --git a/services/Data/src/Data.Application/Python/DataPythonRunner.cs b/services/CoreService/src/CoreService.Api/DataApplication/Python/DataPythonRunner.cs
similarity index 99%
rename from services/Data/src/Data.Application/Python/DataPythonRunner.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Python/DataPythonRunner.cs
index df054034..a304d156 100644
--- a/services/Data/src/Data.Application/Python/DataPythonRunner.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Python/DataPythonRunner.cs
@@ -2,7 +2,7 @@
using System.Text;
using System.Text.Json;
-namespace Data.Application.Python;
+namespace CoreService.Api.DataApplication.Python;
///
/// Runs optional Python modules (alerts, log analysis) when the repo source is available locally.
diff --git a/services/Data/src/Data.Application/Report/IReportSectionService.cs b/services/CoreService/src/CoreService.Api/DataApplication/Report/IReportSectionService.cs
similarity index 88%
rename from services/Data/src/Data.Application/Report/IReportSectionService.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Report/IReportSectionService.cs
index 3155955f..2e482ea2 100644
--- a/services/Data/src/Data.Application/Report/IReportSectionService.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Report/IReportSectionService.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Nodes;
-namespace Data.Application.Report;
+namespace CoreService.Api.DataApplication.Report;
public interface IReportSectionService
{
diff --git a/services/Data/src/Data.Application/Report/ReportPayloadContext.cs b/services/CoreService/src/CoreService.Api/DataApplication/Report/ReportPayloadContext.cs
similarity index 63%
rename from services/Data/src/Data.Application/Report/ReportPayloadContext.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Report/ReportPayloadContext.cs
index b8212a9c..60be84ed 100644
--- a/services/Data/src/Data.Application/Report/ReportPayloadContext.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Report/ReportPayloadContext.cs
@@ -1,3 +1,3 @@
-namespace Data.Application.Report;
+namespace CoreService.Api.DataApplication.Report;
public sealed record ReportPayloadContext(string DataJson, string? CanonicalDomain);
diff --git a/services/Data/src/Data.Application/Report/ReportSectionService.cs b/services/CoreService/src/CoreService.Api/DataApplication/Report/ReportSectionService.cs
similarity index 97%
rename from services/Data/src/Data.Application/Report/ReportSectionService.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Report/ReportSectionService.cs
index 20eb06d9..af3e8bdb 100644
--- a/services/Data/src/Data.Application/Report/ReportSectionService.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Report/ReportSectionService.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using Data.Application.Repositories;
+using CoreService.Api.DataApplication.Repositories;
-namespace Data.Application.Report;
+namespace CoreService.Api.DataApplication.Report;
public sealed class ReportSectionService(
IReportRepository reports,
diff --git a/services/Data/src/Data.Application/Report/SectionFields.cs b/services/CoreService/src/CoreService.Api/DataApplication/Report/SectionFields.cs
similarity index 98%
rename from services/Data/src/Data.Application/Report/SectionFields.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Report/SectionFields.cs
index 846083f2..201cbd4d 100644
--- a/services/Data/src/Data.Application/Report/SectionFields.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Report/SectionFields.cs
@@ -1,4 +1,4 @@
-namespace Data.Application.Report;
+namespace CoreService.Api.DataApplication.Report;
///
/// Port of SECTION_FIELDS from report_loader.py.
diff --git a/services/Data/src/Data.Application/Repositories/BacklinksRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/BacklinksRepository.cs
similarity index 97%
rename from services/Data/src/Data.Application/Repositories/BacklinksRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/BacklinksRepository.cs
index b4d67102..054b9f21 100644
--- a/services/Data/src/Data.Application/Repositories/BacklinksRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/BacklinksRepository.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
using Npgsql;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public interface IBacklinksRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/ClientPreferencesRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/ClientPreferencesRepository.cs
similarity index 98%
rename from services/Data/src/Data.Application/Repositories/ClientPreferencesRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/ClientPreferencesRepository.cs
index e5f1433f..a90d6d05 100644
--- a/services/Data/src/Data.Application/Repositories/ClientPreferencesRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/ClientPreferencesRepository.cs
@@ -1,8 +1,8 @@
+using Npgsql;
using WebsiteProfiling.Contracts.Config;
using WebsiteProfiling.TypedConfig;
-using Npgsql;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public sealed class ClientPreferencesRepository(NpgsqlDataSource dataSource) : IClientPreferencesRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/ContentDraftRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/ContentDraftRepository.cs
similarity index 99%
rename from services/Data/src/Data.Application/Repositories/ContentDraftRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/ContentDraftRepository.cs
index df262805..587c259c 100644
--- a/services/Data/src/Data.Application/Repositories/ContentDraftRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/ContentDraftRepository.cs
@@ -2,7 +2,7 @@
using Npgsql;
using NpgsqlTypes;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public interface IContentDraftRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/GoogleDataRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/GoogleDataRepository.cs
similarity index 96%
rename from services/Data/src/Data.Application/Repositories/GoogleDataRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/GoogleDataRepository.cs
index 1fad877a..6630a8aa 100644
--- a/services/Data/src/Data.Application/Repositories/GoogleDataRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/GoogleDataRepository.cs
@@ -1,13 +1,13 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using Data.Application.Mapping;
-using Data.Application.Persistence;
-using Data.Domain.Entities;
+using CoreService.Api.DataApplication.Mapping;
+using CoreService.Api.DataApplication.Persistence;
+using CoreService.Api.Domain.Data.Entities;
using Microsoft.EntityFrameworkCore;
using WebsiteProfiling.Contracts.Google;
using WebsiteProfiling.Contracts.Json;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public sealed class GoogleDataRepository(DataDbContext db) : IGoogleDataRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/IClientPreferencesRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IClientPreferencesRepository.cs
similarity index 94%
rename from services/Data/src/Data.Application/Repositories/IClientPreferencesRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/IClientPreferencesRepository.cs
index 8ea0bba6..07ad6de2 100644
--- a/services/Data/src/Data.Application/Repositories/IClientPreferencesRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IClientPreferencesRepository.cs
@@ -1,4 +1,4 @@
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public interface IClientPreferencesRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/IGoogleDataRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IGoogleDataRepository.cs
similarity index 94%
rename from services/Data/src/Data.Application/Repositories/IGoogleDataRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/IGoogleDataRepository.cs
index 7d4beae4..433bb1a9 100644
--- a/services/Data/src/Data.Application/Repositories/IGoogleDataRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IGoogleDataRepository.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Nodes;
using WebsiteProfiling.Contracts.Google;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public interface IGoogleDataRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/IIssueStatusRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IIssueStatusRepository.cs
similarity index 71%
rename from services/Data/src/Data.Application/Repositories/IIssueStatusRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/IIssueStatusRepository.cs
index 0f57e3dc..16421b40 100644
--- a/services/Data/src/Data.Application/Repositories/IIssueStatusRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IIssueStatusRepository.cs
@@ -1,6 +1,6 @@
-using Data.Application.Dto.Issues;
+using CoreService.Api.DataApplication.Dto.Issues;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public interface IIssueStatusRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/IPipelineSettingsRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IPipelineSettingsRepository.cs
similarity index 93%
rename from services/Data/src/Data.Application/Repositories/IPipelineSettingsRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/IPipelineSettingsRepository.cs
index ee0fa86c..3675548e 100644
--- a/services/Data/src/Data.Application/Repositories/IPipelineSettingsRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IPipelineSettingsRepository.cs
@@ -1,4 +1,4 @@
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public interface IPipelineSettingsRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/IPortfolioRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IPortfolioRepository.cs
similarity index 92%
rename from services/Data/src/Data.Application/Repositories/IPortfolioRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/IPortfolioRepository.cs
index 58963035..aec71c85 100644
--- a/services/Data/src/Data.Application/Repositories/IPortfolioRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IPortfolioRepository.cs
@@ -1,6 +1,6 @@
-using Data.Application.Dto.Portfolio;
+using CoreService.Api.DataApplication.Dto.Portfolio;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public interface IPortfolioRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/IPropertiesCrudRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IPropertiesCrudRepository.cs
similarity index 95%
rename from services/Data/src/Data.Application/Repositories/IPropertiesCrudRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/IPropertiesCrudRepository.cs
index cde384e9..e7731025 100644
--- a/services/Data/src/Data.Application/Repositories/IPropertiesCrudRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IPropertiesCrudRepository.cs
@@ -1,6 +1,4 @@
-using System.Text.Json;
-
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public interface IPropertiesCrudRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/IPropertyRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IPropertyRepository.cs
similarity index 81%
rename from services/Data/src/Data.Application/Repositories/IPropertyRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/IPropertyRepository.cs
index 6c8b13d9..6d036c4d 100644
--- a/services/Data/src/Data.Application/Repositories/IPropertyRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IPropertyRepository.cs
@@ -1,4 +1,4 @@
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public interface IPropertyRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/IReportRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IReportRepository.cs
similarity index 90%
rename from services/Data/src/Data.Application/Repositories/IReportRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/IReportRepository.cs
index f1619aec..44cf450f 100644
--- a/services/Data/src/Data.Application/Repositories/IReportRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IReportRepository.cs
@@ -1,9 +1,9 @@
using System.Text.Json.Nodes;
-using Data.Application.Dto.Meta;
-using Data.Application.Dto.Report;
-using Data.Application.Report;
+using CoreService.Api.DataApplication.Dto.Meta;
+using CoreService.Api.DataApplication.Dto.Report;
+using CoreService.Api.DataApplication.Report;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public interface IReportRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/ISavedFilterRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/ISavedFilterRepository.cs
similarity index 78%
rename from services/Data/src/Data.Application/Repositories/ISavedFilterRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/ISavedFilterRepository.cs
index 24043789..f4842e6e 100644
--- a/services/Data/src/Data.Application/Repositories/ISavedFilterRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/ISavedFilterRepository.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using Data.Application.Dto.Filters;
+using CoreService.Api.DataApplication.Dto.Filters;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public interface ISavedFilterRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/IUiPreferencesRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IUiPreferencesRepository.cs
similarity index 91%
rename from services/Data/src/Data.Application/Repositories/IUiPreferencesRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/IUiPreferencesRepository.cs
index 3aede62a..e0ea8c4f 100644
--- a/services/Data/src/Data.Application/Repositories/IUiPreferencesRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IUiPreferencesRepository.cs
@@ -1,6 +1,6 @@
using System.Text.Json;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public interface IUiPreferencesRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/IssueStatusRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IssueStatusRepository.cs
similarity index 83%
rename from services/Data/src/Data.Application/Repositories/IssueStatusRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/IssueStatusRepository.cs
index c1bc4774..7912a166 100644
--- a/services/Data/src/Data.Application/Repositories/IssueStatusRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/IssueStatusRepository.cs
@@ -1,10 +1,11 @@
-using Data.Application.Dto.Issues;
-using Data.Application.Issues;
-using Data.Application.Json;
-using Data.Application.Persistence;
+using CoreService.Api.DataApplication.Dto.Issues;
+using CoreService.Api.DataApplication.Issues;
+using CoreService.Api.DataApplication.Json;
+using CoreService.Api.DataApplication.Persistence;
+using CoreService.Api.Domain.Data.Entities;
using Microsoft.EntityFrameworkCore;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public sealed class IssueStatusRepository(DataDbContext db) : IIssueStatusRepository
{
@@ -14,7 +15,7 @@ public sealed class IssueStatusRepository(DataDbContext db) : IIssueStatusReposi
public async Task> ListAsync(
int propertyId, CancellationToken cancellationToken)
{
- var rows = await db.Set()
+ var rows = await db.Set()
.AsNoTracking()
.Where(x => x.PropertyId == propertyId)
.OrderByDescending(x => x.UpdatedAt)
@@ -35,7 +36,7 @@ public async Task UpsertAsync(
var priority = request.Priority ?? "Medium";
var fingerprint = IssueStatusFingerprint.Compute(message, url, request.CategoryId);
- var existing = await db.Set()
+ var existing = await db.Set()
.AsTracking()
.FirstOrDefaultAsync(
x => x.PropertyId == request.PropertyId && x.IssueFingerprint == fingerprint,
@@ -43,7 +44,7 @@ public async Task UpsertAsync(
if (existing is null)
{
- var row = new Data.Domain.Entities.IssueStatus
+ var row = new IssueStatus
{
PropertyId = request.PropertyId,
ReportId = request.ReportId,
@@ -58,7 +59,7 @@ public async Task UpsertAsync(
CreatedAt = DateTimeOffset.UtcNow,
UpdatedAt = DateTimeOffset.UtcNow,
};
- db.Set().Add(row);
+ db.Set().Add(row);
await db.SaveChangesAsync(cancellationToken);
return MapEntity(row);
}
@@ -72,7 +73,7 @@ public async Task UpsertAsync(
return MapEntity(existing);
}
- private static IssueStatusRowDto MapEntity(Data.Domain.Entities.IssueStatus row) => new()
+ private static IssueStatusRowDto MapEntity(IssueStatus row) => new()
{
Id = row.Id,
PropertyId = row.PropertyId,
diff --git a/services/Data/src/Data.Application/Repositories/PageMarkdownRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/PageMarkdownRepository.cs
similarity index 99%
rename from services/Data/src/Data.Application/Repositories/PageMarkdownRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/PageMarkdownRepository.cs
index 72f65fd9..0ed505d7 100644
--- a/services/Data/src/Data.Application/Repositories/PageMarkdownRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/PageMarkdownRepository.cs
@@ -1,7 +1,7 @@
-using Data.Application.Json;
+using CoreService.Api.DataApplication.Json;
using Npgsql;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public interface IPageMarkdownRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/PipelineSettingsRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/PipelineSettingsRepository.cs
similarity index 99%
rename from services/Data/src/Data.Application/Repositories/PipelineSettingsRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/PipelineSettingsRepository.cs
index 8737c183..f44daa7b 100644
--- a/services/Data/src/Data.Application/Repositories/PipelineSettingsRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/PipelineSettingsRepository.cs
@@ -1,7 +1,7 @@
using Npgsql;
using WebsiteProfiling.TypedConfig;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public sealed class PipelineSettingsRepository(NpgsqlDataSource dataSource) : IPipelineSettingsRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/PortfolioRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/PortfolioRepository.cs
similarity index 98%
rename from services/Data/src/Data.Application/Repositories/PortfolioRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/PortfolioRepository.cs
index 8025820f..d0109df3 100644
--- a/services/Data/src/Data.Application/Repositories/PortfolioRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/PortfolioRepository.cs
@@ -1,11 +1,10 @@
-using Data.Application.Dto.Portfolio;
-using Data.Application.Json;
-using Data.Application.Persistence;
+using CoreService.Api.DataApplication.Dto.Portfolio;
+using CoreService.Api.DataApplication.Json;
+using CoreService.Api.DataApplication.Persistence;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Logging;
using Npgsql;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public sealed class PortfolioRepository(
DataDbContext db,
diff --git a/services/Data/src/Data.Application/Repositories/PropertiesCrudRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/PropertiesCrudRepository.cs
similarity index 99%
rename from services/Data/src/Data.Application/Repositories/PropertiesCrudRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/PropertiesCrudRepository.cs
index 41f3a5de..e8ede47e 100644
--- a/services/Data/src/Data.Application/Repositories/PropertiesCrudRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/PropertiesCrudRepository.cs
@@ -1,8 +1,8 @@
-using Data.Application.Json;
+using CoreService.Api.DataApplication.Json;
using Npgsql;
using WebsiteProfiling.Contracts.Properties;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public sealed class PropertiesCrudRepository(NpgsqlDataSource dataSource) : IPropertiesCrudRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/PropertyRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/PropertyRepository.cs
similarity index 91%
rename from services/Data/src/Data.Application/Repositories/PropertyRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/PropertyRepository.cs
index c5836c61..63c224b5 100644
--- a/services/Data/src/Data.Application/Repositories/PropertyRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/PropertyRepository.cs
@@ -1,8 +1,8 @@
-using Data.Application.Persistence;
-using Data.Domain.Entities;
+using CoreService.Api.DataApplication.Persistence;
+using CoreService.Api.Domain.Data.Entities;
using Microsoft.EntityFrameworkCore;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public sealed class PropertyRepository(DataDbContext db) : IPropertyRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/ReportRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/ReportRepository.cs
similarity index 97%
rename from services/Data/src/Data.Application/Repositories/ReportRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/ReportRepository.cs
index 0a547c8d..c2f7e042 100644
--- a/services/Data/src/Data.Application/Repositories/ReportRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/ReportRepository.cs
@@ -1,16 +1,15 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using Data.Application.Dto.Meta;
-using Data.Application.Dto.Report;
-using Data.Application.Json;
-using Data.Application.Persistence;
-using Data.Application.Report;
-using Data.Domain.Entities;
+using CoreService.Api.DataApplication.Dto.Meta;
+using CoreService.Api.DataApplication.Dto.Report;
+using CoreService.Api.DataApplication.Json;
+using CoreService.Api.DataApplication.Persistence;
+using CoreService.Api.DataApplication.Report;
+using CoreService.Api.Domain.Data.Entities;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Logging;
using WebsiteProfiling.Contracts.Report;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public sealed class ReportRepository(DataDbContext db, ILogger logger) : IReportRepository
{
diff --git a/services/Data/src/Data.Application/Repositories/SavedFilterRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/SavedFilterRepository.cs
similarity index 77%
rename from services/Data/src/Data.Application/Repositories/SavedFilterRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/SavedFilterRepository.cs
index 70d9c584..d10de919 100644
--- a/services/Data/src/Data.Application/Repositories/SavedFilterRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/SavedFilterRepository.cs
@@ -1,17 +1,18 @@
using System.Text.Json;
-using Data.Application.Dto.Filters;
-using Data.Application.Json;
-using Data.Application.Persistence;
+using CoreService.Api.DataApplication.Dto.Filters;
+using CoreService.Api.DataApplication.Json;
+using CoreService.Api.DataApplication.Persistence;
+using CoreService.Api.Domain.Data.Entities;
using Microsoft.EntityFrameworkCore;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public sealed class SavedFilterRepository(DataDbContext db) : ISavedFilterRepository
{
public async Task> ListAsync(
int propertyId, CancellationToken cancellationToken)
{
- var rows = await db.Set()
+ var rows = await db.Set()
.AsNoTracking()
.Where(x => x.PropertyId == propertyId)
.OrderBy(x => x.Name)
@@ -23,14 +24,14 @@ public async Task> ListAsync(
public async Task UpsertAsync(
long propertyId, string name, JsonElement filterJson, CancellationToken cancellationToken)
{
- var existing = await db.Set()
+ var existing = await db.Set()
.AsTracking()
.FirstOrDefaultAsync(x => x.PropertyId == propertyId && x.Name == name, cancellationToken);
var raw = filterJson.GetRawText();
if (existing is null)
{
- db.Set().Add(new Data.Domain.Entities.SavedCrawlFilter
+ db.Set().Add(new SavedCrawlFilter
{
PropertyId = propertyId,
Name = name,
@@ -48,13 +49,13 @@ public async Task UpsertAsync(
public async Task DeleteAsync(long propertyId, string name, CancellationToken cancellationToken)
{
- var count = await db.Set()
+ var count = await db.Set()
.Where(x => x.PropertyId == propertyId && x.Name == name)
.ExecuteDeleteAsync(cancellationToken);
return count > 0;
}
- private static SavedFilterRowDto MapEntity(Data.Domain.Entities.SavedCrawlFilter row)
+ private static SavedFilterRowDto MapEntity(SavedCrawlFilter row)
{
JsonElement filterJson;
try
diff --git a/services/Data/src/Data.Application/Repositories/UiPreferencesRepository.cs b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/UiPreferencesRepository.cs
similarity index 98%
rename from services/Data/src/Data.Application/Repositories/UiPreferencesRepository.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Repositories/UiPreferencesRepository.cs
index 28cc20e2..0dfffaa8 100644
--- a/services/Data/src/Data.Application/Repositories/UiPreferencesRepository.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Repositories/UiPreferencesRepository.cs
@@ -1,9 +1,9 @@
using System.Text.Json;
-using WebsiteProfiling.TypedConfig;
using Npgsql;
using NpgsqlTypes;
+using WebsiteProfiling.TypedConfig;
-namespace Data.Application.Repositories;
+namespace CoreService.Api.DataApplication.Repositories;
public sealed class UiPreferencesRepository(NpgsqlDataSource dataSource) : IUiPreferencesRepository
{
diff --git a/services/Data/src/Data.Application/Services/PdfReportService.cs b/services/CoreService/src/CoreService.Api/DataApplication/Services/PdfReportService.cs
similarity index 87%
rename from services/Data/src/Data.Application/Services/PdfReportService.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Services/PdfReportService.cs
index a01b0c0a..23d2ce01 100644
--- a/services/Data/src/Data.Application/Services/PdfReportService.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Services/PdfReportService.cs
@@ -1,12 +1,11 @@
-using Data.Application.Clients;
-using Data.Application.Domain;
-using Data.Application.Mapping;
-using Data.Domain.Models;
-using Data.Rendering;
-using Data.Rendering.Composition;
-using Microsoft.Extensions.Logging;
+using CoreService.Api.DataApplication.Clients;
+using CoreService.Api.DataApplication.Domain;
+using CoreService.Api.DataApplication.Mapping;
+using CoreService.Api.Domain.Data.Models;
+using CoreService.Api.Rendering;
+using CoreService.Api.Rendering.Composition;
-namespace Data.Application.Services;
+namespace CoreService.Api.DataApplication.Services;
public interface IPdfReportService
{
diff --git a/services/Data/src/Data.Application/Services/ReportExportService.cs b/services/CoreService/src/CoreService.Api/DataApplication/Services/ReportExportService.cs
similarity index 93%
rename from services/Data/src/Data.Application/Services/ReportExportService.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Services/ReportExportService.cs
index eda161f4..d5c5af29 100644
--- a/services/Data/src/Data.Application/Services/ReportExportService.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Services/ReportExportService.cs
@@ -1,11 +1,11 @@
using System.Text.Json;
-using Data.Application.Clients;
-using Data.Application.Domain;
-using Data.Application.Mapping;
-using Data.Domain.Models;
-using Data.Rendering.Exports;
+using CoreService.Api.DataApplication.Clients;
+using CoreService.Api.DataApplication.Domain;
+using CoreService.Api.DataApplication.Mapping;
+using CoreService.Api.Domain.Data.Models;
+using CoreService.Api.Rendering.Exports;
-namespace Data.Application.Services;
+namespace CoreService.Api.DataApplication.Services;
public interface IReportExportService
{
diff --git a/services/Data/src/Data.Application/Services/WorkbookReportService.cs b/services/CoreService/src/CoreService.Api/DataApplication/Services/WorkbookReportService.cs
similarity index 90%
rename from services/Data/src/Data.Application/Services/WorkbookReportService.cs
rename to services/CoreService/src/CoreService.Api/DataApplication/Services/WorkbookReportService.cs
index 7c1fb66f..c77e5c4a 100644
--- a/services/Data/src/Data.Application/Services/WorkbookReportService.cs
+++ b/services/CoreService/src/CoreService.Api/DataApplication/Services/WorkbookReportService.cs
@@ -1,10 +1,8 @@
-using System.Text.Json;
-using Data.Application.Clients;
-using Data.Application.Domain;
-using Data.Rendering;
-using Microsoft.Extensions.Logging;
+using CoreService.Api.DataApplication.Clients;
+using CoreService.Api.DataApplication.Domain;
+using CoreService.Api.Rendering;
-namespace Data.Application.Services;
+namespace CoreService.Api.DataApplication.Services;
public interface IWorkbookReportService
{
diff --git a/services/Data/src/Data.Domain/Entities/CrawlResult.cs b/services/CoreService/src/CoreService.Api/Domain/Data/Entities/CrawlResult.cs
similarity index 95%
rename from services/Data/src/Data.Domain/Entities/CrawlResult.cs
rename to services/CoreService/src/CoreService.Api/Domain/Data/Entities/CrawlResult.cs
index 8929fa02..bd538fd7 100644
--- a/services/Data/src/Data.Domain/Entities/CrawlResult.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Data/Entities/CrawlResult.cs
@@ -1,4 +1,4 @@
-namespace Data.Domain.Entities;
+namespace CoreService.Api.Domain.Data.Entities;
///
/// Read-only mapping of the existing crawl_results table (schema owned by services/Schema).
diff --git a/services/Data/src/Data.Domain/Entities/CrawlRun.cs b/services/CoreService/src/CoreService.Api/Domain/Data/Entities/CrawlRun.cs
similarity index 94%
rename from services/Data/src/Data.Domain/Entities/CrawlRun.cs
rename to services/CoreService/src/CoreService.Api/Domain/Data/Entities/CrawlRun.cs
index 8e860f9e..3f07a2ad 100644
--- a/services/Data/src/Data.Domain/Entities/CrawlRun.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Data/Entities/CrawlRun.cs
@@ -1,4 +1,4 @@
-namespace Data.Domain.Entities;
+namespace CoreService.Api.Domain.Data.Entities;
///
/// Read-only mapping of the existing crawl_runs table (schema owned by services/Schema).
diff --git a/services/Data/src/Data.Domain/Entities/GoogleData.cs b/services/CoreService/src/CoreService.Api/Domain/Data/Entities/GoogleData.cs
similarity index 86%
rename from services/Data/src/Data.Domain/Entities/GoogleData.cs
rename to services/CoreService/src/CoreService.Api/Domain/Data/Entities/GoogleData.cs
index e4be955c..9bce5ec0 100644
--- a/services/Data/src/Data.Domain/Entities/GoogleData.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Data/Entities/GoogleData.cs
@@ -1,4 +1,4 @@
-namespace Data.Domain.Entities;
+namespace CoreService.Api.Domain.Data.Entities;
/// Read-only mapping of google_data (GSC/GA4 snapshots per property).
public sealed class GoogleData
diff --git a/services/Data/src/Data.Domain/Entities/IssueStatus.cs b/services/CoreService/src/CoreService.Api/Domain/Data/Entities/IssueStatus.cs
similarity index 94%
rename from services/Data/src/Data.Domain/Entities/IssueStatus.cs
rename to services/CoreService/src/CoreService.Api/Domain/Data/Entities/IssueStatus.cs
index 97458e54..bf782b4e 100644
--- a/services/Data/src/Data.Domain/Entities/IssueStatus.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Data/Entities/IssueStatus.cs
@@ -1,4 +1,4 @@
-namespace Data.Domain.Entities;
+namespace CoreService.Api.Domain.Data.Entities;
///
/// Mapping of the issue_status table (schema owned by services/Schema; issue workflow on the task board).
diff --git a/services/Data/src/Data.Domain/Entities/Property.cs b/services/CoreService/src/CoreService.Api/Domain/Data/Entities/Property.cs
similarity index 81%
rename from services/Data/src/Data.Domain/Entities/Property.cs
rename to services/CoreService/src/CoreService.Api/Domain/Data/Entities/Property.cs
index e38b7edf..78a87898 100644
--- a/services/Data/src/Data.Domain/Entities/Property.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Data/Entities/Property.cs
@@ -1,4 +1,4 @@
-namespace Data.Domain.Entities;
+namespace CoreService.Api.Domain.Data.Entities;
/// Read-only mapping of properties for domain → property_id lookup.
public sealed class Property
diff --git a/services/Data/src/Data.Domain/Entities/ReportPayload.cs b/services/CoreService/src/CoreService.Api/Domain/Data/Entities/ReportPayload.cs
similarity index 93%
rename from services/Data/src/Data.Domain/Entities/ReportPayload.cs
rename to services/CoreService/src/CoreService.Api/Domain/Data/Entities/ReportPayload.cs
index 6d9175d2..aec09a66 100644
--- a/services/Data/src/Data.Domain/Entities/ReportPayload.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Data/Entities/ReportPayload.cs
@@ -1,4 +1,4 @@
-namespace Data.Domain.Entities;
+namespace CoreService.Api.Domain.Data.Entities;
///
/// Read-only mapping of the existing report_payload table (schema owned by services/Schema).
diff --git a/services/Data/src/Data.Domain/Entities/SavedCrawlFilter.cs b/services/CoreService/src/CoreService.Api/Domain/Data/Entities/SavedCrawlFilter.cs
similarity index 91%
rename from services/Data/src/Data.Domain/Entities/SavedCrawlFilter.cs
rename to services/CoreService/src/CoreService.Api/Domain/Data/Entities/SavedCrawlFilter.cs
index 580f67f4..01944d47 100644
--- a/services/Data/src/Data.Domain/Entities/SavedCrawlFilter.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Data/Entities/SavedCrawlFilter.cs
@@ -1,4 +1,4 @@
-namespace Data.Domain.Entities;
+namespace CoreService.Api.Domain.Data.Entities;
///
/// Mapping of the saved_crawl_filters table (schema owned by services/Schema; Links page saved filter presets).
diff --git a/services/Data/src/Data.Domain/Models/AuditReportModel.cs b/services/CoreService/src/CoreService.Api/Domain/Data/Models/AuditReportModel.cs
similarity index 98%
rename from services/Data/src/Data.Domain/Models/AuditReportModel.cs
rename to services/CoreService/src/CoreService.Api/Domain/Data/Models/AuditReportModel.cs
index fde2c581..7a4c689c 100644
--- a/services/Data/src/Data.Domain/Models/AuditReportModel.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Data/Models/AuditReportModel.cs
@@ -1,6 +1,6 @@
using WebsiteProfiling.Contracts.Report;
-namespace Data.Domain.Models;
+namespace CoreService.Api.Domain.Data.Models;
public enum PdfProfile
{
diff --git a/services/Data/src/Data.Domain/Models/ChapterModels.cs b/services/CoreService/src/CoreService.Api/Domain/Data/Models/ChapterModels.cs
similarity index 98%
rename from services/Data/src/Data.Domain/Models/ChapterModels.cs
rename to services/CoreService/src/CoreService.Api/Domain/Data/Models/ChapterModels.cs
index 10a75a65..a89cad33 100644
--- a/services/Data/src/Data.Domain/Models/ChapterModels.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Data/Models/ChapterModels.cs
@@ -1,4 +1,4 @@
-namespace Data.Domain.Models;
+namespace CoreService.Api.Domain.Data.Models;
public sealed class PdfBrandingModel
{
diff --git a/services/Data/src/Data.Domain/Models/PdfSectionId.cs b/services/CoreService/src/CoreService.Api/Domain/Data/Models/PdfSectionId.cs
similarity index 84%
rename from services/Data/src/Data.Domain/Models/PdfSectionId.cs
rename to services/CoreService/src/CoreService.Api/Domain/Data/Models/PdfSectionId.cs
index dfebb4b8..731f352f 100644
--- a/services/Data/src/Data.Domain/Models/PdfSectionId.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Data/Models/PdfSectionId.cs
@@ -1,4 +1,4 @@
-namespace Data.Domain.Models;
+namespace CoreService.Api.Domain.Data.Models;
public enum PdfSectionId
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/CrawlSettingsRow.cs b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/CrawlSettingsRow.cs
similarity index 69%
rename from services/IntegrationsService/src/IntegrationsService.Domain/Entities/CrawlSettingsRow.cs
rename to services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/CrawlSettingsRow.cs
index 2aeb15b2..434a5a96 100644
--- a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/CrawlSettingsRow.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/CrawlSettingsRow.cs
@@ -1,4 +1,4 @@
-namespace IntegrationsService.Domain.Entities;
+namespace CoreService.Api.Domain.Integrations.Entities;
public sealed class CrawlSettingsRow
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/GoogleAppSettings.cs b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/GoogleAppSettings.cs
similarity index 90%
rename from services/IntegrationsService/src/IntegrationsService.Domain/Entities/GoogleAppSettings.cs
rename to services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/GoogleAppSettings.cs
index 7e445138..6c48cbbf 100644
--- a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/GoogleAppSettings.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/GoogleAppSettings.cs
@@ -1,4 +1,4 @@
-namespace IntegrationsService.Domain.Entities;
+namespace CoreService.Api.Domain.Integrations.Entities;
/// Singleton OAuth app settings row (google_app_settings, id=1).
public sealed class GoogleAppSettings
diff --git a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/GoogleData.cs b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/GoogleData.cs
similarity index 83%
rename from services/IntegrationsService/src/IntegrationsService.Domain/Entities/GoogleData.cs
rename to services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/GoogleData.cs
index 20721b62..37d18d6a 100644
--- a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/GoogleData.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/GoogleData.cs
@@ -1,4 +1,4 @@
-namespace IntegrationsService.Domain.Entities;
+namespace CoreService.Api.Domain.Integrations.Entities;
/// GSC/GA4 snapshot row in google_data.
public sealed class GoogleData
diff --git a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/GscLinksDataRow.cs b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/GscLinksDataRow.cs
similarity index 79%
rename from services/IntegrationsService/src/IntegrationsService.Domain/Entities/GscLinksDataRow.cs
rename to services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/GscLinksDataRow.cs
index 6833c601..83471e26 100644
--- a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/GscLinksDataRow.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/GscLinksDataRow.cs
@@ -1,4 +1,4 @@
-namespace IntegrationsService.Domain.Entities;
+namespace CoreService.Api.Domain.Integrations.Entities;
public sealed class GscLinksDataRow
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/IntegrationSecretsRow.cs b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/IntegrationSecretsRow.cs
similarity index 72%
rename from services/IntegrationsService/src/IntegrationsService.Domain/Entities/IntegrationSecretsRow.cs
rename to services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/IntegrationSecretsRow.cs
index 577cc2f3..3a2da906 100644
--- a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/IntegrationSecretsRow.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/IntegrationSecretsRow.cs
@@ -1,4 +1,4 @@
-namespace IntegrationsService.Domain.Entities;
+namespace CoreService.Api.Domain.Integrations.Entities;
public sealed class IntegrationSecretsRow
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/KeywordDataRow.cs b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/KeywordDataRow.cs
similarity index 79%
rename from services/IntegrationsService/src/IntegrationsService.Domain/Entities/KeywordDataRow.cs
rename to services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/KeywordDataRow.cs
index 090e6f89..8f20f39f 100644
--- a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/KeywordDataRow.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/KeywordDataRow.cs
@@ -1,4 +1,4 @@
-namespace IntegrationsService.Domain.Entities;
+namespace CoreService.Api.Domain.Integrations.Entities;
public sealed class KeywordDataRow
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/KeywordHistoryRow.cs b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/KeywordHistoryRow.cs
similarity index 87%
rename from services/IntegrationsService/src/IntegrationsService.Domain/Entities/KeywordHistoryRow.cs
rename to services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/KeywordHistoryRow.cs
index 4f0267a7..faf25912 100644
--- a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/KeywordHistoryRow.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/KeywordHistoryRow.cs
@@ -1,4 +1,4 @@
-namespace IntegrationsService.Domain.Entities;
+namespace CoreService.Api.Domain.Integrations.Entities;
public sealed class KeywordHistoryRow
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/PageGoogleSnapshot.cs b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/PageGoogleSnapshot.cs
similarity index 86%
rename from services/IntegrationsService/src/IntegrationsService.Domain/Entities/PageGoogleSnapshot.cs
rename to services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/PageGoogleSnapshot.cs
index 1fa386e7..abce3090 100644
--- a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/PageGoogleSnapshot.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/PageGoogleSnapshot.cs
@@ -1,4 +1,4 @@
-namespace IntegrationsService.Domain.Entities;
+namespace CoreService.Api.Domain.Integrations.Entities;
/// Per-URL live Google fetch history in page_google_snapshots.
public sealed class PageGoogleSnapshot
diff --git a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/Property.cs b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/Property.cs
similarity index 93%
rename from services/IntegrationsService/src/IntegrationsService.Domain/Entities/Property.cs
rename to services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/Property.cs
index 8d83c062..f49bbc22 100644
--- a/services/IntegrationsService/src/IntegrationsService.Domain/Entities/Property.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Integrations/Entities/Property.cs
@@ -1,4 +1,4 @@
-namespace IntegrationsService.Domain.Entities;
+namespace CoreService.Api.Domain.Integrations.Entities;
/// Property row with Google integration columns from properties.
public sealed class Property
diff --git a/services/ReportService/src/ReportService.Domain/Entities/AuditHealthSnapshot.cs b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/AuditHealthSnapshot.cs
similarity index 89%
rename from services/ReportService/src/ReportService.Domain/Entities/AuditHealthSnapshot.cs
rename to services/CoreService/src/CoreService.Api/Domain/Report/Entities/AuditHealthSnapshot.cs
index 5a657a40..1f54d366 100644
--- a/services/ReportService/src/ReportService.Domain/Entities/AuditHealthSnapshot.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/AuditHealthSnapshot.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Domain.Entities;
+namespace CoreService.Api.Domain.Report.Entities;
public sealed class AuditHealthSnapshot
{
diff --git a/services/ReportService/src/ReportService.Domain/Entities/CrawlGraphEdge.cs b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/CrawlGraphEdge.cs
similarity index 83%
rename from services/ReportService/src/ReportService.Domain/Entities/CrawlGraphEdge.cs
rename to services/CoreService/src/CoreService.Api/Domain/Report/Entities/CrawlGraphEdge.cs
index 82809ed1..865f1643 100644
--- a/services/ReportService/src/ReportService.Domain/Entities/CrawlGraphEdge.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/CrawlGraphEdge.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Domain.Entities;
+namespace CoreService.Api.Domain.Report.Entities;
/// Row in the plot/crawl edges table (internal link pairs).
public sealed class CrawlGraphEdge
diff --git a/services/ReportService/src/ReportService.Domain/Entities/CrawlResult.cs b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/CrawlResult.cs
similarity index 92%
rename from services/ReportService/src/ReportService.Domain/Entities/CrawlResult.cs
rename to services/CoreService/src/CoreService.Api/Domain/Report/Entities/CrawlResult.cs
index 70e14490..14429fc2 100644
--- a/services/ReportService/src/ReportService.Domain/Entities/CrawlResult.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/CrawlResult.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Domain.Entities;
+namespace CoreService.Api.Domain.Report.Entities;
///
/// Read-only mapping of crawl_results (schema owned by services/Schema). ReportService never migrates this table.
diff --git a/services/ReportService/src/ReportService.Domain/Entities/CrawlRun.cs b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/CrawlRun.cs
similarity index 87%
rename from services/ReportService/src/ReportService.Domain/Entities/CrawlRun.cs
rename to services/CoreService/src/CoreService.Api/Domain/Report/Entities/CrawlRun.cs
index 24ffd990..81336647 100644
--- a/services/ReportService/src/ReportService.Domain/Entities/CrawlRun.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/CrawlRun.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Domain.Entities;
+namespace CoreService.Api.Domain.Report.Entities;
public sealed class CrawlRun
{
diff --git a/services/ReportService/src/ReportService.Domain/Entities/LighthouseGlobalSummary.cs b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/LighthouseGlobalSummary.cs
similarity index 78%
rename from services/ReportService/src/ReportService.Domain/Entities/LighthouseGlobalSummary.cs
rename to services/CoreService/src/CoreService.Api/Domain/Report/Entities/LighthouseGlobalSummary.cs
index 56fbc04a..4696fed0 100644
--- a/services/ReportService/src/ReportService.Domain/Entities/LighthouseGlobalSummary.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/LighthouseGlobalSummary.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Domain.Entities;
+namespace CoreService.Api.Domain.Report.Entities;
public sealed class LighthouseGlobalSummary
{
diff --git a/services/ReportService/src/ReportService.Domain/Entities/LighthousePageSummary.cs b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/LighthousePageSummary.cs
similarity index 85%
rename from services/ReportService/src/ReportService.Domain/Entities/LighthousePageSummary.cs
rename to services/CoreService/src/CoreService.Api/Domain/Report/Entities/LighthousePageSummary.cs
index 1f3ba770..c68456cc 100644
--- a/services/ReportService/src/ReportService.Domain/Entities/LighthousePageSummary.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/LighthousePageSummary.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Domain.Entities;
+namespace CoreService.Api.Domain.Report.Entities;
///
/// Read-only mapping of lighthouse_page_summaries (schema owned by services/Schema).
diff --git a/services/ReportService/src/ReportService.Domain/Entities/LinkEdge.cs b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/LinkEdge.cs
similarity index 90%
rename from services/ReportService/src/ReportService.Domain/Entities/LinkEdge.cs
rename to services/CoreService/src/CoreService.Api/Domain/Report/Entities/LinkEdge.cs
index 3d6e784d..71337dcd 100644
--- a/services/ReportService/src/ReportService.Domain/Entities/LinkEdge.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/LinkEdge.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Domain.Entities;
+namespace CoreService.Api.Domain.Report.Entities;
public sealed class LinkEdge
{
diff --git a/services/ReportService/src/ReportService.Domain/Entities/PipelineJob.cs b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/PipelineJob.cs
similarity index 94%
rename from services/ReportService/src/ReportService.Domain/Entities/PipelineJob.cs
rename to services/CoreService/src/CoreService.Api/Domain/Report/Entities/PipelineJob.cs
index 41b2b3ca..f0f4de95 100644
--- a/services/ReportService/src/ReportService.Domain/Entities/PipelineJob.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/PipelineJob.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Domain.Entities;
+namespace CoreService.Api.Domain.Report.Entities;
///
/// Mapping of the existing pipeline_jobs table (schema owned by services/Schema).
diff --git a/services/ReportService/src/ReportService.Domain/Entities/ReportPayload.cs b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/ReportPayload.cs
similarity index 88%
rename from services/ReportService/src/ReportService.Domain/Entities/ReportPayload.cs
rename to services/CoreService/src/CoreService.Api/Domain/Report/Entities/ReportPayload.cs
index 79b63cec..e23c6fe7 100644
--- a/services/ReportService/src/ReportService.Domain/Entities/ReportPayload.cs
+++ b/services/CoreService/src/CoreService.Api/Domain/Report/Entities/ReportPayload.cs
@@ -1,4 +1,4 @@
-namespace ReportService.Domain.Entities;
+namespace CoreService.Api.Domain.Report.Entities;
///
/// Mapping of the existing report_payload table (schema owned by services/Schema).
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/DependencyInjection.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/DependencyInjection.cs
similarity index 79%
rename from services/IntegrationsService/src/IntegrationsService.Application/DependencyInjection.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/DependencyInjection.cs
index a7e3cc35..a80a99a9 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/DependencyInjection.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/DependencyInjection.cs
@@ -1,12 +1,10 @@
-using IntegrationsService.Application.Google;
-using IntegrationsService.Application.Persistence;
-using IntegrationsService.Application.Report;
-using IntegrationsService.Application.Repositories;
-using Microsoft.Extensions.DependencyInjection;
+using CoreService.Api.IntegrationsApplication.Google;
+using CoreService.Api.IntegrationsApplication.Persistence;
+using CoreService.Api.IntegrationsApplication.Report;
+using CoreService.Api.IntegrationsApplication.Repositories;
using WebsiteProfiling.Data;
-using WebsiteProfiling.Data.EntityFrameworkCore;
-namespace IntegrationsService.Application;
+namespace CoreService.Api.IntegrationsApplication;
public static class DependencyInjection
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/BingBacklinksFetchResult.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/BingBacklinksFetchResult.cs
similarity index 90%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/BingBacklinksFetchResult.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/BingBacklinksFetchResult.cs
index 3a6fff63..4332d19f 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/BingBacklinksFetchResult.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/BingBacklinksFetchResult.cs
@@ -1,6 +1,6 @@
using WebsiteProfiling.Contracts.Integrations;
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
public sealed record BingBacklinksFetchResult
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/BingWebmasterService.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/BingWebmasterService.cs
similarity index 99%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/BingWebmasterService.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/BingWebmasterService.cs
index 57af5a8a..a0712d2c 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/BingWebmasterService.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/BingWebmasterService.cs
@@ -1,6 +1,6 @@
using System.Text.Json;
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
public sealed class BingWebmasterService(IHttpClientFactory httpClientFactory)
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/FastApiPythonBridge.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/FastApiPythonBridge.cs
similarity index 98%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/FastApiPythonBridge.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/FastApiPythonBridge.cs
index 6dfb82db..72626d6c 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/FastApiPythonBridge.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/FastApiPythonBridge.cs
@@ -1,8 +1,7 @@
-using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
///
/// Delegates Python-only tasks to the FastAPI container when IntegrationsService has no Python runtime (Docker).
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/Ga4PropertySummary.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/Ga4PropertySummary.cs
similarity index 85%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/Ga4PropertySummary.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/Ga4PropertySummary.cs
index 50cc6ac2..fb8bed72 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/Ga4PropertySummary.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/Ga4PropertySummary.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
public sealed class Ga4PropertySummary
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/GoogleFetchService.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/GoogleFetchService.cs
similarity index 98%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/GoogleFetchService.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/GoogleFetchService.cs
index 383f4a17..1eb8c853 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/GoogleFetchService.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/GoogleFetchService.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-using IntegrationsService.Application.Repositories;
+using CoreService.Api.IntegrationsApplication.Repositories;
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
public sealed class GoogleFetchService(
IGoogleCredentialFactory credentials,
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/GoogleModels.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/GoogleModels.cs
similarity index 97%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/GoogleModels.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/GoogleModels.cs
index 1114681f..23fe1161 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/GoogleModels.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/GoogleModels.cs
@@ -1,6 +1,6 @@
using WebsiteProfiling.Contracts.Google;
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
public sealed class GscFetchResult
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/GoogleOAuthConstants.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/GoogleOAuthConstants.cs
similarity index 91%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/GoogleOAuthConstants.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/GoogleOAuthConstants.cs
index af82d02d..d08a94b4 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/GoogleOAuthConstants.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/GoogleOAuthConstants.cs
@@ -1,4 +1,4 @@
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
internal static class GoogleOAuthConstants
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/GoogleOAuthService.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/GoogleOAuthService.cs
similarity index 98%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/GoogleOAuthService.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/GoogleOAuthService.cs
index 5c8b939e..7caf8e39 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/GoogleOAuthService.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/GoogleOAuthService.cs
@@ -1,9 +1,9 @@
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
-using IntegrationsService.Application.Repositories;
+using CoreService.Api.IntegrationsApplication.Repositories;
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
public sealed class GoogleOAuthService(
PropertyRepository properties,
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/GscRowMappers.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/GscRowMappers.cs
similarity index 93%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/GscRowMappers.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/GscRowMappers.cs
index 158f699f..f10a63f1 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/GscRowMappers.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/GscRowMappers.cs
@@ -1,6 +1,6 @@
using WebsiteProfiling.Contracts.Google;
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
///
/// GSC Search Analytics row mappers — parity with Python gsc._to_query_record / _to_page_record.
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/IGoogleClients.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/IGoogleClients.cs
similarity index 97%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/IGoogleClients.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/IGoogleClients.cs
index 07064a96..582305b8 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/IGoogleClients.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/IGoogleClients.cs
@@ -1,6 +1,6 @@
using Google.Apis.Http;
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
public interface IGoogleCredentialFactory
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/KeywordExpandPlannerService.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/KeywordExpandPlannerService.cs
similarity index 98%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/KeywordExpandPlannerService.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/KeywordExpandPlannerService.cs
index 00304088..ffa92375 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/KeywordExpandPlannerService.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/KeywordExpandPlannerService.cs
@@ -1,7 +1,6 @@
using System.Text.Json;
-using IntegrationsService.Application.Google;
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
public sealed class KeywordExpandPlannerService(
PythonCliRunner python,
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/PageCompareService.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PageCompareService.cs
similarity index 93%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/PageCompareService.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PageCompareService.cs
index edbe03db..5308e1f2 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/PageCompareService.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PageCompareService.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using IntegrationsService.Application.Repositories;
+using CoreService.Api.IntegrationsApplication.Repositories;
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
public sealed class PageCompareService(
GoogleDataReadRepository googleData,
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/PageLiveService.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PageLiveService.cs
similarity index 97%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/PageLiveService.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PageLiveService.cs
index c19f79c6..dc22803e 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/PageLiveService.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PageLiveService.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using IntegrationsService.Application.Repositories;
+using CoreService.Api.IntegrationsApplication.Repositories;
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
public sealed class PageLiveService(
PropertyRepository properties,
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/PageLookupMapper.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PageLookupMapper.cs
similarity index 95%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/PageLookupMapper.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PageLookupMapper.cs
index 9cee9e0c..983cdac3 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/PageLookupMapper.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PageLookupMapper.cs
@@ -1,9 +1,8 @@
using System.Text.Json;
-using WebsiteProfiling.Contracts.Google;
using WebsiteProfiling.Contracts.Integrations;
using WebsiteProfiling.Contracts.Json;
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
public static class PageLookupMapper
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/PageLookupService.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PageLookupService.cs
similarity index 99%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/PageLookupService.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PageLookupService.cs
index 696e1c9c..5b8775b6 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/PageLookupService.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PageLookupService.cs
@@ -1,8 +1,7 @@
using System.Text.Json;
-using IntegrationsService.Application.Google;
using WebsiteProfiling.Contracts.Integrations;
-namespace IntegrationsService.Application.Repositories;
+namespace CoreService.Api.IntegrationsApplication.Google;
public static class PageLookupService
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/PageMetricsCompare.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PageMetricsCompare.cs
similarity index 99%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/PageMetricsCompare.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PageMetricsCompare.cs
index be6e8198..759068a6 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/PageMetricsCompare.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PageMetricsCompare.cs
@@ -1,4 +1,4 @@
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
///
/// Parity with web/src/lib/pageMetricsCompare.ts — page-level GSC/GA4 compare rows.
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/PythonCliRunner.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PythonCliRunner.cs
similarity index 98%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/PythonCliRunner.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PythonCliRunner.cs
index 0b3b409b..d0ec22cd 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/PythonCliRunner.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/PythonCliRunner.cs
@@ -2,7 +2,7 @@
using System.Text;
using System.Text.Json;
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
public sealed class PythonCliRunner
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Google/UrlJoinBuilder.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/UrlJoinBuilder.cs
similarity index 99%
rename from services/IntegrationsService/src/IntegrationsService.Application/Google/UrlJoinBuilder.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/UrlJoinBuilder.cs
index 51dc04f4..8da83ab7 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Google/UrlJoinBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Google/UrlJoinBuilder.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace IntegrationsService.Application.Google;
+namespace CoreService.Api.IntegrationsApplication.Google;
public static class UrlJoinBuilder
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Persistence/IntegrationsDbContext.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Persistence/IntegrationsDbContext.cs
similarity index 98%
rename from services/IntegrationsService/src/IntegrationsService.Application/Persistence/IntegrationsDbContext.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Persistence/IntegrationsDbContext.cs
index 39d66302..335b30c9 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Persistence/IntegrationsDbContext.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Persistence/IntegrationsDbContext.cs
@@ -1,7 +1,7 @@
-using IntegrationsService.Domain.Entities;
+using CoreService.Api.Domain.Integrations.Entities;
using Microsoft.EntityFrameworkCore;
-namespace IntegrationsService.Application.Persistence;
+namespace CoreService.Api.IntegrationsApplication.Persistence;
///
/// EF Core context over the schema owned by services/Schema (EF Core migrations). Does not run migrations itself.
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Report/ReportEnrichmentService.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Report/ReportEnrichmentService.cs
similarity index 97%
rename from services/IntegrationsService/src/IntegrationsService.Application/Report/ReportEnrichmentService.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Report/ReportEnrichmentService.cs
index 597878c8..6420d3d4 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Report/ReportEnrichmentService.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Report/ReportEnrichmentService.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
using System.Text.Json.Nodes;
-using IntegrationsService.Application.Repositories;
+using CoreService.Api.IntegrationsApplication.Repositories;
-namespace IntegrationsService.Application.Report;
+namespace CoreService.Api.IntegrationsApplication.Report;
///
/// Loads Google/GSC/keyword snapshots from Postgres for report payload assembly.
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/GoogleAppSettingsRepository.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/GoogleAppSettingsRepository.cs
similarity index 94%
rename from services/IntegrationsService/src/IntegrationsService.Application/Repositories/GoogleAppSettingsRepository.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/GoogleAppSettingsRepository.cs
index 080532e1..4ae220c2 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/GoogleAppSettingsRepository.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/GoogleAppSettingsRepository.cs
@@ -1,9 +1,9 @@
using System.Text.Json;
-using IntegrationsService.Application.Persistence;
-using IntegrationsService.Domain.Entities;
+using CoreService.Api.Domain.Integrations.Entities;
+using CoreService.Api.IntegrationsApplication.Persistence;
using Microsoft.EntityFrameworkCore;
-namespace IntegrationsService.Application.Repositories;
+namespace CoreService.Api.IntegrationsApplication.Repositories;
public sealed class GoogleAppSettingsRepository(IntegrationsDbContext db)
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/GoogleDataReadRepository.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/GoogleDataReadRepository.cs
similarity index 95%
rename from services/IntegrationsService/src/IntegrationsService.Application/Repositories/GoogleDataReadRepository.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/GoogleDataReadRepository.cs
index 33a62e58..01bd613b 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/GoogleDataReadRepository.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/GoogleDataReadRepository.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
-using IntegrationsService.Application.Persistence;
+using CoreService.Api.IntegrationsApplication.Persistence;
using Microsoft.EntityFrameworkCore;
-namespace IntegrationsService.Application.Repositories;
+namespace CoreService.Api.IntegrationsApplication.Repositories;
public sealed class GoogleDataReadRepository(IntegrationsDbContext db)
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/GoogleDataWriteRepository.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/GoogleDataWriteRepository.cs
similarity index 84%
rename from services/IntegrationsService/src/IntegrationsService.Application/Repositories/GoogleDataWriteRepository.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/GoogleDataWriteRepository.cs
index 1ed6d28a..b528148d 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/GoogleDataWriteRepository.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/GoogleDataWriteRepository.cs
@@ -1,8 +1,8 @@
-using IntegrationsService.Application.Persistence;
-using IntegrationsService.Domain.Entities;
+using CoreService.Api.Domain.Integrations.Entities;
+using CoreService.Api.IntegrationsApplication.Persistence;
using Microsoft.EntityFrameworkCore;
-namespace IntegrationsService.Application.Repositories;
+namespace CoreService.Api.IntegrationsApplication.Repositories;
public sealed class GoogleDataWriteRepository(IntegrationsDbContext db)
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/GscLinksDataRepository.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/GscLinksDataRepository.cs
similarity index 96%
rename from services/IntegrationsService/src/IntegrationsService.Application/Repositories/GscLinksDataRepository.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/GscLinksDataRepository.cs
index 2b620295..2afe4bf5 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/GscLinksDataRepository.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/GscLinksDataRepository.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
-using IntegrationsService.Application.Persistence;
+using CoreService.Api.IntegrationsApplication.Persistence;
using Microsoft.EntityFrameworkCore;
-namespace IntegrationsService.Application.Repositories;
+namespace CoreService.Api.IntegrationsApplication.Repositories;
public sealed class GscLinksDataRepository(IntegrationsDbContext db)
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/KeywordDataRepository.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/KeywordDataRepository.cs
similarity index 93%
rename from services/IntegrationsService/src/IntegrationsService.Application/Repositories/KeywordDataRepository.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/KeywordDataRepository.cs
index 9fbae045..5dbc2f62 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/KeywordDataRepository.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/KeywordDataRepository.cs
@@ -1,9 +1,8 @@
using System.Text.Json;
-using IntegrationsService.Application.Google;
-using IntegrationsService.Application.Persistence;
+using CoreService.Api.IntegrationsApplication.Persistence;
using Microsoft.EntityFrameworkCore;
-namespace IntegrationsService.Application.Repositories;
+namespace CoreService.Api.IntegrationsApplication.Repositories;
public sealed class KeywordDataRepository(IntegrationsDbContext db)
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/PageGoogleSnapshotRepository.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/PageGoogleSnapshotRepository.cs
similarity index 93%
rename from services/IntegrationsService/src/IntegrationsService.Application/Repositories/PageGoogleSnapshotRepository.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/PageGoogleSnapshotRepository.cs
index 44117d93..bb522f51 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/PageGoogleSnapshotRepository.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/PageGoogleSnapshotRepository.cs
@@ -1,10 +1,10 @@
using System.Text.Json;
-using IntegrationsService.Application.Google;
-using IntegrationsService.Application.Persistence;
-using IntegrationsService.Domain.Entities;
+using CoreService.Api.Domain.Integrations.Entities;
+using CoreService.Api.IntegrationsApplication.Google;
+using CoreService.Api.IntegrationsApplication.Persistence;
using Microsoft.EntityFrameworkCore;
-namespace IntegrationsService.Application.Repositories;
+namespace CoreService.Api.IntegrationsApplication.Repositories;
public sealed class PageGoogleSnapshotRepository(IntegrationsDbContext db)
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/PipelineConfigRepository.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/PipelineConfigRepository.cs
similarity index 89%
rename from services/IntegrationsService/src/IntegrationsService.Application/Repositories/PipelineConfigRepository.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/PipelineConfigRepository.cs
index 0d192653..9b1e8523 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/PipelineConfigRepository.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/PipelineConfigRepository.cs
@@ -1,7 +1,7 @@
-using IntegrationsService.Application.Persistence;
+using CoreService.Api.IntegrationsApplication.Persistence;
using Microsoft.EntityFrameworkCore;
-namespace IntegrationsService.Application.Repositories;
+namespace CoreService.Api.IntegrationsApplication.Repositories;
public sealed class PipelineConfigRepository(IntegrationsDbContext db)
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/PropertyRepository.cs b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/PropertyRepository.cs
similarity index 97%
rename from services/IntegrationsService/src/IntegrationsService.Application/Repositories/PropertyRepository.cs
rename to services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/PropertyRepository.cs
index 0937bd25..dd3b0ce9 100644
--- a/services/IntegrationsService/src/IntegrationsService.Application/Repositories/PropertyRepository.cs
+++ b/services/CoreService/src/CoreService.Api/IntegrationsApplication/Repositories/PropertyRepository.cs
@@ -1,11 +1,9 @@
-using System.Text.Json;
-using IntegrationsService.Application.Google;
-using IntegrationsService.Application.Persistence;
-using IntegrationsService.Domain.Entities;
+using CoreService.Api.Domain.Integrations.Entities;
+using CoreService.Api.IntegrationsApplication.Persistence;
using Microsoft.EntityFrameworkCore;
using WebsiteProfiling.Contracts.Properties;
-namespace IntegrationsService.Application.Repositories;
+namespace CoreService.Api.IntegrationsApplication.Repositories;
public sealed class PropertyRepository(IntegrationsDbContext db)
{
diff --git a/services/CoreService/src/CoreService.Api/Program.cs b/services/CoreService/src/CoreService.Api/Program.cs
new file mode 100644
index 00000000..bbab284f
--- /dev/null
+++ b/services/CoreService/src/CoreService.Api/Program.cs
@@ -0,0 +1,32 @@
+using CoreService.Api.Application;
+using CoreService.Api.DataApplication;
+using CoreService.Api.IntegrationsApplication;
+using CoreService.Api.Providers;
+using WebsiteProfiling.Hosting;
+
+var builder = WebApplication.CreateBuilder(args);
+
+builder.AddWebsiteProfilingWebDefaults(
+ "Website Profiling Core API",
+ "Internal core backend service: report build & reads, pipeline orchestration, "
+ + "portfolio, exports, and Google/Bing integrations. "
+ + "Reached by the BFF and worker via CORE_SERVICE_URL.");
+
+builder.Services.AddReportApplication();
+builder.Services.AddDataApplication();
+builder.Services.AddIntegrationsApplication();
+builder.Services.AddGoogleProviders();
+builder.Services.AddControllers();
+
+var app = builder.Build();
+
+app.UseWebsiteProfilingSwaggerUi("Website Profiling Core API");
+
+app.MapControllers();
+
+app.Run();
+
+namespace CoreService.Api
+{
+ public partial class Program;
+}
diff --git a/services/IntegrationsService/src/IntegrationsService.Providers/DependencyInjection.cs b/services/CoreService/src/CoreService.Api/Providers/DependencyInjection.cs
similarity index 69%
rename from services/IntegrationsService/src/IntegrationsService.Providers/DependencyInjection.cs
rename to services/CoreService/src/CoreService.Api/Providers/DependencyInjection.cs
index be248b71..ed71f825 100644
--- a/services/IntegrationsService/src/IntegrationsService.Providers/DependencyInjection.cs
+++ b/services/CoreService/src/CoreService.Api/Providers/DependencyInjection.cs
@@ -1,8 +1,7 @@
-using IntegrationsService.Application.Google;
-using IntegrationsService.Providers.Google;
-using Microsoft.Extensions.DependencyInjection;
+using CoreService.Api.IntegrationsApplication.Google;
+using CoreService.Api.Providers.Google;
-namespace IntegrationsService.Providers;
+namespace CoreService.Api.Providers;
public static class DependencyInjection
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Providers/Google/Ga4ReportClient.cs b/services/CoreService/src/CoreService.Api/Providers/Google/Ga4ReportClient.cs
similarity index 99%
rename from services/IntegrationsService/src/IntegrationsService.Providers/Google/Ga4ReportClient.cs
rename to services/CoreService/src/CoreService.Api/Providers/Google/Ga4ReportClient.cs
index 378b6e2e..5053b7c0 100644
--- a/services/IntegrationsService/src/IntegrationsService.Providers/Google/Ga4ReportClient.cs
+++ b/services/CoreService/src/CoreService.Api/Providers/Google/Ga4ReportClient.cs
@@ -1,13 +1,12 @@
-using Google.Apis.GoogleAnalyticsAdmin.v1alpha;
-using Google.Apis.GoogleAnalyticsAdmin.v1alpha.Data;
+using CoreService.Api.IntegrationsApplication.Google;
using Google.Apis.AnalyticsData.v1beta;
using Google.Apis.AnalyticsData.v1beta.Data;
+using Google.Apis.GoogleAnalyticsAdmin.v1alpha;
using Google.Apis.Http;
using Google.Apis.Services;
-using IntegrationsService.Application.Google;
using WebsiteProfiling.Contracts.Google;
-namespace IntegrationsService.Providers.Google;
+namespace CoreService.Api.Providers.Google;
public sealed class Ga4ReportClient : IGa4ReportClient
{
diff --git a/services/IntegrationsService/src/IntegrationsService.Providers/Google/GoogleCredentialFactory.cs b/services/CoreService/src/CoreService.Api/Providers/Google/GoogleCredentialFactory.cs
similarity index 95%
rename from services/IntegrationsService/src/IntegrationsService.Providers/Google/GoogleCredentialFactory.cs
rename to services/CoreService/src/CoreService.Api/Providers/Google/GoogleCredentialFactory.cs
index 00ba4a77..b53a398e 100644
--- a/services/IntegrationsService/src/IntegrationsService.Providers/Google/GoogleCredentialFactory.cs
+++ b/services/CoreService/src/CoreService.Api/Providers/Google/GoogleCredentialFactory.cs
@@ -1,11 +1,11 @@
+using CoreService.Api.IntegrationsApplication.Google;
+using CoreService.Api.IntegrationsApplication.Repositories;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Auth.OAuth2.Responses;
using Google.Apis.Http;
-using IntegrationsService.Application.Google;
-using IntegrationsService.Application.Repositories;
-namespace IntegrationsService.Providers.Google;
+namespace CoreService.Api.Providers.Google;
public sealed class GoogleCredentialFactory(
PropertyRepository properties,
diff --git a/services/IntegrationsService/src/IntegrationsService.Providers/Google/GscSearchAnalyticsClient.cs b/services/CoreService/src/CoreService.Api/Providers/Google/GscSearchAnalyticsClient.cs
similarity index 99%
rename from services/IntegrationsService/src/IntegrationsService.Providers/Google/GscSearchAnalyticsClient.cs
rename to services/CoreService/src/CoreService.Api/Providers/Google/GscSearchAnalyticsClient.cs
index 6db40a3e..7e25b44c 100644
--- a/services/IntegrationsService/src/IntegrationsService.Providers/Google/GscSearchAnalyticsClient.cs
+++ b/services/CoreService/src/CoreService.Api/Providers/Google/GscSearchAnalyticsClient.cs
@@ -1,11 +1,11 @@
+using CoreService.Api.IntegrationsApplication.Google;
using Google.Apis.Http;
using Google.Apis.SearchConsole.v1;
using Google.Apis.SearchConsole.v1.Data;
using Google.Apis.Services;
-using IntegrationsService.Application.Google;
using WebsiteProfiling.Contracts.Google;
-namespace IntegrationsService.Providers.Google;
+namespace CoreService.Api.Providers.Google;
public sealed class GscSearchAnalyticsClient : IGscSearchAnalyticsClient
{
diff --git a/services/Data/src/Data.Rendering/AuditPdfGenerator.cs b/services/CoreService/src/CoreService.Api/Rendering/AuditPdfGenerator.cs
similarity index 95%
rename from services/Data/src/Data.Rendering/AuditPdfGenerator.cs
rename to services/CoreService/src/CoreService.Api/Rendering/AuditPdfGenerator.cs
index 65fcd2a7..7d12a557 100644
--- a/services/Data/src/Data.Rendering/AuditPdfGenerator.cs
+++ b/services/CoreService/src/CoreService.Api/Rendering/AuditPdfGenerator.cs
@@ -1,10 +1,10 @@
-using Data.Domain.Models;
-using Data.Rendering.Templates;
+using CoreService.Api.Domain.Data.Models;
+using CoreService.Api.Rendering.Templates;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
-namespace Data.Rendering;
+namespace CoreService.Api.Rendering;
public sealed class AuditPdfGenerator
{
diff --git a/services/Data/src/Data.Rendering/AuditWorkbookGenerator.cs b/services/CoreService/src/CoreService.Api/Rendering/AuditWorkbookGenerator.cs
similarity index 99%
rename from services/Data/src/Data.Rendering/AuditWorkbookGenerator.cs
rename to services/CoreService/src/CoreService.Api/Rendering/AuditWorkbookGenerator.cs
index c43e0717..a37a308a 100644
--- a/services/Data/src/Data.Rendering/AuditWorkbookGenerator.cs
+++ b/services/CoreService/src/CoreService.Api/Rendering/AuditWorkbookGenerator.cs
@@ -2,7 +2,7 @@
using System.Text.Json;
using ClosedXML.Excel;
-namespace Data.Rendering;
+namespace CoreService.Api.Rendering;
public sealed class AuditWorkbookGenerator
{
diff --git a/services/Data/src/Data.Rendering/Charts/HorizontalBarChart.cs b/services/CoreService/src/CoreService.Api/Rendering/Charts/HorizontalBarChart.cs
similarity index 93%
rename from services/Data/src/Data.Rendering/Charts/HorizontalBarChart.cs
rename to services/CoreService/src/CoreService.Api/Rendering/Charts/HorizontalBarChart.cs
index 98bce16f..7d461f59 100644
--- a/services/Data/src/Data.Rendering/Charts/HorizontalBarChart.cs
+++ b/services/CoreService/src/CoreService.Api/Rendering/Charts/HorizontalBarChart.cs
@@ -1,7 +1,7 @@
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
-namespace Data.Rendering.Charts;
+namespace CoreService.Api.Rendering.Charts;
public static class HorizontalBarChart
{
diff --git a/services/Data/src/Data.Rendering/Composition/PdfRenderContext.cs b/services/CoreService/src/CoreService.Api/Rendering/Composition/PdfRenderContext.cs
similarity index 82%
rename from services/Data/src/Data.Rendering/Composition/PdfRenderContext.cs
rename to services/CoreService/src/CoreService.Api/Rendering/Composition/PdfRenderContext.cs
index 21c2b98d..5419cbe9 100644
--- a/services/Data/src/Data.Rendering/Composition/PdfRenderContext.cs
+++ b/services/CoreService/src/CoreService.Api/Rendering/Composition/PdfRenderContext.cs
@@ -1,7 +1,7 @@
-using Data.Domain.Models;
+using CoreService.Api.Domain.Data.Models;
using QuestPDF.Infrastructure;
-namespace Data.Rendering.Composition;
+namespace CoreService.Api.Rendering.Composition;
public sealed class PdfRenderContext
{
diff --git a/services/Data/src/Data.Rendering/Composition/SectionRegistry.cs b/services/CoreService/src/CoreService.Api/Rendering/Composition/SectionRegistry.cs
similarity index 95%
rename from services/Data/src/Data.Rendering/Composition/SectionRegistry.cs
rename to services/CoreService/src/CoreService.Api/Rendering/Composition/SectionRegistry.cs
index 382d6223..95505a40 100644
--- a/services/Data/src/Data.Rendering/Composition/SectionRegistry.cs
+++ b/services/CoreService/src/CoreService.Api/Rendering/Composition/SectionRegistry.cs
@@ -1,7 +1,7 @@
-using Data.Domain.Models;
-using Data.Rendering.Sections;
+using CoreService.Api.Domain.Data.Models;
+using CoreService.Api.Rendering.Sections;
-namespace Data.Rendering.Composition;
+namespace CoreService.Api.Rendering.Composition;
public static class SectionRegistry
{
diff --git a/services/Data/src/Data.Rendering/Composition/TocBuilder.cs b/services/CoreService/src/CoreService.Api/Rendering/Composition/TocBuilder.cs
similarity index 96%
rename from services/Data/src/Data.Rendering/Composition/TocBuilder.cs
rename to services/CoreService/src/CoreService.Api/Rendering/Composition/TocBuilder.cs
index 1bcaa506..8bdd3678 100644
--- a/services/Data/src/Data.Rendering/Composition/TocBuilder.cs
+++ b/services/CoreService/src/CoreService.Api/Rendering/Composition/TocBuilder.cs
@@ -1,7 +1,6 @@
-using Data.Domain.Models;
-using Data.Rendering.Composition;
+using CoreService.Api.Domain.Data.Models;
-namespace Data.Rendering.Composition;
+namespace CoreService.Api.Rendering.Composition;
public static class TocBuilder
{
diff --git a/services/Data/src/Data.Rendering/Exports/ReportCsvExporter.cs b/services/CoreService/src/CoreService.Api/Rendering/Exports/ReportCsvExporter.cs
similarity index 99%
rename from services/Data/src/Data.Rendering/Exports/ReportCsvExporter.cs
rename to services/CoreService/src/CoreService.Api/Rendering/Exports/ReportCsvExporter.cs
index bf48e94b..fbb7ef06 100644
--- a/services/Data/src/Data.Rendering/Exports/ReportCsvExporter.cs
+++ b/services/CoreService/src/CoreService.Api/Rendering/Exports/ReportCsvExporter.cs
@@ -1,7 +1,7 @@
using System.Text;
using System.Text.Json;
-namespace Data.Rendering.Exports;
+namespace CoreService.Api.Rendering.Exports;
///
/// CSV export of a report payload. Faithful port of the Python export_audit_csv +
diff --git a/services/Data/src/Data.Rendering/Exports/ReportJsonExporter.cs b/services/CoreService/src/CoreService.Api/Rendering/Exports/ReportJsonExporter.cs
similarity index 90%
rename from services/Data/src/Data.Rendering/Exports/ReportJsonExporter.cs
rename to services/CoreService/src/CoreService.Api/Rendering/Exports/ReportJsonExporter.cs
index 11840cf5..2d82f5a9 100644
--- a/services/Data/src/Data.Rendering/Exports/ReportJsonExporter.cs
+++ b/services/CoreService/src/CoreService.Api/Rendering/Exports/ReportJsonExporter.cs
@@ -1,6 +1,6 @@
using System.Text.Json;
-namespace Data.Rendering.Exports;
+namespace CoreService.Api.Rendering.Exports;
///
/// JSON export = the report payload, pretty-printed. Mirrors the Python
diff --git a/services/Data/src/Data.Rendering/Exports/ReportSitemapExporter.cs b/services/CoreService/src/CoreService.Api/Rendering/Exports/ReportSitemapExporter.cs
similarity index 97%
rename from services/Data/src/Data.Rendering/Exports/ReportSitemapExporter.cs
rename to services/CoreService/src/CoreService.Api/Rendering/Exports/ReportSitemapExporter.cs
index eaa65fce..3b2e2892 100644
--- a/services/Data/src/Data.Rendering/Exports/ReportSitemapExporter.cs
+++ b/services/CoreService/src/CoreService.Api/Rendering/Exports/ReportSitemapExporter.cs
@@ -1,8 +1,8 @@
using System.Text;
using System.Text.Json;
-using Data.Domain.Models;
+using CoreService.Api.Domain.Data.Models;
-namespace Data.Rendering.Exports;
+namespace CoreService.Api.Rendering.Exports;
///
/// XML sitemap of indexable, 2xx URLs from the report payload's links. Faithful port of the
diff --git a/services/Data/src/Data.Rendering/PdfTheme.cs b/services/CoreService/src/CoreService.Api/Rendering/PdfTheme.cs
similarity index 97%
rename from services/Data/src/Data.Rendering/PdfTheme.cs
rename to services/CoreService/src/CoreService.Api/Rendering/PdfTheme.cs
index 96d0be3e..30564282 100644
--- a/services/Data/src/Data.Rendering/PdfTheme.cs
+++ b/services/CoreService/src/CoreService.Api/Rendering/PdfTheme.cs
@@ -1,9 +1,9 @@
-using Data.Domain.Models;
+using CoreService.Api.Domain.Data.Models;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
-namespace Data.Rendering;
+namespace CoreService.Api.Rendering;
public static class PdfTheme
{
diff --git a/services/Data/src/Data.Rendering/Sections/PdfSections.cs b/services/CoreService/src/CoreService.Api/Rendering/Sections/PdfSections.cs
similarity index 99%
rename from services/Data/src/Data.Rendering/Sections/PdfSections.cs
rename to services/CoreService/src/CoreService.Api/Rendering/Sections/PdfSections.cs
index aa8de8d3..01f91ec4 100644
--- a/services/Data/src/Data.Rendering/Sections/PdfSections.cs
+++ b/services/CoreService/src/CoreService.Api/Rendering/Sections/PdfSections.cs
@@ -1,11 +1,11 @@
-using Data.Domain.Models;
-using WebsiteProfiling.Contracts.Report;
-using Data.Rendering.Charts;
-using Data.Rendering.Composition;
+using CoreService.Api.Domain.Data.Models;
+using CoreService.Api.Rendering.Charts;
+using CoreService.Api.Rendering.Composition;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
+using WebsiteProfiling.Contracts.Report;
-namespace Data.Rendering.Sections;
+namespace CoreService.Api.Rendering.Sections;
public sealed class TableOfContentsSection : IPdfSectionComposer
{
diff --git a/services/Data/src/Data.Rendering/Templates/CoverPageTemplate.cs b/services/CoreService/src/CoreService.Api/Rendering/Templates/CoverPageTemplate.cs
similarity index 97%
rename from services/Data/src/Data.Rendering/Templates/CoverPageTemplate.cs
rename to services/CoreService/src/CoreService.Api/Rendering/Templates/CoverPageTemplate.cs
index f21d356b..3ec8f75a 100644
--- a/services/Data/src/Data.Rendering/Templates/CoverPageTemplate.cs
+++ b/services/CoreService/src/CoreService.Api/Rendering/Templates/CoverPageTemplate.cs
@@ -1,10 +1,9 @@
-using Data.Domain.Models;
-using Data.Rendering.Charts;
+using CoreService.Api.Domain.Data.Models;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
-namespace Data.Rendering.Templates;
+namespace CoreService.Api.Rendering.Templates;
public static class CoverPageTemplate
{
diff --git a/services/ReportService/src/ReportService.Api/appsettings.json b/services/CoreService/src/CoreService.Api/appsettings.json
similarity index 100%
rename from services/ReportService/src/ReportService.Api/appsettings.json
rename to services/CoreService/src/CoreService.Api/appsettings.json
diff --git a/services/Data/tests/Data.Tests/ApiErrorPathTests.cs b/services/CoreService/tests/CoreService.Tests/ApiErrorPathTests.cs
similarity index 91%
rename from services/Data/tests/Data.Tests/ApiErrorPathTests.cs
rename to services/CoreService/tests/CoreService.Tests/ApiErrorPathTests.cs
index 4097b41f..ef2e2e5c 100644
--- a/services/Data/tests/Data.Tests/ApiErrorPathTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ApiErrorPathTests.cs
@@ -1,12 +1,12 @@
using System.Net;
using System.Text.Json;
-using Data.Application.Clients;
-using Data.Domain.Models;
+using CoreService.Api.DataApplication.Clients;
+using CoreService.Api.Domain.Data.Models;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
-namespace Data.Tests;
+namespace CoreService.Tests;
public class ApiErrorPathTests
{
@@ -54,8 +54,8 @@ public async Task By_domain_pdf_returns_404_when_domain_unknown()
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
- private static WebApplicationFactory CreateFactory(IReportDataClient reportClient) =>
- new WebApplicationFactory().WithWebHostBuilder(builder =>
+ private static WebApplicationFactory CreateFactory(IReportDataClient reportClient) =>
+ new WebApplicationFactory().WithWebHostBuilder(builder =>
{
builder.ConfigureServices(services =>
{
diff --git a/services/Data/tests/Data.Tests/ApiIntegrationTests.cs b/services/CoreService/tests/CoreService.Tests/ApiIntegrationTests.cs
similarity index 97%
rename from services/Data/tests/Data.Tests/ApiIntegrationTests.cs
rename to services/CoreService/tests/CoreService.Tests/ApiIntegrationTests.cs
index 13d89736..a2b8cdfb 100644
--- a/services/Data/tests/Data.Tests/ApiIntegrationTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ApiIntegrationTests.cs
@@ -2,29 +2,29 @@
using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Nodes;
-using Data.Application.Clients;
-using Data.Application.Dto.Meta;
-using Data.Application.Dto.Filters;
-using Data.Application.Dto.Issues;
-using Data.Application.Dto.Portfolio;
-using Data.Application.Dto.Report;
-using Data.Application.Portfolio;
-using Data.Application.Report;
-using Data.Application.Repositories;
-using Data.Domain.Models;
-using WebsiteProfiling.Contracts.Google;
+using CoreService.Api.DataApplication.Clients;
+using CoreService.Api.DataApplication.Dto.Filters;
+using CoreService.Api.DataApplication.Dto.Issues;
+using CoreService.Api.DataApplication.Dto.Meta;
+using CoreService.Api.DataApplication.Dto.Portfolio;
+using CoreService.Api.DataApplication.Dto.Report;
+using CoreService.Api.DataApplication.Portfolio;
+using CoreService.Api.DataApplication.Report;
+using CoreService.Api.DataApplication.Repositories;
+using CoreService.Api.Domain.Data.Models;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
+using WebsiteProfiling.Contracts.Google;
-namespace Data.Tests;
+namespace CoreService.Tests;
-public class ApiIntegrationTests : IClassFixture>
+public class ApiIntegrationTests : IClassFixture>
{
- private readonly WebApplicationFactory _factory;
+ private readonly WebApplicationFactory _factory;
- public ApiIntegrationTests(WebApplicationFactory factory)
+ public ApiIntegrationTests(WebApplicationFactory factory)
{
_factory = factory.WithWebHostBuilder(builder =>
{
@@ -190,7 +190,7 @@ public async Task Swagger_json_lists_report_routes()
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var json = await response.Content.ReadAsStringAsync();
- Assert.Contains("Website Profiling Data API", json);
+ Assert.Contains("Website Profiling Core API", json);
Assert.Contains("/api/report/meta", json);
Assert.Contains("/api/report/portfolio", json);
Assert.Contains("/api/portfolio/delete", json);
diff --git a/services/Data/tests/Data.Tests/AppSettingsClientTests.cs b/services/CoreService/tests/CoreService.Tests/AppSettingsClientTests.cs
similarity index 97%
rename from services/Data/tests/Data.Tests/AppSettingsClientTests.cs
rename to services/CoreService/tests/CoreService.Tests/AppSettingsClientTests.cs
index 6b6893f2..ca175d5e 100644
--- a/services/Data/tests/Data.Tests/AppSettingsClientTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/AppSettingsClientTests.cs
@@ -1,9 +1,9 @@
using System.Net;
-using Data.Application.Clients;
-using Data.Application.Repositories;
+using CoreService.Api.DataApplication.Clients;
+using CoreService.Api.DataApplication.Repositories;
using Microsoft.Extensions.Logging.Abstractions;
-namespace Data.Tests;
+namespace CoreService.Tests;
public class AppSettingsClientTests
{
diff --git a/services/Data/tests/Data.Tests/AssemblyInfo.cs b/services/CoreService/tests/CoreService.Tests/AssemblyInfo.cs
similarity index 100%
rename from services/Data/tests/Data.Tests/AssemblyInfo.cs
rename to services/CoreService/tests/CoreService.Tests/AssemblyInfo.cs
diff --git a/services/Data/tests/Data.Tests/AuditPdfGeneratorTests.cs b/services/CoreService/tests/CoreService.Tests/AuditPdfGeneratorTests.cs
similarity index 89%
rename from services/Data/tests/Data.Tests/AuditPdfGeneratorTests.cs
rename to services/CoreService/tests/CoreService.Tests/AuditPdfGeneratorTests.cs
index ce8f35f0..c8bb4af1 100644
--- a/services/Data/tests/Data.Tests/AuditPdfGeneratorTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/AuditPdfGeneratorTests.cs
@@ -1,10 +1,10 @@
using System.Text.Json;
-using Data.Application.Mapping;
-using Data.Domain.Models;
-using Data.Rendering;
-using Data.Rendering.Composition;
+using CoreService.Api.DataApplication.Mapping;
+using CoreService.Api.Domain.Data.Models;
+using CoreService.Api.Rendering;
+using CoreService.Api.Rendering.Composition;
-namespace Data.Tests;
+namespace CoreService.Tests;
public class AuditPdfGeneratorTests
{
diff --git a/services/Data/tests/Data.Tests/AuditReportMapperTests.cs b/services/CoreService/tests/CoreService.Tests/AuditReportMapperTests.cs
similarity index 94%
rename from services/Data/tests/Data.Tests/AuditReportMapperTests.cs
rename to services/CoreService/tests/CoreService.Tests/AuditReportMapperTests.cs
index a8d4861f..8f7af5d8 100644
--- a/services/Data/tests/Data.Tests/AuditReportMapperTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/AuditReportMapperTests.cs
@@ -1,10 +1,10 @@
using System.Text.Json;
-using Data.Application.Domain;
-using Data.Application.Mapping;
-using Data.Domain.Models;
-using Data.Rendering.Composition;
+using CoreService.Api.DataApplication.Domain;
+using CoreService.Api.DataApplication.Mapping;
+using CoreService.Api.Domain.Data.Models;
+using CoreService.Api.Rendering.Composition;
-namespace Data.Tests;
+namespace CoreService.Tests;
public class AuditReportMapperTests
{
diff --git a/services/Data/tests/Data.Tests/AuditWorkbookGeneratorTests.cs b/services/CoreService/tests/CoreService.Tests/AuditWorkbookGeneratorTests.cs
similarity index 97%
rename from services/Data/tests/Data.Tests/AuditWorkbookGeneratorTests.cs
rename to services/CoreService/tests/CoreService.Tests/AuditWorkbookGeneratorTests.cs
index 10f9b283..ef7ec676 100644
--- a/services/Data/tests/Data.Tests/AuditWorkbookGeneratorTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/AuditWorkbookGeneratorTests.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
using ClosedXML.Excel;
-using Data.Rendering;
+using CoreService.Api.Rendering;
-namespace Data.Tests;
+namespace CoreService.Tests;
public class AuditWorkbookGeneratorTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/BrowserDiagnosticsAggregatorTests.cs b/services/CoreService/tests/CoreService.Tests/BrowserDiagnosticsAggregatorTests.cs
similarity index 96%
rename from services/ReportService/tests/ReportService.Tests/BrowserDiagnosticsAggregatorTests.cs
rename to services/CoreService/tests/CoreService.Tests/BrowserDiagnosticsAggregatorTests.cs
index 14f43897..053399db 100644
--- a/services/ReportService/tests/ReportService.Tests/BrowserDiagnosticsAggregatorTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/BrowserDiagnosticsAggregatorTests.cs
@@ -1,8 +1,7 @@
-using System.Text.Json;
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class BrowserDiagnosticsAggregatorTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/BrowserDiagnosticsHelperTests.cs b/services/CoreService/tests/CoreService.Tests/BrowserDiagnosticsHelperTests.cs
similarity index 97%
rename from services/ReportService/tests/ReportService.Tests/BrowserDiagnosticsHelperTests.cs
rename to services/CoreService/tests/CoreService.Tests/BrowserDiagnosticsHelperTests.cs
index 541557f8..34a7e860 100644
--- a/services/ReportService/tests/ReportService.Tests/BrowserDiagnosticsHelperTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/BrowserDiagnosticsHelperTests.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using ReportService.Application.Build;
+using CoreService.Api.Application.Build;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class BrowserDiagnosticsHelperTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/CategoryBuilderGoldenTests.cs b/services/CoreService/tests/CoreService.Tests/CategoryBuilderGoldenTests.cs
similarity index 98%
rename from services/ReportService/tests/ReportService.Tests/CategoryBuilderGoldenTests.cs
rename to services/CoreService/tests/CoreService.Tests/CategoryBuilderGoldenTests.cs
index 0801620d..3d2d4ff4 100644
--- a/services/ReportService/tests/ReportService.Tests/CategoryBuilderGoldenTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/CategoryBuilderGoldenTests.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class CategoryBuilderGoldenTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/CategoryBuilderParityTests.cs b/services/CoreService/tests/CoreService.Tests/CategoryBuilderParityTests.cs
similarity index 97%
rename from services/ReportService/tests/ReportService.Tests/CategoryBuilderParityTests.cs
rename to services/CoreService/tests/CoreService.Tests/CategoryBuilderParityTests.cs
index e828aff5..6e3b52be 100644
--- a/services/ReportService/tests/ReportService.Tests/CategoryBuilderParityTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/CategoryBuilderParityTests.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
///
/// Score and issue-count expectations derived from Python category builders on
diff --git a/services/ReportService/tests/ReportService.Tests/CategoryBuilderSlice2Tests.cs b/services/CoreService/tests/CoreService.Tests/CategoryBuilderSlice2Tests.cs
similarity index 96%
rename from services/ReportService/tests/ReportService.Tests/CategoryBuilderSlice2Tests.cs
rename to services/CoreService/tests/CoreService.Tests/CategoryBuilderSlice2Tests.cs
index 7e1fcc6f..5ba2d409 100644
--- a/services/ReportService/tests/ReportService.Tests/CategoryBuilderSlice2Tests.cs
+++ b/services/CoreService/tests/CoreService.Tests/CategoryBuilderSlice2Tests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build.Categories;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build.Categories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class CategoryBuilderSlice2Tests
{
diff --git a/services/ReportService/tests/ReportService.Tests/CategoryHelpersHreflangTests.cs b/services/CoreService/tests/CoreService.Tests/CategoryHelpersHreflangTests.cs
similarity index 85%
rename from services/ReportService/tests/ReportService.Tests/CategoryHelpersHreflangTests.cs
rename to services/CoreService/tests/CoreService.Tests/CategoryHelpersHreflangTests.cs
index 54a05450..6ba5ae48 100644
--- a/services/ReportService/tests/ReportService.Tests/CategoryHelpersHreflangTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/CategoryHelpersHreflangTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class CategoryHelpersHreflangTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/ContactIntelligenceBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/ContactIntelligenceBuilderTests.cs
similarity index 95%
rename from services/ReportService/tests/ReportService.Tests/ContactIntelligenceBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/ContactIntelligenceBuilderTests.cs
index 29417608..a6eaee6a 100644
--- a/services/ReportService/tests/ReportService.Tests/ContactIntelligenceBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ContactIntelligenceBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class ContactIntelligenceBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/ContentAnalyticsBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/ContentAnalyticsBuilderTests.cs
similarity index 97%
rename from services/ReportService/tests/ReportService.Tests/ContentAnalyticsBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/ContentAnalyticsBuilderTests.cs
index 2e2f1592..c8e33203 100644
--- a/services/ReportService/tests/ReportService.Tests/ContentAnalyticsBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ContentAnalyticsBuilderTests.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class ContentAnalyticsBuilderTests
{
diff --git a/services/Data/tests/Data.Tests/ContentBriefBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/ContentBriefBuilderTests.cs
similarity index 92%
rename from services/Data/tests/Data.Tests/ContentBriefBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/ContentBriefBuilderTests.cs
index 73d961ce..0f085433 100644
--- a/services/Data/tests/Data.Tests/ContentBriefBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ContentBriefBuilderTests.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using Data.Application.Content;
+using CoreService.Api.DataApplication.Content;
-namespace Data.Tests;
+namespace CoreService.Tests;
public sealed class ContentBriefBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/ContentUrlListsBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/ContentUrlListsBuilderTests.cs
similarity index 96%
rename from services/ReportService/tests/ReportService.Tests/ContentUrlListsBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/ContentUrlListsBuilderTests.cs
index ace8de69..1ac35108 100644
--- a/services/ReportService/tests/ReportService.Tests/ContentUrlListsBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ContentUrlListsBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class ContentUrlListsBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/ReportService.Tests.csproj b/services/CoreService/tests/CoreService.Tests/CoreService.Tests.csproj
similarity index 78%
rename from services/ReportService/tests/ReportService.Tests/ReportService.Tests.csproj
rename to services/CoreService/tests/CoreService.Tests/CoreService.Tests.csproj
index 9c4567b9..c660ba0e 100644
--- a/services/ReportService/tests/ReportService.Tests/ReportService.Tests.csproj
+++ b/services/CoreService/tests/CoreService.Tests/CoreService.Tests.csproj
@@ -21,8 +21,13 @@
-
-
+
+
+
+
+
+ PreserveNewest
+
diff --git a/services/ReportService/tests/ReportService.Tests/CoreWebVitalsCategoryBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/CoreWebVitalsCategoryBuilderTests.cs
similarity index 93%
rename from services/ReportService/tests/ReportService.Tests/CoreWebVitalsCategoryBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/CoreWebVitalsCategoryBuilderTests.cs
index 93e0b791..4d64d2ba 100644
--- a/services/ReportService/tests/ReportService.Tests/CoreWebVitalsCategoryBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/CoreWebVitalsCategoryBuilderTests.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using ReportService.Application.Build.Categories;
+using CoreService.Api.Application.Build.Categories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class CoreWebVitalsCategoryBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/CrawlControllerBrowserStatusTests.cs b/services/CoreService/tests/CoreService.Tests/CrawlControllerBrowserStatusTests.cs
similarity index 96%
rename from services/ReportService/tests/ReportService.Tests/CrawlControllerBrowserStatusTests.cs
rename to services/CoreService/tests/CoreService.Tests/CrawlControllerBrowserStatusTests.cs
index 0df8250b..44ecddbb 100644
--- a/services/ReportService/tests/ReportService.Tests/CrawlControllerBrowserStatusTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/CrawlControllerBrowserStatusTests.cs
@@ -1,8 +1,7 @@
using System.Diagnostics;
-using System.Text.Json;
-using ReportService.Api.Controllers;
+using CoreService.Api.Controllers;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class CrawlControllerBrowserStatusTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/CrawlRowMapperTests.cs b/services/CoreService/tests/CoreService.Tests/CrawlRowMapperTests.cs
similarity index 91%
rename from services/ReportService/tests/ReportService.Tests/CrawlRowMapperTests.cs
rename to services/CoreService/tests/CoreService.Tests/CrawlRowMapperTests.cs
index 64b82bfc..3b9cd3fa 100644
--- a/services/ReportService/tests/ReportService.Tests/CrawlRowMapperTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/CrawlRowMapperTests.cs
@@ -1,8 +1,8 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
-using ReportService.Domain.Entities;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
+using CoreService.Api.Domain.Report.Entities;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class CrawlRowMapperTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/CrawlRunResolverTests.cs b/services/CoreService/tests/CoreService.Tests/CrawlRunResolverTests.cs
similarity index 82%
rename from services/ReportService/tests/ReportService.Tests/CrawlRunResolverTests.cs
rename to services/CoreService/tests/CoreService.Tests/CrawlRunResolverTests.cs
index 26be09da..9cf7af23 100644
--- a/services/ReportService/tests/ReportService.Tests/CrawlRunResolverTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/CrawlRunResolverTests.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class CrawlRunResolverTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/CrawlSegmentsBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/CrawlSegmentsBuilderTests.cs
similarity index 93%
rename from services/ReportService/tests/ReportService.Tests/CrawlSegmentsBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/CrawlSegmentsBuilderTests.cs
index e2cd0e1f..7cfaae05 100644
--- a/services/ReportService/tests/ReportService.Tests/CrawlSegmentsBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/CrawlSegmentsBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class CrawlSegmentsBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/CruxOriginMetricsFetcherTests.cs b/services/CoreService/tests/CoreService.Tests/CruxOriginMetricsFetcherTests.cs
similarity index 92%
rename from services/ReportService/tests/ReportService.Tests/CruxOriginMetricsFetcherTests.cs
rename to services/CoreService/tests/CoreService.Tests/CruxOriginMetricsFetcherTests.cs
index 28ed3617..21e366cb 100644
--- a/services/ReportService/tests/ReportService.Tests/CruxOriginMetricsFetcherTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/CruxOriginMetricsFetcherTests.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using ReportService.Application.Integrations;
+using CoreService.Api.Application.Integrations;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class CruxOriginMetricsFetcherTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/CtrCurveTests.cs b/services/CoreService/tests/CoreService.Tests/CtrCurveTests.cs
similarity index 92%
rename from services/ReportService/tests/ReportService.Tests/CtrCurveTests.cs
rename to services/CoreService/tests/CoreService.Tests/CtrCurveTests.cs
index 802eeda0..af1e774e 100644
--- a/services/ReportService/tests/ReportService.Tests/CtrCurveTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/CtrCurveTests.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Build;
+using CoreService.Api.Application.Build;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class CtrCurveTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/DashboardsIntegrationTests.cs b/services/CoreService/tests/CoreService.Tests/DashboardsIntegrationTests.cs
similarity index 94%
rename from services/ReportService/tests/ReportService.Tests/DashboardsIntegrationTests.cs
rename to services/CoreService/tests/CoreService.Tests/DashboardsIntegrationTests.cs
index e1f6740b..0dea2dcd 100644
--- a/services/ReportService/tests/ReportService.Tests/DashboardsIntegrationTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/DashboardsIntegrationTests.cs
@@ -5,18 +5,18 @@
using Microsoft.AspNetCore.Mvc.Testing;
using WebsiteProfiling.Testing;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
/// Postgres integration tests for /api/dashboards/* (replaces Python FastAPI tests).
-public class DashboardsIntegrationTests : IClassFixture>, IAsyncLifetime
+public class DashboardsIntegrationTests : IClassFixture>, IAsyncLifetime
{
- private readonly WebApplicationFactory _factory;
+ private readonly WebApplicationFactory _factory;
private HttpClient? _client;
private long? _propertyId;
private long? _dashboardId;
private bool _dbReady;
- public DashboardsIntegrationTests(WebApplicationFactory factory)
+ public DashboardsIntegrationTests(WebApplicationFactory factory)
{
_factory = factory.WithWebHostBuilder(builder => builder.UseEnvironment("Development"));
}
diff --git a/services/Data/tests/Data.Tests/DataPythonRunnerTimeoutTests.cs b/services/CoreService/tests/CoreService.Tests/DataPythonRunnerTimeoutTests.cs
similarity index 96%
rename from services/Data/tests/Data.Tests/DataPythonRunnerTimeoutTests.cs
rename to services/CoreService/tests/CoreService.Tests/DataPythonRunnerTimeoutTests.cs
index d22e9e04..04b57570 100644
--- a/services/Data/tests/Data.Tests/DataPythonRunnerTimeoutTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/DataPythonRunnerTimeoutTests.cs
@@ -1,7 +1,6 @@
-using System.Diagnostics;
-using Data.Application.Python;
+using CoreService.Api.DataApplication.Python;
-namespace Data.Tests;
+namespace CoreService.Tests;
public sealed class DataPythonRunnerTimeoutTests
{
diff --git a/services/Data/tests/Data.Tests/ServiceRegistrationValidationTests.cs b/services/CoreService/tests/CoreService.Tests/DataServiceRegistrationValidationTests.cs
similarity index 74%
rename from services/Data/tests/Data.Tests/ServiceRegistrationValidationTests.cs
rename to services/CoreService/tests/CoreService.Tests/DataServiceRegistrationValidationTests.cs
index 4ec65789..b1cd69d4 100644
--- a/services/Data/tests/Data.Tests/ServiceRegistrationValidationTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/DataServiceRegistrationValidationTests.cs
@@ -1,16 +1,16 @@
-using Data.Application.Portfolio;
-using Data.Application.Report;
-using Data.Application.Repositories;
-using Data.Application.Services;
-using Data.Rendering;
+using CoreService.Api.DataApplication.Portfolio;
+using CoreService.Api.DataApplication.Report;
+using CoreService.Api.DataApplication.Repositories;
+using CoreService.Api.DataApplication.Services;
+using CoreService.Api.Rendering;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using WebsiteProfiling.Testing;
-namespace Data.Tests;
+namespace CoreService.Tests;
-public sealed class ServiceRegistrationValidationTests
+public sealed class DataServiceRegistrationValidationTests
{
[Fact]
public void Web_host_resolves_core_services()
@@ -19,7 +19,7 @@ public void Web_host_resolves_core_services()
env.SetDefaultsForPostgresServices();
env.Set("REPORT_API_URL", "http://127.0.0.1:8096");
- using var factory = new WebApplicationFactory().WithWebHostBuilder(builder =>
+ using var factory = new WebApplicationFactory().WithWebHostBuilder(builder =>
{
builder.UseEnvironment("Development");
});
diff --git a/services/Data/tests/Data.Tests/SiteHealthScoreBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/DataSiteHealthScoreBuilderTests.cs
similarity index 94%
rename from services/Data/tests/Data.Tests/SiteHealthScoreBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/DataSiteHealthScoreBuilderTests.cs
index 27b3c14c..ef782805 100644
--- a/services/Data/tests/Data.Tests/SiteHealthScoreBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/DataSiteHealthScoreBuilderTests.cs
@@ -1,9 +1,9 @@
using System.Text.Json;
using WebsiteProfiling.Contracts.Report;
-namespace Data.Tests;
+namespace CoreService.Tests;
-public sealed class SiteHealthScoreBuilderTests
+public sealed class DataSiteHealthScoreBuilderTests
{
[Fact]
public void ResolveFromPayload_prefers_summary_site_health_score()
diff --git a/services/ReportService/tests/ReportService.Tests/FastApiPythonBridgeTests.cs b/services/CoreService/tests/CoreService.Tests/FastApiPythonBridgeTests.cs
similarity index 94%
rename from services/ReportService/tests/ReportService.Tests/FastApiPythonBridgeTests.cs
rename to services/CoreService/tests/CoreService.Tests/FastApiPythonBridgeTests.cs
index c823b537..732ab066 100644
--- a/services/ReportService/tests/ReportService.Tests/FastApiPythonBridgeTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/FastApiPythonBridgeTests.cs
@@ -1,11 +1,10 @@
using System.Net;
-using System.Net.Http;
using System.Text;
+using CoreService.Api.Application.Bridge;
+using CoreService.Api.Application.Options;
using Microsoft.Extensions.Options;
-using ReportService.Application.Bridge;
-using ReportService.Application.Options;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class FastApiPythonBridgeTests
{
diff --git a/services/IntegrationsService/tests/IntegrationsService.Tests/GoogleFetchPayloadTests.cs b/services/CoreService/tests/CoreService.Tests/GoogleFetchPayloadTests.cs
similarity index 95%
rename from services/IntegrationsService/tests/IntegrationsService.Tests/GoogleFetchPayloadTests.cs
rename to services/CoreService/tests/CoreService.Tests/GoogleFetchPayloadTests.cs
index 88e80441..de8588f3 100644
--- a/services/IntegrationsService/tests/IntegrationsService.Tests/GoogleFetchPayloadTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/GoogleFetchPayloadTests.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using IntegrationsService.Application.Google;
+using CoreService.Api.IntegrationsApplication.Google;
-namespace IntegrationsService.Tests;
+namespace CoreService.Tests;
public sealed class GoogleFetchPayloadTests
{
diff --git a/services/IntegrationsService/tests/IntegrationsService.Tests/GoogleOAuthServiceTests.cs b/services/CoreService/tests/CoreService.Tests/GoogleOAuthServiceTests.cs
similarity index 91%
rename from services/IntegrationsService/tests/IntegrationsService.Tests/GoogleOAuthServiceTests.cs
rename to services/CoreService/tests/CoreService.Tests/GoogleOAuthServiceTests.cs
index cad36702..3d4cb658 100644
--- a/services/IntegrationsService/tests/IntegrationsService.Tests/GoogleOAuthServiceTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/GoogleOAuthServiceTests.cs
@@ -1,6 +1,6 @@
-using IntegrationsService.Application.Google;
+using CoreService.Api.IntegrationsApplication.Google;
-namespace IntegrationsService.Tests;
+namespace CoreService.Tests;
public sealed class GoogleOAuthServiceTests
{
diff --git a/services/IntegrationsService/tests/IntegrationsService.Tests/GscRowMappersTests.cs b/services/CoreService/tests/CoreService.Tests/GscRowMappersTests.cs
similarity index 91%
rename from services/IntegrationsService/tests/IntegrationsService.Tests/GscRowMappersTests.cs
rename to services/CoreService/tests/CoreService.Tests/GscRowMappersTests.cs
index bb85011c..87f8741b 100644
--- a/services/IntegrationsService/tests/IntegrationsService.Tests/GscRowMappersTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/GscRowMappersTests.cs
@@ -1,6 +1,6 @@
-using IntegrationsService.Application.Google;
+using CoreService.Api.IntegrationsApplication.Google;
-namespace IntegrationsService.Tests;
+namespace CoreService.Tests;
///
/// Golden parity with Python gsc._to_query_record / _to_page_record (ctr stored as percent).
diff --git a/services/ReportService/tests/ReportService.Tests/ImageInventoryBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/ImageInventoryBuilderTests.cs
similarity index 91%
rename from services/ReportService/tests/ReportService.Tests/ImageInventoryBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/ImageInventoryBuilderTests.cs
index 4d2506c7..36c92302 100644
--- a/services/ReportService/tests/ReportService.Tests/ImageInventoryBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ImageInventoryBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class ImageInventoryBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/IndexationCoverageIssuesTests.cs b/services/CoreService/tests/CoreService.Tests/IndexationCoverageIssuesTests.cs
similarity index 88%
rename from services/ReportService/tests/ReportService.Tests/IndexationCoverageIssuesTests.cs
rename to services/CoreService/tests/CoreService.Tests/IndexationCoverageIssuesTests.cs
index 8f202e6d..899684f2 100644
--- a/services/ReportService/tests/ReportService.Tests/IndexationCoverageIssuesTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/IndexationCoverageIssuesTests.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class IndexationCoverageIssuesTests
{
diff --git a/services/IntegrationsService/tests/IntegrationsService.Tests/ServiceRegistrationValidationTests.cs b/services/CoreService/tests/CoreService.Tests/IntegrationsServiceRegistrationValidationTests.cs
similarity index 70%
rename from services/IntegrationsService/tests/IntegrationsService.Tests/ServiceRegistrationValidationTests.cs
rename to services/CoreService/tests/CoreService.Tests/IntegrationsServiceRegistrationValidationTests.cs
index 7195219d..8dfd0eb1 100644
--- a/services/IntegrationsService/tests/IntegrationsService.Tests/ServiceRegistrationValidationTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/IntegrationsServiceRegistrationValidationTests.cs
@@ -1,13 +1,13 @@
-using IntegrationsService.Application.Google;
-using IntegrationsService.Application.Report;
+using CoreService.Api.IntegrationsApplication.Google;
+using CoreService.Api.IntegrationsApplication.Report;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using WebsiteProfiling.Testing;
-namespace IntegrationsService.Tests;
+namespace CoreService.Tests;
-public sealed class ServiceRegistrationValidationTests
+public sealed class IntegrationsServiceRegistrationValidationTests
{
[Fact]
public void Web_host_resolves_core_services()
@@ -15,7 +15,7 @@ public void Web_host_resolves_core_services()
using var env = ServiceRegistrationTestEnvironment.Push();
env.SetDefaultsForPostgresServices();
- using var factory = new WebApplicationFactory().WithWebHostBuilder(builder =>
+ using var factory = new WebApplicationFactory().WithWebHostBuilder(builder =>
{
builder.UseEnvironment("Development");
});
diff --git a/services/ReportService/tests/ReportService.Tests/IntelligenceCategoryBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/IntelligenceCategoryBuilderTests.cs
similarity index 96%
rename from services/ReportService/tests/ReportService.Tests/IntelligenceCategoryBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/IntelligenceCategoryBuilderTests.cs
index b5ead32b..649c4e14 100644
--- a/services/ReportService/tests/ReportService.Tests/IntelligenceCategoryBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/IntelligenceCategoryBuilderTests.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using ReportService.Application.Build.Categories;
+using CoreService.Api.Application.Build.Categories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class IntelligenceCategoryBuilderTests
{
diff --git a/services/Data/tests/Data.Tests/IssueStatusFingerprintTests.cs b/services/CoreService/tests/CoreService.Tests/IssueStatusFingerprintTests.cs
similarity index 88%
rename from services/Data/tests/Data.Tests/IssueStatusFingerprintTests.cs
rename to services/CoreService/tests/CoreService.Tests/IssueStatusFingerprintTests.cs
index 33c12af0..ee32a742 100644
--- a/services/Data/tests/Data.Tests/IssueStatusFingerprintTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/IssueStatusFingerprintTests.cs
@@ -1,6 +1,6 @@
-using Data.Application.Issues;
+using CoreService.Api.DataApplication.Issues;
-namespace Data.Tests;
+namespace CoreService.Tests;
public class IssueStatusFingerprintTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/KeywordOpportunitiesBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/KeywordOpportunitiesBuilderTests.cs
similarity index 97%
rename from services/ReportService/tests/ReportService.Tests/KeywordOpportunitiesBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/KeywordOpportunitiesBuilderTests.cs
index bfd6a6d5..6381140f 100644
--- a/services/ReportService/tests/ReportService.Tests/KeywordOpportunitiesBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/KeywordOpportunitiesBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class KeywordOpportunitiesBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/LighthouseReportMergeTests.cs b/services/CoreService/tests/CoreService.Tests/LighthouseReportMergeTests.cs
similarity index 95%
rename from services/ReportService/tests/ReportService.Tests/LighthouseReportMergeTests.cs
rename to services/CoreService/tests/CoreService.Tests/LighthouseReportMergeTests.cs
index 8613ab83..bb292fce 100644
--- a/services/ReportService/tests/ReportService.Tests/LighthouseReportMergeTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/LighthouseReportMergeTests.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Nodes;
-using ReportService.Application.Build;
+using CoreService.Api.Application.Build;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class LighthouseReportMergeTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/LinkEdgesReportBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/LinkEdgesReportBuilderTests.cs
similarity index 96%
rename from services/ReportService/tests/ReportService.Tests/LinkEdgesReportBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/LinkEdgesReportBuilderTests.cs
index 84ccec19..c3e86d6c 100644
--- a/services/ReportService/tests/ReportService.Tests/LinkEdgesReportBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/LinkEdgesReportBuilderTests.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Build;
+using CoreService.Api.Application.Build;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class LinkEdgesReportBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/LinksListBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/LinksListBuilderTests.cs
similarity index 96%
rename from services/ReportService/tests/ReportService.Tests/LinksListBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/LinksListBuilderTests.cs
index e8195fef..309b3c44 100644
--- a/services/ReportService/tests/ReportService.Tests/LinksListBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/LinksListBuilderTests.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class LinksListBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/LocalEnrichmentBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/LocalEnrichmentBuilderTests.cs
similarity index 98%
rename from services/ReportService/tests/ReportService.Tests/LocalEnrichmentBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/LocalEnrichmentBuilderTests.cs
index ce6f0965..5d31ea8a 100644
--- a/services/ReportService/tests/ReportService.Tests/LocalEnrichmentBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/LocalEnrichmentBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class LocalEnrichmentBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/MobileCategoryBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/MobileCategoryBuilderTests.cs
similarity index 90%
rename from services/ReportService/tests/ReportService.Tests/MobileCategoryBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/MobileCategoryBuilderTests.cs
index 1ff0e29f..fb46294e 100644
--- a/services/ReportService/tests/ReportService.Tests/MobileCategoryBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/MobileCategoryBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build.Categories;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build.Categories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class MobileCategoryBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/NativeReportPayloadAssemblerTests.cs b/services/CoreService/tests/CoreService.Tests/NativeReportPayloadAssemblerTests.cs
similarity index 98%
rename from services/ReportService/tests/ReportService.Tests/NativeReportPayloadAssemblerTests.cs
rename to services/CoreService/tests/CoreService.Tests/NativeReportPayloadAssemblerTests.cs
index b4b4f600..b07d6970 100644
--- a/services/ReportService/tests/ReportService.Tests/NativeReportPayloadAssemblerTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/NativeReportPayloadAssemblerTests.cs
@@ -1,7 +1,6 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class NativeReportPayloadAssemblerTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/OptionalAuditUrlsBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/OptionalAuditUrlsBuilderTests.cs
similarity index 95%
rename from services/ReportService/tests/ReportService.Tests/OptionalAuditUrlsBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/OptionalAuditUrlsBuilderTests.cs
index ab25a2ec..20ce4217 100644
--- a/services/ReportService/tests/ReportService.Tests/OptionalAuditUrlsBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/OptionalAuditUrlsBuilderTests.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Build;
+using CoreService.Api.Application.Build;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class OptionalAuditUrlsBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/OptionalAuditsBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/OptionalAuditsBuilderTests.cs
similarity index 97%
rename from services/ReportService/tests/ReportService.Tests/OptionalAuditsBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/OptionalAuditsBuilderTests.cs
index 049310e5..bbb43b3b 100644
--- a/services/ReportService/tests/ReportService.Tests/OptionalAuditsBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/OptionalAuditsBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class OptionalAuditsBuilderTests
{
diff --git a/services/IntegrationsService/tests/IntegrationsService.Tests/PageLookupGoldenTests.cs b/services/CoreService/tests/CoreService.Tests/PageLookupGoldenTests.cs
similarity index 95%
rename from services/IntegrationsService/tests/IntegrationsService.Tests/PageLookupGoldenTests.cs
rename to services/CoreService/tests/CoreService.Tests/PageLookupGoldenTests.cs
index 7da26b90..46379caf 100644
--- a/services/IntegrationsService/tests/IntegrationsService.Tests/PageLookupGoldenTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/PageLookupGoldenTests.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using IntegrationsService.Application.Repositories;
+using CoreService.Api.IntegrationsApplication.Google;
-namespace IntegrationsService.Tests;
+namespace CoreService.Tests;
public sealed class PageLookupGoldenTests
{
diff --git a/services/IntegrationsService/tests/IntegrationsService.Tests/PageMetricsCompareTests.cs b/services/CoreService/tests/CoreService.Tests/PageMetricsCompareTests.cs
similarity index 92%
rename from services/IntegrationsService/tests/IntegrationsService.Tests/PageMetricsCompareTests.cs
rename to services/CoreService/tests/CoreService.Tests/PageMetricsCompareTests.cs
index 3d1bebc5..b1a539de 100644
--- a/services/IntegrationsService/tests/IntegrationsService.Tests/PageMetricsCompareTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/PageMetricsCompareTests.cs
@@ -1,6 +1,6 @@
-using IntegrationsService.Application.Google;
+using CoreService.Api.IntegrationsApplication.Google;
-namespace IntegrationsService.Tests;
+namespace CoreService.Tests;
public sealed class PageMetricsCompareTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/PerformanceCategoryBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/PerformanceCategoryBuilderTests.cs
similarity index 93%
rename from services/ReportService/tests/ReportService.Tests/PerformanceCategoryBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/PerformanceCategoryBuilderTests.cs
index cdf59efb..5b7c61ea 100644
--- a/services/ReportService/tests/ReportService.Tests/PerformanceCategoryBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/PerformanceCategoryBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build.Categories;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build.Categories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class PerformanceCategoryBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/PipelinePreviewControllerTests.cs b/services/CoreService/tests/CoreService.Tests/PipelinePreviewControllerTests.cs
similarity index 96%
rename from services/ReportService/tests/ReportService.Tests/PipelinePreviewControllerTests.cs
rename to services/CoreService/tests/CoreService.Tests/PipelinePreviewControllerTests.cs
index c2a9b2d4..1da55a17 100644
--- a/services/ReportService/tests/ReportService.Tests/PipelinePreviewControllerTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/PipelinePreviewControllerTests.cs
@@ -1,13 +1,13 @@
using System.Net;
using System.Text;
using System.Text.Json;
+using CoreService.Api.Application.Bridge;
+using CoreService.Api.Application.Options;
+using CoreService.Api.Controllers;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
-using ReportService.Api.Controllers;
-using ReportService.Application.Bridge;
-using ReportService.Application.Options;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class PipelinePreviewControllerTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/PipelineStateHelperTests.cs b/services/CoreService/tests/CoreService.Tests/PipelineStateHelperTests.cs
similarity index 93%
rename from services/ReportService/tests/ReportService.Tests/PipelineStateHelperTests.cs
rename to services/CoreService/tests/CoreService.Tests/PipelineStateHelperTests.cs
index d21ff84f..ceffe32a 100644
--- a/services/ReportService/tests/ReportService.Tests/PipelineStateHelperTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/PipelineStateHelperTests.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Pipeline;
+using CoreService.Api.Application.Pipeline;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class PipelineStateHelperTests
{
diff --git a/services/Data/tests/Data.Tests/PortfolioGroupingTests.cs b/services/CoreService/tests/CoreService.Tests/PortfolioGroupingTests.cs
similarity index 94%
rename from services/Data/tests/Data.Tests/PortfolioGroupingTests.cs
rename to services/CoreService/tests/CoreService.Tests/PortfolioGroupingTests.cs
index 76bb808b..621a2e53 100644
--- a/services/Data/tests/Data.Tests/PortfolioGroupingTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/PortfolioGroupingTests.cs
@@ -1,8 +1,8 @@
using System.Text.Json;
-using Data.Application.Dto.Portfolio;
-using Data.Application.Portfolio;
+using CoreService.Api.DataApplication.Dto.Portfolio;
+using CoreService.Api.DataApplication.Portfolio;
-namespace Data.Tests;
+namespace CoreService.Tests;
public class PortfolioGroupingTests
{
diff --git a/services/Data/tests/Data.Tests/PropertiesIntegrationTests.cs b/services/CoreService/tests/CoreService.Tests/PropertiesIntegrationTests.cs
similarity index 95%
rename from services/Data/tests/Data.Tests/PropertiesIntegrationTests.cs
rename to services/CoreService/tests/CoreService.Tests/PropertiesIntegrationTests.cs
index 65aa02b9..903762ff 100644
--- a/services/Data/tests/Data.Tests/PropertiesIntegrationTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/PropertiesIntegrationTests.cs
@@ -5,17 +5,17 @@
using Microsoft.AspNetCore.Mvc.Testing;
using WebsiteProfiling.Testing;
-namespace Data.Tests;
+namespace CoreService.Tests;
/// Postgres integration tests for /api/properties/* (replaces Python FastAPI tests).
-public class PropertiesIntegrationTests : IClassFixture>, IAsyncLifetime
+public class PropertiesIntegrationTests : IClassFixture>, IAsyncLifetime
{
- private readonly WebApplicationFactory _factory;
+ private readonly WebApplicationFactory _factory;
private HttpClient? _client;
private long? _createdPropertyId;
private bool _dbReady;
- public PropertiesIntegrationTests(WebApplicationFactory factory)
+ public PropertiesIntegrationTests(WebApplicationFactory factory)
{
_factory = factory.WithWebHostBuilder(builder => builder.UseEnvironment("Development"));
}
diff --git a/services/Data/tests/Data.Tests/PyIsoTests.cs b/services/CoreService/tests/CoreService.Tests/PyIsoTests.cs
similarity index 94%
rename from services/Data/tests/Data.Tests/PyIsoTests.cs
rename to services/CoreService/tests/CoreService.Tests/PyIsoTests.cs
index 3e397190..a89abaeb 100644
--- a/services/Data/tests/Data.Tests/PyIsoTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/PyIsoTests.cs
@@ -1,6 +1,6 @@
-using Data.Application.Json;
+using CoreService.Api.DataApplication.Json;
-namespace Data.Tests;
+namespace CoreService.Tests;
public class PyIsoTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/ReportBuildKeywordEnrichTests.cs b/services/CoreService/tests/CoreService.Tests/ReportBuildKeywordEnrichTests.cs
similarity index 95%
rename from services/ReportService/tests/ReportService.Tests/ReportBuildKeywordEnrichTests.cs
rename to services/CoreService/tests/CoreService.Tests/ReportBuildKeywordEnrichTests.cs
index 33638297..b8fdc81a 100644
--- a/services/ReportService/tests/ReportService.Tests/ReportBuildKeywordEnrichTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ReportBuildKeywordEnrichTests.cs
@@ -1,13 +1,13 @@
using System.Net;
using System.Reflection;
using System.Text;
+using CoreService.Api.Application.Bridge;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Options;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
-using ReportService.Application.Bridge;
-using ReportService.Application.Build;
-using ReportService.Application.Options;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class ReportBuildKeywordEnrichTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/ReportBuildServiceBridgeTests.cs b/services/CoreService/tests/CoreService.Tests/ReportBuildServiceBridgeTests.cs
similarity index 95%
rename from services/ReportService/tests/ReportService.Tests/ReportBuildServiceBridgeTests.cs
rename to services/CoreService/tests/CoreService.Tests/ReportBuildServiceBridgeTests.cs
index 3144bf70..9d0f1db2 100644
--- a/services/ReportService/tests/ReportService.Tests/ReportBuildServiceBridgeTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ReportBuildServiceBridgeTests.cs
@@ -1,12 +1,12 @@
using System.Net;
using System.Text;
+using CoreService.Api.Application.Bridge;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Options;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
-using ReportService.Application.Bridge;
-using ReportService.Application.Build;
-using ReportService.Application.Options;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class ReportBuildServiceBridgeTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/ReportChartDataBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/ReportChartDataBuilderTests.cs
similarity index 89%
rename from services/ReportService/tests/ReportService.Tests/ReportChartDataBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/ReportChartDataBuilderTests.cs
index 58b931bb..59d61ce5 100644
--- a/services/ReportService/tests/ReportService.Tests/ReportChartDataBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ReportChartDataBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class ReportChartDataBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/ReportEdgeResolverTests.cs b/services/CoreService/tests/CoreService.Tests/ReportEdgeResolverTests.cs
similarity index 92%
rename from services/ReportService/tests/ReportService.Tests/ReportEdgeResolverTests.cs
rename to services/CoreService/tests/CoreService.Tests/ReportEdgeResolverTests.cs
index e4a26a40..a69d31e2 100644
--- a/services/ReportService/tests/ReportService.Tests/ReportEdgeResolverTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ReportEdgeResolverTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class ReportEdgeResolverTests
{
diff --git a/services/IntegrationsService/tests/IntegrationsService.Tests/ReportEnrichmentServiceTests.cs b/services/CoreService/tests/CoreService.Tests/ReportEnrichmentServiceTests.cs
similarity index 92%
rename from services/IntegrationsService/tests/IntegrationsService.Tests/ReportEnrichmentServiceTests.cs
rename to services/CoreService/tests/CoreService.Tests/ReportEnrichmentServiceTests.cs
index 7fdda2d0..e69b2a49 100644
--- a/services/IntegrationsService/tests/IntegrationsService.Tests/ReportEnrichmentServiceTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ReportEnrichmentServiceTests.cs
@@ -1,6 +1,6 @@
-using IntegrationsService.Application.Report;
+using CoreService.Api.IntegrationsApplication.Report;
-namespace IntegrationsService.Tests;
+namespace CoreService.Tests;
public sealed class ReportEnrichmentServiceTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/ReportEnrichmentSliceTests.cs b/services/CoreService/tests/CoreService.Tests/ReportEnrichmentSliceTests.cs
similarity index 90%
rename from services/ReportService/tests/ReportService.Tests/ReportEnrichmentSliceTests.cs
rename to services/CoreService/tests/CoreService.Tests/ReportEnrichmentSliceTests.cs
index 62211ed3..66944801 100644
--- a/services/ReportService/tests/ReportService.Tests/ReportEnrichmentSliceTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ReportEnrichmentSliceTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class SecurityScanBuilderTests
{
@@ -42,7 +42,7 @@ public void Build_marks_competitors_not_in_our_sample()
}
}
-public sealed class UrlJoinBuilderTests
+public sealed partial class UrlJoinBuilderTests
{
[Fact]
public void Build_counts_crawl_only_urls()
diff --git a/services/Data/tests/Data.Tests/ReportExportersTests.cs b/services/CoreService/tests/CoreService.Tests/ReportExportersTests.cs
similarity index 97%
rename from services/Data/tests/Data.Tests/ReportExportersTests.cs
rename to services/CoreService/tests/CoreService.Tests/ReportExportersTests.cs
index e323f4ac..48c8969a 100644
--- a/services/Data/tests/Data.Tests/ReportExportersTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ReportExportersTests.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using Data.Rendering.Exports;
+using CoreService.Api.Rendering.Exports;
-namespace Data.Tests;
+namespace CoreService.Tests;
public class ReportExportersTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/ReportGraphBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/ReportGraphBuilderTests.cs
similarity index 92%
rename from services/ReportService/tests/ReportService.Tests/ReportGraphBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/ReportGraphBuilderTests.cs
index 2f13e731..e0b958d4 100644
--- a/services/ReportService/tests/ReportService.Tests/ReportGraphBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ReportGraphBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class ReportGraphBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/ReportMetadataBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/ReportMetadataBuilderTests.cs
similarity index 91%
rename from services/ReportService/tests/ReportService.Tests/ReportMetadataBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/ReportMetadataBuilderTests.cs
index 047df18a..d531f585 100644
--- a/services/ReportService/tests/ReportService.Tests/ReportMetadataBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ReportMetadataBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class ReportMetadataBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/ReportNativeValidatorCategoryTests.cs b/services/CoreService/tests/CoreService.Tests/ReportNativeValidatorCategoryTests.cs
similarity index 93%
rename from services/ReportService/tests/ReportService.Tests/ReportNativeValidatorCategoryTests.cs
rename to services/CoreService/tests/CoreService.Tests/ReportNativeValidatorCategoryTests.cs
index ed0841ea..3d1e1db0 100644
--- a/services/ReportService/tests/ReportService.Tests/ReportNativeValidatorCategoryTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ReportNativeValidatorCategoryTests.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using ReportService.Application.Build;
+using CoreService.Api.Application.Build;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class ReportNativeValidatorCategoryTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/ReportNativeValidatorLinksTests.cs b/services/CoreService/tests/CoreService.Tests/ReportNativeValidatorLinksTests.cs
similarity index 89%
rename from services/ReportService/tests/ReportService.Tests/ReportNativeValidatorLinksTests.cs
rename to services/CoreService/tests/CoreService.Tests/ReportNativeValidatorLinksTests.cs
index 3cd6bf50..e1fce965 100644
--- a/services/ReportService/tests/ReportService.Tests/ReportNativeValidatorLinksTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ReportNativeValidatorLinksTests.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using ReportService.Application.Build;
+using CoreService.Api.Application.Build;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class ReportNativeValidatorLinksTests
{
diff --git a/services/Data/tests/Data.Tests/ReportSectionServiceTests.cs b/services/CoreService/tests/CoreService.Tests/ReportSectionServiceTests.cs
similarity index 96%
rename from services/Data/tests/Data.Tests/ReportSectionServiceTests.cs
rename to services/CoreService/tests/CoreService.Tests/ReportSectionServiceTests.cs
index d10afdeb..88488c38 100644
--- a/services/Data/tests/Data.Tests/ReportSectionServiceTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ReportSectionServiceTests.cs
@@ -1,11 +1,11 @@
using System.Text.Json.Nodes;
-using Data.Application.Dto.Meta;
-using Data.Application.Dto.Report;
-using Data.Application.Report;
-using Data.Application.Repositories;
+using CoreService.Api.DataApplication.Dto.Meta;
+using CoreService.Api.DataApplication.Dto.Report;
+using CoreService.Api.DataApplication.Report;
+using CoreService.Api.DataApplication.Repositories;
using WebsiteProfiling.Contracts.Google;
-namespace Data.Tests;
+namespace CoreService.Tests;
public sealed class PropertyRepositoryTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/ServiceRegistrationValidationTests.cs b/services/CoreService/tests/CoreService.Tests/ReportServiceRegistrationValidationTests.cs
similarity index 73%
rename from services/ReportService/tests/ReportService.Tests/ServiceRegistrationValidationTests.cs
rename to services/CoreService/tests/CoreService.Tests/ReportServiceRegistrationValidationTests.cs
index 37586d6d..26c59f9d 100644
--- a/services/ReportService/tests/ReportService.Tests/ServiceRegistrationValidationTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ReportServiceRegistrationValidationTests.cs
@@ -1,13 +1,13 @@
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Orchestration;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
-using ReportService.Application.Build;
-using ReportService.Application.Orchestration;
using WebsiteProfiling.Testing;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
-public sealed class ServiceRegistrationValidationTests
+public sealed class ReportServiceRegistrationValidationTests
{
[Fact]
public void Web_host_resolves_core_services()
@@ -16,7 +16,7 @@ public void Web_host_resolves_core_services()
env.SetDefaultsForPostgresServices();
env.Set("INTEGRATIONS_SERVICE_URL", "http://127.0.0.1:8093");
- using var factory = new WebApplicationFactory().WithWebHostBuilder(builder =>
+ using var factory = new WebApplicationFactory().WithWebHostBuilder(builder =>
{
builder.UseEnvironment("Development");
});
diff --git a/services/Data/tests/Data.Tests/ReportServiceTests.cs b/services/CoreService/tests/CoreService.Tests/ReportServiceTests.cs
similarity index 94%
rename from services/Data/tests/Data.Tests/ReportServiceTests.cs
rename to services/CoreService/tests/CoreService.Tests/ReportServiceTests.cs
index 76249169..4d0ca918 100644
--- a/services/Data/tests/Data.Tests/ReportServiceTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ReportServiceTests.cs
@@ -1,11 +1,11 @@
using System.Text.Json;
-using Data.Application.Clients;
-using Data.Application.Services;
-using Data.Domain.Models;
-using Data.Rendering;
+using CoreService.Api.DataApplication.Clients;
+using CoreService.Api.DataApplication.Services;
+using CoreService.Api.Domain.Data.Models;
+using CoreService.Api.Rendering;
using Microsoft.Extensions.Logging.Abstractions;
-namespace Data.Tests;
+namespace CoreService.Tests;
public class ReportServiceTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/SiteHealthScoreBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/ReportSiteHealthScoreBuilderTests.cs
similarity index 91%
rename from services/ReportService/tests/ReportService.Tests/SiteHealthScoreBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/ReportSiteHealthScoreBuilderTests.cs
index 105f2ee9..81e89269 100644
--- a/services/ReportService/tests/ReportService.Tests/SiteHealthScoreBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/ReportSiteHealthScoreBuilderTests.cs
@@ -1,8 +1,8 @@
-using ReportService.Application.Build;
+using CoreService.Api.Application.Build;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
-public sealed class SiteHealthScoreBuilderTests
+public sealed class ReportSiteHealthScoreBuilderTests
{
[Fact]
public void Compute_excludes_search_performance_and_intelligence()
diff --git a/services/ReportService/tests/ReportService.Tests/SearchPerformanceCategoryBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/SearchPerformanceCategoryBuilderTests.cs
similarity index 97%
rename from services/ReportService/tests/ReportService.Tests/SearchPerformanceCategoryBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/SearchPerformanceCategoryBuilderTests.cs
index e1e6dbd3..f576cea1 100644
--- a/services/ReportService/tests/ReportService.Tests/SearchPerformanceCategoryBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/SearchPerformanceCategoryBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Build.Categories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Build.Categories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class SearchPerformanceCategoryBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/SecurityCategoryBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/SecurityCategoryBuilderTests.cs
similarity index 94%
rename from services/ReportService/tests/ReportService.Tests/SecurityCategoryBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/SecurityCategoryBuilderTests.cs
index d8fcf789..996f6f32 100644
--- a/services/ReportService/tests/ReportService.Tests/SecurityCategoryBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/SecurityCategoryBuilderTests.cs
@@ -1,8 +1,8 @@
-using ReportService.Application.Build;
-using ReportService.Application.Build.Categories;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Build.Categories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class SecurityCategoryBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/SeoSummaryBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/SeoSummaryBuilderTests.cs
similarity index 94%
rename from services/ReportService/tests/ReportService.Tests/SeoSummaryBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/SeoSummaryBuilderTests.cs
index 4e562ce0..038af6db 100644
--- a/services/ReportService/tests/ReportService.Tests/SeoSummaryBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/SeoSummaryBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class SeoSummaryBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/SiteFileParserTests.cs b/services/CoreService/tests/CoreService.Tests/SiteFileParserTests.cs
similarity index 95%
rename from services/ReportService/tests/ReportService.Tests/SiteFileParserTests.cs
rename to services/CoreService/tests/CoreService.Tests/SiteFileParserTests.cs
index fae04f88..9dd7fc3e 100644
--- a/services/ReportService/tests/ReportService.Tests/SiteFileParserTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/SiteFileParserTests.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Build;
+using CoreService.Api.Application.Build;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class SiteFileParserTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/SubdomainInventoryBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/SubdomainInventoryBuilderTests.cs
similarity index 93%
rename from services/ReportService/tests/ReportService.Tests/SubdomainInventoryBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/SubdomainInventoryBuilderTests.cs
index d4b9546b..f4ef471a 100644
--- a/services/ReportService/tests/ReportService.Tests/SubdomainInventoryBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/SubdomainInventoryBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class SubdomainInventoryBuilderTests
{
diff --git a/services/ReportService/tests/ReportService.Tests/TechnicalSeoCategoryBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/TechnicalSeoCategoryBuilderTests.cs
similarity index 97%
rename from services/ReportService/tests/ReportService.Tests/TechnicalSeoCategoryBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/TechnicalSeoCategoryBuilderTests.cs
index f1664b2a..df3cd277 100644
--- a/services/ReportService/tests/ReportService.Tests/TechnicalSeoCategoryBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/TechnicalSeoCategoryBuilderTests.cs
@@ -1,7 +1,7 @@
-using ReportService.Application.Build.Categories;
-using ReportService.Application.Repositories;
+using CoreService.Api.Application.Build.Categories;
+using CoreService.Api.Application.Repositories;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class TechnicalSeoCategoryBuilderTests
{
diff --git a/services/Data/tests/Data.Tests/TestHttpHandler.cs b/services/CoreService/tests/CoreService.Tests/TestHttpHandler.cs
similarity index 96%
rename from services/Data/tests/Data.Tests/TestHttpHandler.cs
rename to services/CoreService/tests/CoreService.Tests/TestHttpHandler.cs
index 67ded927..093e823f 100644
--- a/services/Data/tests/Data.Tests/TestHttpHandler.cs
+++ b/services/CoreService/tests/CoreService.Tests/TestHttpHandler.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Data.Tests;
+namespace CoreService.Tests;
internal sealed class TestHttpHandler(Func responder) : HttpMessageHandler
{
diff --git a/services/ReportService/tests/ReportService.Tests/TypedConfigValueCoercionTests.cs b/services/CoreService/tests/CoreService.Tests/TypedConfigValueCoercionTests.cs
similarity index 97%
rename from services/ReportService/tests/ReportService.Tests/TypedConfigValueCoercionTests.cs
rename to services/CoreService/tests/CoreService.Tests/TypedConfigValueCoercionTests.cs
index 5ca9a31d..0ce67080 100644
--- a/services/ReportService/tests/ReportService.Tests/TypedConfigValueCoercionTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/TypedConfigValueCoercionTests.cs
@@ -1,6 +1,6 @@
using WebsiteProfiling.Contracts.Config;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class TypedConfigValueCoercionTests
{
diff --git a/services/IntegrationsService/tests/IntegrationsService.Tests/UrlJoinBuilderTests.cs b/services/CoreService/tests/CoreService.Tests/UrlJoinBuilderTests.cs
similarity index 93%
rename from services/IntegrationsService/tests/IntegrationsService.Tests/UrlJoinBuilderTests.cs
rename to services/CoreService/tests/CoreService.Tests/UrlJoinBuilderTests.cs
index 843a1b55..fb6437d5 100644
--- a/services/IntegrationsService/tests/IntegrationsService.Tests/UrlJoinBuilderTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/UrlJoinBuilderTests.cs
@@ -1,8 +1,8 @@
-using IntegrationsService.Application.Google;
+using CoreService.Api.IntegrationsApplication.Google;
-namespace IntegrationsService.Tests;
+namespace CoreService.Tests;
-public sealed class UrlJoinBuilderTests
+public sealed partial class UrlJoinBuilderTests
{
[Theory]
[InlineData("https://WWW.Example.com/page/", "example.com/page/")]
diff --git a/services/ReportService/tests/ReportService.Tests/UrlNormalizeHelperTests.cs b/services/CoreService/tests/CoreService.Tests/UrlNormalizeHelperTests.cs
similarity index 87%
rename from services/ReportService/tests/ReportService.Tests/UrlNormalizeHelperTests.cs
rename to services/CoreService/tests/CoreService.Tests/UrlNormalizeHelperTests.cs
index b8988f8d..2388b864 100644
--- a/services/ReportService/tests/ReportService.Tests/UrlNormalizeHelperTests.cs
+++ b/services/CoreService/tests/CoreService.Tests/UrlNormalizeHelperTests.cs
@@ -1,6 +1,6 @@
-using ReportService.Application.Build;
+using CoreService.Api.Application.Build;
-namespace ReportService.Tests;
+namespace CoreService.Tests;
public sealed class UrlNormalizeHelperTests
{
diff --git a/services/Data/tests/Data.Tests/fixtures/full-payload.json b/services/CoreService/tests/CoreService.Tests/fixtures/full-payload.json
similarity index 100%
rename from services/Data/tests/Data.Tests/fixtures/full-payload.json
rename to services/CoreService/tests/CoreService.Tests/fixtures/full-payload.json
diff --git a/services/Data/tests/Data.Tests/fixtures/minimal-payload.json b/services/CoreService/tests/CoreService.Tests/fixtures/minimal-payload.json
similarity index 100%
rename from services/Data/tests/Data.Tests/fixtures/minimal-payload.json
rename to services/CoreService/tests/CoreService.Tests/fixtures/minimal-payload.json
diff --git a/services/Data/.dockerignore b/services/Data/.dockerignore
deleted file mode 100644
index ab41d99e..00000000
--- a/services/Data/.dockerignore
+++ /dev/null
@@ -1,4 +0,0 @@
-**/bin/
-**/obj/
-**/.vs/
-**/TestResults/
diff --git a/services/Data/Dockerfile b/services/Data/Dockerfile
deleted file mode 100644
index b0db6a25..00000000
--- a/services/Data/Dockerfile
+++ /dev/null
@@ -1,34 +0,0 @@
-FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
-WORKDIR /src
-COPY services/Shared/WebsiteProfiling.Contracts/WebsiteProfiling.Contracts.csproj services/Shared/WebsiteProfiling.Contracts/
-COPY services/Shared/WebsiteProfiling.Data/WebsiteProfiling.Data.csproj services/Shared/WebsiteProfiling.Data/
-COPY services/Shared/WebsiteProfiling.Data.EntityFrameworkCore/WebsiteProfiling.Data.EntityFrameworkCore.csproj services/Shared/WebsiteProfiling.Data.EntityFrameworkCore/
-COPY services/Shared/WebsiteProfiling.TypedConfig/WebsiteProfiling.TypedConfig.csproj services/Shared/WebsiteProfiling.TypedConfig/
-COPY services/Shared/WebsiteProfiling.Hosting/WebsiteProfiling.Hosting.csproj services/Shared/WebsiteProfiling.Hosting/
-COPY services/Data/src/Data.Domain/Data.Domain.csproj services/Data/src/Data.Domain/
-COPY services/Data/src/Data.Rendering/Data.Rendering.csproj services/Data/src/Data.Rendering/
-COPY services/Data/src/Data.Application/Data.Application.csproj services/Data/src/Data.Application/
-COPY services/Data/src/Data.Api/Data.Api.csproj services/Data/src/Data.Api/
-RUN dotnet restore services/Data/src/Data.Api/Data.Api.csproj
-COPY services/Shared/WebsiteProfiling.Contracts/ services/Shared/WebsiteProfiling.Contracts/
-COPY services/Shared/WebsiteProfiling.Data/ services/Shared/WebsiteProfiling.Data/
-COPY services/Shared/WebsiteProfiling.Data.EntityFrameworkCore/ services/Shared/WebsiteProfiling.Data.EntityFrameworkCore/
-COPY services/Shared/WebsiteProfiling.TypedConfig/ services/Shared/WebsiteProfiling.TypedConfig/
-COPY services/Shared/WebsiteProfiling.Hosting/ services/Shared/WebsiteProfiling.Hosting/
-COPY config/typed_config_manifest.json config/typed_config_manifest.json
-COPY services/Data/src/ services/Data/src/
-RUN dotnet publish services/Data/src/Data.Api/Data.Api.csproj -c Release -o /app/publish --no-restore
-
-FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
-WORKDIR /app
-# curl is used by the compose healthcheck; libgssapi-krb5-2 silences Npgsql's harmless
-# GSSAPI probe warning on connect. Neither ships in the aspnet image.
-RUN apt-get update \
- && apt-get install -y --no-install-recommends curl libgssapi-krb5-2 \
- && rm -rf /var/lib/apt/lists/*
-ENV ASPNETCORE_URLS=http://+:8091
-ENV WEBSITE_PROFILING_ROOT=/app
-EXPOSE 8091
-COPY --from=build /app/publish .
-COPY --from=build /src/config/typed_config_manifest.json /app/config/typed_config_manifest.json
-ENTRYPOINT ["dotnet", "Data.Api.dll"]
diff --git a/services/Data/src/Data.Api/Data.Api.csproj b/services/Data/src/Data.Api/Data.Api.csproj
deleted file mode 100644
index 9883a00a..00000000
--- a/services/Data/src/Data.Api/Data.Api.csproj
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- net10.0
- enable
- enable
-
-
-
diff --git a/services/Data/src/Data.Api/Program.cs b/services/Data/src/Data.Api/Program.cs
deleted file mode 100644
index 19f4bc2c..00000000
--- a/services/Data/src/Data.Api/Program.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using Data.Application;
-using WebsiteProfiling.Hosting;
-
-var builder = WebApplication.CreateBuilder(args);
-
-builder.AddWebsiteProfilingWebDefaults(
- "Website Profiling Data API",
- "Internal data service for reports, portfolio, issues, filters, typed config "
- + "(pipeline settings, UI preferences, client preferences), and PDF/Excel/CSV/JSON/sitemap "
- + "report export. Reads Postgres directly and incrementally replaces FastAPI endpoints. "
- + "Reached only by the BFF (not browser-facing).");
-
-builder.Services.AddDataApplication();
-builder.Services.AddControllers();
-
-var app = builder.Build();
-
-app.UseWebsiteProfilingSwaggerUi("Website Profiling Data API");
-
-app.MapControllers();
-
-app.Run();
-
-public partial class Program;
diff --git a/services/Data/src/Data.Api/appsettings.Development.json b/services/Data/src/Data.Api/appsettings.Development.json
deleted file mode 100644
index 39d4c23b..00000000
--- a/services/Data/src/Data.Api/appsettings.Development.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft.EntityFrameworkCore": "Information"
- }
- }
-}
diff --git a/services/Data/src/Data.Api/appsettings.json b/services/Data/src/Data.Api/appsettings.json
deleted file mode 100644
index 9793c99a..00000000
--- a/services/Data/src/Data.Api/appsettings.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "Urls": "http://+:8091",
- "Database": {
- "ConnectionString": "",
- "MinPoolSize": 2,
- "MaxPoolSize": 20,
- "CommandTimeoutSeconds": 30
- },
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft.AspNetCore": "Warning",
- "Microsoft.EntityFrameworkCore": "Warning"
- }
- },
- "AllowedHosts": "*"
-}
diff --git a/services/Data/src/Data.Application/Data.Application.csproj b/services/Data/src/Data.Application/Data.Application.csproj
deleted file mode 100644
index f410b545..00000000
--- a/services/Data/src/Data.Application/Data.Application.csproj
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- net10.0
- enable
- enable
-
-
-
-
-
-
-
-
-
-
-
diff --git a/services/Data/src/Data.Domain/Data.Domain.csproj b/services/Data/src/Data.Domain/Data.Domain.csproj
deleted file mode 100644
index 6c428d14..00000000
--- a/services/Data/src/Data.Domain/Data.Domain.csproj
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
- net10.0
- enable
- enable
-
-
-
diff --git a/services/Data/src/Data.Rendering/Data.Rendering.csproj b/services/Data/src/Data.Rendering/Data.Rendering.csproj
deleted file mode 100644
index dc106a46..00000000
--- a/services/Data/src/Data.Rendering/Data.Rendering.csproj
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- net10.0
- enable
- enable
-
-
-
diff --git a/services/Data/tests/Data.Tests/Data.Tests.csproj b/services/Data/tests/Data.Tests/Data.Tests.csproj
deleted file mode 100644
index c82391a1..00000000
--- a/services/Data/tests/Data.Tests/Data.Tests.csproj
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
- net10.0
- enable
- enable
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
-
-
diff --git a/services/IntegrationsService/.dockerignore b/services/IntegrationsService/.dockerignore
deleted file mode 100644
index 9d7417a8..00000000
--- a/services/IntegrationsService/.dockerignore
+++ /dev/null
@@ -1,6 +0,0 @@
-**/bin/
-**/obj/
-**/.vs/
-**/*.user
-**/*.suo
-tests/
diff --git a/services/IntegrationsService/Dockerfile b/services/IntegrationsService/Dockerfile
deleted file mode 100644
index 8ebf785a..00000000
--- a/services/IntegrationsService/Dockerfile
+++ /dev/null
@@ -1,29 +0,0 @@
-FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
-WORKDIR /src
-COPY Shared/WebsiteProfiling.Contracts/WebsiteProfiling.Contracts.csproj Shared/WebsiteProfiling.Contracts/
-COPY Shared/WebsiteProfiling.Hosting/WebsiteProfiling.Hosting.csproj Shared/WebsiteProfiling.Hosting/
-COPY Shared/WebsiteProfiling.Data/WebsiteProfiling.Data.csproj Shared/WebsiteProfiling.Data/
-COPY Shared/WebsiteProfiling.Data.EntityFrameworkCore/WebsiteProfiling.Data.EntityFrameworkCore.csproj Shared/WebsiteProfiling.Data.EntityFrameworkCore/
-COPY IntegrationsService/src/IntegrationsService.Domain/IntegrationsService.Domain.csproj IntegrationsService/src/IntegrationsService.Domain/
-COPY IntegrationsService/src/IntegrationsService.Application/IntegrationsService.Application.csproj IntegrationsService/src/IntegrationsService.Application/
-COPY IntegrationsService/src/IntegrationsService.Providers/IntegrationsService.Providers.csproj IntegrationsService/src/IntegrationsService.Providers/
-COPY IntegrationsService/src/IntegrationsService.Api/IntegrationsService.Api.csproj IntegrationsService/src/IntegrationsService.Api/
-RUN dotnet restore IntegrationsService/src/IntegrationsService.Api/IntegrationsService.Api.csproj
-COPY Shared/WebsiteProfiling.Contracts/ Shared/WebsiteProfiling.Contracts/
-COPY Shared/WebsiteProfiling.Hosting/ Shared/WebsiteProfiling.Hosting/
-COPY Shared/WebsiteProfiling.Data/ Shared/WebsiteProfiling.Data/
-COPY Shared/WebsiteProfiling.Data.EntityFrameworkCore/ Shared/WebsiteProfiling.Data.EntityFrameworkCore/
-COPY IntegrationsService/src/ IntegrationsService/src/
-RUN dotnet publish IntegrationsService/src/IntegrationsService.Api/IntegrationsService.Api.csproj -c Release -o /app/publish --no-restore
-
-FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
-WORKDIR /app
-# curl is used by the compose healthcheck; libgssapi-krb5-2 silences Npgsql's harmless
-# GSSAPI probe warning on connect. Neither ships in the aspnet image.
-RUN apt-get update \
- && apt-get install -y --no-install-recommends curl libgssapi-krb5-2 \
- && rm -rf /var/lib/apt/lists/*
-ENV ASPNETCORE_URLS=http://+:8093
-EXPOSE 8093
-COPY --from=build /app/publish .
-ENTRYPOINT ["dotnet", "IntegrationsService.Api.dll"]
diff --git a/services/IntegrationsService/README.md b/services/IntegrationsService/README.md
deleted file mode 100644
index 59fa6485..00000000
--- a/services/IntegrationsService/README.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# IntegrationsService
-
-Internal .NET microservice for Google Search Console, GA4, Bing sync, and keyword enrichment.
-
-- **Port:** 8093 (`INTEGRATIONS_SERVICE_URL`)
-- **Stack:** ASP.NET Core 10, EF Core + Npgsql (Postgres), Google API client libraries
-- **Consumers:** BFF (browser-facing `/api/*` proxy), Python worker/CLI via `INTEGRATIONS_SERVICE_URL`
-
-## Run locally
-
-```bash
-cd services/IntegrationsService
-DATABASE_URL=postgres://profiling:profiling@127.0.0.1:5432/website_profiling \
- FASTAPI_URL=http://127.0.0.1:8096 \
- USE_FASTAPI_PYTHON_BRIDGE=1 \
- ASPNETCORE_URLS=http://127.0.0.1:8093 \
- dotnet run --project src/IntegrationsService.Api --no-launch-profile
-```
-
-Or use `./local-run` / `./local-prod` from the repo root (starts IntegrationsService on 8093 when `dotnet` is available).
-
-In **Development**, Swagger UI is at **http://localhost:8093/docs** (OpenAPI JSON at `/swagger/v1/swagger.json`).
-
-## Environment
-
-| Variable | Purpose |
-|----------|---------|
-| `DATABASE_URL` | Postgres (property credentials, `google_data`) |
-| `FASTAPI_URL` | Python bridge for keyword enrich + GSC link import when `USE_FASTAPI_PYTHON_BRIDGE=1` |
-| `USE_FASTAPI_PYTHON_BRIDGE` | `1` in Docker/local prod — IntegrationsService image has no Python |
-| `AUTH_SECRET` | Required when `ASPNETCORE_ENVIRONMENT=Production` (OAuth state signing) |
-| `GOOGLE_REDIRECT_URI` | OAuth callback (default dev: `http://localhost:8090/api/integrations/google/callback`) |
-| `APP_PUBLIC_URL` | Post-login redirect base (default dev: `http://localhost:3000`) |
-
-## Endpoints
-
-| Route | Purpose |
-|-------|---------|
-| `GET /health` | Health check |
-| `POST /internal/integrations/google/fetch` | Worker fetch (stores `google_data`) |
-| `POST /internal/integrations/keywords/enrich` | Pipeline keyword enrichment |
-| `GET /internal/integrations/report/enrichment?propertyId=` | Report build: latest Google/keyword/GSC links snapshots |
-| `GET/POST /api/properties/{id}/google/*` | Property Google config, credentials, test, disconnect |
-| `GET/POST /api/integrations/google/*` | OAuth auth/callback, status, page-data, page-live, url-inspection, keywords |
-| `POST /api/integrations/bing/sync` | Bing Webmaster sync |
-
-BFF routes Google/Bing traffic via `INTEGRATIONS_ROUTES` (see `services/Bff/`). Property `/google/*` paths are auto-proxied when `INTEGRATIONS_SERVICE_URL` is set.
-
-Swagger UI: `/docs` (Development only).
-
-## Tests
-
-```bash
-# From repo root — all .NET services:
-dotnet test services/WebsiteProfiling.slnx
-
-# Or from services/:
-cd services && dotnet test WebsiteProfiling.slnx
-
-# This service only:
-dotnet test services/IntegrationsService/tests/IntegrationsService.Tests/IntegrationsService.Tests.csproj
-```
-
-## Docker
-
-Included in `docker-compose.yml`, `docker-compose.prod.yml`, and `docker-compose.pull.yml`. FastAPI runs with `DEPRECATE_PYTHON_INTEGRATIONS=1`; worker uses `INTEGRATIONS_SERVICE_URL=http://integrations:8093`.
diff --git a/services/IntegrationsService/src/IntegrationsService.Api/Controllers/HealthController.cs b/services/IntegrationsService/src/IntegrationsService.Api/Controllers/HealthController.cs
deleted file mode 100644
index 4a084985..00000000
--- a/services/IntegrationsService/src/IntegrationsService.Api/Controllers/HealthController.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Microsoft.AspNetCore.Mvc;
-
-namespace IntegrationsService.Api.Controllers;
-
-[ApiController]
-[Route("")]
-[Tags("Health")]
-public sealed class HealthController : ControllerBase
-{
- [HttpGet("health")]
- [ProducesResponseType(StatusCodes.Status200OK)]
- public IActionResult Get() => Ok(new { status = "ok" });
-}
diff --git a/services/IntegrationsService/src/IntegrationsService.Api/IntegrationsService.Api.csproj b/services/IntegrationsService/src/IntegrationsService.Api/IntegrationsService.Api.csproj
deleted file mode 100644
index 56c3d299..00000000
--- a/services/IntegrationsService/src/IntegrationsService.Api/IntegrationsService.Api.csproj
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
- net10.0
- enable
- enable
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/services/IntegrationsService/src/IntegrationsService.Api/IntegrationsService.Api.http b/services/IntegrationsService/src/IntegrationsService.Api/IntegrationsService.Api.http
deleted file mode 100644
index f25238a6..00000000
--- a/services/IntegrationsService/src/IntegrationsService.Api/IntegrationsService.Api.http
+++ /dev/null
@@ -1,6 +0,0 @@
-@IntegrationsService.Api_HostAddress = http://localhost:5200
-
-GET {{IntegrationsService.Api_HostAddress}}/weatherforecast/
-Accept: application/json
-
-###
diff --git a/services/IntegrationsService/src/IntegrationsService.Api/Program.cs b/services/IntegrationsService/src/IntegrationsService.Api/Program.cs
deleted file mode 100644
index 4fdf064b..00000000
--- a/services/IntegrationsService/src/IntegrationsService.Api/Program.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using IntegrationsService.Application;
-using IntegrationsService.Providers;
-using WebsiteProfiling.Hosting;
-
-var builder = WebApplication.CreateBuilder(args);
-
-builder.AddWebsiteProfilingWebDefaults(
- "Website Profiling Integrations API",
- "Internal Google integrations service (GSC/GA4 fetch, property OAuth state). "
- + "Reached by the BFF and worker via INTEGRATIONS_SERVICE_URL.");
-
-builder.Services.AddIntegrationsApplication();
-builder.Services.AddGoogleProviders();
-builder.Services.AddControllers();
-
-var app = builder.Build();
-
-app.UseWebsiteProfilingSwaggerUi("Website Profiling Integrations API");
-
-app.MapControllers();
-
-app.Run();
-
-public partial class Program;
diff --git a/services/IntegrationsService/src/IntegrationsService.Api/Properties/launchSettings.json b/services/IntegrationsService/src/IntegrationsService.Api/Properties/launchSettings.json
deleted file mode 100644
index e7dbbc0f..00000000
--- a/services/IntegrationsService/src/IntegrationsService.Api/Properties/launchSettings.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "$schema": "https://json.schemastore.org/launchsettings.json",
- "profiles": {
- "http": {
- "commandName": "Project",
- "dotnetRunMessages": true,
- "launchBrowser": false,
- "applicationUrl": "http://localhost:5200",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- },
- "https": {
- "commandName": "Project",
- "dotnetRunMessages": true,
- "launchBrowser": false,
- "applicationUrl": "https://localhost:7247;http://localhost:5200",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- }
- }
-}
diff --git a/services/IntegrationsService/src/IntegrationsService.Api/appsettings.Development.json b/services/IntegrationsService/src/IntegrationsService.Api/appsettings.Development.json
deleted file mode 100644
index ff66ba6b..00000000
--- a/services/IntegrationsService/src/IntegrationsService.Api/appsettings.Development.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft.AspNetCore": "Warning"
- }
- }
-}
diff --git a/services/IntegrationsService/src/IntegrationsService.Api/appsettings.json b/services/IntegrationsService/src/IntegrationsService.Api/appsettings.json
deleted file mode 100644
index ab22b878..00000000
--- a/services/IntegrationsService/src/IntegrationsService.Api/appsettings.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "Database": {
- "ConnectionString": "",
- "MinPoolSize": 2,
- "MaxPoolSize": 20,
- "CommandTimeoutSeconds": 120
- },
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft.AspNetCore": "Warning"
- }
- },
- "AllowedHosts": "*"
-}
diff --git a/services/IntegrationsService/src/IntegrationsService.Application/IntegrationsService.Application.csproj b/services/IntegrationsService/src/IntegrationsService.Application/IntegrationsService.Application.csproj
deleted file mode 100644
index 90b43f20..00000000
--- a/services/IntegrationsService/src/IntegrationsService.Application/IntegrationsService.Application.csproj
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
- net10.0
- enable
- enable
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/services/IntegrationsService/src/IntegrationsService.Domain/IntegrationsService.Domain.csproj b/services/IntegrationsService/src/IntegrationsService.Domain/IntegrationsService.Domain.csproj
deleted file mode 100644
index b7601447..00000000
--- a/services/IntegrationsService/src/IntegrationsService.Domain/IntegrationsService.Domain.csproj
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- net10.0
- enable
- enable
-
-
-
diff --git a/services/IntegrationsService/src/IntegrationsService.Providers/IntegrationsService.Providers.csproj b/services/IntegrationsService/src/IntegrationsService.Providers/IntegrationsService.Providers.csproj
deleted file mode 100644
index fd91cb72..00000000
--- a/services/IntegrationsService/src/IntegrationsService.Providers/IntegrationsService.Providers.csproj
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
- net10.0
- enable
- enable
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/services/IntegrationsService/tests/IntegrationsService.Tests/IntegrationsService.Tests.csproj b/services/IntegrationsService/tests/IntegrationsService.Tests/IntegrationsService.Tests.csproj
deleted file mode 100644
index d80e2313..00000000
--- a/services/IntegrationsService/tests/IntegrationsService.Tests/IntegrationsService.Tests.csproj
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
- net10.0
- enable
- enable
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/services/ReportService/Dockerfile b/services/ReportService/Dockerfile
deleted file mode 100644
index 5fbd0ca5..00000000
--- a/services/ReportService/Dockerfile
+++ /dev/null
@@ -1,31 +0,0 @@
-FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
-WORKDIR /src
-COPY services/Shared/WebsiteProfiling.Hosting/WebsiteProfiling.Hosting.csproj services/Shared/WebsiteProfiling.Hosting/
-COPY services/Shared/WebsiteProfiling.Contracts/WebsiteProfiling.Contracts.csproj services/Shared/WebsiteProfiling.Contracts/
-COPY services/Shared/WebsiteProfiling.Data/WebsiteProfiling.Data.csproj services/Shared/WebsiteProfiling.Data/
-COPY services/Shared/WebsiteProfiling.Data.EntityFrameworkCore/WebsiteProfiling.Data.EntityFrameworkCore.csproj services/Shared/WebsiteProfiling.Data.EntityFrameworkCore/
-COPY services/Shared/WebsiteProfiling.TypedConfig/WebsiteProfiling.TypedConfig.csproj services/Shared/WebsiteProfiling.TypedConfig/
-COPY services/ReportService/src/ReportService.Domain/ReportService.Domain.csproj services/ReportService/src/ReportService.Domain/
-COPY services/ReportService/src/ReportService.Application/ReportService.Application.csproj services/ReportService/src/ReportService.Application/
-COPY services/ReportService/src/ReportService.Api/ReportService.Api.csproj services/ReportService/src/ReportService.Api/
-RUN dotnet restore services/ReportService/src/ReportService.Api/ReportService.Api.csproj
-COPY services/Shared/WebsiteProfiling.Hosting/ services/Shared/WebsiteProfiling.Hosting/
-COPY services/Shared/WebsiteProfiling.Contracts/ services/Shared/WebsiteProfiling.Contracts/
-COPY services/Shared/WebsiteProfiling.Data/ services/Shared/WebsiteProfiling.Data/
-COPY services/Shared/WebsiteProfiling.Data.EntityFrameworkCore/ services/Shared/WebsiteProfiling.Data.EntityFrameworkCore/
-COPY services/Shared/WebsiteProfiling.TypedConfig/ services/Shared/WebsiteProfiling.TypedConfig/
-COPY config/typed_config_manifest.json config/typed_config_manifest.json
-COPY services/ReportService/src/ services/ReportService/src/
-RUN dotnet publish services/ReportService/src/ReportService.Api/ReportService.Api.csproj -c Release -o /app/publish --no-restore
-
-FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
-WORKDIR /app
-# curl is used by the compose healthcheck; libgssapi-krb5-2 silences Npgsql's harmless
-# GSSAPI probe warning on connect. Neither ships in the aspnet image.
-RUN apt-get update \
- && apt-get install -y --no-install-recommends curl libgssapi-krb5-2 \
- && rm -rf /var/lib/apt/lists/*
-ENV ASPNETCORE_URLS=http://+:8094
-EXPOSE 8094
-COPY --from=build /app/publish .
-ENTRYPOINT ["dotnet", "ReportService.Api.dll"]
diff --git a/services/ReportService/README.md b/services/ReportService/README.md
deleted file mode 100644
index 8a97fe79..00000000
--- a/services/ReportService/README.md
+++ /dev/null
@@ -1,72 +0,0 @@
-# ReportService
-
-Internal .NET microservice for **report payload build**, **pipeline job orchestration**, and **C# worker loop**.
-
-- **Port:** 8094 (`REPORT_SERVICE_URL`)
-- **Stack:** ASP.NET Core 10, Npgsql, FuzzySharp, LanguageIdentification
-- **Consumers:** BFF (pipeline jobs, dashboards, compare, crawl UI helpers)
-
-## Run locally
-
-```bash
-cd services/ReportService
-DATABASE_URL=postgres://profiling:profiling@127.0.0.1:5432/website_profiling \
- INTEGRATIONS_SERVICE_URL=http://127.0.0.1:8093 \
- WEBSITE_PROFILING_ROOT=/path/to/repo \
- PYTHON=/path/to/.venv/bin/python \
- REPORT_SERVICE_USE_PYTHON_BRIDGE=0 \
- REPORT_SERVICE_VALIDATE_NATIVE=1 \
- ASPNETCORE_URLS=http://127.0.0.1:8094 \
- dotnet run --project src/ReportService.Api --no-launch-profile
-```
-
-Or use `./local-run` from the repo root (starts ReportService with native build and embedded C# worker).
-
-In **Development**, Swagger UI is at **http://localhost:8094/docs** (OpenAPI JSON at `/swagger/v1/swagger.json`).
-
-## Environment
-
-| Variable | Purpose |
-|----------|---------|
-| `DATABASE_URL` | Postgres (crawl rows, edges, lighthouse summaries, report metadata, pipeline_jobs) |
-| `INTEGRATIONS_SERVICE_URL` | Google/keyword/GSC links snapshots for native build |
-| `REPORT_SERVICE_USE_PYTHON_BRIDGE` | `0` (default) native C# build; `1` delegates to removed Python bridge |
-| `REPORT_SERVICE_VALIDATE_NATIVE` | `1` in local dev — parity warnings when bridge mode is enabled |
-| `REPORT_SERVICE_WORKER_ENABLED` | `1` (default) runs embedded pipeline worker BackgroundService |
-| `WEBSITE_PROFILING_ROOT` / `PYTHON` | Repo root and Python executable for crawl/lighthouse subprocesses |
-| `FASTAPI_URL` | Optional — only needed if `REPORT_SERVICE_USE_PYTHON_BRIDGE=1` (legacy) |
-
-## Architecture
-
-The **C# worker** polls `pipeline_jobs`, spawns `python -m src crawl|lighthouse` subprocesses, and runs report build in-process via `NativeReportBuilder`.
-
-Browser-facing routes on this service (via BFF `REPORT_ROUTES`):
-
-| Route | Purpose |
-|-------|---------|
-| `POST /api/run`, `GET /api/jobs/*` | Pipeline job API |
-| `GET/POST/PUT/DELETE /api/dashboards/*` | Dashboard CRUD (native) |
-| `POST /api/compare/export` | Compare CSV export (native) |
-| `GET /api/crawl/*` | Browser status + stored page HTML |
-| `POST /api/schedule/check` | Scheduled crawl check stub |
-| `POST /internal/report/build` | Report payload build (native) |
-| `POST /internal/pipeline/run` | Full-audit orchestration |
-
-## Key paths
-
-```
-src/ReportService.Application/Build/
- NativeReportBuilder.cs, LocalEnrichmentBuilder.cs
- SiteLevelBuilder.cs, ContactIntelligenceBuilder.cs, ImageInventoryBuilder.cs
-src/ReportService.Application/Pipeline/
- PipelineWorkerBackgroundService.cs, PipelineJobRunner.cs
-```
-
-## Tests
-
-```bash
-dotnet test services/ReportService/tests/ReportService.Tests/ReportService.Tests.csproj
-dotnet test services/WebsiteProfiling.slnx
-```
-
-Included in `./local-test` and CI.
diff --git a/services/ReportService/src/ReportService.Api/Controllers/HealthController.cs b/services/ReportService/src/ReportService.Api/Controllers/HealthController.cs
deleted file mode 100644
index 2291091d..00000000
--- a/services/ReportService/src/ReportService.Api/Controllers/HealthController.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Microsoft.AspNetCore.Mvc;
-
-namespace ReportService.Api.Controllers;
-
-[ApiController]
-[Route("health")]
-public sealed class HealthController : ControllerBase
-{
- [HttpGet]
- public IActionResult Get() => Ok(new { status = "ok", service = "report" });
-}
diff --git a/services/ReportService/src/ReportService.Api/Program.cs b/services/ReportService/src/ReportService.Api/Program.cs
deleted file mode 100644
index 98db8021..00000000
--- a/services/ReportService/src/ReportService.Api/Program.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using ReportService.Application;
-using WebsiteProfiling.Hosting;
-
-var builder = WebApplication.CreateBuilder(args);
-
-builder.AddWebsiteProfilingWebDefaults(
- "Website Profiling Report API",
- "Internal report build and pipeline orchestration service. "
- + "Reached by the worker and BFF via REPORT_SERVICE_URL.");
-
-builder.Services.AddReportApplication();
-builder.Services.AddControllers();
-
-var app = builder.Build();
-
-app.UseWebsiteProfilingSwaggerUi("Website Profiling Report API");
-
-app.MapControllers();
-
-app.Run();
-
-public partial class Program;
diff --git a/services/ReportService/src/ReportService.Api/ReportService.Api.csproj b/services/ReportService/src/ReportService.Api/ReportService.Api.csproj
deleted file mode 100644
index a7878a6f..00000000
--- a/services/ReportService/src/ReportService.Api/ReportService.Api.csproj
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- net10.0
- enable
- enable
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/services/ReportService/src/ReportService.Application/ReportService.Application.csproj b/services/ReportService/src/ReportService.Application/ReportService.Application.csproj
deleted file mode 100644
index 256ea4c0..00000000
--- a/services/ReportService/src/ReportService.Application/ReportService.Application.csproj
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
- net10.0
- enable
- enable
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/services/ReportService/src/ReportService.Domain/ReportService.Domain.csproj b/services/ReportService/src/ReportService.Domain/ReportService.Domain.csproj
deleted file mode 100644
index 9ed914b5..00000000
--- a/services/ReportService/src/ReportService.Domain/ReportService.Domain.csproj
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- net10.0
- enable
- enable
-
-
-
diff --git a/services/ReportService/tests/ReportService.Tests/AssemblyInfo.cs b/services/ReportService/tests/ReportService.Tests/AssemblyInfo.cs
deleted file mode 100644
index 21712008..00000000
--- a/services/ReportService/tests/ReportService.Tests/AssemblyInfo.cs
+++ /dev/null
@@ -1,3 +0,0 @@
-using Xunit;
-
-[assembly: CollectionBehavior(DisableTestParallelization = true)]
diff --git a/services/Schema/Dockerfile b/services/Schema/Dockerfile
index 09adb02a..6407f9f2 100644
--- a/services/Schema/Dockerfile
+++ b/services/Schema/Dockerfile
@@ -1,10 +1,10 @@
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
-COPY Shared/WebsiteProfiling.Data/WebsiteProfiling.Data.csproj Shared/WebsiteProfiling.Data/
+COPY Shared/WebsiteProfiling.Shared/WebsiteProfiling.Shared.csproj Shared/WebsiteProfiling.Shared/
COPY Schema/src/Schema.Model/Schema.Model.csproj Schema/src/Schema.Model/
COPY Schema/src/Schema.Migrator/Schema.Migrator.csproj Schema/src/Schema.Migrator/
RUN dotnet restore Schema/src/Schema.Migrator/Schema.Migrator.csproj
-COPY Shared/WebsiteProfiling.Data/ Shared/WebsiteProfiling.Data/
+COPY Shared/WebsiteProfiling.Shared/ Shared/WebsiteProfiling.Shared/
COPY Schema/src/ Schema/src/
RUN dotnet publish Schema/src/Schema.Migrator/Schema.Migrator.csproj -c Release -o /app/publish --no-restore
diff --git a/services/Schema/src/Schema.Migrator/Schema.Migrator.csproj b/services/Schema/src/Schema.Migrator/Schema.Migrator.csproj
index f5d1c0b0..30b06509 100644
--- a/services/Schema/src/Schema.Migrator/Schema.Migrator.csproj
+++ b/services/Schema/src/Schema.Migrator/Schema.Migrator.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/services/Schema/src/Schema.Model/Schema.Model.csproj b/services/Schema/src/Schema.Model/Schema.Model.csproj
index 72dcc7db..65fc9a8f 100644
--- a/services/Schema/src/Schema.Model/Schema.Model.csproj
+++ b/services/Schema/src/Schema.Model/Schema.Model.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/services/Shared/TYPED_MODELS.md b/services/Shared/TYPED_MODELS.md
index 0e617a54..b3b4c8c2 100644
--- a/services/Shared/TYPED_MODELS.md
+++ b/services/Shared/TYPED_MODELS.md
@@ -1,6 +1,6 @@
# Typed models conventions (.NET services)
-Shared contracts live in `services/Shared/WebsiteProfiling.Contracts/`.
+Shared contracts live in `services/Shared/WebsiteProfiling.Shared/Contracts/`.
## Rules
@@ -14,9 +14,8 @@ Shared contracts live in `services/Shared/WebsiteProfiling.Contracts/`.
| Service | Mapper location |
|---------|-----------------|
-| AiService tools | `AiService.Tools/Mapping/` |
-| Data | `Data.Application/Mapping/` (`PayloadSliceMapper`, `AuditReportMapper`, `ChapterMappers` — the latter two absorbed from the former FileService) |
-| IntegrationsService | `IntegrationsService.Application/Google/PageLookupMapper.cs` |
+| AiService | `src/AiService.Api/Tools/Mapping/` |
+| CoreService | `src/CoreService.Api/DataApplication/Mapping/` (`PayloadSliceMapper`, `AuditReportMapper`, `ChapterMappers`), `src/CoreService.Api/IntegrationsApplication/Google/PageLookupMapper.cs` |
## Coercion
diff --git a/services/Shared/WebsiteProfiling.Contracts.Tests/WebsiteProfiling.Contracts.Tests.csproj b/services/Shared/WebsiteProfiling.Contracts.Tests/WebsiteProfiling.Contracts.Tests.csproj
deleted file mode 100644
index 55ac6122..00000000
--- a/services/Shared/WebsiteProfiling.Contracts.Tests/WebsiteProfiling.Contracts.Tests.csproj
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
- net10.0
- enable
- enable
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/services/Shared/WebsiteProfiling.Contracts/WebsiteProfiling.Contracts.csproj b/services/Shared/WebsiteProfiling.Contracts/WebsiteProfiling.Contracts.csproj
deleted file mode 100644
index 51404264..00000000
--- a/services/Shared/WebsiteProfiling.Contracts/WebsiteProfiling.Contracts.csproj
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
- net10.0
- enable
- enable
- WebsiteProfiling.Contracts
-
-
-
diff --git a/services/Shared/WebsiteProfiling.Data.EntityFrameworkCore/WebsiteProfiling.Data.EntityFrameworkCore.csproj b/services/Shared/WebsiteProfiling.Data.EntityFrameworkCore/WebsiteProfiling.Data.EntityFrameworkCore.csproj
deleted file mode 100644
index 1d15e68f..00000000
--- a/services/Shared/WebsiteProfiling.Data.EntityFrameworkCore/WebsiteProfiling.Data.EntityFrameworkCore.csproj
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
- net10.0
- enable
- enable
- WebsiteProfiling.Data.EntityFrameworkCore
-
-
-
-
-
-
-
-
-
-
-
diff --git a/services/Shared/WebsiteProfiling.Data/WebsiteProfiling.Data.csproj b/services/Shared/WebsiteProfiling.Data/WebsiteProfiling.Data.csproj
deleted file mode 100644
index d8c9af60..00000000
--- a/services/Shared/WebsiteProfiling.Data/WebsiteProfiling.Data.csproj
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
- net10.0
- enable
- enable
- WebsiteProfiling.Data
-
-
-
-
-
-
-
-
-
diff --git a/services/Shared/WebsiteProfiling.Data.Tests/NpgsqlDsnTests.cs b/services/Shared/WebsiteProfiling.Shared.Tests/NpgsqlDsnTests.cs
similarity index 98%
rename from services/Shared/WebsiteProfiling.Data.Tests/NpgsqlDsnTests.cs
rename to services/Shared/WebsiteProfiling.Shared.Tests/NpgsqlDsnTests.cs
index ed12c03e..2ed3ac9e 100644
--- a/services/Shared/WebsiteProfiling.Data.Tests/NpgsqlDsnTests.cs
+++ b/services/Shared/WebsiteProfiling.Shared.Tests/NpgsqlDsnTests.cs
@@ -1,7 +1,7 @@
using Npgsql;
using WebsiteProfiling.Data;
-namespace WebsiteProfiling.Data.Tests;
+namespace WebsiteProfiling.Shared.Tests;
public class NpgsqlDsnTests
{
diff --git a/services/Shared/WebsiteProfiling.Contracts.Tests/PropertyDomainHelperTests.cs b/services/Shared/WebsiteProfiling.Shared.Tests/PropertyDomainHelperTests.cs
similarity index 98%
rename from services/Shared/WebsiteProfiling.Contracts.Tests/PropertyDomainHelperTests.cs
rename to services/Shared/WebsiteProfiling.Shared.Tests/PropertyDomainHelperTests.cs
index 206491ae..4a91bf12 100644
--- a/services/Shared/WebsiteProfiling.Contracts.Tests/PropertyDomainHelperTests.cs
+++ b/services/Shared/WebsiteProfiling.Shared.Tests/PropertyDomainHelperTests.cs
@@ -1,6 +1,6 @@
using WebsiteProfiling.Contracts.Properties;
-namespace WebsiteProfiling.Contracts.Tests;
+namespace WebsiteProfiling.Shared.Tests;
public class PropertyDomainHelperTests
{
diff --git a/services/Shared/WebsiteProfiling.Data.Tests/WebsiteProfiling.Data.Tests.csproj b/services/Shared/WebsiteProfiling.Shared.Tests/WebsiteProfiling.Shared.Tests.csproj
similarity index 87%
rename from services/Shared/WebsiteProfiling.Data.Tests/WebsiteProfiling.Data.Tests.csproj
rename to services/Shared/WebsiteProfiling.Shared.Tests/WebsiteProfiling.Shared.Tests.csproj
index c450b323..b4f3cc9f 100644
--- a/services/Shared/WebsiteProfiling.Data.Tests/WebsiteProfiling.Data.Tests.csproj
+++ b/services/Shared/WebsiteProfiling.Shared.Tests/WebsiteProfiling.Shared.Tests.csproj
@@ -19,7 +19,7 @@
-
+
diff --git a/services/Shared/WebsiteProfiling.Contracts/Chat/PersistedToolResultDto.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Chat/PersistedToolResultDto.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Chat/PersistedToolResultDto.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Chat/PersistedToolResultDto.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Config/ApiErrorBodies.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Config/ApiErrorBodies.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Config/ApiErrorBodies.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Config/ApiErrorBodies.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Config/TypedConfigValueCoercion.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Config/TypedConfigValueCoercion.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Config/TypedConfigValueCoercion.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Config/TypedConfigValueCoercion.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Crawl/CrawlRow.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Crawl/CrawlRow.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Crawl/CrawlRow.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Crawl/CrawlRow.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Google/GoogleRecords.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Google/GoogleRecords.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Google/GoogleRecords.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Google/GoogleRecords.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Integrations/PageLookupRecords.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Integrations/PageLookupRecords.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Integrations/PageLookupRecords.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Integrations/PageLookupRecords.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Json/ContractJsonOptions.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Json/ContractJsonOptions.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Json/ContractJsonOptions.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Json/ContractJsonOptions.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Json/JsonCoercion.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Json/JsonCoercion.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Json/JsonCoercion.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Json/JsonCoercion.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Properties/PropertyDomainHelper.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Properties/PropertyDomainHelper.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Properties/PropertyDomainHelper.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Properties/PropertyDomainHelper.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Report/CategoryScoreRecord.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Report/CategoryScoreRecord.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Report/CategoryScoreRecord.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Report/CategoryScoreRecord.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Report/ContentDisposition.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Report/ContentDisposition.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Report/ContentDisposition.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Report/ContentDisposition.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Report/CrawlPreviewDto.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Report/CrawlPreviewDto.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Report/CrawlPreviewDto.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Report/CrawlPreviewDto.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Report/IssueRecord.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Report/IssueRecord.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Report/IssueRecord.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Report/IssueRecord.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Report/IssuesBucketSlice.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Report/IssuesBucketSlice.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Report/IssuesBucketSlice.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Report/IssuesBucketSlice.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Report/PdfProfiles.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Report/PdfProfiles.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Report/PdfProfiles.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Report/PdfProfiles.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Report/ReportExportFormats.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Report/ReportExportFormats.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Report/ReportExportFormats.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Report/ReportExportFormats.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Report/ReportExportRoutes.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Report/ReportExportRoutes.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Report/ReportExportRoutes.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Report/ReportExportRoutes.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Report/ReportMetaSlice.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Report/ReportMetaSlice.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Report/ReportMetaSlice.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Report/ReportMetaSlice.cs
diff --git a/services/Shared/WebsiteProfiling.Contracts/Report/SiteHealthScoreBuilder.cs b/services/Shared/WebsiteProfiling.Shared/Contracts/Report/SiteHealthScoreBuilder.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Contracts/Report/SiteHealthScoreBuilder.cs
rename to services/Shared/WebsiteProfiling.Shared/Contracts/Report/SiteHealthScoreBuilder.cs
diff --git a/services/Shared/WebsiteProfiling.Data/DatabaseOptions.cs b/services/Shared/WebsiteProfiling.Shared/Data/DatabaseOptions.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Data/DatabaseOptions.cs
rename to services/Shared/WebsiteProfiling.Shared/Data/DatabaseOptions.cs
diff --git a/services/Shared/WebsiteProfiling.Data/DatabaseServiceCollectionExtensions.cs b/services/Shared/WebsiteProfiling.Shared/Data/DatabaseServiceCollectionExtensions.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Data/DatabaseServiceCollectionExtensions.cs
rename to services/Shared/WebsiteProfiling.Shared/Data/DatabaseServiceCollectionExtensions.cs
diff --git a/services/Shared/WebsiteProfiling.Data.EntityFrameworkCore/DbContextRegistrationExtensions.cs b/services/Shared/WebsiteProfiling.Shared/Data/DbContextRegistrationExtensions.cs
similarity index 97%
rename from services/Shared/WebsiteProfiling.Data.EntityFrameworkCore/DbContextRegistrationExtensions.cs
rename to services/Shared/WebsiteProfiling.Shared/Data/DbContextRegistrationExtensions.cs
index f4426aad..ea517056 100644
--- a/services/Shared/WebsiteProfiling.Data.EntityFrameworkCore/DbContextRegistrationExtensions.cs
+++ b/services/Shared/WebsiteProfiling.Shared/Data/DbContextRegistrationExtensions.cs
@@ -3,7 +3,7 @@
using Microsoft.Extensions.Options;
using Npgsql;
-namespace WebsiteProfiling.Data.EntityFrameworkCore;
+namespace WebsiteProfiling.Data;
///
/// EF Core registration over the shared registered by
diff --git a/services/Shared/WebsiteProfiling.Data/NpgsqlDsn.cs b/services/Shared/WebsiteProfiling.Shared/Data/NpgsqlDsn.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Data/NpgsqlDsn.cs
rename to services/Shared/WebsiteProfiling.Shared/Data/NpgsqlDsn.cs
diff --git a/services/Shared/WebsiteProfiling.Hosting/WebDefaultsExtensions.cs b/services/Shared/WebsiteProfiling.Shared/Hosting/WebDefaultsExtensions.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.Hosting/WebDefaultsExtensions.cs
rename to services/Shared/WebsiteProfiling.Shared/Hosting/WebDefaultsExtensions.cs
diff --git a/services/Shared/WebsiteProfiling.TypedConfig/TypedConfigManifest.cs b/services/Shared/WebsiteProfiling.Shared/TypedConfig/TypedConfigManifest.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.TypedConfig/TypedConfigManifest.cs
rename to services/Shared/WebsiteProfiling.Shared/TypedConfig/TypedConfigManifest.cs
diff --git a/services/Shared/WebsiteProfiling.TypedConfig/TypedConfigPipelineStore.cs b/services/Shared/WebsiteProfiling.Shared/TypedConfig/TypedConfigPipelineStore.cs
similarity index 100%
rename from services/Shared/WebsiteProfiling.TypedConfig/TypedConfigPipelineStore.cs
rename to services/Shared/WebsiteProfiling.Shared/TypedConfig/TypedConfigPipelineStore.cs
diff --git a/services/Shared/WebsiteProfiling.Hosting/WebsiteProfiling.Hosting.csproj b/services/Shared/WebsiteProfiling.Shared/WebsiteProfiling.Shared.csproj
similarity index 66%
rename from services/Shared/WebsiteProfiling.Hosting/WebsiteProfiling.Hosting.csproj
rename to services/Shared/WebsiteProfiling.Shared/WebsiteProfiling.Shared.csproj
index 8598496b..e6acba89 100644
--- a/services/Shared/WebsiteProfiling.Hosting/WebsiteProfiling.Hosting.csproj
+++ b/services/Shared/WebsiteProfiling.Shared/WebsiteProfiling.Shared.csproj
@@ -4,7 +4,7 @@
net10.0
enable
enable
- WebsiteProfiling.Hosting
+ WebsiteProfiling
@@ -12,6 +12,8 @@
+
+
diff --git a/services/Shared/WebsiteProfiling.TypedConfig/WebsiteProfiling.TypedConfig.csproj b/services/Shared/WebsiteProfiling.TypedConfig/WebsiteProfiling.TypedConfig.csproj
deleted file mode 100644
index 34a58d65..00000000
--- a/services/Shared/WebsiteProfiling.TypedConfig/WebsiteProfiling.TypedConfig.csproj
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
- net10.0
- enable
- enable
- WebsiteProfiling.TypedConfig
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/services/WebsiteProfiling.slnx b/services/WebsiteProfiling.slnx
index 596361f1..972a658c 100644
--- a/services/WebsiteProfiling.slnx
+++ b/services/WebsiteProfiling.slnx
@@ -1,48 +1,20 @@
-
-
+
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/src/website_profiling/api/routers/report.py b/src/website_profiling/api/routers/report.py
index c99fb623..8d3eff1b 100644
--- a/src/website_profiling/api/routers/report.py
+++ b/src/website_profiling/api/routers/report.py
@@ -1,5 +1,5 @@
-"""Report data routers — /api/report/* — ported to the .NET Data service."""
-# All routes previously here have been moved to services/Data.
+"""Report data routers — /api/report/* — ported to .NET CoreService."""
+# All routes previously here have been moved to services/CoreService.
# This file is intentionally empty; the router is kept only to avoid import errors
# in code that references report.router until the include_router call is removed.
from fastapi import APIRouter
diff --git a/src/website_profiling/clients/file_service.py b/src/website_profiling/clients/file_service.py
index f860e4b2..30a0a61e 100644
--- a/src/website_profiling/clients/file_service.py
+++ b/src/website_profiling/clients/file_service.py
@@ -11,12 +11,12 @@
import requests
-_DEFAULT_BASE = "http://127.0.0.1:8091"
+_DEFAULT_BASE = "http://127.0.0.1:8094"
_TIMEOUT_SECONDS = 120
def _base_url() -> str:
- return (os.environ.get("DATA_SERVICE_URL") or _DEFAULT_BASE).strip().rstrip("/")
+ return (os.environ.get("CORE_SERVICE_URL") or os.environ.get("DATA_SERVICE_URL") or _DEFAULT_BASE).strip().rstrip("/")
def _get_bytes(path: str, *, params: Optional[dict[str, str]] = None) -> bytes:
diff --git a/src/website_profiling/crawl/crawler.py b/src/website_profiling/crawl/crawler.py
index 5587fc4f..f167bbea 100644
--- a/src/website_profiling/crawl/crawler.py
+++ b/src/website_profiling/crawl/crawler.py
@@ -880,54 +880,13 @@ def run_crawler(
# it via create_crawl_run. Without this, an empty link_edges_accum on a streamed
# run leaves run_id unbound at the compare_mobile_desktop check.
run_id: Optional[int] = stream_run_id
- if output_db and crawler.link_edges_accum:
+ if output_db and crawler.link_edges_accum and run_id is not None:
from ..db import db_session
from ..db.crawl_store import write_link_edges
- run_id = stream_run_id
- if run_id is None:
- with db_session() as conn:
- from ..db.crawl_store import get_latest_crawl_run_id
-
- run_id = get_latest_crawl_run_id(conn)
- if run_id is not None:
- with db_session() as conn:
- write_link_edges(conn, crawler.link_edges_accum, crawl_run_id=run_id)
- if output_db and not df.empty and stream_run_id is None:
- console_print(" Writing crawl results to DB...", flush=True)
- from ..db import backup_db_if_exists, create_crawl_run, db_session, read_historical_data, restore_historical_data, write_crawl
- from ..db.storage import ensure_crawl_tables_cleared
- historical = {}
- backup_path = None
- if not preserve_crawl_history:
- historical = read_historical_data()
- n_reports = len(historical.get("report_payload", []))
- if n_reports:
- console_print(f" Preserving {n_reports} historical report(s) from existing DB...", flush=True)
- backup_path = backup_db_if_exists()
- if backup_path:
- console_print(f" Backed up existing DB to {backup_path}", flush=True)
with db_session() as conn:
- if not preserve_crawl_history:
- ensure_crawl_tables_cleared(conn)
- if historical:
- restore_historical_data(conn, historical)
- run_id = create_crawl_run(
- conn, start_url, property_id=property_id, render_mode=render_mode,
- discovery_mode=disc_label,
- )
- write_crawl(conn, df, crawl_run_id=run_id)
- html_buffer = getattr(crawler, "_html_buffer", None) or []
- if getattr(crawler, "store_page_html", False) and html_buffer:
- from ..db.html_store import write_page_html_batch
-
- write_page_html_batch(conn, html_buffer, run_id, commit=True)
- if crawler.link_edges_accum:
- from ..db.crawl_store import write_link_edges
-
- write_link_edges(conn, crawler.link_edges_accum, crawl_run_id=run_id)
- console_print(" Crawl DB write complete.", flush=True)
- elif output_db and stream_run_id is not None:
+ write_link_edges(conn, crawler.link_edges_accum, crawl_run_id=run_id)
+ if output_db and stream_run_id is not None:
console_print(" Crawl streamed to DB during fetch.", flush=True)
# Second pass: run mobile crawl and pair the two runs via mobile_run_id FK
diff --git a/src/website_profiling/tools/audit_tools/export/export_tools.py b/src/website_profiling/tools/audit_tools/export/export_tools.py
index 396ef84c..58563919 100644
--- a/src/website_profiling/tools/audit_tools/export/export_tools.py
+++ b/src/website_profiling/tools/audit_tools/export/export_tools.py
@@ -302,7 +302,7 @@ def list_export_formats(_conn: Connection, _ctx: AuditToolContext, _args: dict[s
"Compare this report to report 38 as CSV",
],
"notes": [
- "PDF requires the Data service (DATA_SERVICE_URL; see services/Data/)",
+ "PDF requires CoreService (CORE_SERVICE_URL or DATA_SERVICE_URL; see services/CoreService/)",
"Artifacts expire after 24 hours",
"Chat UI shows download buttons after export tools run",
],
diff --git a/tests/api/test_api_integration.py b/tests/api/test_api_integration.py
index b2ade153..1ec228a7 100644
--- a/tests/api/test_api_integration.py
+++ b/tests/api/test_api_integration.py
@@ -6,9 +6,9 @@
audit-tool dispatch, and internal CLI bridges.
PostgreSQL integration coverage for migrated routes:
-- services/Data/tests/Data.Tests/PropertiesIntegrationTests.cs
-- services/Data/tests/Data.Tests/ServiceRegistrationValidationTests.cs (typed config)
-- services/ReportService/tests/ReportService.Tests/DashboardsIntegrationTests.cs
+- services/CoreService/tests/CoreService.Tests/PropertiesIntegrationTests.cs
+- services/CoreService/tests/CoreService.Tests/DataServiceRegistrationValidationTests.cs (typed config)
+- services/CoreService/tests/CoreService.Tests/DashboardsIntegrationTests.cs
"""
from __future__ import annotations
diff --git a/tests/reporting/test_reporting_gaps.py b/tests/reporting/test_reporting_gaps.py
index 4a7c1e7a..08ed93e4 100644
--- a/tests/reporting/test_reporting_gaps.py
+++ b/tests/reporting/test_reporting_gaps.py
@@ -322,3 +322,83 @@ def test_amp_canonical_mismatch_and_axe_static_skip():
{"enable_axe": "true", "crawl_render_mode": "static"},
)
assert meta.get("axe_skipped")
+
+
+def test_reporting_gaps_branch_coverage():
+ from website_profiling.reporting.categories._helpers import _indexation_coverage_issues
+ from website_profiling.reporting.categories.accessibility import contrast_issues_from_sources
+ from website_profiling.reporting.categories.technical_seo import category_technical_seo
+ from website_profiling.reporting.content_analytics import _build_tech_stack_summary, _parse_tech_stack_list
+ from website_profiling.reporting.seo_summary import _compute_summary_seo_issues
+ from website_profiling.reporting.thin_content_helper import count_thin_rows, is_thin_row, thin_content_message
+
+ # 1. _helpers.py: noindex in sitemap >= 15 break
+ sitemap = [f"https://x.com/p{i}" for i in range(20)]
+ df_noindex = pd.DataFrame([
+ {"url": f"https://x.com/p{i}", "status": 200, "noindex": True}
+ for i in range(20)
+ ])
+ indexation = {"sitemap_urls": sitemap}
+ issues = _indexation_coverage_issues(df_noindex, indexation)
+ assert len([i for i in issues if "sitemap" in i.get("message", "").lower()]) == 15
+
+ # 2. accessibility.py: >= 40 axe issues break
+ violations1 = [{"id": "color-contrast", "description": f"desc {i}", "help": "help"} for i in range(25)]
+ violations2 = [{"id": "color-contrast", "description": f"desc2 {i}", "help": "help"} for i in range(25)]
+ df_axe = pd.DataFrame([
+ {"url": "https://x.com/1", "status": 200, "page_analysis": json.dumps({"axe_violations": violations1})},
+ {"url": "https://x.com/2", "status": 200, "page_analysis": json.dumps({"axe_violations": violations2})},
+ ])
+ axe_issues = contrast_issues_from_sources(df_axe, {})
+ assert len(axe_issues) == 40
+
+ # 3. technical_seo.py: missing canon > MAX_ISSUES (30), cross canon == url, cross canon > MAX_ISSUES
+ rows_canon = []
+ # 35 missing canonical
+ for i in range(35):
+ rows_canon.append({"url": f"https://x.com/missing-{i}", "status": 200, "canonical_url": ""})
+ # Same canonical (url == canon)
+ rows_canon.append({"url": "https://x.com/same", "status": 200, "canonical_url": "https://x.com/same"})
+ # 35 cross canonical
+ for i in range(35):
+ rows_canon.append({"url": f"https://x.com/cross-{i}", "status": 200, "canonical_url": "https://x.com/other"})
+ df_canon = pd.DataFrame(rows_canon)
+ tech_res = category_technical_seo(df_canon, {})
+ assert any("canonical points to different" in i["message"].lower() for i in tech_res.get("issues", []))
+
+ # 4. content_analytics.py
+ assert _parse_tech_stack_list(None) == []
+ assert _parse_tech_stack_list({"not": "a list"}) == []
+ df_tech = pd.DataFrame([
+ {"url": "https://x.com/about", "status": 200, "content_type": "text/html", "tech_stack": '["React"]'},
+ {"url": "https://x.com/", "status": 200, "content_type": "text/html", "tech_stack": '["Next.js"]'},
+ ])
+ summary = _build_tech_stack_summary(df_tech, start_url="https://x.com")
+ assert summary.get("homepage_url") == "https://x.com/"
+
+ # 5. seo_summary.py: title_long, meta_desc_long
+ df_seo = pd.DataFrame([{
+ "url": "https://x.com/long",
+ "status": 200,
+ "title": "A" * 80,
+ "meta_description": "B" * 200,
+ "meta_description_len": 200,
+ "h1_count": 1,
+ }])
+ seo_res = _compute_summary_seo_issues(df_seo)
+ assert any(i["type"] == "title_long" for i in seo_res.get("issues", {}).get("seo", []))
+ assert any(i["type"] == "meta_desc_long" for i in seo_res.get("issues", {}).get("seo", []))
+
+ # 6. thin_content_helper.py
+ assert count_thin_rows(pd.DataFrame()) == 0
+ assert count_thin_rows(pd.DataFrame([{"status": 500, "word_count": 10}]), success_only=True) == 0
+ assert count_thin_rows(pd.DataFrame([{"status": 200, "other": "x"}]), success_only=True) == 0
+ assert count_thin_rows(pd.DataFrame([{"status": 200, "word_count": 50}]), success_only=True) == 1
+ assert not is_thin_row(pd.Series({"word_count": 300}))
+ assert not is_thin_row(pd.Series({"content_length": 2000}))
+ assert is_thin_row(pd.Series({"content_length": 100}))
+ assert not is_thin_row(pd.Series({}))
+ msg1 = thin_content_message(pd.Series({"word_count": 50}))
+ assert "50 words" in msg1
+ msg2 = thin_content_message(pd.Series({"content_length": 100}))
+ assert "100 chars" in msg2
diff --git a/tests/test_common_analysis_commands_db_unit.py b/tests/test_common_analysis_commands_db_unit.py
index adf4fd30..3223578d 100644
--- a/tests/test_common_analysis_commands_db_unit.py
+++ b/tests/test_common_analysis_commands_db_unit.py
@@ -144,7 +144,7 @@ def __init__(self, url, html, headers):
class FakeWapp:
@staticmethod
- def latest():
+ def latest(*args, **kwargs):
return FakeWapp()
def analyze(self, _page):
@@ -186,6 +186,45 @@ def analyze(self, _page):
assert "Vue.js" in out3
+def test_tech_parsing_branches(monkeypatch) -> None:
+ from pathlib import Path
+ from website_profiling.parsing import tech
+
+ # 1. WAPPALYZER_TECHNOLOGIES_FILE override
+ monkeypatch.setenv("WAPPALYZER_TECHNOLOGIES_FILE", "/custom/tech.json")
+ assert tech._technologies_file_path() == "/custom/tech.json"
+ monkeypatch.delenv("WAPPALYZER_TECHNOLOGIES_FILE", raising=False)
+
+ # 2. Bundled technologies missing
+ monkeypatch.setattr(tech, "_BUNDLED_TECHNOLOGIES", Path("/non/existent/path/tech.json"))
+ assert tech._technologies_file_path() is None
+
+ # 3. _load_wappalyzer_instance when no tech_file
+ class MockWapp:
+ created = 0
+ @classmethod
+ def latest(cls, *args, **kwargs):
+ cls.created += 1
+ return cls()
+
+ monkeypatch.setitem(__import__("sys").modules, "Wappalyzer", types.SimpleNamespace(Wappalyzer=MockWapp))
+ tech.reset_wappalyzer_state()
+ inst1 = tech._load_wappalyzer_instance()
+ # 4. _load_wappalyzer_instance cached instance (hits line 105)
+ inst2 = tech._load_wappalyzer_instance()
+ assert inst1 is inst2
+ assert MockWapp.created == 1
+ tech.reset_wappalyzer_state()
+
+ # 5. parse_tech_stack patterns
+ from bs4 import BeautifulSoup
+ soup_wp = BeautifulSoup('', "lxml")
+ res_wp = tech.parse_tech_stack(soup_wp, {"Server": "Apache/2.4"}, "https://a.com")
+ assert "Drupal" in res_wp
+ assert "WordPress" in res_wp
+ assert "Apache" in res_wp
+
+
def test_reset_wappalyzer_state_clears_cache() -> None:
from website_profiling import common
diff --git a/tests/test_crawl_fetchers.py b/tests/test_crawl_fetchers.py
index 48d6a000..f329b32e 100644
--- a/tests/test_crawl_fetchers.py
+++ b/tests/test_crawl_fetchers.py
@@ -329,7 +329,7 @@ def test_needs_js_render_after_parse_spa_with_many_same_domain_links():
result = _static_result(html)
assert needs_js_render_after_parse(
result, link_count=12, same_domain_link_count=12
- ) is True
+ ) is False
def test_hybrid_refetch_rendered_uses_browser(monkeypatch):
diff --git a/tests/test_crawler_deep.py b/tests/test_crawler_deep.py
index 7352cde4..9e1aacda 100644
--- a/tests/test_crawler_deep.py
+++ b/tests/test_crawler_deep.py
@@ -617,7 +617,7 @@ def test_run_crawler_streaming_db_path(monkeypatch):
class FakeCrawler:
def __init__(self, **_kwargs):
- self.link_edges_accum = []
+ self.link_edges_accum = [("https://a.com", "https://b.com", "link")]
def crawl(self, **_kwargs):
return pd.DataFrame([{"url": "https://a.com", "status": 200}])
@@ -638,8 +638,10 @@ def __exit__(self, _t, _v, _tb):
restore_historical_data=lambda *_a, **_k: None,
)
fake_storage = types.SimpleNamespace(ensure_crawl_tables_cleared=lambda *_a, **_k: None)
+ fake_crawl_store = types.SimpleNamespace(write_link_edges=lambda *_a, **_k: None)
monkeypatch.setitem(__import__("sys").modules, "website_profiling.db", fake_db)
monkeypatch.setitem(__import__("sys").modules, "website_profiling.db.storage", fake_storage)
+ monkeypatch.setitem(__import__("sys").modules, "website_profiling.db.crawl_store", fake_crawl_store)
df, _ = mod.run_crawler("https://a.com", output_db=True, crawl_stream_to_db=True, show_progress=False)
assert not df.empty
diff --git a/tests/test_db_stores_unit.py b/tests/test_db_stores_unit.py
index 7b63c4da..b0d423d4 100644
--- a/tests/test_db_stores_unit.py
+++ b/tests/test_db_stores_unit.py
@@ -61,6 +61,10 @@ def test_llm_cache_roundtrip_parsing() -> None:
conn.set_next_cursor(FakeCursor(fetchone_value={"response_json": {"a": 1}}))
assert read_llm_cache(conn, "k") == '{"a": 1}' # type: ignore[arg-type]
+ conn = FakeConn()
+ conn.set_next_cursor(FakeCursor(fetchone_value={"response_json": None}))
+ assert read_llm_cache(conn, "k") is None # type: ignore[arg-type]
+
conn = FakeConn()
conn.set_next_cursor(
FakeCursor(
diff --git a/tests/test_fetchers_sitemap_config_unit.py b/tests/test_fetchers_sitemap_config_unit.py
index 43f93436..c11387b5 100644
--- a/tests/test_fetchers_sitemap_config_unit.py
+++ b/tests/test_fetchers_sitemap_config_unit.py
@@ -490,3 +490,22 @@ def test_browser_diagnostics_aggregate_empty_df():
assert aggregate_browser_diagnostics_df(None) == {}
assert aggregate_browser_diagnostics_df(pd.DataFrame()) == {}
+
+
+def test_browser_diagnostics_aggregate_failed_requests_and_page_error_skips():
+ from website_profiling.crawl.fetchers.browser_diagnostics import aggregate_browser_diagnostics_df
+
+ pa = json.dumps(
+ {
+ "browser": {
+ "failed_requests": [{"url": "https://a.com/fail"}],
+ "page_errors": ["not-a-dict", {"message": " "}, {"message": "real error"}],
+ }
+ }
+ )
+ df = pd.DataFrame([{"url": "https://a.com", "page_analysis": pa}])
+ agg = aggregate_browser_diagnostics_df(df)
+ assert agg["pages_with_failed_requests"] == 1
+ assert agg["total_failed_requests"] == 1
+ assert agg["pages_with_page_errors"] == 1
+ assert agg["top_page_errors"][0]["text"] == "real error"
diff --git a/tests/test_scoring.py b/tests/test_scoring.py
index 2399978e..d598714c 100644
--- a/tests/test_scoring.py
+++ b/tests/test_scoring.py
@@ -26,6 +26,8 @@ def test_site_health_score_from_categories_weighted_fixture() -> None:
{"id": "intelligence", "score": 0},
]
assert site_health_score_from_categories(categories) == 70
+ assert site_health_score_from_categories(["not-a-dict"]) is None
+ assert site_health_score_from_categories([]) is None
def test_site_health_score_from_payload_prefers_summary() -> None:
@@ -35,3 +37,6 @@ def test_site_health_score_from_payload_prefers_summary() -> None:
"categories": [{"id": "technical_seo", "score": 10}],
}
assert site_health_score_from_payload(payload) == 72
+ assert site_health_score_from_payload({"site_health_score": 65}) == 65
+ assert site_health_score_from_payload({"categories": [{"id": "technical_seo", "score": 80}]}) == 80
+ assert site_health_score_from_payload({}) is None
diff --git a/tests/tools/test_sql_query_tool.py b/tests/tools/test_sql_query_tool.py
index a4328ed0..fdeda95d 100644
--- a/tests/tools/test_sql_query_tool.py
+++ b/tests/tools/test_sql_query_tool.py
@@ -986,6 +986,15 @@ def test_sql_tools_excluded_when_disabled(self) -> None:
assert "get_sql_schema" not in selected
assert "run_sql_query" not in selected
+ def test_sql_tools_dispatch_disabled(self) -> None:
+ from website_profiling.tools.audit_tools.registry import dispatch_tool
+
+ with patch.dict(os.environ, {"CHAT_SQL_TOOL_ENABLED": "false"}):
+ res = dispatch_tool("run_sql_query", {"query": "SELECT 1"})
+ assert res == {"error": "tool disabled: run_sql_query"}
+ res2 = dispatch_tool("get_sql_schema", {})
+ assert res2 == {"error": "tool disabled: get_sql_schema"}
+
# ---------------------------------------------------------------------------
# Remaining branch coverage