sqlinsight-pro/CONTRIBUTING.md
Søren Eggert Lundsteen Olsen cb99778a3f Review 1.5: SQL Scripts for Windows servers and synthetic checks follow main's structure and registry
After the rebase onto 1.4 the 16 SQLI-WIN/SQLI-SYN scripts had their own /* */ format,
so SqlScriptTests (rule ids, review header, -- Kilde: blocks) failed.

- The scripts have main's header (Regel-id, Titel, Alvor, Versioner, Vurdering,
  Grænseværdier, Rettigheder, Data kommer fra, Regelkode, Read-only); the Windows
  WQL/XPath stays word for word in comments.
- The synthetic SQL check's SQL is registered (SyntheticCheckRunner.UseDatabaseSql,
  BeginTransactionSql, RollbackSql, SyntheticCheckSettings.DefaultQuery) and shown
  as -- Kilde: blocks in SQLI-SYN-001/002 and _collectors/SyntheticCheckRunner.sql.
- SqlScriptTests know ServerRuleCatalog; only those rules may be without SQL blocks.
- ServerScriptTests: every CimQueries query/filter is in a SQLI-WIN script word for word.
- The SQL check cancels the rest of a large answer instead of draining it on close.
- Rule counts: README (108 built-in: 92 SQL Server + 13 Windows + 3 synthetic),
  SQL Scripts/README (rule table, 124 rules, Windows/synthetic section), RuleCatalogTests,
  CONTRIBUTING (how to add a server rule).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 15:18:24 +02:00

58 lines
4.4 KiB
Markdown

# Bidrag til SQLInsight Pro
Tak fordi du vil hjælpe. De mest værdifulde bidrag er **SQL Server-ekspertise**: problemer du har set i produktion, hvordan de måles, og hvordan de løses. Opret dem som et issue med skabelonen *Forslag til regel*.
## Byg og test
Du skal bruge [.NET 10 SDK](https://dotnet.microsoft.com/download) og, til integrationstests, Docker.
```bash
dotnet build
dotnet test --filter "Category!=Integration" # unit tests, ingen afhængigheder
dotnet test tests/SQLInsight.IntegrationTests # starter SQL Server 2022 i Docker
SQLINSIGHT_MSSQL_IMAGE=mcr.microsoft.com/mssql/server:2019-latest \
dotnet test tests/SQLInsight.IntegrationTests # anden version
```
Warnings behandles som fejl, og .NET-analyzers kører på niveauet `latest-recommended`.
## Struktur
| Mappe | Indhold |
|---|---|
| `src/SQLInsight.Core` | Domænemodel: versioner, capabilities, findings |
| `src/SQLInsight.Connectivity` | Forbindelser (SqlClient + ODBC-fallback) og registrering af instansen |
| `src/SQLInsight.Rules` | Regelmotor og regler |
| `src/SQLInsight.Agent` | Windows Service / systemd-agent |
| `src/SQLInsight.Web` | On-prem web-UI (Fase 1) |
| `src/SQLInsight.Contracts` | Wire-kontrakt mellem agent og Hub |
| `src/SQLInsight.Hub` | Centralt API til findings, PostgreSQL (Fase 3) |
| `db/permissions` | Least-privilege-script til agentens login |
| `SQL Scripts` | Ét script pr. regel med præcis den SQL, SQLInsight kører, til gennemgang af en DBA (se [SQL Scripts/README.md](SQL%20Scripts/README.md)) |
| `tests/` | Unit og integrationstests |
## Sådan skriver du en regel
1. Implementér `IRule` i `src/SQLInsight.Rules`. Giv den et nyt, fast id (`SQLI-<OMRÅDE>-<NR>`). Et id genbruges aldrig.
2. Angiv i `RequiredCapabilities` alt, hvad reglen kræver. Motoren rapporterer den som *ikke målbar* på versioner, der mangler noget. Reglen må aldrig selv returnere `Passed`, når den ikke har kunnet måle.
3. Et finding skal have **evidens** (de konkrete tal), **forklaring** (hvorfor det er et problem) og **anbefaling** (hvad man gør). Fix-scripts vises for brugeren og køres aldrig automatisk.
4. Skriv unit tests for alle udfald: fundet, ikke fundet, grænseværdier og versioner, hvor reglen ikke kan måles.
5. Registrér reglen i `BuiltInRules`.
6. Tilføj `SQL Scripts/<id>.sql` med den danske header (hvad, vurdering, grænser, alvor, rettigheder, versioner, collector) og collectorens SQL, ordret og med en `-- Kilde:`-linje pr. variant. Brug en eksisterende fil som skabelon. `SqlScriptTests` fejler, hvis filen mangler, eller hvis SQL'en ikke længere er den, koden sender.
En regel om en Windows-server eller et syntetisk tjek (fra 1.5, `SQLI-WIN-…`/`SQLI-SYN-…`) implementerer `IScopedRule<TContext>` i `src/SQLInsight.Rules/Servers/` og registreres i `WindowsServerRules.Create()` eller `SyntheticCheckRules.Create()` (dermed i `ServerRuleCatalog`). Dens `SQL Scripts/<id>.sql` har samme header; forespørgslerne mod Windows står ordret i kommentarer og skal stå i `src/SQLInsight.Servers/CimQueries.cs` (`ServerScriptTests` tjekker det). Agenten må kun læse: CIM-`SELECT`, hændelsesloggen og skrivebeskyttede metoder som Task Schedulers `GetInfoByName`, aldrig start/stop eller ændringer.
### Uden C#: community-regler
Mange regler kan skrives som en SQL-forespørgsel i en JSON-fil under `rules/community/`. De kræver ingen C# og kan afprøves direkte mod en instans med `SQLInsight.Agent rules test`. Se [docs/regler.md](docs/regler.md). Også en community-regel skal have sin `SQL Scripts/<id>.sql` med forespørgslen ordret (se fx `SQL Scripts/COM-SEC-001.sql`).
## Queries mod overvågede servere
- De skal være **read-only** og kunne køre med rettighederne fra `db/permissions/grant-least-privilege.sql`. Kræver de mere, skal scriptet og `LeastPrivilegeTests` opdateres i samme ændring.
- De skal være billige: ingen `DETAILED`-scans, grænser på antal rækker og intet, der kan tage låse på brugerdata.
- Tjek, hvilke versioner DMV'en og kolonnerne findes i, og angiv det som capabilities.
- Læg SQL'en i en `internal const` eller en `internal static Build…Sql`-metode i collectoren, ikke inline i `CollectAsync`, og registrér den i `tests/SQLInsight.Collectors.Tests/SqlScripts/SqlScriptSources.cs`. Opdatér `SQL Scripts/_collectors/<Collector>.sql` og regelfilerne, der bruger collectoren. `SqlScriptTests` fejler ellers.
## Commits
Små, fokuserede commits med en besked, der forklarer *hvorfor*.