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
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>
This commit is contained in:
@@ -25,7 +25,9 @@ public class DemoSeedController : CafeApiControllerBase
|
|||||||
CancellationToken ct)
|
CancellationToken ct)
|
||||||
{
|
{
|
||||||
if (EnsureCafeAccess(cafeId, tenant) is { } denied) return denied;
|
if (EnsureCafeAccess(cafeId, tenant) is { } denied) return denied;
|
||||||
if (EnsureOwner(tenant) is { } ownerDenied) return ownerDenied;
|
// Demo data is a setup helper; Owner or Manager may run it (matches the
|
||||||
|
// dashboard banner, which is shown to both roles).
|
||||||
|
if (EnsureManager(tenant) is { } managerDenied) return managerDenied;
|
||||||
|
|
||||||
var result = await _demoSeed.SeedAsync(cafeId, ct);
|
var result = await _demoSeed.SeedAsync(cafeId, ct);
|
||||||
return Ok(new ApiResponse<DemoSeedResult>(true, result));
|
return Ok(new ApiResponse<DemoSeedResult>(true, result));
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
import { Sparkles, Loader2 } from "lucide-react";
|
import { Sparkles, Loader2 } from "lucide-react";
|
||||||
import { apiPost } from "@/lib/api/client";
|
import { ApiClientError, apiPost } from "@/lib/api/client";
|
||||||
|
import { notify } from "@/lib/notify";
|
||||||
import { useAuthStore } from "@/lib/stores/auth.store";
|
import { useAuthStore } from "@/lib/stores/auth.store";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
@@ -39,6 +40,13 @@ export function DemoDataBanner({ invalidateKeys, className }: Props) {
|
|||||||
qc.invalidateQueries({ queryKey: key });
|
qc.invalidateQueries({ queryKey: key });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onError: (err) => {
|
||||||
|
notify.error(
|
||||||
|
err instanceof ApiClientError
|
||||||
|
? err.message
|
||||||
|
: "افزودن دادههای نمونه ناموفق بود. دوباره تلاش کنید."
|
||||||
|
);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!cafeId || (role !== "Owner" && role !== "Manager")) return null;
|
if (!cafeId || (role !== "Owner" && role !== "Manager")) return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user