Commit Graph
13 Commits
Author SHA1 Message Date
MMD 0ea0322967 Revert 253c922: restore the PM/RBAC work to the integration
Reverting the production revert so the pm branch can merge cleanly on
top of the restored RBAC base. Conflicts against newer integration work
resolved by combining:
- App.tsx: v7's bot-draft wizard bypass + login returnUrl kept alongside
  the supervisor gating (no-project block screen, panel scoping)
- LoginPage: returnUrl navigation kept, supervisor routing added
- migration.sql: bot_drafts table kept, unified-projects ALTERs restored
2026-10-01 15:24:56 +03:30
whqreza 09245cdc2c revert(stt): remove STT configuration and keep bot in text-only mode 2026-09-29 00:10:57 +03:30
whqreza dc31f837fd feat(docker): add procurement-bot service with Groq STT and compose integration 2026-09-29 00:04:56 +03:30
whqreza 4cfb9ec6f6 feat(wizard): add real-time bi-directional sync, debounced auto-save, and bot draft prefill 2026-09-21 20:22:12 +03:30
MMD baa32a2652 feat(files): preview attachments via short-lived signed URLs
Downloads require an Authorization header, which <iframe>/<img> cannot
send. The previous blob: workaround broke under download managers (IDM
hooks blob URLs, fails to resolve them, and leaves a 0-byte file) and in
Chrome's mobile emulation, which has no inline PDF plugin.

Backend:
- preview_token.py: HMAC-signed token bound to one (quote, kind, file)
  with a 5-minute TTL, keyed off an existing secret
- GET /quotes/{id}/preview-url/{kind}/{attachment} mints the URL
- the two file GET routes accept a Bearer session OR the signed ?t= token
  (they leave the global auth dep, so the other six file routes now carry
  it explicitly — nothing is open by omission)

Frontend:
- api.files.previewUrl() replaces the blob helper
- shared FilePreviewModal + useFilePreview; FileList and the dashboard
  quote card both use it
- PDFs render with the browser's native viewer on desktop and pdf.js on
  canvas where no inline viewer exists (mobile); pdf.js is fed the bytes
  in memory so no PDF URL is exposed for a download manager to intercept
- removed the per-attachment download buttons on the dashboard card and
  the modal header

Ops:
- nginx: explicit MIME types (.mjs as text/javascript) — a module worker
  served as octet-stream is refused and crashed the page
- frontend service bypasses the nginx entrypoint, whose apk manifest call
  hangs when the package mirror is unreachable (502s)
2026-09-20 20:35:16 +03:30
MMD e03d94207b fix(compose): duplicate networks block on api service; overridable NPM_REGISTRY build arg 2026-09-19 00:11:24 +03:30
MMD 32323565e6 feat(hardening): login rate limiting, per-service memory limits, pinned images
- slowapi limiter on POST /auth/login (10/min per IP, Persian error msg);
  edge-level coarse limits stay in Traefik
- mem_limit on every main-compose service (~4.4GB worst case, protects the
  8GB shared host during rebuilds)
- monitoring images pinned to verified tags (prom v3.4.1, grafana 11.6.3,
  loki/promtail 3.5.0, node-exporter v1.9.1, postgres-exporter v0.17.1,
  cadvisor v0.49.1); exporter image name fixed to postgres-exporter
2026-09-18 22:27:59 +03:30
MMD e5d6c77c3c feat(data-safety): scheduled DB backups + audit trail + verified actor attribution
- db-backup sidecar: pg_dump -Fc of procurement+casdoor every
  BACKUP_INTERVAL_SECONDS into BACKUP_DIR, retention via BACKUP_KEEP_DAYS
- audit_log table (migration.sql + runtime ensure_audit_table) with
  model + transactional helper (utils/audit.record) — wired into user
  create/role-change and inventory transaction creation
- get_actor: quote_events.actor now stores the VERIFIED user's display
  name instead of the raw bearer token
2026-09-18 22:23:34 +03:30
MMD e17d1f0883 feat(monitoring): observability stack + app instrumentation
- /health/ready (DB+MinIO+Casdoor checks, webhook post-deploy gate),
  /metrics via prometheus-fastapi-instrumentator, Sentry/GlitchTip capture,
  X-Request-ID middleware + JSON access logging (PROCUREMENT_LOG_FORMAT)
- server-side analytics (OpenPanel Track API): login, quote lifecycle,
  receipts — fire-and-forget, disabled without env config
- monitoring/ compose project: GlitchTip(+pg), Prometheus(+alerts),
  Grafana(provisioned ERP dashboard), Loki+Promtail, node/postgres
  exporters, cAdvisor — mem-limited (~2.2GB), loopback admin UIs,
  separate from app deploys; erp_shared network for scraping
- frontend: @openpanel/web + @sentry/react (build-arg gated, no-op when
  unset), funnel events (login, wizard steps, quote submitted)
- compose: api healthcheck, observability env wiring, .env.example keys
2026-09-18 22:18:02 +03:30
MMD 43e317eeba chore(security): remove committed secrets/dumps, .env-based config, hardened deploy webhook
- Delete backups/*.dump and all real credentials from README/docs
  (prod MinIO creds, Casdoor passwords, server IP, admin password)
- All stack secrets now come from git-ignored .env (.env.example added);
  docker-compose.prod.yml refuses to boot without them (${VAR:?})
- seed_casdoor.py: bcrypt password hashing, generated console/client secrets
- Harden infra/deploy-webhook: HMAC-verified Gitea webhook receiver
  + systemd unit + README (replaces unauthenticated deploy endpoint)
- docs/SECRET-MANAGEMENT.md: secret inventory + rotation checklist
2026-09-18 21:55:24 +03:30
ali_mohaghegh 8825f333a7 infra: single postgres instance (casdoor DB merged) + Traefik v3 edge
- remove the separate casdoor-postgres container; casdoor uses the main
  postgres (db casdoor, created by sql/02-casdoor-db.sql on fresh volumes);
  data migrated via pg_dump/pg_restore (backups kept outside the repo)
- Traefik v3.6 as the public edge (ports 80/443): docker provider pinned to
  the dedicated traefik_network (fixed-name network), host rules for
  app/api/auth/s3/storage (env-overridable, localhost defaults), frontend
  nginx demoted to internal SPA server; docker-compose.prod.yml adds real
  domains + Let's Encrypt + HTTP→HTTPS redirect (redirect middleware in
  infra/traefik-dynamic.yml)
- v3.6 required (Traefik <=3.3 fails against Docker Engine 29.x); socket
  mounted rw (Docker Desktop rejects :ro)
- start.ps1: app URL now http://localhost, casdoor + db notes
2026-09-01 17:28:33 +03:30
ali_mohaghegh fde2168606 feat(casdoor): seeder for current Casdoor version + wire api env and dev-login build arg
- seed_casdoor.py: JSON type=login + cookie session (the old form-encoded
  login-normal API is gone), application with grantTypes incl. password,
  passwordType=plain for the seeded users, idempotent re-runs; adds a
  dedicated tester user
- docker-compose: Casdoor env for the api service (endpoint casdoor:8000
  in-network, issuer http://localhost:8080 as advertised by discovery) and
  the DEV_LOGIN_ENABLED build arg for the frontend
2026-08-29 14:44:01 +03:30
ali_mohaghegh 5b27647a0a chore: add repo scaffolding (compose, scripts, gitignore, env example) 2026-08-25 19:08:02 +03:30