# Comparison Map: SmartStack.app ↔ CLI Templates

> This file defines the **exact mapping** between SmartStack.app (source of truth)
> and CLI templates. Used by `/cli-app-sync` to detect drift.

## Paths

| Alias | Path |
|---|---|
| `APP_API` | `D:/01 - projets/SmartStack.app/02-Develop/src/SmartStack.Api` |
| `APP_WEB` | `D:/01 - projets/SmartStack.app/02-Develop/web/smartstack-web` |
| `CLI_TPL` | `D:/01 - projets/SmartStack.cli/02-Develop/templates/project` |
| `CLI_INIT` | `D:/01 - projets/SmartStack.cli/02-Develop/src/commands/init.ts` |

---

## Backend Comparisons

### `program-cs` — Program.cs startup pipeline

| | Path |
|---|---|
| **Reference** | `APP_API/Program.cs` |
| **Template** | `CLI_TPL/Program.cs.template` |

**Patterns to verify (ordered by startup sequence):**

| # | Pattern | Grep/search | Critical |
|---|---|---|---|
| 1 | Serilog usings | `using Serilog;` + `using Serilog.Events;` | YES |
| 2 | Bootstrap logger | `Log.Logger = new LoggerConfiguration()` | YES |
| 3 | try/catch/finally | `try {` ... `catch (Exception` ... `finally` | YES |
| 4 | Kestrel HTTP/1.1 | `ConfigureKestrel` + `HttpProtocols.Http1` | YES |
| 5 | appsettings.Local.json | `AddJsonFile("appsettings.Local.json"` | YES |
| 6 | Serilog from config | `UseSmartStackSerilog()` | YES |
| 7 | Application Insights | `AddApplicationInsightsTelemetry` | YES |
| 8 | AddSmartStack | `AddSmartStack(builder.Configuration` | YES |
| 9 | InitializeSmartStackAsync | `InitializeSmartStackAsync()` | YES |
| 10 | Swagger | `UseSmartStackSwagger()` | YES |
| 11 | Middleware pipeline | `UseSmartStack()` then `MapSmartStack()` | YES |
| 12 | Success log | `Log.Information(` ... `started successfully` | NO |
| 13 | Fatal log | `Log.Fatal(ex,` | YES |
| 14 | CloseAndFlush | `Log.CloseAndFlush()` | YES |

**Template-specific additions (not in app):**
- `using Microsoft.EntityFrameworkCore;` (for ExtensionsDbContext migration)
- `Add{{ProjectName}}Infrastructure` / `Add{{ProjectName}}Application` (client DI)
- ExtensionsDbContext migration block (after InitializeSmartStackAsync)

---

### `di-app` — DependencyInjection.Application.cs

| | Path |
|---|---|
| **Reference** | *(no app equivalent — client-only pattern)* |
| **Template** | `CLI_TPL/DependencyInjection.Application.cs.template` |

**Patterns to verify:**

| # | Pattern | Search | Critical |
|---|---|---|---|
| 1 | MediatR warning | `MediatR is already registered` or `do NOT register it again` | YES |
| 2 | No AddMediatR example | must NOT contain `services.AddMediatR(cfg =>` | YES |

---

### `di-infra` — DependencyInjection.Infrastructure.cs

| | Path |
|---|---|
| **Reference** | `APP_API/../SmartStack.Infrastructure/DependencyInjection.cs` |
| **Template** | `CLI_TPL/DependencyInjection.Infrastructure.cs.template` |

**Patterns to verify:**

| # | Pattern | Search | Critical |
|---|---|---|---|
| 1 | AddDbContext pattern | `AddDbContext<ExtensionsDbContext>` | YES |
| 2 | SQL Server | `UseSqlServer` | YES |
| 3 | Connection string | `GetConnectionString` | YES |

---

### `appsettings` — appsettings.json

| | Path |
|---|---|
| **Reference** | `APP_API/appsettings.json` |
| **Template** | `CLI_TPL/appsettings.json.template` |

**Patterns to verify:**

| # | Pattern | Search | Critical |
|---|---|---|---|
| 1 | Serilog config section | `"Serilog"` | YES |
| 2 | ConnectionStrings | `"ConnectionStrings"` | YES |
| 3 | Logging sinks | `"Logging"` section | NO |

---

## Frontend Comparisons

### `package-json` — package.json dependencies and scripts

| | Path |
|---|---|
| **Reference** | `APP_WEB/package.json` |
| **Template** | `CLI_INIT` → variable `packageJson` (search: `const packageJson = {`) |

**Dependency version checks:**

| Package | Category | Compare rule |
|---|---|---|
| `@types/node` | devDependencies | Major range must match app (e.g., `^24` vs `^26`) |
| `typescript` | devDependencies | Range strategy and major must match (`~5.9` vs `~5.9`) |
| `eslint-plugin-react-refresh` | devDependencies | Major range must match |
| `react` | dependencies | Major range must match |
| `react-dom` | dependencies | Major range must match |
| `vite` | devDependencies | Major range must match |
| `tailwindcss` | dependencies | Major range must match |

**Testing stack (must be present in template):**

| Package | Required |
|---|---|
| `vitest` | YES |
| `@vitest/coverage-v8` | YES |
| `@testing-library/react` | YES |
| `@testing-library/jest-dom` | YES |
| `@testing-library/user-event` | YES |
| `jsdom` | YES |

**Scripts (must be present in template):**

| Script | Command |
|---|---|
| `test` | `vitest run` |
| `test:watch` | `vitest` |
| `test:coverage` | `vitest run --coverage` |

---

### `vite-config` — vite.config.ts proxy and plugins

| | Path |
|---|---|
| **Reference** | `APP_WEB/vite.config.ts` |
| **Template** | `CLI_INIT` → variable `viteConfig` (search: `` const viteConfig = ` ``) |

**Patterns to verify:**

| # | Pattern | Search | Critical |
|---|---|---|---|
| 1 | React plugin | `react()` | YES |
| 2 | Tailwind plugin | `tailwindcss()` | YES |
| 3 | API proxy | `'/api':` | YES |
| 4 | Proxy bypass | `bypass(req` or `bypass:` | YES |
| 5 | HTML accept check | `accept?.includes('text/html')` | YES |
| 6 | SignalR proxy | `'/hubs':` | YES |
| 7 | WebSocket flag | `ws: true` | YES |
| 8 | Path alias | `'@': '/src'` or `'@/': './src'` | YES |

---

### `tsconfig` — tsconfig.json compiler options

| | Path |
|---|---|
| **Reference** | `APP_WEB/tsconfig.json` or `APP_WEB/tsconfig.app.json` |
| **Template** | `CLI_INIT` → variable `tsConfig` (search: `const tsConfig = {`) |

**Options to verify:**

| Option | Expected value | Critical |
|---|---|---|
| `target` | `ES2022` | YES |
| `lib` | includes `ES2022` | YES |
| `verbatimModuleSyntax` | `true` | YES |
| `erasableSyntaxOnly` | `true` | YES |
| `isolatedModules` | must NOT be present (deprecated) | YES |
| `moduleResolution` | `bundler` | YES |
| `jsx` | `react-jsx` | YES |
| `strict` | `true` | YES |

---

### `index-css` — index.css Tailwind directives

| | Path |
|---|---|
| **Reference** | `APP_WEB/src/index.css` |
| **Template** | `CLI_INIT` → variable `indexCss` (search: `` const indexCss = ` ``) |

**Patterns to verify:**

| # | Pattern | Search | Critical |
|---|---|---|---|
| 1 | Tailwind import | `@import "tailwindcss"` | YES |
| 2 | Source directive | `@source "../node_modules/@atlashub/smartstack` | YES |
| 3 | Dark mode variant | `@custom-variant dark` | YES |

---

## Intentional Exclusions (SKIP)

These comparisons should **always** return `[SKIP]` — differences are by design.

| Item | Reason |
|---|---|
| `App.tsx` | Client uses `PageRegistry`+`DynamicRouter` (v3.7+); app uses DynamicRouter exclusively (mergeRoutes removed in v3.7) |
| `api.ts` | Client re-exports SmartStack client — wrapper pattern is correct |
| `ExtensionsDbContext` | Intentionally simplified vs `CoreDbContext` |
| `GlobalUsings.cs` | App has platform-wide usings; client has minimal set |
| Skills/Agents/Hooks | Installed globally via `ss install`, not by `ss init` |
| Platform-specific skills | `bugfix-issue`, `feature-test`, `sonar`, `version-bump` |
| CI/CD files | `azure-pipelines.yml` is platform-specific |
| `CLAUDE.md` | Each project has its own instructions |

---

## Maintenance

When adding a new comparison point:
1. Add an entry to the appropriate section above
2. Define the reference path and template location
3. List the key patterns to check with criticality
4. Update the SKILL.md `<comparison_categories>` table
