Commit Graph

223 Commits

Author SHA1 Message Date
soroush.asadi 7122df57b2 feat(menu): delete category/item + fix RTL availability toggle
CI/CD / CI · API (dotnet build + test) (push) Successful in 56s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 58s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m4s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
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 3m18s
- Add DELETE /api/cafes/{cafeId}/menu/items/{id} (DeleteItemAsync soft-delete,
  mirroring the existing category delete) — item delete had no backend route.
- Dashboard menu admin: destructive "delete" action in the item and category
  edit modals, behind a shared confirm dialog (AlertDialog). Deleting the
  selected category falls back to "all items".
- Fix the availability ToggleSwitch in RTL: force dir="ltr" so the knob's
  translate-x stays inside the track instead of escaping on the right
  (same fix as the admin-panel toggles).
- i18n: deleteItem/deleteCategory confirm + success strings (fa/en/ar).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 12:24:09 +03:30
soroush.asadi 72f95aa0db fix(demo-seed): stop truncating ingredient/table ids to 36 chars
CI/CD / CI · API (dotnet build + test) (push) Successful in 1m9s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 47s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m6s
CI/CD / CI · Admin Web (tsc) (push) Successful in 36s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 50s
CI/CD / Deploy · all services (push) Successful in 1m24s
BuildDemoIngredients/BuildDemoTables built ids as
"{cafeId}_ing_{guid}"[..36]. For a real cafe (32-char hex id) the
first 36 chars are just "{cafeId}_ing" — the unique guid is cut off,
so all 15 ingredients (and all 10 tables) get the SAME id, causing a
primary-key collision on SaveChanges -> 500. cafe_demo_001 has a short
id so the guid survived, which is why the bug only hit real cafes.

The Id columns are text (no length limit), so the truncation served no
purpose. Removed [..36] from both so the full unique id is kept.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 11:55:06 +03:30
soroush.asadi bab3453e41 fix(auth): read role claim under mapped name so Owner/Manager gates work
CI/CD / CI · API (dotnet build + test) (push) Successful in 43s
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 36s
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 1m27s
ROOT CAUSE of demo-seed/billing/etc. returning 403 for real owners: .NET's JWT
handler remaps the short "role" claim to ClaimTypes.Role on inbound, so
TenantMiddleware's FindFirst("role") returned null and tenant.Role (EmployeeRole?)
stayed null. EnsureManager/EnsureOwner then rejected even a valid Owner token with
MANAGER_REQUIRED / OWNER_REQUIRED, while reads (no role gate) worked and
[Authorize(Roles=...)] worked (it reads the remapped claim). Now reads the role
under both MeeziClaimTypes.Role ("role") and ClaimTypes.Role. Same fix applied to
the AuthController whoami role. Fixes demo seed, subscription billing, and every
other tenant.Role-gated action.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 11:18:10 +03:30
soroush.asadi 24da1e0522 feat(orders): per-item kitchen/bar notes (POS + QR app + KDS)
CI/CD / CI · API (dotnet build + test) (push) Successful in 57s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 57s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m6s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
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 2m43s
Lets the POS agent and the QR/app customer attach a free-text note to each
order line (e.g. "no tomato", "extra hot") that reaches the kitchen/bar.

- Backend already supported it (OrderItem.Notes persists; CreateOrderItemRequest
  and OrderItemDto carry Notes; LiveOrderDto items include it) — this wires the UI.
- cart.store: add setNotes(menuItemId, notes); notes already travel in
  getPendingLines and round-trip via hydrateFromOrder.
- POS pos-screen: a note input under each cart line.
- QR guest menu: a note input under each cart line (QrCartLine.note).
- KDS: render the note prominently under each item so kitchen/bar sees it.
- i18n: pos.itemNotePlaceholder + qrMenu.itemNote (fa/ar/en).

Note: notes are captured on items being added; editing a note on an
already-submitted line is out of scope (no pending delta to re-send).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 09:37:59 +03:30
soroush.asadi 2203ecbdaf fix(koja): remove over-broad short-URL redirect that 500'd the home page
CI/CD / CI · API (dotnet build + test) (push) Failing after 3m18s
CI/CD / CI · Admin API (dotnet build) (push) Failing after 2m22s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m5s
CI/CD / CI · Admin Web (tsc) (push) Successful in 36s
CI/CD / CI · Website (tsc) (push) Successful in 45s
CI/CD / CI · Koja (tsc) (push) Successful in 50s
CI/CD / Deploy · all services (push) Has been skipped
The redirect source "/:slug([a-z0-9][a-z0-9-]*[a-z0-9])" matched single-segment
paths including the locale itself, so /fa redirected to /fa/cafe/fa (slug "fa")
and /en to /fa/cafe/en — non-existent cafés that returned Internal Server Error.
Visiting koja.meezi.ir (-> /fa) hit this. Removed the redirect so the home page
renders; short café URLs can be re-added via middleware with reserved-word guards.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 08:29:27 +03:30
soroush.asadi 1aaab6c593 fix(admin): integrations save uses rendered list (fixes dropped Zarinpal merchantId)
CI/CD / CI · API (dotnet build + test) (push) Successful in 58s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 33s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m6s
CI/CD / CI · Admin Web (tsc) (push) Successful in 38s
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 1m42s
The integrations form rendered from  (gateways state, falling back to fetched data) but SAVED from the  state and edited via updateGateway on . If gateways hadn't hydrated, edits (e.g. Zarinpal merchantId) were written to an empty array and the save sent nothing. Now updateGateway seeds from fetched data on first edit, and the save maps over  — render, edit, and save share one source. NOTE: prod admin had also been stale because recent deploys aborted on the main-API crash before the admin containers restarted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 08:15:16 +03:30
soroush.asadi 09bba5f8cd fix(seed): count soft-deleted rows + make platform seeding non-fatal
CI/CD / CI · API (dotnet build + test) (push) Successful in 45s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 33s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m4s
CI/CD / CI · Admin Web (tsc) (push) Successful in 34s
CI/CD / CI · Website (tsc) (push) Successful in 43s
CI/CD / CI · Koja (tsc) (push) Successful in 48s
CI/CD / Deploy · all services (push) Successful in 1m20s
Root cause of the crash-loop: a soft-deleted Free plan still occupies its Tier in the unique index, but the existing-row check queried THROUGH the soft-delete global filter and missed it, so the seeder re-inserted Free and violated IX_PlatformPlanDefinitions_Tier on boot. Fixes: (1) IgnoreQueryFilters() on the plan/feature existing-checks so soft-deleted tiers/keys are counted; (2) wrap plan/feature/location seeding in try/catch so any seeding failure logs and startup continues — non-essential seeding must never crash-loop the API.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 02:26:11 +03:30
soroush.asadi 3b8dcf3af6 fix(seed): dedupe plans by Tier and features by Key (hotfix crash-loop)
CI/CD / CI · API (dotnet build + test) (push) Successful in 2m39s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 31s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m2s
CI/CD / CI · Admin Web (tsc) (push) Successful in 34s
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 1m27s
The previous change deduped on Id, but the unique constraints are on PlatformPlanDefinitions.Tier and PlatformFeatures.Key. Prod's existing Free plan has a different Id, so seeding re-inserted a Free-tier row and crashed on IX_PlatformPlanDefinitions_Tier (23505), crash-looping the API. Now skips any tier/key that already exists.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 02:11:42 +03:30
soroush.asadi 087563bce7 feat(settings): use-my-current-location button; surface ticket-load error
CI/CD / CI · Admin API (dotnet build) (push) Successful in 52s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m5s
CI/CD / CI · Admin Web (tsc) (push) Successful in 36s
CI/CD / CI · Website (tsc) (push) Successful in 45s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / CI · API (dotnet build + test) (push) Successful in 41s
CI/CD / Deploy · all services (push) Failing after 2m34s
Location card gets a 'موقعیت فعلی من' button that fills lat/lng from the browser's geolocation. Support ticket list now shows the resolved (localized) error instead of a generic message, so a failure is diagnosable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 01:52:29 +03:30
soroush.asadi e839db7331 fix(koja): default to fa (no browser locale guess); guard null discoverProfile
Koja auto-detected locale from the browser Accept-Language (en for many Persian users); set localeDetection:false so locale-less URLs default to fa. Also guarded cafe.discoverProfile across the cafe page, cafe card, and JSON-LD — a café without a discover profile crashed the page (500). The cafe page now resolves the café first and notFound()s an unknown slug before fetching menu/reviews.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 01:51:50 +03:30
soroush.asadi a83edf7667 fix: seed all plans/features in prod (upsert); fix admin toggle RTL knob
CI/CD / CI · API (dotnet build + test) (push) Successful in 50s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 39s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m5s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 45s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Failing after 5m44s
Plan + feature seeding was dev-gated and all-or-nothing, so production only had the Free plan (admin Plans page showed one). Now runs in every environment and upserts missing rows (adds Pro/Business/Enterprise on top of the existing Free). Also force LTR on the admin toggle switch so the knob doesn't render off-track under the RTL page.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 00:23:17 +03:30
soroush.asadi 75d5bbc84a fix(i18n): localize API error messages by code (no more raw English)
Error toasts surfaced the raw English backend message. Added an errors namespace (fa/ar/en) keyed by error code + a useApiError() resolver that maps ApiClientError.code to the localized message (fallback to a localized generic). Wired into menu, tables, demo banner, and subscription checkout; hardened getErrorMessage so it never returns the raw backend message.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 00:04:48 +03:30
soroush.asadi 7519f474f3 fix(demo): allow Manager to seed demo data + surface seed errors
CI/CD / CI · API (dotnet build + test) (push) Successful in 1m1s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 46s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m6s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 45s
CI/CD / CI · Koja (tsc) (push) Successful in 50s
CI/CD / Deploy · all services (push) Successful in 3m15s
The dashboard demo-data banner is shown to Owner and Manager, but the /demo/seed endpoint required strictly Owner, so a Manager clicking it got a silent 403 (the banner had no error handler) — appearing as 'nothing happens, no tables or items'. The endpoint now allows Owner or Manager, and the banner shows the error on failure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 23:23:39 +03:30
soroush.asadi 35494d8b32 fix(i18n): keep locale on website->dashboard links; dashboard defaults to fa
Marketing-site login/register/dashboard links were locale-less (app.meezi.ir/login), so the dashboard auto-detected locale from the browser Accept-Language (en-US) and redirected Persian users to /en. Links now carry the current locale, and the dashboard sets localeDetection:false so any locale-less entry defaults to fa (Iran-first) instead of guessing from the browser.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 23:23:09 +03:30
soroush.asadi 4c7783884c feat(map): backfill café coordinates from city on startup (prod-safe)
CI/CD / CI · API (dotnet build + test) (push) Successful in 56s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 32s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m5s
CI/CD / CI · Admin Web (tsc) (push) Successful in 36s
CI/CD / CI · Website (tsc) (push) Successful in 45s
CI/CD / CI · Koja (tsc) (push) Successful in 48s
CI/CD / Deploy · all services (push) Successful in 1m40s
Real cafés without a map pin now get approximate coordinates at their city centre (with a deterministic per-café offset) on every boot, in all environments, so the public Iran map lights up with merchant dots. Only fills rows where Latitude/Longitude is null and the city is recognised (20 major Iranian cities); never overwrites an owner-set pin. Owners can drop an exact pin from Settings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 22:38:28 +03:30
soroush.asadi 8ce0b3e3e8 feat(discover): seed showcase café coordinates so the map shows blinking lights
CI/CD / CI · API (dotnet build + test) (push) Successful in 40s
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 35s
CI/CD / CI · Website (tsc) (push) Successful in 45s
CI/CD / CI · Koja (tsc) (push) Successful in 48s
CI/CD / Deploy · all services (push) Successful in 4m11s
Showcase cafés (dev/staging only) now get Latitude/Longitude scattered around their real city (Tehran/Karaj) with a deterministic per-id offset, so the homepage Iran map renders a realistic cluster of blinking merchant lights. Backfills existing rows where coords are null. Production cafés get coordinates when owners set their location in dashboard Settings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 22:00:14 +03:30
soroush.asadi b5a6b1b68d fix(website): accurate Iran border on homepage map + slow on/off marker blink
CI/CD / CI · API (dotnet build + test) (pull_request) Successful in 46s
CI/CD / CI · Admin API (dotnet build) (pull_request) Successful in 31s
CI/CD / CI · Dashboard (tsc) (pull_request) Successful in 1m5s
CI/CD / CI · Admin Web (tsc) (pull_request) Successful in 35s
CI/CD / CI · Website (tsc) (pull_request) Successful in 45s
CI/CD / CI · Koja (tsc) (pull_request) Successful in 51s
CI/CD / Deploy · all services (pull_request) Has been skipped
Replaced the rough 40-point hand-drawn polygon with the real national border (74 vertices, Natural Earth via world.geo.json) and fitted the projection bounding box to Iran's true extent, so the silhouette is recognisable and café markers stay aligned. Reworked the marker animation from a radar-style expanding ring into a slow 3.6s ease-in-out lamp fade (opacity 1->0.2->1) with a halo that glows on and off in sync. Verified via the SVG timeline: opacity 1.0 at 0s, 0.2 at 1.8s, 1.0 at 3.6s.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 21:38:25 +03:30
soroush.asadi f813cc4854 test: repair test suite broken by feature drift (red -> 81 passing)
CI/CD / CI · API (dotnet build + test) (pull_request) Successful in 43s
CI/CD / CI · Admin API (dotnet build) (pull_request) Successful in 44s
CI/CD / CI · Dashboard (tsc) (pull_request) Successful in 1m7s
CI/CD / CI · Admin Web (tsc) (pull_request) Successful in 36s
CI/CD / CI · Website (tsc) (pull_request) Successful in 45s
CI/CD / CI · Koja (tsc) (pull_request) Successful in 51s
CI/CD / Deploy · all services (pull_request) Has been skipped
The test project no longer compiled: recent feature commits changed
interfaces and DTOs without updating the test doubles/call sites, so the
whole suite (and therefore CI) was failing to build.

- NoOpInventoryService: add IInventoryService.GetPurchasesSummaryAsync and
  the new string? userId param on AdjustAsync.
- NoOpLoyaltyService: add ILoyaltyService.RedeemOnOrderAsync.
- NoOpOrderNotificationService: add NotifyCallWaiterAsync.
- New NoOpAbuseProtectionService and NoOpMediaStorageService test doubles.
- QrMenuTests: ReviewService/PublicService gained IAbuseProtectionService +
  IHttpContextAccessor (and ReviewService an IMediaStorageService); wire the
  new no-op doubles + a real HttpContextAccessor.
- PrintingTests: OrderDto gained a DisplayNumber int between CreatedAt and
  Items; pass it.
- DiscoverFilterTests: add missing `using Xunit;` and the new openNow arg on
  DiscoverFilterParams.FromQuery.

Result: dotnet test -> Passed: 81, Failed: 0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 18:44:41 +03:30
soroush.asadi 024a455ab3 fix: menu item/category create, demo banner reach, token refresh, blog publish
Dashboard & API bug fixes for owner-reported breakage:

- MenuController validators (PosValidators): NameEn was required but the
  dashboard sends null when blank, so every manual menu-item create failed
  and category create failed 100% (the form never sends nameEn). Now optional.
- DemoDataBanner: only showed when a cafe was exactly empty, so
  showcase-seeded cafes (2-3 cats / 3-5 items) could never trigger the
  one-click seed. Widened gate to sparse menus (<5 cats && <10 items) and
  added a clear "nothing to add" message when already populated.
- client.ts: added one-time JWT refresh-and-retry on 401 (shared in-flight
  promise) before bouncing to /login. Expired access tokens silently broke
  ticket list, add-table, and other reads.
- Surface API errors as toasts on menu + table mutations (were swallowed
  silently, so failures looked like "nothing happens").
- Admin blog editor: saving an edit dropped IsPublished (defaulted false,
  silently unpublishing the post on every save); now persisted with a
  toggle. Also hoisted the inner Field component to module scope - it was
  remounting every input on each keystroke and dropping focus.
- Admin integrations: replaced raw radio gateway selector with a styled
  RadioDot matching the iOS toggles.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 18:25:34 +03:30
soroush.asadi f687178238 fix(migration): add [Migration] attribute so EF discovers AddCafeLocation
CI/CD / CI · API (dotnet build + test) (push) Successful in 57s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 46s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m5s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
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 1m27s
Manual migration was missing the [Migration("...")] and [DbContext] attributes
that EF Core requires to discover and apply migrations via MigrateAsync().
Without them the Latitude/Longitude columns were never added to Cafes, causing
every query involving the Cafe entity to throw 42703 column-not-found errors.

Columns must be applied manually on the server before the next deploy:
  ALTER TABLE "Cafes" ADD COLUMN IF NOT EXISTS "Latitude" double precision, ...

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 15:59:08 +03:30
soroush.asadi dc07eb9594 ci: prune dangling images after successful deploy
CI/CD / CI · API (dotnet build + test) (push) Successful in 58s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 1m1s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m5s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
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 23s
Removes <none>-tagged images left over from previous builds.
Only affects untagged images (dangling=true) — never touches other
projects' named images (soroushasadi-site, drsousan, etc.).
Also logs disk usage after prune.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 15:35:18 +03:30
soroush.asadi 5e980cdfc0 feat: plan limits, café location, nearby API, Iran map section
CI/CD / CI · API (dotnet build + test) (push) Successful in 56s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 49s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m4s
CI/CD / CI · Admin Web (tsc) (push) Successful in 34s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 50s
CI/CD / Deploy · all services (push) Successful in 3m15s
• PlanLimits: add MaxMenuCategories (Free→3), MaxMenuItems (Free→30),
  CanAccessCrm and CanAccessStatistics (Pro+ only)
• MenuController: enforce category/item limits before create (403 + PLAN_LIMIT_REACHED)
• Cafe entity + EF migration: Latitude/Longitude (double?, nullable)
• CafeSettingsController: PATCH accepts lat/lng with range validation
• PublicController: GET /api/public/map-markers (marketing SVG map feed)
  and GET /api/public/nearby (Koja nearby-cafés with Haversine sort)
• Dashboard settings: location card with OSM iframe preview + Neshan link
• Website homepage: IranMapSection — stylised SVG silhouette with
  SMIL-animated blinking dots at real café coordinates

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 15:09:09 +03:30
soroush.asadi 665e3ca279 fix(demo): scope category/item IDs per café to prevent PK collisions
CI/CD / CI · API (dotnet build + test) (push) Successful in 56s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 52s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m3s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 43s
CI/CD / CI · Koja (tsc) (push) Successful in 48s
CI/CD / Deploy · all services (push) Successful in 1m31s
DemoMenuSeeder used hardcoded IDs like cat_demo_coffee for every café.
If the dev seeder (runs when ASPNETCORE_ENVIRONMENT=Development) already
inserted those IDs for cafe_demo_001, a production café clicking
"Add demo data" hit a primary-key constraint violation.

Fix: EnsureMenuAsync now accepts useScopedIds=true which prefixes every
category and item ID with cafeId (e.g. cafe_abc_cat_demo_coffee).
CategoryId FKs on items are remapped through the same function.

DemoSeedService (the API endpoint handler) always passes useScopedIds=true.
DevelopmentDataSeeder keeps useScopedIds=false (default) so the existing
cafe_demo_001 rows in dev databases are not touched.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 13:59:48 +03:30
soroush.asadi c3ca39ed15 fix(ci): staged deploy with crash detection and full diagnostics
CI/CD / CI · API (dotnet build + test) (push) Successful in 1m4s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 35s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m4s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 54s
CI/CD / Deploy · all services (push) Successful in 22s
- Start api alone first; web/admin-api each wait for their own step
  so a health-check wait never blocks unrelated services
- Detect crash-loops via RestartCount > 1 (restart:unless-stopped hides
  the exited state behind rapid restarts — count is reliable)
- Dump up to 120 lines of api logs immediately on crash/timeout
- Log infra network state (json) in attach step + failure dump so we
  can see exactly which aliases are registered on meezi_default
- admin-api and admin-web are now started in separate steps, same pattern

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 13:44:52 +03:30
soroush.asadi dac59cd180 fix(ci): use --alias when connecting infra to meezi_default network
CI/CD / CI · API (dotnet build + test) (push) Successful in 44s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 47s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m4s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 48s
CI/CD / Deploy · all services (push) Successful in 1m36s
Without --alias, meezi-db joins meezi_default but is only reachable
as "meezi-db". The API uses Host=postgres — DNS lookup fails after
~5s, migration throws, container crashes.

Fix: disconnect first, then reconnect with service-name aliases
so "postgres" and "redis" resolve correctly on meezi_default.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 09:36:03 +03:30
soroush.asadi c3ea07d6e4 fix(ci): attach infra containers to meezi_default network before deploy
CI/CD / CI · API (dotnet build + test) (push) Successful in 40s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 36s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m2s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 48s
CI/CD / Deploy · all services (push) Failing after 10s
postgres/redis were created before the compose project name was locked
to "meezi", so they're on a different Docker network. New app containers
join meezi_default — the API crashes immediately because it can't reach
Host=postgres.

Fix: create meezi_default if needed, then docker network connect
meezi-db and meezi-redis to it before starting the app containers.

Also dump API and admin-api logs on failure to make future failures
easier to diagnose.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 08:39:35 +03:30
soroush.asadi aea1d20fdc fix(admin): redirect to edit page after creating blog post
CI/CD / CI · API (dotnet build + test) (push) Successful in 41s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 29s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m3s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 43s
CI/CD / CI · Koja (tsc) (push) Successful in 48s
CI/CD / Deploy · all services (push) Failing after 2m2s
Root cause: after successful creation the form stayed on /blog/new.
User couldn't tell it worked, clicked Save again, the second attempt
hit the unique slug constraint and showed an error — making it look
like creation was broken.

Fix: adminPost is now typed, onSuccess redirects to /blog/{id} on new
posts so the user lands on the edit page immediately.

Also fixes commentCount being undefined in the list (MapPost now
includes comment count via eager-loaded Comments).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 08:24:57 +03:30
soroush.asadi 9f002433c7 fix(ci): explicitly stop old app containers before redeploy
CI/CD / CI · API (dotnet build + test) (push) Successful in 39s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 31s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m3s
CI/CD / CI · Admin Web (tsc) (push) Successful in 34s
CI/CD / CI · Website (tsc) (push) Successful in 43s
CI/CD / CI · Koja (tsc) (push) Successful in 48s
CI/CD / Deploy · all services (push) Failing after 7s
Existing containers lack compose project labels so Compose cannot claim
them — it tries to CREATE alongside them and hits a name conflict.

Fix: stop + rm only the 6 meezi app containers by name before compose up.
Postgres, redis, and all other projects are never touched.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 08:08:19 +03:30
soroush.asadi 5ba09c2ef1 fix(website): move launch countdown to 1 Tir 1405 (June 22, 2026)
CI/CD / CI · API (dotnet build + test) (push) Successful in 40s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 30s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m3s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 43s
CI/CD / CI · Koja (tsc) (push) Successful in 48s
CI/CD / Deploy · all services (push) Failing after 1m27s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 07:59:22 +03:30
soroush.asadi 631cac8c3c fix(ci): never touch postgres/redis in deploy — app containers only
CI/CD / CI · API (dotnet build + test) (push) Successful in 54s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 45s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m3s
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
The meezi-redis container was created before the name:meezi label existed
in docker-compose.yml, so Compose doesn't recognise it as its own project
container and tries to CREATE a new one, causing the name conflict.

Real fix: postgres and redis are persistent infrastructure — CI should
never restart them. Remove them from all deploy steps entirely.
Only api, web, website, koja, admin-api, admin-web are cycled on deploy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 07:56:16 +03:30
soroush.asadi 1a6a0dc495 fix(ci): split infra vs app services to prevent redis name conflict
CI/CD / CI · API (dotnet build + test) (push) Successful in 43s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 31s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m4s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Failing after 10s
docker compose up without --no-recreate tries to recreate postgres/redis
when it detects a config change or finds a stopped container, which causes
"container name already in use" when the container is still running.

Fix: infrastructure (postgres, redis) uses --no-recreate so a healthy
container is never touched. App services (api, web, website, koja,
admin-api, admin-web) use --force-recreate so freshly-built images are
always applied.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 07:47:07 +03:30
soroush.asadi ffdc218e20 fix(admin): add missing useEffect import in admin-website-screens
CI/CD / CI · API (dotnet build + test) (push) Successful in 1m8s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 54s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m3s
CI/CD / CI · Admin Web (tsc) (push) Successful in 34s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 47s
CI/CD / Deploy · all services (push) Failing after 3m34s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 00:29:04 +03:30
soroush.asadi 260429afba feat: demo data seeder — one-click setup for new cafés
CI/CD / CI · API (dotnet build + test) (push) Successful in 47s
CI/CD / CI · Admin API (dotnet build) (push) Has been cancelled
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
Adds POST /api/cafes/{cafeId}/demo/seed (owner-only) that seeds:
- 9% default VAT tax
- 7 menu categories + 59+ items via DemoMenuSeeder
- 15 inventory ingredients (coffee shop staples)
- 10 tables across 3 floors on the first active branch

Frontend DemoDataBanner appears on menu, tables, and inventory
pages when the café is completely empty, so owners can populate
demo data in one click instead of entering everything manually.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 00:27:34 +03:30
soroush.asadi ae5896d440 fix: credentials lost on refresh + admin UI improvements + CI safe deploy
CI/CD / CI · API (dotnet build + test) (push) Successful in 39s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 30s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m2s
CI/CD / CI · Admin Web (tsc) (push) Failing after 35s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 48s
CI/CD / Deploy · all services (push) Has been skipped
- dashboard layout: wait for Zustand _hasHydrated before redirecting to /login
  (was redirecting on first render before localStorage was read)
- admin shell: same fix using new _hasHydrated on admin auth store
- admin-auth.store: add _hasHydrated + onRehydrateStorage to mirror merchant store
- AdminPlansScreen: replace direct cache mutation with per-plan PlanCard component
  that owns its own useState — fixes other plans disappearing after save
- AdminSettingsScreen: detect boolean values and render iOS-style Toggle switches
- AdminIntegrationsScreen: replace all <input type=checkbox> with Toggle switches;
  replace OpenAI model text input with <select> dropdown (gpt-4o-mini/4o/4-turbo/4/3.5)
- blog editor: fix form never syncing existing post data into state (editing was broken);
  all fields now use local form state, save uses form directly
- blog links: fix broken relative hrefs (website/blog/new → /admin/website/blog/new)
  and back button using proper Link components
- ci-cd: remove image prune step entirely — never removes containers or images

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 23:56:16 +03:30
soroush.asadi aec5b21f98 fix: lock compose project name to 'meezi', scope image prune to meezi only
CI/CD / CI · API (dotnet build + test) (push) Successful in 1m40s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 1m22s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m0s
CI/CD / CI · Admin Web (tsc) (push) Successful in 33s
CI/CD / CI · Website (tsc) (push) Successful in 43s
CI/CD / CI · Koja (tsc) (push) Successful in 47s
CI/CD / Deploy · all services (push) Failing after 2s
Prevents runner workspace collisions with other projects (DrSousan etc.)
causing containers to be treated as orphans and stopped on deploy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 23:45:07 +03:30
soroush.asadi 57c83185da fix: zarinpal silent failure + show payment error in checkout
CI/CD / CI · API (dotnet build + test) (push) Successful in 1m15s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 30s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m4s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 43s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Successful in 4m45s
Previously the subscribe mutation had no onError handler, so any
payment initiation failure (wrong merchant ID, ZarinPal API error,
disabled payment method) would silently re-enable the button with
no user feedback. Now errors are shown below the Pay button.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 22:40:04 +03:30
soroush.asadi cd1af30bbc fix: sidebar accordion + koja slug + support ticket LINQ crash
CI/CD / CI · API (dotnet build + test) (push) Successful in 5m50s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 32s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m3s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 48s
CI/CD / Deploy · all services (push) Has been cancelled
Sidebar:
- All groups start collapsed on first load (v4 storage key resets old state)
- Opening one group closes all others (accordion)
- Navigating to a section opens only that section's group

Koja slug:
- SlugHelper: Persian->Latin transliteration, slug validation
- Registration accepts optional custom slug; auto-derives from cafe name
- Slug can be updated from dashboard Settings -> Profile
- Settings PATCH validates uniqueness (SLUG_TAKEN) and format (INVALID_SLUG)
- koja.meezi.ir/{slug} now redirects to /fa/cafe/{slug} (short URL support)

Bug fix:
- SupportTicketService: cafeId/status filters applied before Select() projection
  to fix EF "could not be translated" crash on the support tickets page

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 22:28:25 +03:30
soroush.asadi 38e3f6a5a2 fix(admin-auth): normalize phone before OTP validation to fix 400 on verify-otp
CI/CD / CI · API (dotnet build + test) (push) Successful in 46s
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 34s
CI/CD / CI · Website (tsc) (push) Successful in 43s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Successful in 27s
VerifyOtpRequestValidator was passing the raw phone string to
IsValidIranMobile which requires a pre-normalized 11-digit "09…" string.
Any other format (country code prefix, Persian digits, etc.) failed
validation instantly — causing verify-otp to return HTTP 400 in ~2ms
before the service logic could ever run.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 21:00:37 +03:30
soroush.asadi 5ae350e25b fix: auto-create default branch on cafe registration + backfill existing
CI/CD / CI · API (dotnet build + test) (push) Successful in 42s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 34s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m3s
CI/CD / CI · Admin Web (tsc) (push) Successful in 34s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Has been cancelled
- VerifyRegisterAsync: create a Branch named after the café alongside
  the Café and Owner, so new owners can use the dashboard immediately
  without hitting the "select a branch" gate
- PlatformDataSeeder: EnsureDefaultBranchesAsync runs on every boot and
  creates a default branch for any existing café that has none (covers
  cafés registered before this fix)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 20:53:33 +03:30
soroush.asadi 255695e8ae fix(deploy): auto-migrate on boot + seed admin credentials from env
CI/CD / CI · API (dotnet build + test) (push) Successful in 47s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 43s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m5s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 46s
CI/CD / CI · Koja (tsc) (push) Successful in 48s
CI/CD / Deploy · all services (push) Successful in 3m36s
- docker-compose.admin.yml: RUN_MIGRATIONS was hardcoded false → now
  uses ${RUN_MIGRATIONS:-true} so migrations run automatically on deploy
- Both compose files: expose Seed__SystemAdminPhone/Username/Password
  env vars so the seeder sets admin credentials without manual SQL
- .env.example: document SEED_ADMIN_* variables

On next deploy: migrations run, Username='admin' is patched on the
existing admin, and password is hashed from SEED_ADMIN_PASSWORD.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 20:10:56 +03:30
soroush.asadi a4975cdb2d fix(seeder): patch existing admin username/password on every boot
CI/CD / CI · API (dotnet build + test) (push) Has been cancelled
CI/CD / CI · Admin API (dotnet build) (push) Has been cancelled
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
EnsureOwnerAdminAsync now sets Username='admin' (configurable via
Seed:SystemAdminUsername) on any existing admin that has no username,
and hashes Seed:SystemAdminPassword if provided and no hash is stored.
Covers fresh deploys and existing prod admins created before credentials
were added.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 20:07:33 +03:30
soroush.asadi 639d5c305e feat: username/password authentication for admin and merchant panels
CI/CD / CI · API (dotnet build + test) (push) Successful in 49s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 42s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m8s
CI/CD / CI · Admin Web (tsc) (push) Successful in 37s
CI/CD / CI · Website (tsc) (push) Successful in 46s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Has been cancelled
- Add PasswordHasher utility (PBKDF2/SHA-256, 100k iterations)
- Add Username + PasswordHash fields to Employee and SystemAdmin entities
- EF migration: AddPasswordLogin (nullable columns on both tables)
- Meezi.API: POST /api/auth/login (employee password login, CHOOSE_CAFE support)
- Meezi.API: PUT/DELETE /api/cafes/{id}/employees/{id}/credentials (Owner/Manager only)
- Meezi.Admin.API: POST /api/admin/auth/login + PUT /api/admin/auth/password
- Dashboard login page: OTP / Password tabs
- Admin login page: OTP / Password tabs
- HR screen: new Credentials tab for setting employee username/password
- PlatformDataSeeder: ensure system admin + integration settings in production
- Trial countdown banner: updated deadline to 1 Tir 1405 (Jun 22)
- i18n: fa/en/ar updated for all new UI strings

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 19:58:54 +03:30
soroush.asadi d0117f3171 fix(dashboard): sync lockfile and bump three to satisfy model-viewer peer
CI/CD / CI · API (dotnet build + test) (push) Successful in 59s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 32s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m5s
CI/CD / CI · Admin Web (tsc) (push) Successful in 37s
CI/CD / CI · Website (tsc) (push) Successful in 46s
CI/CD / CI · Koja (tsc) (push) Successful in 51s
CI/CD / Deploy · all services (push) Successful in 33s
npm ci failed in Docker because package-lock.json was stale (missing three
and the workbox/PWA deps) and @google/model-viewer@4.2.0 requires three@^0.182.0
while package.json pinned ^0.163.0. Bumped three and regenerated the lockfile.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 14:16:42 +03:30
soroush.asadi 2c15ae0062 CI CD 6
CI/CD / CI · API (dotnet build + test) (push) Successful in 44s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 31s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m7s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 48s
CI/CD / Deploy · all services (push) Failing after 59s
2026-05-31 13:01:38 +03:30
soroush.asadi 861b762e18 CI CD 5
CI/CD / CI · API (dotnet build + test) (push) Successful in 54s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 35s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m8s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 45s
CI/CD / CI · Koja (tsc) (push) Successful in 53s
CI/CD / Deploy · all services (push) Failing after 10m25s
2026-05-31 12:34:04 +03:30
soroush.asadi 234649c65e CI CD 4
CI/CD / CI · API (dotnet build + test) (push) Successful in 41s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 47s
CI/CD / CI · Dashboard (tsc) (push) Successful in 2m3s
CI/CD / CI · Admin Web (tsc) (push) Successful in 44s
CI/CD / CI · Website (tsc) (push) Successful in 46s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Failing after 14m30s
2026-05-31 12:03:46 +03:30
soroush.asadi a9222590ac CI CD 3
CI/CD / CI · API (dotnet build + test) (push) Successful in 41s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 34s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m44s
CI/CD / CI · Website (tsc) (push) Successful in 5m27s
CI/CD / CI · Koja (tsc) (push) Successful in 4m16s
CI/CD / Deploy · all services (push) Failing after 1m19s
2026-05-31 11:36:48 +03:30
soroush.asadi aec68eff34 CI CD 2 2026-05-31 11:31:05 +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 51e422272d bugfix : remove orphan 2026-05-30 09:42:32 +03:30