# TarninaHub **Wersja: 0.0.1** Platforma Małopolskiego Hubu Innowacji Społecznych (MVP hackathonu). - **backend/** — aplikacja backendowa w C# (ASP.NET Core, `TarninaHub`). - **client/** — aplikacja frontendowa Vue 3 + TypeScript (Vite). - **scripts/** — skrypty budujące całość. - `TarninaHub.slnx` — solution .NET. - `Dockerfile` + `docker-compose.yaml` — uruchomienie kontenerowe. ## Wymagania - .NET SDK 10+ - Node.js 22+ (npm) - PowerShell Core 7+ (`pwsh`) — wymagany do uruchomienia `scripts/*.ps1`. Windows nie kojarzy domyślnie plików `.ps1`, dlatego skrypty uruchamiaj przez `pwsh` (np. `pwsh ./scripts/docker-push.ps1`), a nie przez dwuklik / samo `./scripts/docker-push.ps1`. Instalacja: https://aka.ms/powershell (PowerShell 7.6.6: https://github.com/powershell/powershell/releases#release-v7.6.6) ## Praca lokalna Backend (dev) domyślnie nasłuchuje na `http://localhost:5078` (profil `http`), a opcjonalnie na `https://localhost:7080` (profil `https`). Dev-serwer Vite działa po HTTPS na `https://localhost:7081` i przekierowuje `/api` do backendu (`http://localhost:5078`). Certyfikat HTTPS dla Vite pochodzi z `dotnet dev-certs` — wygeneruj go raz (wymaga `pwsh`): ```pwsh pwsh ./scripts/dev-certs.ps1 # lub: npm --prefix client run certs ``` ```pwsh # terminal 1 — backend (profil http, port 5078) dotnet run --project backend # terminal 2 — client (Vite, https://localhost:7081, proxy /api -> http://localhost:5078) npm --prefix client install npm --prefix client run dev ``` Aby użyć profilu `https` backendu (port 7080), uruchom `dotnet run --project backend --launch-profile https` i zmień `proxy.target` w `client/vite.config.ts` na `https://localhost:7080`. Domyślna konfiguracja nie wymaga żadnych zmiennych środowiskowych. ## Skrypty ```pwsh npm --prefix client run dev # uruchamia Vite (dev server, HTTPS :7081) npm --prefix client run certs # eksport certyfikatu dev do client/.certs (dotnet dev-certs) npm --prefix client run build # buduje aplikację Vite do client/dist npm --prefix client run copy # kopiuje client/dist -> backend/wwwroot node scripts/build.mjs # buduje całość (client + copy + backend) ``` ## Docker Szablon pobiera gotowy obraz z rejestru Gitea (pełna ścieżka), bez lokalnego buildowania: ```pwsh cp docker-compose.yaml.example docker-compose.yaml docker compose pull docker compose up -d ``` - Aplikacja: http://localhost:8075 - Dane: `./data` (bind mount, trwałe — SurrealDB embedded RocksDB) - Obraz: `git.rtynski.pl/rtynski/hy2026:latest` Port hosta można wskazać zmienną `TARNINAHUB_PORT` (domyślnie `8075`), a wersję obrazu zmienną `APP_VERSION` (domyślnie `latest`). Plik `docker-compose.yaml.example` jest szablonem; `docker-compose.yaml` możesz dostosować lokalnie. ### Publikacja obrazu do Gitea Token dostępu utworzysz w Gitea: - https://git.rtynski.pl/user/settings/applications - **Generate New Token** → zakres **`write:package`** (wystarcza do pushu obrazu). Wymagany **PowerShell Core 7+** (`pwsh`). Windows nie uruchamia domyślnie plików `.ps1`, więc skrypt wywołaj jawnie przez `pwsh`: ```pwsh $env:GITEA_USER = "rtynski"; $env:GITEA_TOKEN = "" pwsh ./scripts/docker-push.ps1 ``` Skrypt najpierw sprawdza połączenie z demonem Docker i rejestrem, czyta wersję z `backend/TarninaHub.csproj`. Jeśli dana wersja jest już wypchnięta do rejestru, kończy pracę z czerwonym komunikatem; w przeciwnym razie buduje frontend, kopiuje go do `backend/wwwroot`, buduje backend, buduje obraz Docker i wypycha go do `git.rtynski.pl/rtynski/hy2026` jako `` oraz `latest`. Nadpisanie sprawdzenia: `-Force`. ## CI/CD Pipeline działa w **Gitea Actions** (`.gitea/workflows/`): > **Uwaga:** workflow są zakomentowane w całości — do repozytorium nie jest podpięty runner Gitea. Odkomentuj po zarejestrowaniu runera (Settings → Actions → Runners). - `ci.yml` — na `push`/PR do `main`: build backendu (.NET 10), `dotnet format --verify-no-changes` oraz build klienta (Node 22, `vue-tsc` + bundle). - `cd.yml` — na `main`/tag `v*`: build obrazu i push do `git.rtynski.pl/rtynski/hy2026` (`` + `latest`); deploy demo opcjonalnie przez sekrety CI. Sekrety CI: `GITEA_TOKEN` (`write:package`), opcjonalnie `DEPLOY_HOST`/`DEPLOY_USER`/`DEPLOY_SSH_KEY`. Klucz `LLM__ApiKey` przekazujemy wyłącznie na runtime — nigdy do repo ani warstw obrazu. ## Środowiska i konfiguracja - **dev** — `appsettings.Development.json`, dane w `backend/data`. - **demo** — obraz z rejestru, `docker-compose.yaml.example`, port `TARNINAHUB_PORT` (8075), wersja `APP_VERSION`. - **staging** (opcjonalne) — kandydat wydania przed demo. Konfiguracja przez zmienne środowiskowe (`SurrealDb__*`, `LLM__ApiKey`, `OTEL_*`); szablon: [`.env.example`](.env.example). ## Observability - Healthcheck: `GET /api/health` (używany też przez Docker healthcheck). - Logi strukturalne (JSON) do `stdout`/`stderr`, z correlation ID. - Docelowo: `/metrics` (Prometheus) i OpenTelemetry (traces). ## Struktura ``` TarninaHub/ ├─ backend/ # ASP.NET Core Web API (API host) + wwwroot + migrations │ ├─ Controllers/ # warstwa API (kontrolery, DTO wejścia/wyjścia) │ ├─ Errors/ # globalna obsługa błędów (ProblemDetails) │ ├─ Configuration/ # konfiguracja Swagger/OpenAPI │ ├─ Domain/ # warstwa domeny (enumy, reguły) │ ├─ Application/ # DTO i abstrakcje (interfejsy) │ ├─ Infrastructure/ # SurrealDB, migracje, DI │ └─ migrations/ # *.surql (aplikowane przy starcie) ├─ client/ # Vue 3 + TS + Vite ├─ tests/TarninaHub.Tests/ # testy jednostkowe (xUnit) ├─ scripts/ │ ├─ build.mjs # build całości │ └─ copy-client.mjs # client/dist -> backend/wwwroot ├─ Dockerfile # multi-stage: client + backend ├─ docker-compose.yaml # uruchomienie (bind ./data) ├─ docker-compose.yaml.example ├─ TarninaHub.slnx └─ README.md ``` ## API - Swagger UI: `GET /swagger` (dokument per wersja, np. `/swagger/v1/swagger.json`). - Wersjonowanie: `?api-version=1.0` lub nagłówek `X-Api-Version` (domyślnie `1.0`). - Błędy: `ProblemDetails` (RFC 7807), globalny handler wyjątków. - Healthcheck: `GET /api/health` (bez wersji, dla infrastruktury). - Migracje SurrealQL są aplikowane automatycznie przy starcie (katalog `migrations/`). - Uwierzytelnianie: JWT Bearer (`POST /api/auth/signup`, `POST /api/auth/signin`), role `user`/`jst`/`operator`/`manager`/`admin` i polityki RBAC. Hasła (Argon2) i zgody w SurrealDB; różne poziomy dostępu (`by-consent`/`temporary`/`anonymized`) + rejestr odczytu (`audit_log`).