/** * GET /api/products * * Returns a list of products visible to the current user based on their active role. * * Role-based Visibility (MVP): * - Unauthenticated users: See NO products (empty array) * - Authenticated users: See products assigned to their ACTIVE role only * - Products WITHOUT role assignments: NOT visible (opt-in visibility) * * Query Parameters: * - category: Filter by category (optional, comma-separated for multiple) * * Phase 2/3: This will be extended with role request/approval workflow */ import { eq, and, inArray } from 'drizzle-orm' import { products } from '../../database/schema' import { getVisibleProductIdsForRole } from '../../utils/roles' import { getUserActiveRole } from '../../utils/role-session' export default defineEventHandler(async (event) => { const db = useDatabase() const query = getQuery(event) const categoryParam = query.category as string | undefined try { // Get user session (if authenticated) const { user } = await getUserSession(event) // MVP: Unauthenticated users cannot see any products if (!user) { return [] } // Get user's active role (validates with TTL, auto-fallback if revoked) const activeRole = await getUserActiveRole(event) // Get product IDs visible for the active role only const visibleProductIds = await getVisibleProductIdsForRole(user.id, activeRole) // If user has no access to products in their active role if (visibleProductIds.length === 0) { return [] } // Build where conditions const conditions = [ eq(products.active, true), inArray(products.id, visibleProductIds), // Role-based filtering ] // Filter by category if provided if (categoryParam) { const categories = categoryParam.split(',').map((c) => c.trim()) conditions.push(inArray(products.category, categories)) } // Fetch products with filters const visibleProducts = await db.query.products.findMany({ where: and(...conditions), orderBy: (products, { asc }) => [asc(products.category), asc(products.name)], }) return visibleProducts } catch (error) { console.error('Error fetching products:', error) throw createError({ statusCode: 500, statusMessage: 'Failed to fetch products', }) } })