route.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import { listBranches } from "@/lib/storage";
  2. import { getSession } from "@/lib/auth/session";
  3. import { filterBranchesForSession } from "@/lib/auth/permissions";
  4. import {
  5. withErrorHandling,
  6. json,
  7. unauthorized,
  8. ApiError,
  9. } from "@/lib/api/errors";
  10. /**
  11. * Next.js Route Handler caching configuration (RHL-006):
  12. *
  13. * We force this route to execute dynamically on every request.
  14. *
  15. * Reasons:
  16. * - NAS contents can change at any time (new scans).
  17. * - Auth/RBAC-protected responses must not be cached/shared across users.
  18. * - We rely on a small storage-layer TTL micro-cache instead of Next route caching.
  19. */
  20. export const dynamic = "force-dynamic";
  21. /**
  22. * GET /api/branches
  23. *
  24. * Returns the list of branches (e.g. ["NL01", "NL02", ...]) based on the
  25. * directory names under NAS_ROOT_PATH.
  26. *
  27. * RBAC:
  28. * - 401 if no session
  29. * - branch role: only returns its own branch
  30. * - admin/dev: returns all branches
  31. *
  32. * Happy-path response must remain unchanged:
  33. * { "branches": ["NL01", ...] }
  34. */
  35. export const GET = withErrorHandling(
  36. async function GET() {
  37. const session = await getSession();
  38. if (!session) {
  39. throw unauthorized("AUTH_UNAUTHENTICATED", "Unauthorized");
  40. }
  41. try {
  42. const branches = await listBranches();
  43. const visibleBranches = filterBranchesForSession(session, branches);
  44. return json({ branches: visibleBranches }, 200);
  45. } catch (err) {
  46. // Treat any storage read failures as internal server errors.
  47. // We do NOT expose filesystem error messages to the client.
  48. throw new ApiError({
  49. status: 500,
  50. code: "FS_STORAGE_ERROR",
  51. message: "Internal server error",
  52. cause: err,
  53. });
  54. }
  55. },
  56. { logPrefix: "[api/branches]" }
  57. );