Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions .dockerignore

This file was deleted.

19 changes: 18 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: CI

# Läuft bei jedem Push und jedem Pull Request auf den Hauptzweig.
# Alle vier Schritte sind dieselben, die auch lokal über `npm run check` laufen.
# Alle Prüfungen entsprechen dem lokalen `npm run check`.
on:
push:
branches: [master, main]
Expand All @@ -26,6 +26,10 @@ jobs:
node-version: 22
cache: npm

- uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Abhängigkeiten installieren
run: npm ci

Expand All @@ -38,10 +42,23 @@ jobs:
- name: Tests
run: npm test

- name: Python-Tests
run: npm run test:python

# Der Build deckt ab, was die Tests nicht sehen: Server-Komponenten,
# Metadaten und das Zusammenspiel der Seiten.
- name: Produktionsbuild
run: npm run build
env:
# Kein Zugriff auf eine Datenbank im Build; der Gastmodus genügt.
NEXT_TELEMETRY_DISABLED: "1"

desktop:
runs-on: windows-latest
timeout-minutes: 15

steps:
- uses: actions/checkout@v4

- name: Desktop-Anwendung bauen
run: cmd /c desktop\build.bat
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ yarn-error.log*
*.tsbuildinfo
next-env.d.ts

# python
__pycache__/
*.py[cod]

# C++ desktop application (desktop/) - details in desktop/.gitignore
/desktop/build/
*.obj
Expand Down
80 changes: 67 additions & 13 deletions README.de.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,34 @@ implementieren und in `src/lib/providers/registry.ts` eintragen.
## Installation

```bash
npm install
cp .env.example .env.local # Werte anpassen; alles ist optional
npm run dev # http://localhost:3000
./run.sh --install # nur npm-Abhängigkeiten installieren/prüfen
./run.sh --local # lokal bauen und starten, ohne MongoDB
```

Produktivbetrieb: `npm run build && npm start`.
`run.sh` benötigt Node.js 22+ und npm. Das Skript wählt automatisch einen
freien Port; mit `./run.sh --local --port 3001` lässt sich ein Wunschport
angeben. Für die Entwicklung mit Hot Reload nach `./run.sh --install`
`npm run dev` verwenden.

Für den vollständigen Produktivbetrieb mit MongoDB `./run.sh --docker`
verwenden. Docker Engine und das Docker Compose Plugin müssen bereits
installiert sein. Das Skript erzeugt bei Bedarf private Anwendungsschlüssel in
`.env.local` und startet die Dienste auf einem freien Port. Mit
`./run.sh --docker --port 3001` lässt sich ein Wunschport setzen; wenn er
belegt ist, wird der nächste freie Port gewählt.

`./run.sh --install` installiert oder prüft nur die lokalen npm-Abhängigkeiten;
die Anwendung wird weder gebaut noch gestartet. Python ist zum Ausführen von
Chainer nicht erforderlich. Python 3.10+ wird nur vom Werkzeug zum Aufzeichnen
der Provider-Prüfdaten und dessen Offline-Unit-Tests verwendet. Es nutzt die
Python-Standardbibliothek und benötigt keine zusätzlichen Python-Pakete.

Für einen manuellen Docker-Compose-Start `AUTH_SECRET` in der Umgebung setzen
oder `.env.local` explizit angeben:

```bash
docker compose --env-file .env.local up -d
```

Ohne `MONGODB_URI` läuft alles im Gastmodus. Für Login, Fälle, Watchlist, Teams und den dauerhaften Cache
werden `MONGODB_URI` und `AUTH_SECRET` benötigt.
Expand Down Expand Up @@ -163,13 +185,16 @@ src/lib/apitoken.ts Zugriffstoken für Skripte
src/lib/caseRefresh.ts Automatische Fallaktualisierung
src/lib/logger.ts Strukturierte Protokollierung mit Anfragekennung
src/lib/migrate.ts Schemaversionierung gespeicherter Fälle
src/middleware.ts Vergabe der Anfragekennung
src/proxy.ts Vergabe der Anfragekennung
src/lib/ratelimit.ts Rate-Limit der teuren Endpunkte
src/lib/cache.ts Zweistufiger Cache (Speicher und MongoDB)
src/lib/auth.ts Session, Nutzer-Keys, Provider-Kontext
src/lib/watch.ts Watchlist-Prüfung und Benachrichtigung
src/lib/models Mongoose-Modelle (User, Org, Case, Annotation, Watch, CacheEntry)
src/instrumentation.ts Optionaler Zeitgeber für die Watchlist
scripts/record_fixtures.py Zeichnet Live-Antworten auf und kürzt sie für Offline-Tests
scripts/test_record_fixtures.py Offline-Tests für das Kürzen der Prüfdaten
run.sh Linux-Setup der Abhängigkeiten und lokaler/Docker-Start
```

## API
Expand Down Expand Up @@ -217,19 +242,45 @@ OpenAPI-Dokument unter `/api/openapi` wird übersetzt.

### Fortlaufende Prüfung

`.github/workflows/ci.yml` prüft bei jedem Push und jedem Pull Request Typen, Stil, Tests und einen Produktionsbuild.
Dieselben vier Schritte laufen lokal mit `npm run check`.
`.github/workflows/ci.yml` prüft bei jedem Push und Pull Request Typen, Stil, TypeScript- und Python-Tests sowie
einen Produktionsbuild. `npm run check` führt diese Web-Prüfungen lokal aus. Ein separater Windows-Job baut die
Desktop-Anwendung.

Wartungsänderungen: Die Anfragenkennung verwendet jetzt die Next.js-16-Konvention `proxy.ts` statt des veralteten
Middleware-Musters. Nodemailer wurde auf die korrigierte Hauptversion 10 aktualisiert, um Sicherheitswarnungen der
Abhängigkeiten zu beheben.

### Docker

Für eine Linux-Installation mit MongoDB:

```bash
./run.sh --docker
```

Das Skript erzeugt bei Bedarf private Anwendungsschlüssel in `.env.local`,
baut die Container und startet die Dienste. Docker Engine und das Docker
Compose Plugin müssen bereits installiert sein. Für eine lokale Installation
im Gastmodus ohne MongoDB `./run.sh --local` verwenden; dafür sind Node.js 22+
und npm erforderlich. Beide Varianten starten die Produktionsversion und
wählen automatisch einen freien Port. Mit `./run.sh --docker --port 3001`
lässt sich ein Wunschport angeben. Python 3.10+ wird nur für Python-Tests und
zum Aufzeichnen der Provider-Prüfdaten benötigt.

Mit `./run.sh --install` werden nur die lokalen npm-Abhängigkeiten installiert
oder aktualisiert; es wird weder gebaut noch gestartet. Node.js 22+ und npm
müssen bereits installiert sein.

Für den manuellen Start:

```bash
export AUTH_SECRET=$(node -e "console.log(require('crypto').randomBytes(32).toString('hex'))")
docker compose up -d
```

Das mitgelieferte `docker-compose.yml` startet die Anwendung zusammen mit einer MongoDB. Der Container nutzt die
Standalone-Ausgabe von Next.js, läuft als unprivilegierter Nutzer und bringt eine Zustandsprüfung mit. Alle
Umgebungsvariablen aus `.env.example` lassen sich durchreichen.
Standalone-Ausgabe von Next.js, läuft als unprivilegierter Nutzer und bringt eine Zustandsprüfung mit. Optionale
Konfigurationswerte können in `.env.local` gesetzt werden.

### Datenschutz

Expand Down Expand Up @@ -266,10 +317,13 @@ npm test # einmalig
npm run test:watch
```

`npm run test:ui` führt nur die Komponententests aus, `npm run check` alles, was auch die CI prüft (Typen, Stil,
Tests, Build).
`npm run test:ui` führt nur die Komponententests aus; `npm run check` führt die Web-Prüfungen aus (Typen, Stil,
TypeScript- und Python-Tests, Produktionsbuild).
Für `npm run check` und `npm run fixtures` wird Python 3.10+ benötigt.

Die Tests decken vier Ebenen ab und greifen weder auf das Netz noch auf die Datenbank zu:
Die Tests decken vier Ebenen ab und greifen weder auf das Netz noch auf die Datenbank zu. Die Python-Unit-Tests
prüfen zusätzlich das Kürzen der Prüfdaten ohne Netzwerkzugriff; nur `npm run fixtures` kontaktiert Provider-APIs,
um aktuelle Prüfdaten aufzuzeichnen.

- **Logik**: die Trace-Engine und die Verbindungssuche gegen eine erfundene Kette, Taint-Modelle, Wechselgeld-,
Peeling- und Einzahlungserkennung, Zeitmuster, Risikoeinstufung, Wallet-Fingerabdruck, Adressformate,
Expand All @@ -280,7 +334,7 @@ Die Tests decken vier Ebenen ab und greifen weder auf das Netz noch auf die Date
Tabelle stillschweigend deutschen Text in die englische Oberfläche tragen.
- **Umwandlung der Anbieterdaten**: aufgezeichnete echte Antworten in `src/lib/providers/__fixtures__/` werden durch
die Provider geschickt und das Ergebnis geprüft. Ändert ein Anbieter sein Format, fällt es hier auf. Neu
aufzeichnen mit `npm run fixtures`.
aufzeichnen mit `npm run fixtures` (Python 3.10+ erforderlich).
- **API-Routen und Komponenten**: Validierung, Berechtigungen, Fehlercodes und Ratenbegrenzung aller Endpunkte mit
ausgetauschten Providern; die Komponenten werden unter jsdom in beiden Sprachen gerendert.

Expand Down
73 changes: 60 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,31 @@ register it in `src/lib/providers/registry.ts`.
## Installation

```bash
npm install
cp .env.example .env.local # adjust the values; everything is optional
npm run dev # http://localhost:3000
./run.sh --install # install/check npm dependencies only
./run.sh --local # build and run locally, without MongoDB
```

For production: `npm run build && npm start`.
`run.sh` requires Node.js 22+ and npm. It picks an available port automatically;
set a preferred port with `./run.sh --local --port 3001`. For development with
hot reload, use `npm run dev` after `./run.sh --install`.

For the full production setup with MongoDB, use `./run.sh --docker`. Docker
Engine and the Docker Compose plugin must already be installed. The script
creates `.env.local` with private application secrets when needed and starts
the services on an available port. Use `./run.sh --docker --port 3001` to
choose a preferred port; if it is occupied, the next free port is selected.

`./run.sh --install` only installs/checks the local npm dependencies; it does
not build or start the app. Python is not required to run Chainer. Python 3.10+
is used only by the provider-fixture recording tool and its offline unit tests;
it uses Python's standard library and adds no Python package dependencies.

For a manual Docker Compose setup, provide `AUTH_SECRET` in the environment or
use the generated `.env.local` explicitly:

```bash
docker compose --env-file .env.local up -d
```

Without `MONGODB_URI` everything runs in guest mode. Login, cases, watchlist, teams and the persistent cache need
`MONGODB_URI` and `AUTH_SECRET`.
Expand Down Expand Up @@ -166,13 +185,16 @@ src/lib/apitoken.ts Access tokens for scripts
src/lib/caseRefresh.ts Automatic case refresh
src/lib/logger.ts Structured logging with a request id
src/lib/migrate.ts Schema versioning of stored cases
src/middleware.ts Assignment of the request id
src/proxy.ts Assignment of the request id
src/lib/ratelimit.ts Rate limit for the expensive endpoints
src/lib/cache.ts Two-tier cache (memory and MongoDB)
src/lib/auth.ts Session, user keys, provider context
src/lib/watch.ts Watchlist check and notification
src/lib/models Mongoose models (User, Org, Case, Annotation, Watch, CacheEntry)
src/instrumentation.ts Optional timer for the watchlist
scripts/record_fixtures.py Records live responses and trims them for offline tests
scripts/test_record_fixtures.py Offline tests for fixture trimming
run.sh Linux dependency setup and local/Docker runner
```

## API
Expand Down Expand Up @@ -220,19 +242,42 @@ OpenAPI document at `/api/openapi` is translated as well.

### Continuous integration

`.github/workflows/ci.yml` runs types, style, tests and a production build on every push and pull request. The same
four steps run locally with `npm run check`.
`.github/workflows/ci.yml` runs types, style, TypeScript and Python tests, and a production build on every push and
pull request. `npm run check` runs those web checks locally. A separate Windows job builds the desktop app.

Maintenance fixes: request-ID handling now uses the Next.js 16 `proxy.ts` convention instead of deprecated
middleware, and Nodemailer was upgraded to patched major version 10 to resolve dependency security advisories.

### Docker

For a Linux installation with MongoDB, run:

```bash
./run.sh --docker
```

The script creates private application secrets in `.env.local` if needed,
builds the containers, and starts the services. Docker Engine and the Docker
Compose plugin must already be installed. For a local guest-mode setup without
MongoDB, use `./run.sh --local` instead; it requires Node.js 22+ and npm.
Both options start the production app and select a free port automatically.
Use `./run.sh --docker --port 3001` to set a preferred port. Python 3.10+ is
only needed for Python tests and recording provider fixtures.

To install or refresh only the local npm dependencies without building or
starting Chainer, run `./run.sh --install`. Node.js 22+ and npm must already
be installed.

To run the stack manually:

```bash
export AUTH_SECRET=$(node -e "console.log(require('crypto').randomBytes(32).toString('hex'))")
docker compose up -d
```

The bundled `docker-compose.yml` starts the application together with a MongoDB. The container uses the standalone
output of Next.js, runs as an unprivileged user and comes with a health check. All environment variables from
`.env.example` can be passed through.
output of Next.js, runs as an unprivileged user and comes with a health check. Optional configuration values can be
set in `.env.local`.

### Privacy

Expand Down Expand Up @@ -269,10 +314,12 @@ npm test # once
npm run test:watch
```

`npm run test:ui` runs only the component tests, `npm run check` everything that CI runs (types, style, tests,
build).
`npm run test:ui` runs only the component tests; `npm run check` runs the web checks (types, style, TypeScript and
Python tests, production build).
Python 3.10+ is required for `npm run check` and `npm run fixtures`.

The tests cover four levels and touch neither the network nor the database:
The tests cover four levels and touch neither the network nor the database. The Python unit tests also check fixture
trimming without network access; only `npm run fixtures` contacts provider APIs to record fresh data.

- **Logic**: the trace engine and the connection search against a synthetic chain, taint models, change, peeling and
deposit detection, timing patterns, risk classification, wallet fingerprint, address formats, formatting,
Expand All @@ -283,7 +330,7 @@ The tests cover four levels and touch neither the network nor the database:
German text into the English interface.
- **Conversion of the provider data**: recorded real responses in `src/lib/providers/__fixtures__/` are sent through
the providers and the result is checked. If a provider changes its format, it shows up here. Re-record with
`npm run fixtures`.
`npm run fixtures` (requires Python 3.10+).
- **API routes and components**: validation, permissions, error codes and rate limiting of all endpoints with the
providers swapped out; the components render under jsdom in both languages.

Expand Down
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ services:
mongo:
condition: service_healthy
ports:
- "3000:3000"
- "${CHAINER_PORT:-3000}:3000"
environment:
MONGODB_URI: mongodb://mongo:27017/chainer
# Pflicht: zufälligen Wert setzen, z. B. mit
# node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
AUTH_SECRET: ${AUTH_SECRET:?AUTH_SECRET muss gesetzt sein}
ENCRYPTION_KEY: ${ENCRYPTION_KEY:-}
APP_URL: ${APP_URL:-http://localhost:3000}
APP_URL: "${APP_URL:-http://localhost:${CHAINER_PORT:-3000}}"
ALLOW_REGISTRATION: ${ALLOW_REGISTRATION:-true}
# Optionale Schlüssel der Datenquellen
BLOCKCYPHER_TOKEN: ${BLOCKCYPHER_TOKEN:-}
Expand Down
Loading