# iLED — Sklep z lampami Polish lamp e-commerce platform with .NET modular monolith API, Angular shop, and Angular admin panel. ## Structure ``` Shop/ design/ Figma exports src/ backend/ .NET 10 API (Clean Architecture + CQRS) shop/ Angular customer webshop (port 4200) admin/ Angular admin panel (port 4201) docker/ PostgreSQL, Redis, OpenObserve, optional API .drone.yml Drone CI (build) + SSH deploy ``` ## Drone CI / deploy Pipeline file: [`.drone.yml`](.drone.yml). **CI** (every push / PR): build API, shop, admin. **Deploy** (`master`/`main` push, after CI): SSH to the host, `git checkout` the commit, `docker compose --profile full up -d --build`. Drone secrets to configure: | Secret | Purpose | |--------|---------| | `ssh_host` | Deploy server hostname/IP | | `ssh_user` | SSH user | | `ssh_key` | Private key (PEM) | | `ssh_port` | SSH port (use `22` if unused) | | `deploy_path` | Absolute clone path, e.g. `/opt/iled-shop` | On the host once: ```bash git clone ssh://git@git.zea.lt:2222/miczek/iled-shop.git /opt/iled-shop cd /opt/iled-shop/docker cp .env.example .env # edit passwords / CORS origins ``` Shop/admin Angular apps are built in CI; production static hosting (nginx) can be wired next. ## Quick start ### 1. Infrastructure ```bash cd docker docker compose up -d postgres redis openobserve ``` - PostgreSQL: `localhost:5433` (db/user/pass `iled` / `iled123`) - Redis: `localhost:6379` - OpenObserve UI: http://localhost:5080 — `root@iled.local` / `Complexpass#123` ### 2. Backend API ```bash cd src/backend dotnet run --project src/iLED.Api ``` API: http://localhost:5000 Swagger: http://localhost:5000/swagger Health: http://localhost:5000/health Sitemap: http://localhost:5000/api/v1/seo/sitemap.xml Leave `OpenTelemetry:OtlpEndpoint` empty to disable exporters (default). With OpenObserve running, set endpoint/headers via env or User Secrets (see Observability below). Optional full stack (API in Docker): ```bash cd docker docker compose --profile full up -d --build ``` ### 3. Shop (customer) ```bash cd src/shop npm start ``` http://localhost:4200 ### 4. Admin ```bash cd src/admin npm start ``` http://localhost:4201 **Admin login:** `admin@iled.pl` / `Admin123!` ## Shop routes | Path | Purpose | |------|---------| | `/` | Home | | `/products`, `/products/:slug` | Catalog / product detail | | `/cart`, `/checkout` | Cart & checkout | | `/login`, `/account` | Auth & orders | | `/privacy`, `/terms` | Legal (draft copy) | | `/**` | Custom 404 | Footer links to privacy/terms. Cookie banner gates OpenPanel analytics only (OpenObserve is server-side and does not use browser cookies). ## Payments (PayU) - Default: `PayU:UseSandbox: true` — local redirect simulation. - Live: set `UseSandbox` to `false` and configure via User Secrets / env: - `PayU:PosId`, `ClientId`, `ClientSecret`, `SecondKey` - `OAuthUrl` / `OrdersUrl` (sandbox hosts are in `appsettings.json`; production: `https://secure.payu.com/...`) - `NotifyUrl`, `ContinueUrl` - Webhook: `POST /api/v1/payments/webhook` (signature header `OpenPayu-Signature`). Failures appear in OpenObserve traces/logs. - Status sync (no admin button): thank-you page pulls PayU on return; `PayUPaymentSyncBackgroundService` polls pending payments (`PayU:StatusPollEnabled`, `PayU:StatusPollIntervalSeconds` — 30s in Development). Needed locally when PayU cannot reach `NotifyUrl`. **Do not commit secrets.** Use `dotnet user-secrets` or environment variables. ## Shipping (InPost / DHL / DPD) - Default: `Shipping:UseSandbox: true` — mock **labels**; InPost map can still use the real Geowidget (sandbox SDK). - **InPost map (localhost):** token from [sandbox Parcel Manager](https://sandbox-manager.paczkomaty.pl) → API → Geowidget → Generate **without a domain**, then set `Shipping:InPost:GeowidgetSandboxToken`. SDK: `https://sandbox-easy-geowidget-sdk.easypack24.net`. - **InPost map (prod):** `GeowidgetPublicToken` bound to your domain. - DHL/DPD: widget URLs in config; fallback = demo Leaflet map. - Live labels (`UseSandbox: false`) need carrier API credentials. Pickup checkout shows a billing/invoice address hint (locker is not the invoice address). ## Observability ### OpenObserve (API) Compose service `openobserve` on port **5080**. OTLP/HTTP base endpoint (SDK appends `/v1/traces|metrics|logs`): ``` OpenTelemetry__OtlpEndpoint=http://localhost:5080/api/default OpenTelemetry__OtlpHeaders=Authorization=Basic OpenTelemetry__ServiceName=iled-api ``` For the default compose user, Basic value is: `cm9vdEBpbGVkLmxvY2FsOkNvbXBsZXhwYXNzIzEyMw==` ### OpenPanel (shop product analytics) OpenPanel’s official stack is multi-service (API, dashboard, ClickHouse, etc.). Deploy with their self-hosting guide: https://openpanel.dev/docs/self-hosting/deploy-docker-compose Then set shop env: ```ts // src/shop/src/environments/environment.ts openPanelApiUrl: 'https://your-openpanel-host/api', openPanelClientId: '', ``` The tracker loads only after cookie consent is accepted. ## SEO & legal - Per-route meta title/description/Open Graph via `SeoService` - Favicon / apple-touch / `og-default` in `src/shop/public` - Static `robots.txt` + API sitemap - Privacy & Terms mention self-hosted OpenPanel + OpenObserve (draft for lawyer review) ## Features ### Shop - Homepage, product list with filters, product detail - Cart, checkout, PayU (sandbox by default) - Login/register, favorites, account/orders - InPost / DHL / DPD pickup widgets + sandbox map - Product reviews, newsletter signup - Cookie consent, 404, legal pages ### Admin - Dashboard KPIs - Product CRUD (incl. image alt text), stock management - Orders & shipping labels - Discount rules & promo codes - Newsletter subscribers & campaigns - Review moderation ### API modules - Catalog, Identity, Cart, Orders, Payments, Shipping, Marketing, Reviews, SEO ## Design Brand colors: `#FFBC39`, `#000000`, `#8C8C8C`, `#D9D9D9`