Vendor-assign events and scope event catalog to vendor
Some checks failed
CI / Server — typecheck & build (push) Has been cancelled
CI / Client — typecheck & build (push) Has been cancelled
CI / Docker build (smoke test) (push) Has been cancelled

- Add vendorWhereClause() helper: admin + ?vendorId= filters to that
  vendor; admin with no filter sees all; other roles locked to own
- Fix events GET / to use vendorWhereClause so vendor filter works
- EventFormModal: admin sees a Vendor picker when creating a new event,
  pre-populated from the active VendorFilter; POST includes ?vendorId=
- EventConfigPanel: scope /taxes and /products fetches to event.vendorId
  so only the event's vendor's catalog items are selectable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-21 17:48:44 -05:00
parent e1b1a82e07
commit 31e539102b
3 changed files with 58 additions and 8 deletions

View File

@@ -14,3 +14,22 @@ export function resolveVendorId(
}
return authReq.auth.vendorId;
}
/**
* Returns a Prisma `where` fragment for vendor filtering on list queries.
* - Admin with ?vendorId= → filter to that vendor
* - Admin without ?vendorId= → no filter (sees all)
* - Other roles → always locked to own vendorId
*/
export function vendorWhereClause(
authReq: AuthenticatedRequest,
query: Record<string, unknown> = {}
): Record<string, string> {
if (authReq.auth.roleName === "admin") {
if (typeof query.vendorId === "string" && query.vendorId) {
return { vendorId: query.vendorId };
}
return {};
}
return { vendorId: authReq.auth.vendorId };
}

View File

@@ -5,7 +5,7 @@ import { requireAuth, requireRole } from "../middleware/auth.js";
import { AppError } from "../middleware/errorHandler.js";
import { parsePage, paginatedResponse } from "../lib/pagination.js";
import { AuthenticatedRequest } from "../types/index.js";
import { resolveVendorId } from "../lib/vendorScope.js";
import { resolveVendorId, vendorWhereClause } from "../lib/vendorScope.js";
const router = Router();
const auth = requireAuth as unknown as (r: Request, s: Response, n: NextFunction) => void;
@@ -39,7 +39,7 @@ router.get("/", auth, vendorUp, async (req: Request, res: Response, next: NextFu
try {
const authReq = req as AuthenticatedRequest;
const { page, limit, skip } = parsePage(req.query as Record<string, unknown>);
const where = vendorScope(authReq);
const where = vendorWhereClause(authReq, req.query as Record<string, unknown>);
const [data, total] = await Promise.all([
prisma.event.findMany({