Commit Graph

7 Commits

Author SHA1 Message Date
soroush.asadi 27ca80fd54 fix(orders): block cancelling an order once the kitchen has started it
CI/CD / CI · API (dotnet build + test) (push) Successful in 52s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 29s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m8s
CI/CD / CI · Admin Web (tsc) (push) Successful in 39s
CI/CD / CI · Website (tsc) (push) Successful in 45s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Successful in 1m40s
Anti-fraud / integrity: a cashier could fire an order to the kitchen, take cash
without recording a payment, then cancel (soft-delete) the unpaid order to erase
it. CancelOrderAsync now only allows cancelling a still-Pending order; once the
kitchen has acted on it (Confirmed/Preparing/Ready) it returns ORDER_IN_PREPARATION
and a started order can no longer be removed — it must be completed (and refunded
through the audited refund flow if needed). Delivered → ORDER_NOT_OPEN; paid →
ORDER_HAS_PAYMENTS (unchanged). Orders are never hard-deleted and every cancel is
already audited with the actor. Applies to all roles, independent of permissions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 10:41:30 +03:30
soroush.asadi 63e3cb6962 fix(security,pos): close payment/push/PII gaps from app review
CI/CD / CI · API (dotnet build + test) (push) Successful in 59s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 33s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m10s
CI/CD / CI · Admin Web (tsc) (push) Successful in 40s
CI/CD / CI · Website (tsc) (push) Successful in 48s
CI/CD / CI · Koja (tsc) (push) Successful in 52s
CI/CD / Deploy · all services (push) Successful in 2m13s
- Payments: reject RecordPaymentsAsync when the order is already Delivered/
  Cancelled (ORDER_ALREADY_CLOSED) — prevents duplicate payments, double loyalty
  earn, and overstated cash drawer from a double-tap or paying a reopened order.
- Push broadcast: POST /api/push/broadcast was [Authorize]-only (any user → any
  topic, platform-wide). Now requires SendSms + café context and is forced to the
  caller's own topic (cafe-{slug}); arbitrary/cross-café topics rejected.
- HR reads: GetEmployees/GetAttendance/GetShifts now require ViewStaff/
  ViewAttendance/ViewSchedules (were café-access-only, leaking roster PII the UI
  already hid). Expenses list now requires ViewExpenses.
- Receipt: removed the auto-print on full payment so the POS success sheet is the
  single print path (no more double receipt).

Local build blocked by NU1301 (NuGet network unreachable); CI builds via mirror.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 15:40:20 +03:30
soroush.asadi 958addf734 feat(kds): filter the kitchen display by station (kitchen / bar)
CI/CD / CI · API (dotnet build + test) (push) Successful in 44s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 30s
CI/CD / CI · Dashboard (tsc) (push) Has been cancelled
CI/CD / CI · Admin Web (tsc) (push) Has been cancelled
CI/CD / CI · Website (tsc) (push) Has been cancelled
CI/CD / CI · Koja (tsc) (push) Has been cancelled
CI/CD / Deploy · all services (push) Has been cancelled
Complements the separate kitchen/bar printers with an on-screen split. The live
order DTO now carries each item's prep station (MenuItem → Category →
KitchenStation), and the KDS shows station tabs (All / Kitchen / Bar / …) that
appear only once ≥2 stations are in play. Selecting a station shows just the
tickets — and just the items within each ticket — for that station, so bar staff
see drinks and kitchen staff see food. Single-station cafés see the board
unchanged. fa/en/ar strings added.

Note: order status is still per-order (one advance button); the split is for
viewing/printing, not per-item status.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 10:27:40 +03:30
soroush.asadi c47922414a feat: اصلاح سند payment corrections + audit-log & daily P&L views
CI/CD / CI · API (dotnet build + test) (push) Successful in 51s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 31s
CI/CD / CI · Dashboard (tsc) (push) Failing after 1m12s
CI/CD / CI · Admin Web (tsc) (push) Successful in 40s
CI/CD / CI · Website (tsc) (push) Successful in 46s
CI/CD / CI · Koja (tsc) (push) Successful in 51s
CI/CD / Deploy · all services (push) Has been skipped
Backend:
- POST /orders/{id}/payments/corrections (Manager/Owner): void wrong
  payments (marked Refunded, never deleted) and/or record replacements
  atomically; mandatory reason; requires an open register shift; full
  before/after written to the immutable audit trail.
- GET /orders/closed?date= — closed orders of one Iran-calendar day,
  paged, the browsing surface for corrections.
- CalculateExpectedCash now subtracts cash refunds so corrections keep
  the drawer expectation honest.

Dashboard (reports screen now has three tabs):
- عملکرد و سود: existing KPIs/charts + new day-by-day breakdown table
  (orders, revenue, expenses, net profit per Jalali day).
- اصلاح سند: closed-orders browser with payment chips + correction
  dialog (void checkboxes, replacement rows, live balance, reason).
- گزارش عملیات: filterable audit-log viewer (category, Jalali range,
  branch) with expandable structured details.

fa/en/ar translations included. 86 backend tests pass; dashboard tsc clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 01:24:19 +03:30
soroush.asadi dcdb0d5747 feat(realtime): global guest-order alert on the dashboard
CI/CD / CI · API (dotnet build + test) (push) Successful in 47s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 32s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m4s
CI/CD / CI · Admin Web (tsc) (push) Successful in 37s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Successful in 3m9s
Guest orders from the QR/digital menu already notified via SignalR, but only
screens that were open (KDS/POS/tables) reacted — and silently (a data refresh,
no alert). So staff on any other screen never knew a menu order arrived.

- Add a global useOrderAlerts() mounted in the dashboard shell: connects to
  /hubs/kds, joins the café group, and on a new GUEST order plays a chime + shows
  a toast (localized fa/en/ar) + nudges order/KDS/POS lists to refresh — on every
  screen.
- Filter to guest QR-menu orders only (not staff POS orders): LiveOrderDto now
  carries Source, set in MapLiveOrder (+ the delivery/snappfood mappers).

86 API tests pass; dashboard tsc + build clean.
2026-06-03 02:42:29 +03:30
soroush.asadi 345ae0a4b5 first commit
CI/CD / CI · Admin API (dotnet build) (push) Successful in 41s
CI/CD / CI · Admin Web (tsc) (push) Failing after 5s
CI/CD / CI · Website (tsc) (push) Failing after 4s
CI/CD / CI · Koja (tsc) (push) Failing after 5s
CI/CD / CI · API (dotnet build + test) (push) Successful in 1m13s
CI/CD / CI · Dashboard (tsc) (push) Failing after 2m32s
CI/CD / Deploy · all services (push) Has been skipped
2026-05-31 11:06:24 +03:30
soroush.asadi ef15fd6247 feat(api): .NET 10 multi-tenant REST API
Full backend implementation:
- Multi-tenant cafe/restaurant management (menus, orders, tables, staff)
- POS order flow with ZarinPal and Snappfood payment integration
- OTP authentication via Kavenegar SMS
- QR digital menu with public discover/finder endpoints
- Customer loyalty, coupons, CRM
- PostgreSQL via EF Core, Redis for caching/sessions
- Background jobs, webhook handlers
- Full migration history

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-27 21:33:48 +03:30