/home/techb158/balavpn.abdallabala.com/.next/cache/webpack/server-production
Edit: /home/techb158/balavpn.abdallabala.com/.next/cache/webpack/server-production/5.pack (223672B)
wpc i webpack/lib/cache/PackFileCacheStrategyPackContentItems`~ ResolverCachePlugin|normal|default|alias=|false|mainFields=[|0=|main|]|conditionNames=[|0=|node|1=|import|]|fullySpecified=|true|dependencyType=|esm|modules=[|0=|node_modules|]|fallback=|false|exportsFields=[|0=|exports|]|importsFields=[|0=|imports|]|descriptionFiles=[|0=|package.json|]|extensions=[|0=|.js|1=|.json|2=|.node|]|enforceExtensions=|false|symlinks=|true|mainFiles=[|0=|index|]|roots=[|]|preferRelative=|false|preferAbsolute=|false|restrictions=[|]|path=|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\lib|request=|./redis ResolverCachePlugin|normal|default|alias=[|server-only$=|next/dist/compiled/server-only/empty|client-only$=|next/dist/compiled/client-only/error|next/dist/compiled/server-only$=|next/dist/compiled/server-only/empty|next/dist/compiled/client-only$=|next/dist/compiled/client-only/error|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\head.js=|next/dist/client/components/noop-head|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\image.js=|next/dist/api/image|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\constants.js=|next/dist/api/constants|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\router.js=|next/dist/api/router|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dynamic.js=|next/dist/api/app-dynamic|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\script.js=|next/dist/api/script|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\link.js=|next/dist/client/app-dir/link|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\form.js=|next/dist/client/app-dir/form|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\navigation.js=|next/dist/api/navigation.react-server|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\headers.js=|next/dist/api/headers|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\og.js=|next/dist/api/og|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\server.js=|next/dist/api/server|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\document.js=|next/dist/api/document|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\app.js=|next/dist/api/app|react$=|next/dist/server/route-modules/app-page/vendored/rsc/react|react/compiler-runtime$=|next/dist/server/route-modules/app-page/vendored/rsc/react-compiler-runtime|react/jsx-dev-runtime$=|next/dist/server/route-modules/app-page/vendored/rsc/react-jsx-dev-runtime|react/jsx-runtime$=|next/dist/server/route-modules/app-page/vendored/rsc/react-jsx-runtime|react-dom$=|next/dist/server/route-modules/app-page/vendored/rsc/react-dom|react-dom/client$=|next/dist/compiled/react-dom/client|react-dom/server$=|next/dist/compiled/react-dom/server.node|react-dom/server.browser$=|next/dist/compiled/react-dom/server.browser|react-dom/server.edge$=|next/dist/build/webpack/alias/react-dom-server.js|react-dom/static$=|next/dist/compiled/react-dom/static.node|react-dom/static.browser$=|next/dist/compiled/react-dom/static.browser|react-dom/static.edge$=|next/dist/compiled/react-dom/static.edge|react-server-dom-webpack/client$=|next/dist/compiled/react-server-dom-webpack/client.node|react-server-dom-webpack/server$=|next/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-webpack-server|react-server-dom-webpack/server.node$=|next/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-webpack-server|react-server-dom-webpack/static$=|next/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-webpack-static|@vercel/turbopack-ecmascript-runtime/browser/dev/hmr-client/hmr-client.ts=|next/dist/client/dev/noop-turbopack-hmr|next=|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next|]|mainFields=[|0=|module|1=|main|]|conditionNames=[|0=|react-server|1=|...|]|fullySpecified=|false|dependencyType=|esm|path=|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\lib|request=|./redis~ ResolverCachePlugin|normal|default|alias=|false|mainFields=[|0=|main|]|conditionNames=[|0=|node|1=|import|]|fullySpecified=|true|dependencyType=|esm|modules=[|0=|node_modules|]|fallback=|false|exportsFields=[|0=|exports|]|importsFields=[|0=|imports|]|descriptionFiles=[|0=|package.json|]|extensions=[|0=|.js|1=|.json|2=|.node|]|enforceExtensions=|false|symlinks=|true|mainFiles=[|0=|index|]|roots=[|]|preferRelative=|false|preferAbsolute=|false|restrictions=[|]|path=|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\lib|request=|ioredis ResolverCachePlugin|normal|default|alias=[|server-only$=|next/dist/compiled/server-only/empty|client-only$=|next/dist/compiled/client-only/error|next/dist/compiled/server-only$=|next/dist/compiled/server-only/empty|next/dist/compiled/client-only$=|next/dist/compiled/client-only/error|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\head.js=|next/dist/client/components/noop-head|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\image.js=|next/dist/api/image|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\constants.js=|next/dist/api/constants|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\router.js=|next/dist/api/router|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dynamic.js=|next/dist/api/app-dynamic|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\script.js=|next/dist/api/script|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\link.js=|next/dist/client/app-dir/link|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\form.js=|next/dist/client/app-dir/form|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\navigation.js=|next/dist/api/navigation.react-server|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\headers.js=|next/dist/api/headers|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\og.js=|next/dist/api/og|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\server.js=|next/dist/api/server|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\document.js=|next/dist/api/document|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\app.js=|next/dist/api/app|react$=|next/dist/server/route-modules/app-page/vendored/rsc/react|react/compiler-runtime$=|next/dist/server/route-modules/app-page/vendored/rsc/react-compiler-runtime|react/jsx-dev-runtime$=|next/dist/server/route-modules/app-page/vendored/rsc/react-jsx-dev-runtime|react/jsx-runtime$=|next/dist/server/route-modules/app-page/vendored/rsc/react-jsx-runtime|react-dom$=|next/dist/server/route-modules/app-page/vendored/rsc/react-dom|react-dom/client$=|next/dist/compiled/react-dom/client|react-dom/server$=|next/dist/compiled/react-dom/server.node|react-dom/server.browser$=|next/dist/compiled/react-dom/server.browser|react-dom/server.edge$=|next/dist/build/webpack/alias/react-dom-server.js|react-dom/static$=|next/dist/compiled/react-dom/static.node|react-dom/static.browser$=|next/dist/compiled/react-dom/static.browser|react-dom/static.edge$=|next/dist/compiled/react-dom/static.edge|react-server-dom-webpack/client$=|next/dist/compiled/react-server-dom-webpack/client.node|react-server-dom-webpack/server$=|next/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-webpack-server|react-server-dom-webpack/server.node$=|next/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-webpack-server|react-server-dom-webpack/static$=|next/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-webpack-static|@vercel/turbopack-ecmascript-runtime/browser/dev/hmr-client/hmr-client.ts=|next/dist/client/dev/noop-turbopack-hmr|next=|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next|]|mainFields=[|0=|module|1=|main|]|conditionNames=[|0=|react-server|1=|...|]|fullySpecified=|false|dependencyType=|esm|path=|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\lib|request=|ioredis% ResolverCachePlugin|normal|default|dependencyType=|esm|fallback=|false|exportsFields=[|0=|exports|]|importsFields=[|0=|imports|]|conditionNames=[|0=|node|1=|import|]|descriptionFiles=[|0=|package.json|]|enforceExtensions=|false|symlinks=|true|mainFields=[|0=|main|]|mainFiles=[|0=|index|]|roots=[|]|preferRelative=|false|preferAbsolute=|false|restrictions=[|]|alias=|false|path=|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\lib|request=|./redis% ResolverCachePlugin|normal|default|dependencyType=|esm|fallback=|false|exportsFields=[|0=|exports|]|importsFields=[|0=|imports|]|conditionNames=[|0=|node|1=|import|]|descriptionFiles=[|0=|package.json|]|enforceExtensions=|false|symlinks=|true|mainFields=[|0=|main|]|mainFiles=[|0=|index|]|roots=[|]|preferRelative=|false|preferAbsolute=|false|restrictions=[|]|alias=|false|path=|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\lib|request=|ioredis FlagDependencyExportsPlugin|javascript/auto|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-flight-loader\index.js!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-swc-loader.js??ruleSet[1].rules[16].oneOf[4].use[0]!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\lib\idempotency.js|rsc FlagDependencyExportsPlugin|javascript/auto|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-flight-loader\index.js!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-swc-loader.js??ruleSet[1].rules[16].oneOf[4].use[0]!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\lib\redis.js|rsc Compilation/codeGeneration|javascript/auto|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-flight-loader\index.js!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-swc-loader.js??ruleSet[1].rules[16].oneOf[4].use[0]!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\lib\idempotency.js|rsc|6fc1995a7d03c1a7|webpack-runtimeCompilation/assets|chunk2622MinifierWebpackPlugin|2622.jswebpack/lib/cache/ResolverCachePlugin
webpack/lib/FileSystemInfoSnapshot@ $yB C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\package.jsonsafeTimetimestamphash! yB yB13b98c72f42c0046 @ C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\lib\package.json C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\package.json C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\lib\redis`_ResolverCachePluginCacheMisscontextpathrequestqueryfragmentmoduledirectoryfileinternalfullySpecifieddescriptionFilePathdescriptionFileDatadescriptionFileRootrelativePathissuerissuerLayercompiler C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\lib\idempotency.jsrscserver C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\lib\redis.js nameversionprivatedescriptionscriptsdependenciesdevDependenciesenginescosmic-ai-risk-saas0.1.0 Commercial SaaS rebuild of the COSMIC AI-Risk Dashboard with multi-tenant workspaces, PostgreSQL, Prisma, invite-only auth, billing entitlements, and enterprise-ready boundaries.`devbuildstartlinttestprisma:generatedb:migratedb:pushdb:seedcheck:configtest:locallocal:fallbackmock-oidcdev:ssosso:setupnext dev -p 8091next buildnext start -p 8091next lint node tests/saas-domain.test.js && node tests/tenant-security.test.js && node tests/idempotency.test.js && node tests/metrics.test.js && node tests/oidc.test.js && node tests/rate-limit.test.js && node tests/integration-service.test.jsprisma generateprisma migrate deployprisma db pushnode prisma/seed.jsnode scripts/check-config.jsnode tests/local-server.test.jsnode local-server.jsnode mock-oidc-provider.jsnode mock-oidc-provider.js & npm run dev@prisma/clientbcryptjsioredisnextreactreact-domstripezod^5.22.0^2.4.3^5.11.1^15.0.3^19.0.0^17.3.1^3.23.8eslinteslint-config-nextprisma^9.14.0node>=20.11.0 C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app./src/lib/redis.js@ %yB@ yB yB C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\applicationC:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission FreezeC:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk DashboardC:\Users\abd_b\OneDrive\DesktopC:\Users\abd_b\OneDriveC:\Users\abd_bC:\UsersC:\ $yB C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\lib C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\srcy! yB yB346b829ed2f647a2w v | C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\ioredis\built\index.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\ioredis\package.json`maintypesfilesrepositorykeywordstsdauthorlicensefundingnycmocha5.11.1A robust, performance-focused and full-featured Redis client for Node.js../built/index.js./built/index.d.tsbuilt/`docker:setupdocker:teardowntest:tsdtest:jstest:covtest:clusterdocsformatformat-checkprepublishOnlysemantic-releasedocker compose -f test/docker-compose.yml up -d --waitdocker compose -f test/docker-compose.yml down --volumes --remove-orphansnpm run build && tsd TS_NODE_TRANSPILE_ONLY=true NODE_ENV=test mocha --no-experimental-strip-types "test/helpers/*.ts" "test/unit/**/*.ts" "test/functional/**/*.ts"nyc npm run test:jsTS_NODE_TRANSPILE_ONLY=true NODE_ENV=test mocha --no-experimental-strip-types "test/cluster/**/*.ts"npm run test:js && npm run test:tsdeslint --ext .js,.ts ./libnpx typedoc --logLevel Error --excludeExternals --excludeProtected --excludePrivate --readme none lib/index.tsprettier --write "{,!(node_modules)/**/}*.{js,ts}"prettier --check "{,!(node_modules)/**/}*.{js,ts}"rm -rf built && tscnpm run buildtypeurlgitgit://github.com/luin/ioredis.gitredisclustersentinelpipeliningJtest/typingZihua Li
(http://zihua.li)MITopencollectivehttps://opencollective.com/ioredis@ioredis/commandscluster-key-slotdebugdenqueredis-errorsredis-parserstandard-as-callback1.10.01.1.14.4.32.1.01.2.03.0.0`@ioredis/interface-generator@semantic-release/changelog@semantic-release/commit-analyzer@semantic-release/git@types/chai@types/chai-as-promised@types/debug@types/mocha@types/node@types/redis-errors@types/sinon@typescript-eslint/eslint-plugin@typescript-eslint/parserchaichai-as-promisedseslint-config-prettierprettierserver-destroysinonts-nodetypedoctypescriptuuid^1.3.0^6.0.1^9.0.2^10.0.1^4.3.0^7.1.5^4.1.5^9.1.0^14.18.12^1.2.1^10.0.11^5.48.1^4.3.6^7.1.1^8.31.0^8.6.0^11.7.6^15.1.0^2.6.1^19.0.2^1.0.1^13.0.1^10.4.0^0.19.1^0.22.18^4.6.3^9.0.0reporterlcovP>=12.22.0exittimeoutrecursiverequire@@ ts-node/register C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\ioredis~@ &yB C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules Z@ C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\lib\node_modules C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\node_modules@ C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\ioredis.node*missing@ C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\package.json C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\ioredis.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\ioredis.jsonioredis@5.11.1@ X@ X C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\ioredis\built@ @ C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\ioredis\built\package.jsonH IX@ &yB 7@ C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\ioredis.mjs C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\ioredis.tsx C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\ioredis.ts C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\ioredis.jsx C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\ioredis.wasm@ @ pryB)12 3B@ uyB0"webpack/lib/ModuleGraphRestoreProvidedDataprovidedcanMangleProvideterminalBindingexportsInfogetIdempotencyKeywithIdempotency
redisDelredisFlushredisGetredisIncrredisSetredisTtl
sourcesdataruntimeRequirementsjavascriptwebpack/lib/util/registerExternalSerializerwebpack-sources/CachedSource = webpack/lib/util/registerExternalSerializerwebpack-sources/ConcatSourcewebpack/lib/util/registerExternalSerializerwebpack-sources/RawSource // ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
getIdempotencyKey: () => (/* binding */ getIdempotencyKey),
withIdempotency: () => (/* binding */ withIdempotency)
});
// EXTERNAL MODULE: ./node_modules/ioredis/built/index.js
var built = __webpack_require__(50453);
var built_default = /*#__PURE__*/__webpack_require__.n(built);
;// ./src/lib/redis.js
webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSourcewebpack/lib/util/registerExternalSerializerwebpack-sources/CachedSource w webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSourcewebpack/lib/util/registerExternalSerializerwebpack-sources/RawSource@ import Redis from 'ioredis';
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
const ENABLED = process.env.COSMIC_REDIS_ENABLED !== 'false';
let redis = null;
let fallbackStore = new Map();
let fallbackTimers = new Map();
function createClient() {
if (!ENABLED) return null;
try {
const client = new Redis(REDIS_URL, {
maxRetriesPerRequest: 1,
retryStrategy (times) {
if (times > 3) return null;
return Math.min(times * 200, 2000);
},
lazyConnect: true,
enableOfflineQueue: false
});
client.on('error', ()=>{});
client.on('close', ()=>{});
return client;
} catch {
return null;
}
}
async function ensureConnected() {
if (redis === null) redis = createClient();
if (!redis || redis.status === 'ready') return redis;
if (redis.status === 'connecting' || redis.status === 'connect') return redis;
try {
await redis.connect();
return redis;
} catch {
return null;
}
}
function fallbackGet(key) {
const entry = fallbackStore.get(key);
if (!entry) return null;
if (entry.expiry && Date.now() > entry.expiry) {
fallbackStore.delete(key);
return null;
}
return entry.value;
}
function fallbackSet(key, value, ttlMs) {
fallbackStore.set(key, {
value,
expiry: ttlMs ? Date.now() + ttlMs : null
});
if (fallbackTimers.has(key)) clearTimeout(fallbackTimers.get(key));
if (ttlMs) {
const timer = setTimeout(()=>{
fallbackStore.delete(key);
fallbackTimers.delete(key);
}, ttlMs);
timer.unref();
fallbackTimers.set(key, timer);
}
}
function fallbackDel(key) {
fallbackStore.delete(key);
if (fallbackTimers.has(key)) {
clearTimeout(fallbackTimers.get(key));
fallbackTimers.delete(key);
}
}
export async function redisGet(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.get(key);
} catch {
return null;
}
}
return fallbackGet(key);
}
export async function redisSet(key, value, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
if (ttlMs) await client.set(key, value, 'PX', ttlMs);
else await client.set(key, value);
return;
} catch {}
}
fallbackSet(key, value, ttlMs);
}
export async function redisDel(key) {
const client = await ensureConnected();
if (client) {
try {
await client.del(key);
return;
} catch {}
}
fallbackDel(key);
}
export async function redisIncr(key, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
const val = await client.incr(key);
if (ttlMs && val === 1) await client.pexpire(key, ttlMs);
return val;
} catch {}
}
const val = (parseInt(fallbackGet(key), 10) || 0) + 1;
fallbackSet(key, String(val), ttlMs);
return val;
}
export async function redisTtl(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.ttl(key);
} catch {
return -2;
}
}
const entry = fallbackStore.get(key);
if (!entry || !entry.expiry) return -1;
const remaining = Math.max(0, Math.floor((entry.expiry - Date.now()) / 1000));
return remaining > 0 ? remaining : -2;
}
export async function redisFlush() {
const client = await ensureConnected();
if (client) {
try {
await client.flushdb();
return;
} catch {}
}
fallbackStore.clear();
for (const timer of fallbackTimers.values())clearTimeout(timer);
fallbackTimers.clear();
}
`MO S
S Y
__WEBPACK_MODULE_REFERENCE__0_5b2264656661756c74225d_directImport_asiSafe1__._buffersourcesizemapshashC
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
const ENABLED = process.env.COSMIC_REDIS_ENABLED !== 'false';
let redis = null;
let fallbackStore = new Map();
let fallbackTimers = new Map();
function createClient() {
if (!ENABLED) return null;
try {
const client = new __WEBPACK_MODULE_REFERENCE__0_5b2264656661756c74225d_directImport_asiSafe1__._(REDIS_URL, {
maxRetriesPerRequest: 1,
retryStrategy (times) {
if (times > 3) return null;
return Math.min(times * 200, 2000);
},
lazyConnect: true,
enableOfflineQueue: false
});
client.on('error', ()=>{});
client.on('close', ()=>{});
return client;
} catch {
return null;
}
}
async function ensureConnected() {
if (redis === null) redis = createClient();
if (!redis || redis.status === 'ready') return redis;
if (redis.status === 'connecting' || redis.status === 'connect') return redis;
try {
await redis.connect();
return redis;
} catch {
return null;
}
}
function fallbackGet(key) {
const entry = fallbackStore.get(key);
if (!entry) return null;
if (entry.expiry && Date.now() > entry.expiry) {
fallbackStore.delete(key);
return null;
}
return entry.value;
}
function fallbackSet(key, value, ttlMs) {
fallbackStore.set(key, {
value,
expiry: ttlMs ? Date.now() + ttlMs : null
});
if (fallbackTimers.has(key)) clearTimeout(fallbackTimers.get(key));
if (ttlMs) {
const timer = setTimeout(()=>{
fallbackStore.delete(key);
fallbackTimers.delete(key);
}, ttlMs);
timer.unref();
fallbackTimers.set(key, timer);
}
}
function fallbackDel(key) {
fallbackStore.delete(key);
if (fallbackTimers.has(key)) {
clearTimeout(fallbackTimers.get(key));
fallbackTimers.delete(key);
}
}
async function redisGet(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.get(key);
} catch {
return null;
}
}
return fallbackGet(key);
}
async function redisSet(key, value, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
if (ttlMs) await client.set(key, value, 'PX', ttlMs);
else await client.set(key, value);
return;
} catch {}
}
fallbackSet(key, value, ttlMs);
}
async function redisDel(key) {
const client = await ensureConnected();
if (client) {
try {
await client.del(key);
return;
} catch {}
}
fallbackDel(key);
}
async function redisIncr(key, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
const val = await client.incr(key);
if (ttlMs && val === 1) await client.pexpire(key, ttlMs);
return val;
} catch {}
}
const val = (parseInt(fallbackGet(key), 10) || 0) + 1;
fallbackSet(key, String(val), ttlMs);
return val;
}
async function redisTtl(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.ttl(key);
} catch {
return -2;
}
}
const entry = fallbackStore.get(key);
if (!entry || !entry.expiry) return -1;
const remaining = Math.max(0, Math.floor((entry.expiry - Date.now()) / 1000));
return remaining > 0 ? remaining : -2;
}
async function redisFlush() {
const client = await ensureConnected();
if (client) {
try {
await client.flushdb();
return;
} catch {}
}
fallbackStore.clear();
for (const timer of fallbackTimers.values())clearTimeout(timer);
fallbackTimers.clear();
}
{"finalSource":false}mapbufferedMap ReplaceSourceRawSource@ import Redis from 'ioredis';
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
const ENABLED = process.env.COSMIC_REDIS_ENABLED !== 'false';
let redis = null;
let fallbackStore = new Map();
let fallbackTimers = new Map();
function createClient() {
if (!ENABLED) return null;
try {
const client = new Redis(REDIS_URL, {
maxRetriesPerRequest: 1,
retryStrategy (times) {
if (times > 3) return null;
return Math.min(times * 200, 2000);
},
lazyConnect: true,
enableOfflineQueue: false
});
client.on('error', ()=>{});
client.on('close', ()=>{});
return client;
} catch {
return null;
}
}
async function ensureConnected() {
if (redis === null) redis = createClient();
if (!redis || redis.status === 'ready') return redis;
if (redis.status === 'connecting' || redis.status === 'connect') return redis;
try {
await redis.connect();
return redis;
} catch {
return null;
}
}
function fallbackGet(key) {
const entry = fallbackStore.get(key);
if (!entry) return null;
if (entry.expiry && Date.now() > entry.expiry) {
fallbackStore.delete(key);
return null;
}
return entry.value;
}
function fallbackSet(key, value, ttlMs) {
fallbackStore.set(key, {
value,
expiry: ttlMs ? Date.now() + ttlMs : null
});
if (fallbackTimers.has(key)) clearTimeout(fallbackTimers.get(key));
if (ttlMs) {
const timer = setTimeout(()=>{
fallbackStore.delete(key);
fallbackTimers.delete(key);
}, ttlMs);
timer.unref();
fallbackTimers.set(key, timer);
}
}
function fallbackDel(key) {
fallbackStore.delete(key);
if (fallbackTimers.has(key)) {
clearTimeout(fallbackTimers.get(key));
fallbackTimers.delete(key);
}
}
export async function redisGet(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.get(key);
} catch {
return null;
}
}
return fallbackGet(key);
}
export async function redisSet(key, value, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
if (ttlMs) await client.set(key, value, 'PX', ttlMs);
else await client.set(key, value);
return;
} catch {}
}
fallbackSet(key, value, ttlMs);
}
export async function redisDel(key) {
const client = await ensureConnected();
if (client) {
try {
await client.del(key);
return;
} catch {}
}
fallbackDel(key);
}
export async function redisIncr(key, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
const val = await client.incr(key);
if (ttlMs && val === 1) await client.pexpire(key, ttlMs);
return val;
} catch {}
}
const val = (parseInt(fallbackGet(key), 10) || 0) + 1;
fallbackSet(key, String(val), ttlMs);
return val;
}
export async function redisTtl(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.ttl(key);
} catch {
return -2;
}
}
const entry = fallbackStore.get(key);
if (!entry || !entry.expiry) return -1;
const remaining = Math.max(0, Math.floor((entry.expiry - Date.now()) / 1000));
return remaining > 0 ? remaining : -2;
}
export async function redisFlush() {
const client = await ensureConnected();
if (client) {
try {
await client.flushdb();
return;
} catch {}
}
fallbackStore.clear();
for (const timer of fallbackTimers.values())clearTimeout(timer);
fallbackTimers.clear();
}
027undefined335339__WEBPACK_MODULE_REFERENCE__0_5b2264656661756c74225d_directImport_asiSafe1__._undefined19551961undefined22022208undefined25272533undefined27462752undefined31553161undefined35833589undefinedA3 (built_default())
;// ./src/lib/idempotency.js
webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSourcewebpack/lib/util/registerExternalSerializerwebpack-sources/RawSource3 import { redisGet, redisSet } from './redis';
const TTL_MS = 86400000;
async function withIdempotency(key, handler) {
if (!key) return handler();
const existing = await redisGet(`idemp:${key}`);
if (existing) return JSON.parse(existing);
const result = await handler();
await redisSet(`idemp:${key}`, JSON.stringify(result), TTL_MS);
return result;
}
function getIdempotencyKey(request) {
return request.headers.get("Idempotency-Key") || request.headers.get("idempotency-key") || null;
}
export { withIdempotency, getIdempotencyKey };
`,E ( / 1 __WEBPACK_MODULE_REFERENCE__1_5b227265646973476574225d_call_directImport_asiSafe1__.___WEBPACK_MODULE_REFERENCE__1_5b227265646973536574225d_call_directImport_asiSafe1__._r
const TTL_MS = 86400000;
async function withIdempotency(key, handler) {
if (!key) return handler();
const existing = await __WEBPACK_MODULE_REFERENCE__1_5b227265646973476574225d_call_directImport_asiSafe1__._(`idemp:${key}`);
if (existing) return JSON.parse(existing);
const result = await handler();
await __WEBPACK_MODULE_REFERENCE__1_5b227265646973536574225d_call_directImport_asiSafe1__._(`idemp:${key}`, JSON.stringify(result), TTL_MS);
return result;
}
function getIdempotencyKey(request) {
return request.headers.get("Idempotency-Key") || request.headers.get("idempotency-key") || null;
}
3 import { redisGet, redisSet } from './redis';
const TTL_MS = 86400000;
async function withIdempotency(key, handler) {
if (!key) return handler();
const existing = await redisGet(`idemp:${key}`);
if (existing) return JSON.parse(existing);
const result = await handler();
await redisSet(`idemp:${key}`, JSON.stringify(result), TTL_MS);
return result;
}
function getIdempotencyKey(request) {
return request.headers.get("Idempotency-Key") || request.headers.get("idempotency-key") || null;
}
export { withIdempotency, getIdempotencyKey };
044undefined177184__WEBPACK_MODULE_REFERENCE__1_5b227265646973476574225d_call_directImport_asiSafe1__._undefined296303__WEBPACK_MODULE_REFERENCE__1_5b227265646973536574225d_call_directImport_asiSafe1__._undefined516561undefinedC H redisGetredisSetbuffersourcesizemapsx // ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
getIdempotencyKey: () => (/* binding */ getIdempotencyKey),
withIdempotency: () => (/* binding */ withIdempotency)
});
// EXTERNAL MODULE: ./node_modules/ioredis/built/index.js
var built = __webpack_require__(50453);
var built_default = /*#__PURE__*/__webpack_require__.n(built);
;// ./src/lib/redis.js
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
const ENABLED = process.env.COSMIC_REDIS_ENABLED !== 'false';
let redis = null;
let fallbackStore = new Map();
let fallbackTimers = new Map();
function createClient() {
if (!ENABLED) return null;
try {
const client = new (built_default())(REDIS_URL, {
maxRetriesPerRequest: 1,
retryStrategy (times) {
if (times > 3) return null;
return Math.min(times * 200, 2000);
},
lazyConnect: true,
enableOfflineQueue: false
});
client.on('error', ()=>{});
client.on('close', ()=>{});
return client;
} catch {
return null;
}
}
async function ensureConnected() {
if (redis === null) redis = createClient();
if (!redis || redis.status === 'ready') return redis;
if (redis.status === 'connecting' || redis.status === 'connect') return redis;
try {
await redis.connect();
return redis;
} catch {
return null;
}
}
function fallbackGet(key) {
const entry = fallbackStore.get(key);
if (!entry) return null;
if (entry.expiry && Date.now() > entry.expiry) {
fallbackStore.delete(key);
return null;
}
return entry.value;
}
function fallbackSet(key, value, ttlMs) {
fallbackStore.set(key, {
value,
expiry: ttlMs ? Date.now() + ttlMs : null
});
if (fallbackTimers.has(key)) clearTimeout(fallbackTimers.get(key));
if (ttlMs) {
const timer = setTimeout(()=>{
fallbackStore.delete(key);
fallbackTimers.delete(key);
}, ttlMs);
timer.unref();
fallbackTimers.set(key, timer);
}
}
function fallbackDel(key) {
fallbackStore.delete(key);
if (fallbackTimers.has(key)) {
clearTimeout(fallbackTimers.get(key));
fallbackTimers.delete(key);
}
}
async function redisGet(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.get(key);
} catch {
return null;
}
}
return fallbackGet(key);
}
async function redisSet(key, value, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
if (ttlMs) await client.set(key, value, 'PX', ttlMs);
else await client.set(key, value);
return;
} catch {}
}
fallbackSet(key, value, ttlMs);
}
async function redisDel(key) {
const client = await ensureConnected();
if (client) {
try {
await client.del(key);
return;
} catch {}
}
fallbackDel(key);
}
async function redisIncr(key, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
const val = await client.incr(key);
if (ttlMs && val === 1) await client.pexpire(key, ttlMs);
return val;
} catch {}
}
const val = (parseInt(fallbackGet(key), 10) || 0) + 1;
fallbackSet(key, String(val), ttlMs);
return val;
}
async function redisTtl(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.ttl(key);
} catch {
return -2;
}
}
const entry = fallbackStore.get(key);
if (!entry || !entry.expiry) return -1;
const remaining = Math.max(0, Math.floor((entry.expiry - Date.now()) / 1000));
return remaining > 0 ? remaining : -2;
}
async function redisFlush() {
const client = await ensureConnected();
if (client) {
try {
await client.flushdb();
return;
} catch {}
}
fallbackStore.clear();
for (const timer of fallbackTimers.values())clearTimeout(timer);
fallbackTimers.clear();
}
;// ./src/lib/idempotency.js
const TTL_MS = 86400000;
async function withIdempotency(key, handler) {
if (!key) return handler();
const existing = await redisGet(`idemp:${key}`);
if (existing) return JSON.parse(existing);
const result = await handler();
await redisSet(`idemp:${key}`, JSON.stringify(result), TTL_MS);
return result;
}
function getIdempotencyKey(request) {
return request.headers.get("Idempotency-Key") || request.headers.get("idempotency-key") || null;
}
{"finalSource":true}mapbufferedMap`
ConcatSourceRawSource // ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
getIdempotencyKey: () => (/* binding */ getIdempotencyKey),
withIdempotency: () => (/* binding */ withIdempotency)
});
// EXTERNAL MODULE: ./node_modules/ioredis/built/index.js
var built = __webpack_require__(50453);
var built_default = /*#__PURE__*/__webpack_require__.n(built);
;// ./src/lib/redis.js
ReplaceSource ReplaceSourceRawSource@ import Redis from 'ioredis';
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
const ENABLED = process.env.COSMIC_REDIS_ENABLED !== 'false';
let redis = null;
let fallbackStore = new Map();
let fallbackTimers = new Map();
function createClient() {
if (!ENABLED) return null;
try {
const client = new Redis(REDIS_URL, {
maxRetriesPerRequest: 1,
retryStrategy (times) {
if (times > 3) return null;
return Math.min(times * 200, 2000);
},
lazyConnect: true,
enableOfflineQueue: false
});
client.on('error', ()=>{});
client.on('close', ()=>{});
return client;
} catch {
return null;
}
}
async function ensureConnected() {
if (redis === null) redis = createClient();
if (!redis || redis.status === 'ready') return redis;
if (redis.status === 'connecting' || redis.status === 'connect') return redis;
try {
await redis.connect();
return redis;
} catch {
return null;
}
}
function fallbackGet(key) {
const entry = fallbackStore.get(key);
if (!entry) return null;
if (entry.expiry && Date.now() > entry.expiry) {
fallbackStore.delete(key);
return null;
}
return entry.value;
}
function fallbackSet(key, value, ttlMs) {
fallbackStore.set(key, {
value,
expiry: ttlMs ? Date.now() + ttlMs : null
});
if (fallbackTimers.has(key)) clearTimeout(fallbackTimers.get(key));
if (ttlMs) {
const timer = setTimeout(()=>{
fallbackStore.delete(key);
fallbackTimers.delete(key);
}, ttlMs);
timer.unref();
fallbackTimers.set(key, timer);
}
}
function fallbackDel(key) {
fallbackStore.delete(key);
if (fallbackTimers.has(key)) {
clearTimeout(fallbackTimers.get(key));
fallbackTimers.delete(key);
}
}
export async function redisGet(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.get(key);
} catch {
return null;
}
}
return fallbackGet(key);
}
export async function redisSet(key, value, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
if (ttlMs) await client.set(key, value, 'PX', ttlMs);
else await client.set(key, value);
return;
} catch {}
}
fallbackSet(key, value, ttlMs);
}
export async function redisDel(key) {
const client = await ensureConnected();
if (client) {
try {
await client.del(key);
return;
} catch {}
}
fallbackDel(key);
}
export async function redisIncr(key, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
const val = await client.incr(key);
if (ttlMs && val === 1) await client.pexpire(key, ttlMs);
return val;
} catch {}
}
const val = (parseInt(fallbackGet(key), 10) || 0) + 1;
fallbackSet(key, String(val), ttlMs);
return val;
}
export async function redisTtl(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.ttl(key);
} catch {
return -2;
}
}
const entry = fallbackStore.get(key);
if (!entry || !entry.expiry) return -1;
const remaining = Math.max(0, Math.floor((entry.expiry - Date.now()) / 1000));
return remaining > 0 ? remaining : -2;
}
export async function redisFlush() {
const client = await ensureConnected();
if (client) {
try {
await client.flushdb();
return;
} catch {}
}
fallbackStore.clear();
for (const timer of fallbackTimers.values())clearTimeout(timer);
fallbackTimers.clear();
}
027undefined335339__WEBPACK_MODULE_REFERENCE__0_5b2264656661756c74225d_directImport_asiSafe1__._undefined19551961undefined22022208undefined25272533undefined27462752undefined31553161undefined35833589undefined) 307384(built_default())undefinedRawSource
;// ./src/lib/idempotency.js
3 import { redisGet, redisSet } from './redis';
const TTL_MS = 86400000;
async function withIdempotency(key, handler) {
if (!key) return handler();
const existing = await redisGet(`idemp:${key}`);
if (existing) return JSON.parse(existing);
const result = await handler();
await redisSet(`idemp:${key}`, JSON.stringify(result), TTL_MS);
return result;
}
function getIdempotencyKey(request) {
return request.headers.get("Idempotency-Key") || request.headers.get("idempotency-key") || null;
}
export { withIdempotency, getIdempotencyKey };
044undefined177184__WEBPACK_MODULE_REFERENCE__1_5b227265646973476574225d_call_directImport_asiSafe1__._undefined296303__WEBPACK_MODULE_REFERENCE__1_5b227265646973536574225d_call_directImport_asiSafe1__._undefined516561undefined. 132216redisGetundefined328412redisSetundefinedtopLevelDeclarations`builtbuilt_namespaceObjectbuilt_defaultREDIS_URLENABLED!fallbackStorefallbackTimerscreateClientensureConnectedfallbackGetfallbackSetfallbackDelǕredis_namespaceObjectTTL_MSidempotency_namespaceObject__webpack_exports____webpack_require__.d__webpack_require__.r__webpack_require____webpack_require__.n webpack/lib/util/registerExternalSerializerwebpack-sources/ConcatSource webpack/lib/util/registerExternalSerializerwebpack-sources/RawSourceY "use strict";
exports.id = 2622;
exports.ids = [2622];
exports.modules = {
/***/ 23518:
webpack/lib/util/registerExternalSerializerwebpack-sources/CachedSource webpack/lib/util/registerExternalSerializerwebpack-sources/ConcatSourcewebpack/lib/util/registerExternalSerializerwebpack-sources/RawSourceE /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
webpack/lib/util/registerExternalSerializerwebpack-sources/CachedSource webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSourcewebpack/lib/util/registerExternalSerializerwebpack-sources/RawSource "use strict";
const { prisma } = require("../lib/prisma");
async function writeAuditEvent({ organizationId, workspaceId = null, projectId = null, actorUserId = null, entityType, entityId, action, beforeJson = null, afterJson = null, request = null }) {
return prisma.auditEvent.create({
data: {
organizationId,
workspaceId,
projectId,
actorUserId,
entityType,
entityId,
action,
beforeJson,
afterJson,
ipAddress: request ? request.headers.get("x-forwarded-for") || null : null,
userAgent: request ? request.headers.get("user-agent") || null : null
}
});
}
module.exports = {
writeAuditEvent
};
d!')7__webpack_require__17964buffersourcesizemapshash
const { prisma } = __webpack_require__(17964);
async function writeAuditEvent({ organizationId, workspaceId = null, projectId = null, actorUserId = null, entityType, entityId, action, beforeJson = null, afterJson = null, request = null }) {
return prisma.auditEvent.create({
data: {
organizationId,
workspaceId,
projectId,
actorUserId,
entityType,
entityId,
action,
beforeJson,
afterJson,
ipAddress: request ? request.headers.get("x-forwarded-for") || null : null,
userAgent: request ? request.headers.get("user-agent") || null : null
}
});
}
module.exports = {
writeAuditEvent
};
{"finalSource":true}mapbufferedMap ReplaceSourceRawSource "use strict";
const { prisma } = require("../lib/prisma");
async function writeAuditEvent({ organizationId, workspaceId = null, projectId = null, actorUserId = null, entityType, entityId, action, beforeJson = null, afterJson = null, request = null }) {
return prisma.auditEvent.create({
data: {
organizationId,
workspaceId,
projectId,
actorUserId,
entityType,
entityId,
action,
beforeJson,
afterJson,
ipAddress: request ? request.headers.get("x-forwarded-for") || null : null,
userAgent: request ? request.headers.get("user-agent") || null : null
}
});
}
module.exports = {
writeAuditEvent
};
> 012undefined3339__webpack_require__undefined415517964undefined
/***/ })buffersourcesizemapshash5 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const { prisma } = __webpack_require__(17964);
async function writeAuditEvent({ organizationId, workspaceId = null, projectId = null, actorUserId = null, entityType, entityId, action, beforeJson = null, afterJson = null, request = null }) {
return prisma.auditEvent.create({
data: {
organizationId,
workspaceId,
projectId,
actorUserId,
entityType,
entityId,
action,
beforeJson,
afterJson,
ipAddress: request ? request.headers.get("x-forwarded-for") || null : null,
userAgent: request ? request.headers.get("user-agent") || null : null
}
});
}
module.exports = {
writeAuditEvent
};
/***/ }){"finalSource":true}mapbufferedMap ConcatSourceRawSourceE /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
ReplaceSourceRawSource "use strict";
const { prisma } = require("../lib/prisma");
async function writeAuditEvent({ organizationId, workspaceId = null, projectId = null, actorUserId = null, entityType, entityId, action, beforeJson = null, afterJson = null, request = null }) {
return prisma.auditEvent.create({
data: {
organizationId,
workspaceId,
projectId,
actorUserId,
entityType,
entityId,
action,
beforeJson,
afterJson,
ipAddress: request ? request.headers.get("x-forwarded-for") || null : null,
userAgent: request ? request.headers.get("user-agent") || null : null
}
});
}
module.exports = {
writeAuditEvent
};
> 012undefined3339__webpack_require__undefined415517964undefined RawSource
/***/ }) ,
/***/ 54775:
webpack/lib/util/registerExternalSerializerwebpack-sources/ConcatSourcewebpack/lib/util/registerExternalSerializerwebpack-sources/RawSource /***/ ((module) => {
webpack/lib/util/registerExternalSerializerwebpack-sources/CachedSource < webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSourcewebpack/lib/util/registerExternalSerializerwebpack-sources/RawSource "use strict";
const counters = {
requests: 0,
errors: 0,
methods: {},
routes: {}
};
const timings = [];
function trackRequest(method, pathname, statusCode, durationMs) {
counters.requests++;
counters.methods[method] = (counters.methods[method] || 0) + 1;
const route = pathname.replace(/\/[a-z0-9]{20,}/gi, "/:id").replace(/\/[a-z0-9-]{20,}/gi, "/:id");
counters.routes[route] = (counters.routes[route] || 0) + 1;
if (statusCode >= 400) counters.errors++;
timings.push({
method,
pathname,
statusCode,
durationMs,
timestamp: Date.now()
});
if (timings.length > 1000) timings.splice(0, timings.length - 1000);
}
function getMetrics() {
const avgDuration = timings.length ? Math.round(timings.reduce((s, t)=>s + t.durationMs, 0) / timings.length) : 0;
return {
uptime: process.uptime(),
totalRequests: counters.requests,
totalErrors: counters.errors,
avgDurationMs: avgDuration,
methods: counters.methods,
routes: counters.routes,
recentTimings: timings.slice(-20)
};
}
module.exports = {
trackRequest,
getMetrics
};
`buffersourcesizemapshash
const counters = {
requests: 0,
errors: 0,
methods: {},
routes: {}
};
const timings = [];
function trackRequest(method, pathname, statusCode, durationMs) {
counters.requests++;
counters.methods[method] = (counters.methods[method] || 0) + 1;
const route = pathname.replace(/\/[a-z0-9]{20,}/gi, "/:id").replace(/\/[a-z0-9-]{20,}/gi, "/:id");
counters.routes[route] = (counters.routes[route] || 0) + 1;
if (statusCode >= 400) counters.errors++;
timings.push({
method,
pathname,
statusCode,
durationMs,
timestamp: Date.now()
});
if (timings.length > 1000) timings.splice(0, timings.length - 1000);
}
function getMetrics() {
const avgDuration = timings.length ? Math.round(timings.reduce((s, t)=>s + t.durationMs, 0) / timings.length) : 0;
return {
uptime: process.uptime(),
totalRequests: counters.requests,
totalErrors: counters.errors,
avgDurationMs: avgDuration,
methods: counters.methods,
routes: counters.routes,
recentTimings: timings.slice(-20)
};
}
module.exports = {
trackRequest,
getMetrics
};
{"finalSource":true}mapbufferedMap ReplaceSourceRawSource "use strict";
const counters = {
requests: 0,
errors: 0,
methods: {},
routes: {}
};
const timings = [];
function trackRequest(method, pathname, statusCode, durationMs) {
counters.requests++;
counters.methods[method] = (counters.methods[method] || 0) + 1;
const route = pathname.replace(/\/[a-z0-9]{20,}/gi, "/:id").replace(/\/[a-z0-9-]{20,}/gi, "/:id");
counters.routes[route] = (counters.routes[route] || 0) + 1;
if (statusCode >= 400) counters.errors++;
timings.push({
method,
pathname,
statusCode,
durationMs,
timestamp: Date.now()
});
if (timings.length > 1000) timings.splice(0, timings.length - 1000);
}
function getMetrics() {
const avgDuration = timings.length ? Math.round(timings.reduce((s, t)=>s + t.durationMs, 0) / timings.length) : 0;
return {
uptime: process.uptime(),
totalRequests: counters.requests,
totalErrors: counters.errors,
avgDurationMs: avgDuration,
methods: counters.methods,
routes: counters.routes,
recentTimings: timings.slice(-20)
};
}
module.exports = {
trackRequest,
getMetrics
};
012undefined
/***/ }) /***/ ((module) => {
const counters = {
requests: 0,
errors: 0,
methods: {},
routes: {}
};
const timings = [];
function trackRequest(method, pathname, statusCode, durationMs) {
counters.requests++;
counters.methods[method] = (counters.methods[method] || 0) + 1;
const route = pathname.replace(/\/[a-z0-9]{20,}/gi, "/:id").replace(/\/[a-z0-9-]{20,}/gi, "/:id");
counters.routes[route] = (counters.routes[route] || 0) + 1;
if (statusCode >= 400) counters.errors++;
timings.push({
method,
pathname,
statusCode,
durationMs,
timestamp: Date.now()
});
if (timings.length > 1000) timings.splice(0, timings.length - 1000);
}
function getMetrics() {
const avgDuration = timings.length ? Math.round(timings.reduce((s, t)=>s + t.durationMs, 0) / timings.length) : 0;
return {
uptime: process.uptime(),
totalRequests: counters.requests,
totalErrors: counters.errors,
avgDurationMs: avgDuration,
methods: counters.methods,
routes: counters.routes,
recentTimings: timings.slice(-20)
};
}
module.exports = {
trackRequest,
getMetrics
};
/***/ }) /***/ ((module) => {
"use strict";
const counters = {
requests: 0,
errors: 0,
methods: {},
routes: {}
};
const timings = [];
function trackRequest(method, pathname, statusCode, durationMs) {
counters.requests++;
counters.methods[method] = (counters.methods[method] || 0) + 1;
const route = pathname.replace(/\/[a-z0-9]{20,}/gi, "/:id").replace(/\/[a-z0-9-]{20,}/gi, "/:id");
counters.routes[route] = (counters.routes[route] || 0) + 1;
if (statusCode >= 400) counters.errors++;
timings.push({
method,
pathname,
statusCode,
durationMs,
timestamp: Date.now()
});
if (timings.length > 1000) timings.splice(0, timings.length - 1000);
}
function getMetrics() {
const avgDuration = timings.length ? Math.round(timings.reduce((s, t)=>s + t.durationMs, 0) / timings.length) : 0;
return {
uptime: process.uptime(),
totalRequests: counters.requests,
totalErrors: counters.errors,
avgDurationMs: avgDuration,
methods: counters.methods,
routes: counters.routes,
recentTimings: timings.slice(-20)
};
}
module.exports = {
trackRequest,
getMetrics
};
012undefined ,
/***/ 62159:
#g webpack/lib/util/registerExternalSerializerwebpack-sources/ConcatSourcewebpack/lib/util/registerExternalSerializerwebpack-sources/RawSourceQ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
webpack/lib/util/registerExternalSerializerwebpack-sources/CachedSource = webpack/lib/util/registerExternalSerializerwebpack-sources/ConcatSourcewebpack/lib/util/registerExternalSerializerwebpack-sources/RawSource // ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
getIdempotencyKey: () => (/* binding */ getIdempotencyKey),
withIdempotency: () => (/* binding */ withIdempotency)
});
// EXTERNAL MODULE: ./node_modules/ioredis/built/index.js
var built = __webpack_require__(50453);
var built_default = /*#__PURE__*/__webpack_require__.n(built);
;// ./src/lib/redis.js
webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSourcewebpack/lib/util/registerExternalSerializerwebpack-sources/CachedSource w webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSourcewebpack/lib/util/registerExternalSerializerwebpack-sources/RawSource@ import Redis from 'ioredis';
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
const ENABLED = process.env.COSMIC_REDIS_ENABLED !== 'false';
let redis = null;
let fallbackStore = new Map();
let fallbackTimers = new Map();
function createClient() {
if (!ENABLED) return null;
try {
const client = new Redis(REDIS_URL, {
maxRetriesPerRequest: 1,
retryStrategy (times) {
if (times > 3) return null;
return Math.min(times * 200, 2000);
},
lazyConnect: true,
enableOfflineQueue: false
});
client.on('error', ()=>{});
client.on('close', ()=>{});
return client;
} catch {
return null;
}
}
async function ensureConnected() {
if (redis === null) redis = createClient();
if (!redis || redis.status === 'ready') return redis;
if (redis.status === 'connecting' || redis.status === 'connect') return redis;
try {
await redis.connect();
return redis;
} catch {
return null;
}
}
function fallbackGet(key) {
const entry = fallbackStore.get(key);
if (!entry) return null;
if (entry.expiry && Date.now() > entry.expiry) {
fallbackStore.delete(key);
return null;
}
return entry.value;
}
function fallbackSet(key, value, ttlMs) {
fallbackStore.set(key, {
value,
expiry: ttlMs ? Date.now() + ttlMs : null
});
if (fallbackTimers.has(key)) clearTimeout(fallbackTimers.get(key));
if (ttlMs) {
const timer = setTimeout(()=>{
fallbackStore.delete(key);
fallbackTimers.delete(key);
}, ttlMs);
timer.unref();
fallbackTimers.set(key, timer);
}
}
function fallbackDel(key) {
fallbackStore.delete(key);
if (fallbackTimers.has(key)) {
clearTimeout(fallbackTimers.get(key));
fallbackTimers.delete(key);
}
}
export async function redisGet(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.get(key);
} catch {
return null;
}
}
return fallbackGet(key);
}
export async function redisSet(key, value, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
if (ttlMs) await client.set(key, value, 'PX', ttlMs);
else await client.set(key, value);
return;
} catch {}
}
fallbackSet(key, value, ttlMs);
}
export async function redisDel(key) {
const client = await ensureConnected();
if (client) {
try {
await client.del(key);
return;
} catch {}
}
fallbackDel(key);
}
export async function redisIncr(key, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
const val = await client.incr(key);
if (ttlMs && val === 1) await client.pexpire(key, ttlMs);
return val;
} catch {}
}
const val = (parseInt(fallbackGet(key), 10) || 0) + 1;
fallbackSet(key, String(val), ttlMs);
return val;
}
export async function redisTtl(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.ttl(key);
} catch {
return -2;
}
}
const entry = fallbackStore.get(key);
if (!entry || !entry.expiry) return -1;
const remaining = Math.max(0, Math.floor((entry.expiry - Date.now()) / 1000));
return remaining > 0 ? remaining : -2;
}
export async function redisFlush() {
const client = await ensureConnected();
if (client) {
try {
await client.flushdb();
return;
} catch {}
}
fallbackStore.clear();
for (const timer of fallbackTimers.values())clearTimeout(timer);
fallbackTimers.clear();
}
`MO S
S Y
__WEBPACK_MODULE_REFERENCE__0_5b2264656661756c74225d_directImport_asiSafe1__._buffersourcesizemapshashC
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
const ENABLED = process.env.COSMIC_REDIS_ENABLED !== 'false';
let redis = null;
let fallbackStore = new Map();
let fallbackTimers = new Map();
function createClient() {
if (!ENABLED) return null;
try {
const client = new __WEBPACK_MODULE_REFERENCE__0_5b2264656661756c74225d_directImport_asiSafe1__._(REDIS_URL, {
maxRetriesPerRequest: 1,
retryStrategy (times) {
if (times > 3) return null;
return Math.min(times * 200, 2000);
},
lazyConnect: true,
enableOfflineQueue: false
});
client.on('error', ()=>{});
client.on('close', ()=>{});
return client;
} catch {
return null;
}
}
async function ensureConnected() {
if (redis === null) redis = createClient();
if (!redis || redis.status === 'ready') return redis;
if (redis.status === 'connecting' || redis.status === 'connect') return redis;
try {
await redis.connect();
return redis;
} catch {
return null;
}
}
function fallbackGet(key) {
const entry = fallbackStore.get(key);
if (!entry) return null;
if (entry.expiry && Date.now() > entry.expiry) {
fallbackStore.delete(key);
return null;
}
return entry.value;
}
function fallbackSet(key, value, ttlMs) {
fallbackStore.set(key, {
value,
expiry: ttlMs ? Date.now() + ttlMs : null
});
if (fallbackTimers.has(key)) clearTimeout(fallbackTimers.get(key));
if (ttlMs) {
const timer = setTimeout(()=>{
fallbackStore.delete(key);
fallbackTimers.delete(key);
}, ttlMs);
timer.unref();
fallbackTimers.set(key, timer);
}
}
function fallbackDel(key) {
fallbackStore.delete(key);
if (fallbackTimers.has(key)) {
clearTimeout(fallbackTimers.get(key));
fallbackTimers.delete(key);
}
}
async function redisGet(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.get(key);
} catch {
return null;
}
}
return fallbackGet(key);
}
async function redisSet(key, value, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
if (ttlMs) await client.set(key, value, 'PX', ttlMs);
else await client.set(key, value);
return;
} catch {}
}
fallbackSet(key, value, ttlMs);
}
async function redisDel(key) {
const client = await ensureConnected();
if (client) {
try {
await client.del(key);
return;
} catch {}
}
fallbackDel(key);
}
async function redisIncr(key, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
const val = await client.incr(key);
if (ttlMs && val === 1) await client.pexpire(key, ttlMs);
return val;
} catch {}
}
const val = (parseInt(fallbackGet(key), 10) || 0) + 1;
fallbackSet(key, String(val), ttlMs);
return val;
}
async function redisTtl(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.ttl(key);
} catch {
return -2;
}
}
const entry = fallbackStore.get(key);
if (!entry || !entry.expiry) return -1;
const remaining = Math.max(0, Math.floor((entry.expiry - Date.now()) / 1000));
return remaining > 0 ? remaining : -2;
}
async function redisFlush() {
const client = await ensureConnected();
if (client) {
try {
await client.flushdb();
return;
} catch {}
}
fallbackStore.clear();
for (const timer of fallbackTimers.values())clearTimeout(timer);
fallbackTimers.clear();
}
{"finalSource":false}mapbufferedMap ReplaceSourceRawSource@ import Redis from 'ioredis';
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
const ENABLED = process.env.COSMIC_REDIS_ENABLED !== 'false';
let redis = null;
let fallbackStore = new Map();
let fallbackTimers = new Map();
function createClient() {
if (!ENABLED) return null;
try {
const client = new Redis(REDIS_URL, {
maxRetriesPerRequest: 1,
retryStrategy (times) {
if (times > 3) return null;
return Math.min(times * 200, 2000);
},
lazyConnect: true,
enableOfflineQueue: false
});
client.on('error', ()=>{});
client.on('close', ()=>{});
return client;
} catch {
return null;
}
}
async function ensureConnected() {
if (redis === null) redis = createClient();
if (!redis || redis.status === 'ready') return redis;
if (redis.status === 'connecting' || redis.status === 'connect') return redis;
try {
await redis.connect();
return redis;
} catch {
return null;
}
}
function fallbackGet(key) {
const entry = fallbackStore.get(key);
if (!entry) return null;
if (entry.expiry && Date.now() > entry.expiry) {
fallbackStore.delete(key);
return null;
}
return entry.value;
}
function fallbackSet(key, value, ttlMs) {
fallbackStore.set(key, {
value,
expiry: ttlMs ? Date.now() + ttlMs : null
});
if (fallbackTimers.has(key)) clearTimeout(fallbackTimers.get(key));
if (ttlMs) {
const timer = setTimeout(()=>{
fallbackStore.delete(key);
fallbackTimers.delete(key);
}, ttlMs);
timer.unref();
fallbackTimers.set(key, timer);
}
}
function fallbackDel(key) {
fallbackStore.delete(key);
if (fallbackTimers.has(key)) {
clearTimeout(fallbackTimers.get(key));
fallbackTimers.delete(key);
}
}
export async function redisGet(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.get(key);
} catch {
return null;
}
}
return fallbackGet(key);
}
export async function redisSet(key, value, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
if (ttlMs) await client.set(key, value, 'PX', ttlMs);
else await client.set(key, value);
return;
} catch {}
}
fallbackSet(key, value, ttlMs);
}
export async function redisDel(key) {
const client = await ensureConnected();
if (client) {
try {
await client.del(key);
return;
} catch {}
}
fallbackDel(key);
}
export async function redisIncr(key, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
const val = await client.incr(key);
if (ttlMs && val === 1) await client.pexpire(key, ttlMs);
return val;
} catch {}
}
const val = (parseInt(fallbackGet(key), 10) || 0) + 1;
fallbackSet(key, String(val), ttlMs);
return val;
}
export async function redisTtl(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.ttl(key);
} catch {
return -2;
}
}
const entry = fallbackStore.get(key);
if (!entry || !entry.expiry) return -1;
const remaining = Math.max(0, Math.floor((entry.expiry - Date.now()) / 1000));
return remaining > 0 ? remaining : -2;
}
export async function redisFlush() {
const client = await ensureConnected();
if (client) {
try {
await client.flushdb();
return;
} catch {}
}
fallbackStore.clear();
for (const timer of fallbackTimers.values())clearTimeout(timer);
fallbackTimers.clear();
}
027undefined335339__WEBPACK_MODULE_REFERENCE__0_5b2264656661756c74225d_directImport_asiSafe1__._undefined19551961undefined22022208undefined25272533undefined27462752undefined31553161undefined35833589undefinedA3 (built_default())
;// ./src/lib/idempotency.js
webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSourcewebpack/lib/util/registerExternalSerializerwebpack-sources/RawSource3 import { redisGet, redisSet } from './redis';
const TTL_MS = 86400000;
async function withIdempotency(key, handler) {
if (!key) return handler();
const existing = await redisGet(`idemp:${key}`);
if (existing) return JSON.parse(existing);
const result = await handler();
await redisSet(`idemp:${key}`, JSON.stringify(result), TTL_MS);
return result;
}
function getIdempotencyKey(request) {
return request.headers.get("Idempotency-Key") || request.headers.get("idempotency-key") || null;
}
export { withIdempotency, getIdempotencyKey };
`,E ( / 1 __WEBPACK_MODULE_REFERENCE__1_5b227265646973476574225d_call_directImport_asiSafe1__.___WEBPACK_MODULE_REFERENCE__1_5b227265646973536574225d_call_directImport_asiSafe1__._r
const TTL_MS = 86400000;
async function withIdempotency(key, handler) {
if (!key) return handler();
const existing = await __WEBPACK_MODULE_REFERENCE__1_5b227265646973476574225d_call_directImport_asiSafe1__._(`idemp:${key}`);
if (existing) return JSON.parse(existing);
const result = await handler();
await __WEBPACK_MODULE_REFERENCE__1_5b227265646973536574225d_call_directImport_asiSafe1__._(`idemp:${key}`, JSON.stringify(result), TTL_MS);
return result;
}
function getIdempotencyKey(request) {
return request.headers.get("Idempotency-Key") || request.headers.get("idempotency-key") || null;
}
3 import { redisGet, redisSet } from './redis';
const TTL_MS = 86400000;
async function withIdempotency(key, handler) {
if (!key) return handler();
const existing = await redisGet(`idemp:${key}`);
if (existing) return JSON.parse(existing);
const result = await handler();
await redisSet(`idemp:${key}`, JSON.stringify(result), TTL_MS);
return result;
}
function getIdempotencyKey(request) {
return request.headers.get("Idempotency-Key") || request.headers.get("idempotency-key") || null;
}
export { withIdempotency, getIdempotencyKey };
044undefined177184__WEBPACK_MODULE_REFERENCE__1_5b227265646973476574225d_call_directImport_asiSafe1__._undefined296303__WEBPACK_MODULE_REFERENCE__1_5b227265646973536574225d_call_directImport_asiSafe1__._undefined516561undefinedC H redisGetredisSetbuffersourcesizemapshash // ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
getIdempotencyKey: () => (/* binding */ getIdempotencyKey),
withIdempotency: () => (/* binding */ withIdempotency)
});
// EXTERNAL MODULE: ./node_modules/ioredis/built/index.js
var built = __webpack_require__(50453);
var built_default = /*#__PURE__*/__webpack_require__.n(built);
;// ./src/lib/redis.js
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
const ENABLED = process.env.COSMIC_REDIS_ENABLED !== 'false';
let redis = null;
let fallbackStore = new Map();
let fallbackTimers = new Map();
function createClient() {
if (!ENABLED) return null;
try {
const client = new (built_default())(REDIS_URL, {
maxRetriesPerRequest: 1,
retryStrategy (times) {
if (times > 3) return null;
return Math.min(times * 200, 2000);
},
lazyConnect: true,
enableOfflineQueue: false
});
client.on('error', ()=>{});
client.on('close', ()=>{});
return client;
} catch {
return null;
}
}
async function ensureConnected() {
if (redis === null) redis = createClient();
if (!redis || redis.status === 'ready') return redis;
if (redis.status === 'connecting' || redis.status === 'connect') return redis;
try {
await redis.connect();
return redis;
} catch {
return null;
}
}
function fallbackGet(key) {
const entry = fallbackStore.get(key);
if (!entry) return null;
if (entry.expiry && Date.now() > entry.expiry) {
fallbackStore.delete(key);
return null;
}
return entry.value;
}
function fallbackSet(key, value, ttlMs) {
fallbackStore.set(key, {
value,
expiry: ttlMs ? Date.now() + ttlMs : null
});
if (fallbackTimers.has(key)) clearTimeout(fallbackTimers.get(key));
if (ttlMs) {
const timer = setTimeout(()=>{
fallbackStore.delete(key);
fallbackTimers.delete(key);
}, ttlMs);
timer.unref();
fallbackTimers.set(key, timer);
}
}
function fallbackDel(key) {
fallbackStore.delete(key);
if (fallbackTimers.has(key)) {
clearTimeout(fallbackTimers.get(key));
fallbackTimers.delete(key);
}
}
async function redisGet(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.get(key);
} catch {
return null;
}
}
return fallbackGet(key);
}
async function redisSet(key, value, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
if (ttlMs) await client.set(key, value, 'PX', ttlMs);
else await client.set(key, value);
return;
} catch {}
}
fallbackSet(key, value, ttlMs);
}
async function redisDel(key) {
const client = await ensureConnected();
if (client) {
try {
await client.del(key);
return;
} catch {}
}
fallbackDel(key);
}
async function redisIncr(key, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
const val = await client.incr(key);
if (ttlMs && val === 1) await client.pexpire(key, ttlMs);
return val;
} catch {}
}
const val = (parseInt(fallbackGet(key), 10) || 0) + 1;
fallbackSet(key, String(val), ttlMs);
return val;
}
async function redisTtl(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.ttl(key);
} catch {
return -2;
}
}
const entry = fallbackStore.get(key);
if (!entry || !entry.expiry) return -1;
const remaining = Math.max(0, Math.floor((entry.expiry - Date.now()) / 1000));
return remaining > 0 ? remaining : -2;
}
async function redisFlush() {
const client = await ensureConnected();
if (client) {
try {
await client.flushdb();
return;
} catch {}
}
fallbackStore.clear();
for (const timer of fallbackTimers.values())clearTimeout(timer);
fallbackTimers.clear();
}
;// ./src/lib/idempotency.js
const TTL_MS = 86400000;
async function withIdempotency(key, handler) {
if (!key) return handler();
const existing = await redisGet(`idemp:${key}`);
if (existing) return JSON.parse(existing);
const result = await handler();
await redisSet(`idemp:${key}`, JSON.stringify(result), TTL_MS);
return result;
}
function getIdempotencyKey(request) {
return request.headers.get("Idempotency-Key") || request.headers.get("idempotency-key") || null;
}
{"finalSource":true}mapbufferedMap`
ConcatSourceRawSource // ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
getIdempotencyKey: () => (/* binding */ getIdempotencyKey),
withIdempotency: () => (/* binding */ withIdempotency)
});
// EXTERNAL MODULE: ./node_modules/ioredis/built/index.js
var built = __webpack_require__(50453);
var built_default = /*#__PURE__*/__webpack_require__.n(built);
;// ./src/lib/redis.js
ReplaceSource ReplaceSourceRawSource@ import Redis from 'ioredis';
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
const ENABLED = process.env.COSMIC_REDIS_ENABLED !== 'false';
let redis = null;
let fallbackStore = new Map();
let fallbackTimers = new Map();
function createClient() {
if (!ENABLED) return null;
try {
const client = new Redis(REDIS_URL, {
maxRetriesPerRequest: 1,
retryStrategy (times) {
if (times > 3) return null;
return Math.min(times * 200, 2000);
},
lazyConnect: true,
enableOfflineQueue: false
});
client.on('error', ()=>{});
client.on('close', ()=>{});
return client;
} catch {
return null;
}
}
async function ensureConnected() {
if (redis === null) redis = createClient();
if (!redis || redis.status === 'ready') return redis;
if (redis.status === 'connecting' || redis.status === 'connect') return redis;
try {
await redis.connect();
return redis;
} catch {
return null;
}
}
function fallbackGet(key) {
const entry = fallbackStore.get(key);
if (!entry) return null;
if (entry.expiry && Date.now() > entry.expiry) {
fallbackStore.delete(key);
return null;
}
return entry.value;
}
function fallbackSet(key, value, ttlMs) {
fallbackStore.set(key, {
value,
expiry: ttlMs ? Date.now() + ttlMs : null
});
if (fallbackTimers.has(key)) clearTimeout(fallbackTimers.get(key));
if (ttlMs) {
const timer = setTimeout(()=>{
fallbackStore.delete(key);
fallbackTimers.delete(key);
}, ttlMs);
timer.unref();
fallbackTimers.set(key, timer);
}
}
function fallbackDel(key) {
fallbackStore.delete(key);
if (fallbackTimers.has(key)) {
clearTimeout(fallbackTimers.get(key));
fallbackTimers.delete(key);
}
}
export async function redisGet(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.get(key);
} catch {
return null;
}
}
return fallbackGet(key);
}
export async function redisSet(key, value, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
if (ttlMs) await client.set(key, value, 'PX', ttlMs);
else await client.set(key, value);
return;
} catch {}
}
fallbackSet(key, value, ttlMs);
}
export async function redisDel(key) {
const client = await ensureConnected();
if (client) {
try {
await client.del(key);
return;
} catch {}
}
fallbackDel(key);
}
export async function redisIncr(key, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
const val = await client.incr(key);
if (ttlMs && val === 1) await client.pexpire(key, ttlMs);
return val;
} catch {}
}
const val = (parseInt(fallbackGet(key), 10) || 0) + 1;
fallbackSet(key, String(val), ttlMs);
return val;
}
export async function redisTtl(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.ttl(key);
} catch {
return -2;
}
}
const entry = fallbackStore.get(key);
if (!entry || !entry.expiry) return -1;
const remaining = Math.max(0, Math.floor((entry.expiry - Date.now()) / 1000));
return remaining > 0 ? remaining : -2;
}
export async function redisFlush() {
const client = await ensureConnected();
if (client) {
try {
await client.flushdb();
return;
} catch {}
}
fallbackStore.clear();
for (const timer of fallbackTimers.values())clearTimeout(timer);
fallbackTimers.clear();
}
027undefined335339__WEBPACK_MODULE_REFERENCE__0_5b2264656661756c74225d_directImport_asiSafe1__._undefined19551961undefined22022208undefined25272533undefined27462752undefined31553161undefined35833589undefined) 307384(built_default())undefinedRawSource
;// ./src/lib/idempotency.js
3 import { redisGet, redisSet } from './redis';
const TTL_MS = 86400000;
async function withIdempotency(key, handler) {
if (!key) return handler();
const existing = await redisGet(`idemp:${key}`);
if (existing) return JSON.parse(existing);
const result = await handler();
await redisSet(`idemp:${key}`, JSON.stringify(result), TTL_MS);
return result;
}
function getIdempotencyKey(request) {
return request.headers.get("Idempotency-Key") || request.headers.get("idempotency-key") || null;
}
export { withIdempotency, getIdempotencyKey };
044undefined177184__WEBPACK_MODULE_REFERENCE__1_5b227265646973476574225d_call_directImport_asiSafe1__._undefined296303__WEBPACK_MODULE_REFERENCE__1_5b227265646973536574225d_call_directImport_asiSafe1__._undefined516561undefined. 132216redisGetundefined328412redisSetundefined
/***/ }) /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
getIdempotencyKey: () => (/* binding */ getIdempotencyKey),
withIdempotency: () => (/* binding */ withIdempotency)
});
// EXTERNAL MODULE: ./node_modules/ioredis/built/index.js
var built = __webpack_require__(50453);
var built_default = /*#__PURE__*/__webpack_require__.n(built);
;// ./src/lib/redis.js
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
const ENABLED = process.env.COSMIC_REDIS_ENABLED !== 'false';
let redis = null;
let fallbackStore = new Map();
let fallbackTimers = new Map();
function createClient() {
if (!ENABLED) return null;
try {
const client = new (built_default())(REDIS_URL, {
maxRetriesPerRequest: 1,
retryStrategy (times) {
if (times > 3) return null;
return Math.min(times * 200, 2000);
},
lazyConnect: true,
enableOfflineQueue: false
});
client.on('error', ()=>{});
client.on('close', ()=>{});
return client;
} catch {
return null;
}
}
async function ensureConnected() {
if (redis === null) redis = createClient();
if (!redis || redis.status === 'ready') return redis;
if (redis.status === 'connecting' || redis.status === 'connect') return redis;
try {
await redis.connect();
return redis;
} catch {
return null;
}
}
function fallbackGet(key) {
const entry = fallbackStore.get(key);
if (!entry) return null;
if (entry.expiry && Date.now() > entry.expiry) {
fallbackStore.delete(key);
return null;
}
return entry.value;
}
function fallbackSet(key, value, ttlMs) {
fallbackStore.set(key, {
value,
expiry: ttlMs ? Date.now() + ttlMs : null
});
if (fallbackTimers.has(key)) clearTimeout(fallbackTimers.get(key));
if (ttlMs) {
const timer = setTimeout(()=>{
fallbackStore.delete(key);
fallbackTimers.delete(key);
}, ttlMs);
timer.unref();
fallbackTimers.set(key, timer);
}
}
function fallbackDel(key) {
fallbackStore.delete(key);
if (fallbackTimers.has(key)) {
clearTimeout(fallbackTimers.get(key));
fallbackTimers.delete(key);
}
}
async function redisGet(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.get(key);
} catch {
return null;
}
}
return fallbackGet(key);
}
async function redisSet(key, value, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
if (ttlMs) await client.set(key, value, 'PX', ttlMs);
else await client.set(key, value);
return;
} catch {}
}
fallbackSet(key, value, ttlMs);
}
async function redisDel(key) {
const client = await ensureConnected();
if (client) {
try {
await client.del(key);
return;
} catch {}
}
fallbackDel(key);
}
async function redisIncr(key, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
const val = await client.incr(key);
if (ttlMs && val === 1) await client.pexpire(key, ttlMs);
return val;
} catch {}
}
const val = (parseInt(fallbackGet(key), 10) || 0) + 1;
fallbackSet(key, String(val), ttlMs);
return val;
}
async function redisTtl(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.ttl(key);
} catch {
return -2;
}
}
const entry = fallbackStore.get(key);
if (!entry || !entry.expiry) return -1;
const remaining = Math.max(0, Math.floor((entry.expiry - Date.now()) / 1000));
return remaining > 0 ? remaining : -2;
}
async function redisFlush() {
const client = await ensureConnected();
if (client) {
try {
await client.flushdb();
return;
} catch {}
}
fallbackStore.clear();
for (const timer of fallbackTimers.values())clearTimeout(timer);
fallbackTimers.clear();
}
;// ./src/lib/idempotency.js
const TTL_MS = 86400000;
async function withIdempotency(key, handler) {
if (!key) return handler();
const existing = await redisGet(`idemp:${key}`);
if (existing) return JSON.parse(existing);
const result = await handler();
await redisSet(`idemp:${key}`, JSON.stringify(result), TTL_MS);
return result;
}
function getIdempotencyKey(request) {
return request.headers.get("Idempotency-Key") || request.headers.get("idempotency-key") || null;
}
/***/ })`Q /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
getIdempotencyKey: () => (/* binding */ getIdempotencyKey),
withIdempotency: () => (/* binding */ withIdempotency)
});
// EXTERNAL MODULE: ./node_modules/ioredis/built/index.js
var built = __webpack_require__(50453);
var built_default = /*#__PURE__*/__webpack_require__.n(built);
;// ./src/lib/redis.js
ReplaceSource@ import Redis from 'ioredis';
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
const ENABLED = process.env.COSMIC_REDIS_ENABLED !== 'false';
let redis = null;
let fallbackStore = new Map();
let fallbackTimers = new Map();
function createClient() {
if (!ENABLED) return null;
try {
const client = new Redis(REDIS_URL, {
maxRetriesPerRequest: 1,
retryStrategy (times) {
if (times > 3) return null;
return Math.min(times * 200, 2000);
},
lazyConnect: true,
enableOfflineQueue: false
});
client.on('error', ()=>{});
client.on('close', ()=>{});
return client;
} catch {
return null;
}
}
async function ensureConnected() {
if (redis === null) redis = createClient();
if (!redis || redis.status === 'ready') return redis;
if (redis.status === 'connecting' || redis.status === 'connect') return redis;
try {
await redis.connect();
return redis;
} catch {
return null;
}
}
function fallbackGet(key) {
const entry = fallbackStore.get(key);
if (!entry) return null;
if (entry.expiry && Date.now() > entry.expiry) {
fallbackStore.delete(key);
return null;
}
return entry.value;
}
function fallbackSet(key, value, ttlMs) {
fallbackStore.set(key, {
value,
expiry: ttlMs ? Date.now() + ttlMs : null
});
if (fallbackTimers.has(key)) clearTimeout(fallbackTimers.get(key));
if (ttlMs) {
const timer = setTimeout(()=>{
fallbackStore.delete(key);
fallbackTimers.delete(key);
}, ttlMs);
timer.unref();
fallbackTimers.set(key, timer);
}
}
function fallbackDel(key) {
fallbackStore.delete(key);
if (fallbackTimers.has(key)) {
clearTimeout(fallbackTimers.get(key));
fallbackTimers.delete(key);
}
}
export async function redisGet(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.get(key);
} catch {
return null;
}
}
return fallbackGet(key);
}
export async function redisSet(key, value, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
if (ttlMs) await client.set(key, value, 'PX', ttlMs);
else await client.set(key, value);
return;
} catch {}
}
fallbackSet(key, value, ttlMs);
}
export async function redisDel(key) {
const client = await ensureConnected();
if (client) {
try {
await client.del(key);
return;
} catch {}
}
fallbackDel(key);
}
export async function redisIncr(key, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
const val = await client.incr(key);
if (ttlMs && val === 1) await client.pexpire(key, ttlMs);
return val;
} catch {}
}
const val = (parseInt(fallbackGet(key), 10) || 0) + 1;
fallbackSet(key, String(val), ttlMs);
return val;
}
export async function redisTtl(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.ttl(key);
} catch {
return -2;
}
}
const entry = fallbackStore.get(key);
if (!entry || !entry.expiry) return -1;
const remaining = Math.max(0, Math.floor((entry.expiry - Date.now()) / 1000));
return remaining > 0 ? remaining : -2;
}
export async function redisFlush() {
const client = await ensureConnected();
if (client) {
try {
await client.flushdb();
return;
} catch {}
}
fallbackStore.clear();
for (const timer of fallbackTimers.values())clearTimeout(timer);
fallbackTimers.clear();
}
027undefined335339__WEBPACK_MODULE_REFERENCE__0_5b2264656661756c74225d_directImport_asiSafe1__._undefined19551961undefined22022208undefined25272533undefined27462752undefined31553161undefined35833589undefined) 307384(built_default())undefinedRawSource
;// ./src/lib/idempotency.js
3 import { redisGet, redisSet } from './redis';
const TTL_MS = 86400000;
async function withIdempotency(key, handler) {
if (!key) return handler();
const existing = await redisGet(`idemp:${key}`);
if (existing) return JSON.parse(existing);
const result = await handler();
await redisSet(`idemp:${key}`, JSON.stringify(result), TTL_MS);
return result;
}
function getIdempotencyKey(request) {
return request.headers.get("Idempotency-Key") || request.headers.get("idempotency-key") || null;
}
export { withIdempotency, getIdempotencyKey };
044undefined177184__WEBPACK_MODULE_REFERENCE__1_5b227265646973476574225d_call_directImport_asiSafe1__._undefined296303__WEBPACK_MODULE_REFERENCE__1_5b227265646973536574225d_call_directImport_asiSafe1__._undefined516561undefined. 132216redisGetundefined328412redisSetundefined ,
/***/ 69698:
5 webpack/lib/util/registerExternalSerializerwebpack-sources/ConcatSourcewebpack/lib/util/registerExternalSerializerwebpack-sources/RawSourceE /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
webpack/lib/util/registerExternalSerializerwebpack-sources/CachedSource 6: webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSourcewebpack/lib/util/registerExternalSerializerwebpack-sources/RawSourceK9 "use strict";
const { prisma } = require("../lib/prisma");
const { scoreRisk } = require("../domain/risk-engine");
const { writeAuditEvent } = require("./audit-service");
function normalizeRiskStatus(value) {
if (value === "In mitigation" || value === "IN_MITIGATION") return "IN_MITIGATION";
if (value === "Accepted" || value === "ACCEPTED") return "ACCEPTED";
if (value === "Closed" || value === "CLOSED") return "CLOSED";
return "OPEN";
}
function normalizeApprovalStatus(value) {
if (value === "Approved" || value === "APPROVED") return "APPROVED";
if (value === "Rejected" || value === "REJECTED") return "REJECTED";
if (value === "Accepted" || value === "ACCEPTED") return "ACCEPTED";
return "PENDING";
}
function normalizeMitigationStatus(value) {
if (value === "In progress" || value === "IN_PROGRESS") return "IN_PROGRESS";
if (value === "Done" || value === "DONE") return "DONE";
if (value === "Rejected" || value === "REJECTED") return "REJECTED";
return "NOT_STARTED";
}
async function listRisks(projectId) {
const risks = await prisma.risk.findMany({
where: {
projectId
},
include: {
mitigations: true,
evidence: true
},
orderBy: {
createdAt: "asc"
}
});
return risks.map((risk)=>scoreRisk(Object.assign({}, risk, {
mitigationProgress: risk.mitigations.length ? Math.round(risk.mitigations.reduce((sum, item)=>sum + item.progressPercent, 0) / risk.mitigations.length) : 0,
mitigationEffectiveness: risk.mitigations.length ? Math.round(risk.mitigations.reduce((sum, item)=>sum + item.effectivenessPercent, 0) / risk.mitigations.length) : 0
})));
}
async function createRisk({ projectScope, actor, payload, request }) {
if (!payload.title) throw new Error("title is required");
const risk = await prisma.risk.create({
data: {
projectId: projectScope.project.id,
ownerDisplayName: payload.ownerDisplayName || payload.owner || actor.displayName,
title: payload.title,
description: payload.description || "",
dimension: payload.dimension || "Technical",
domain: payload.domain || "Technical risks",
lifecyclePhase: payload.lifecyclePhase || projectScope.project.currentLifecyclePhase || "Needs identification",
probability: Number(payload.probability || 3),
impact: Number(payload.impact || 3),
detectability: Number(payload.detectability || 3),
status: normalizeRiskStatus(payload.status),
approvalStatus: normalizeApprovalStatus(payload.approvalStatus),
dueDate: payload.dueDate ? new Date(payload.dueDate) : null,
evidenceSummary: payload.evidenceSummary || payload.evidence || ""
}
});
if (payload.evidenceTitle || payload.evidenceSummary || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: risk.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceSummary || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: risk.id,
action: "create",
afterJson: risk,
request
});
return scoreRisk(risk);
}
async function updateRisk({ projectScope, riskId, actor, payload, request }) {
const before = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!before || before.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
const risk = await prisma.risk.update({
where: {
id: riskId
},
data: {
title: payload.title ?? before.title,
description: payload.description ?? before.description,
dimension: payload.dimension ?? before.dimension,
domain: payload.domain ?? before.domain,
lifecyclePhase: payload.lifecyclePhase ?? before.lifecyclePhase,
probability: payload.probability !== undefined ? Number(payload.probability) : before.probability,
impact: payload.impact !== undefined ? Number(payload.impact) : before.impact,
detectability: payload.detectability !== undefined ? Number(payload.detectability) : before.detectability,
status: payload.status !== undefined ? normalizeRiskStatus(payload.status) : before.status,
approvalStatus: payload.approvalStatus !== undefined ? normalizeApprovalStatus(payload.approvalStatus) : before.approvalStatus,
dueDate: payload.dueDate !== undefined ? payload.dueDate ? new Date(payload.dueDate) : null : before.dueDate,
evidenceSummary: payload.evidenceSummary ?? before.evidenceSummary
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: risk.id,
action: "update",
beforeJson: before,
afterJson: risk,
request
});
return scoreRisk(risk);
}
async function deleteRisk({ projectScope, riskId, actor, request }) {
const before = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!before || before.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
await prisma.risk.delete({
where: {
id: riskId
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: riskId,
action: "delete",
beforeJson: before,
request
});
return {
deleted: true
};
}
async function createMitigation({ projectScope, riskId, actor, payload, request }) {
const risk = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!risk || risk.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
const mitigation = await prisma.mitigation.create({
data: {
riskId,
ownerDisplayName: payload.ownerDisplayName || payload.owner || actor.displayName,
title: payload.title,
description: payload.description || "",
status: normalizeMitigationStatus(payload.status),
progressPercent: Number(payload.progressPercent ?? payload.progress_percent ?? 0),
effectivenessPercent: Number(payload.effectivenessPercent ?? payload.effectiveness_percent ?? 0),
dueDate: payload.dueDate ? new Date(payload.dueDate) : null,
sequence: Number(payload.sequence || 1)
}
});
if (payload.evidenceTitle || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId,
mitigationId: mitigation.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigation.id,
action: "create",
afterJson: mitigation,
request
});
return mitigation;
}
async function getMitigation(mitigationId) {
const mitigation = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
evidence: true,
risk: {
select: {
id: true,
title: true,
dimension: true,
projectId: true
}
}
}
});
if (!mitigation) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
return mitigation;
}
async function listProjectMitigations(projectId) {
return prisma.mitigation.findMany({
where: {
risk: {
projectId
}
},
include: {
evidence: true,
risk: {
select: {
id: true,
title: true,
dimension: true
}
}
},
orderBy: {
createdAt: "desc"
}
});
}
async function updateMitigation({ projectScope, mitigationId, actor, payload, request }) {
const before = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!before || before.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
const mitigation = await prisma.mitigation.update({
where: {
id: mitigationId
},
data: {
title: payload.title ?? before.title,
description: payload.description ?? before.description,
ownerDisplayName: payload.ownerDisplayName ?? payload.owner ?? before.ownerDisplayName,
status: payload.status !== undefined ? normalizeMitigationStatus(payload.status) : before.status,
progressPercent: payload.progressPercent !== undefined ? Number(payload.progressPercent) : before.progressPercent,
effectivenessPercent: payload.effectivenessPercent !== undefined ? Number(payload.effectivenessPercent) : before.effectivenessPercent,
dueDate: payload.dueDate !== undefined ? payload.dueDate ? new Date(payload.dueDate) : null : before.dueDate,
sequence: payload.sequence !== undefined ? Number(payload.sequence) : before.sequence
}
});
if (payload.evidenceTitle || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: before.riskId,
mitigationId: mitigation.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigation.id,
action: "update",
beforeJson: before,
afterJson: mitigation,
request
});
return mitigation;
}
async function deleteMitigation({ projectScope, mitigationId, actor, request }) {
const before = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!before || before.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
await prisma.mitigation.delete({
where: {
id: mitigationId
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigationId,
action: "delete",
beforeJson: before,
request
});
return {
deleted: true
};
}
async function addEvidenceToMitigation({ projectScope, mitigationId, actor, payload, request }) {
const mitigation = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!mitigation || mitigation.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
const evidence = await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: mitigation.riskId,
mitigationId: mitigation.id,
type: payload.type || "Review",
title: payload.title,
uri: payload.uri || null,
createdById: actor.id
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Evidence",
entityId: evidence.id,
action: "create",
afterJson: evidence,
request
});
return evidence;
}
module.exports = {
listRisks,
createRisk,
updateRisk,
deleteRisk,
createMitigation,
getMitigation,
listProjectMitigations,
updateMitigation,
deleteMitigation,
addEvidenceToMitigation,
normalizeRiskStatus,
normalizeApprovalStatus
};
h!')7QWYoC __webpack_require__179645556723518buffersourcesizemapshash:9
const { prisma } = __webpack_require__(17964);
const { scoreRisk } = __webpack_require__(55567);
const { writeAuditEvent } = __webpack_require__(23518);
function normalizeRiskStatus(value) {
if (value === "In mitigation" || value === "IN_MITIGATION") return "IN_MITIGATION";
if (value === "Accepted" || value === "ACCEPTED") return "ACCEPTED";
if (value === "Closed" || value === "CLOSED") return "CLOSED";
return "OPEN";
}
function normalizeApprovalStatus(value) {
if (value === "Approved" || value === "APPROVED") return "APPROVED";
if (value === "Rejected" || value === "REJECTED") return "REJECTED";
if (value === "Accepted" || value === "ACCEPTED") return "ACCEPTED";
return "PENDING";
}
function normalizeMitigationStatus(value) {
if (value === "In progress" || value === "IN_PROGRESS") return "IN_PROGRESS";
if (value === "Done" || value === "DONE") return "DONE";
if (value === "Rejected" || value === "REJECTED") return "REJECTED";
return "NOT_STARTED";
}
async function listRisks(projectId) {
const risks = await prisma.risk.findMany({
where: {
projectId
},
include: {
mitigations: true,
evidence: true
},
orderBy: {
createdAt: "asc"
}
});
return risks.map((risk)=>scoreRisk(Object.assign({}, risk, {
mitigationProgress: risk.mitigations.length ? Math.round(risk.mitigations.reduce((sum, item)=>sum + item.progressPercent, 0) / risk.mitigations.length) : 0,
mitigationEffectiveness: risk.mitigations.length ? Math.round(risk.mitigations.reduce((sum, item)=>sum + item.effectivenessPercent, 0) / risk.mitigations.length) : 0
})));
}
async function createRisk({ projectScope, actor, payload, request }) {
if (!payload.title) throw new Error("title is required");
const risk = await prisma.risk.create({
data: {
projectId: projectScope.project.id,
ownerDisplayName: payload.ownerDisplayName || payload.owner || actor.displayName,
title: payload.title,
description: payload.description || "",
dimension: payload.dimension || "Technical",
domain: payload.domain || "Technical risks",
lifecyclePhase: payload.lifecyclePhase || projectScope.project.currentLifecyclePhase || "Needs identification",
probability: Number(payload.probability || 3),
impact: Number(payload.impact || 3),
detectability: Number(payload.detectability || 3),
status: normalizeRiskStatus(payload.status),
approvalStatus: normalizeApprovalStatus(payload.approvalStatus),
dueDate: payload.dueDate ? new Date(payload.dueDate) : null,
evidenceSummary: payload.evidenceSummary || payload.evidence || ""
}
});
if (payload.evidenceTitle || payload.evidenceSummary || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: risk.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceSummary || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: risk.id,
action: "create",
afterJson: risk,
request
});
return scoreRisk(risk);
}
async function updateRisk({ projectScope, riskId, actor, payload, request }) {
const before = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!before || before.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
const risk = await prisma.risk.update({
where: {
id: riskId
},
data: {
title: payload.title ?? before.title,
description: payload.description ?? before.description,
dimension: payload.dimension ?? before.dimension,
domain: payload.domain ?? before.domain,
lifecyclePhase: payload.lifecyclePhase ?? before.lifecyclePhase,
probability: payload.probability !== undefined ? Number(payload.probability) : before.probability,
impact: payload.impact !== undefined ? Number(payload.impact) : before.impact,
detectability: payload.detectability !== undefined ? Number(payload.detectability) : before.detectability,
status: payload.status !== undefined ? normalizeRiskStatus(payload.status) : before.status,
approvalStatus: payload.approvalStatus !== undefined ? normalizeApprovalStatus(payload.approvalStatus) : before.approvalStatus,
dueDate: payload.dueDate !== undefined ? payload.dueDate ? new Date(payload.dueDate) : null : before.dueDate,
evidenceSummary: payload.evidenceSummary ?? before.evidenceSummary
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: risk.id,
action: "update",
beforeJson: before,
afterJson: risk,
request
});
return scoreRisk(risk);
}
async function deleteRisk({ projectScope, riskId, actor, request }) {
const before = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!before || before.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
await prisma.risk.delete({
where: {
id: riskId
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: riskId,
action: "delete",
beforeJson: before,
request
});
return {
deleted: true
};
}
async function createMitigation({ projectScope, riskId, actor, payload, request }) {
const risk = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!risk || risk.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
const mitigation = await prisma.mitigation.create({
data: {
riskId,
ownerDisplayName: payload.ownerDisplayName || payload.owner || actor.displayName,
title: payload.title,
description: payload.description || "",
status: normalizeMitigationStatus(payload.status),
progressPercent: Number(payload.progressPercent ?? payload.progress_percent ?? 0),
effectivenessPercent: Number(payload.effectivenessPercent ?? payload.effectiveness_percent ?? 0),
dueDate: payload.dueDate ? new Date(payload.dueDate) : null,
sequence: Number(payload.sequence || 1)
}
});
if (payload.evidenceTitle || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId,
mitigationId: mitigation.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigation.id,
action: "create",
afterJson: mitigation,
request
});
return mitigation;
}
async function getMitigation(mitigationId) {
const mitigation = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
evidence: true,
risk: {
select: {
id: true,
title: true,
dimension: true,
projectId: true
}
}
}
});
if (!mitigation) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
return mitigation;
}
async function listProjectMitigations(projectId) {
return prisma.mitigation.findMany({
where: {
risk: {
projectId
}
},
include: {
evidence: true,
risk: {
select: {
id: true,
title: true,
dimension: true
}
}
},
orderBy: {
createdAt: "desc"
}
});
}
async function updateMitigation({ projectScope, mitigationId, actor, payload, request }) {
const before = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!before || before.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
const mitigation = await prisma.mitigation.update({
where: {
id: mitigationId
},
data: {
title: payload.title ?? before.title,
description: payload.description ?? before.description,
ownerDisplayName: payload.ownerDisplayName ?? payload.owner ?? before.ownerDisplayName,
status: payload.status !== undefined ? normalizeMitigationStatus(payload.status) : before.status,
progressPercent: payload.progressPercent !== undefined ? Number(payload.progressPercent) : before.progressPercent,
effectivenessPercent: payload.effectivenessPercent !== undefined ? Number(payload.effectivenessPercent) : before.effectivenessPercent,
dueDate: payload.dueDate !== undefined ? payload.dueDate ? new Date(payload.dueDate) : null : before.dueDate,
sequence: payload.sequence !== undefined ? Number(payload.sequence) : before.sequence
}
});
if (payload.evidenceTitle || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: before.riskId,
mitigationId: mitigation.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigation.id,
action: "update",
beforeJson: before,
afterJson: mitigation,
request
});
return mitigation;
}
async function deleteMitigation({ projectScope, mitigationId, actor, request }) {
const before = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!before || before.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
await prisma.mitigation.delete({
where: {
id: mitigationId
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigationId,
action: "delete",
beforeJson: before,
request
});
return {
deleted: true
};
}
async function addEvidenceToMitigation({ projectScope, mitigationId, actor, payload, request }) {
const mitigation = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!mitigation || mitigation.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
const evidence = await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: mitigation.riskId,
mitigationId: mitigation.id,
type: payload.type || "Review",
title: payload.title,
uri: payload.uri || null,
createdById: actor.id
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Evidence",
entityId: evidence.id,
action: "create",
afterJson: evidence,
request
});
return evidence;
}
module.exports = {
listRisks,
createRisk,
updateRisk,
deleteRisk,
createMitigation,
getMitigation,
listProjectMitigations,
updateMitigation,
deleteMitigation,
addEvidenceToMitigation,
normalizeRiskStatus,
normalizeApprovalStatus
};
{"finalSource":true}mapbufferedMap ReplaceSourceRawSourceK9 "use strict";
const { prisma } = require("../lib/prisma");
const { scoreRisk } = require("../domain/risk-engine");
const { writeAuditEvent } = require("./audit-service");
function normalizeRiskStatus(value) {
if (value === "In mitigation" || value === "IN_MITIGATION") return "IN_MITIGATION";
if (value === "Accepted" || value === "ACCEPTED") return "ACCEPTED";
if (value === "Closed" || value === "CLOSED") return "CLOSED";
return "OPEN";
}
function normalizeApprovalStatus(value) {
if (value === "Approved" || value === "APPROVED") return "APPROVED";
if (value === "Rejected" || value === "REJECTED") return "REJECTED";
if (value === "Accepted" || value === "ACCEPTED") return "ACCEPTED";
return "PENDING";
}
function normalizeMitigationStatus(value) {
if (value === "In progress" || value === "IN_PROGRESS") return "IN_PROGRESS";
if (value === "Done" || value === "DONE") return "DONE";
if (value === "Rejected" || value === "REJECTED") return "REJECTED";
return "NOT_STARTED";
}
async function listRisks(projectId) {
const risks = await prisma.risk.findMany({
where: {
projectId
},
include: {
mitigations: true,
evidence: true
},
orderBy: {
createdAt: "asc"
}
});
return risks.map((risk)=>scoreRisk(Object.assign({}, risk, {
mitigationProgress: risk.mitigations.length ? Math.round(risk.mitigations.reduce((sum, item)=>sum + item.progressPercent, 0) / risk.mitigations.length) : 0,
mitigationEffectiveness: risk.mitigations.length ? Math.round(risk.mitigations.reduce((sum, item)=>sum + item.effectivenessPercent, 0) / risk.mitigations.length) : 0
})));
}
async function createRisk({ projectScope, actor, payload, request }) {
if (!payload.title) throw new Error("title is required");
const risk = await prisma.risk.create({
data: {
projectId: projectScope.project.id,
ownerDisplayName: payload.ownerDisplayName || payload.owner || actor.displayName,
title: payload.title,
description: payload.description || "",
dimension: payload.dimension || "Technical",
domain: payload.domain || "Technical risks",
lifecyclePhase: payload.lifecyclePhase || projectScope.project.currentLifecyclePhase || "Needs identification",
probability: Number(payload.probability || 3),
impact: Number(payload.impact || 3),
detectability: Number(payload.detectability || 3),
status: normalizeRiskStatus(payload.status),
approvalStatus: normalizeApprovalStatus(payload.approvalStatus),
dueDate: payload.dueDate ? new Date(payload.dueDate) : null,
evidenceSummary: payload.evidenceSummary || payload.evidence || ""
}
});
if (payload.evidenceTitle || payload.evidenceSummary || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: risk.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceSummary || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: risk.id,
action: "create",
afterJson: risk,
request
});
return scoreRisk(risk);
}
async function updateRisk({ projectScope, riskId, actor, payload, request }) {
const before = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!before || before.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
const risk = await prisma.risk.update({
where: {
id: riskId
},
data: {
title: payload.title ?? before.title,
description: payload.description ?? before.description,
dimension: payload.dimension ?? before.dimension,
domain: payload.domain ?? before.domain,
lifecyclePhase: payload.lifecyclePhase ?? before.lifecyclePhase,
probability: payload.probability !== undefined ? Number(payload.probability) : before.probability,
impact: payload.impact !== undefined ? Number(payload.impact) : before.impact,
detectability: payload.detectability !== undefined ? Number(payload.detectability) : before.detectability,
status: payload.status !== undefined ? normalizeRiskStatus(payload.status) : before.status,
approvalStatus: payload.approvalStatus !== undefined ? normalizeApprovalStatus(payload.approvalStatus) : before.approvalStatus,
dueDate: payload.dueDate !== undefined ? payload.dueDate ? new Date(payload.dueDate) : null : before.dueDate,
evidenceSummary: payload.evidenceSummary ?? before.evidenceSummary
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: risk.id,
action: "update",
beforeJson: before,
afterJson: risk,
request
});
return scoreRisk(risk);
}
async function deleteRisk({ projectScope, riskId, actor, request }) {
const before = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!before || before.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
await prisma.risk.delete({
where: {
id: riskId
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: riskId,
action: "delete",
beforeJson: before,
request
});
return {
deleted: true
};
}
async function createMitigation({ projectScope, riskId, actor, payload, request }) {
const risk = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!risk || risk.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
const mitigation = await prisma.mitigation.create({
data: {
riskId,
ownerDisplayName: payload.ownerDisplayName || payload.owner || actor.displayName,
title: payload.title,
description: payload.description || "",
status: normalizeMitigationStatus(payload.status),
progressPercent: Number(payload.progressPercent ?? payload.progress_percent ?? 0),
effectivenessPercent: Number(payload.effectivenessPercent ?? payload.effectiveness_percent ?? 0),
dueDate: payload.dueDate ? new Date(payload.dueDate) : null,
sequence: Number(payload.sequence || 1)
}
});
if (payload.evidenceTitle || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId,
mitigationId: mitigation.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigation.id,
action: "create",
afterJson: mitigation,
request
});
return mitigation;
}
async function getMitigation(mitigationId) {
const mitigation = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
evidence: true,
risk: {
select: {
id: true,
title: true,
dimension: true,
projectId: true
}
}
}
});
if (!mitigation) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
return mitigation;
}
async function listProjectMitigations(projectId) {
return prisma.mitigation.findMany({
where: {
risk: {
projectId
}
},
include: {
evidence: true,
risk: {
select: {
id: true,
title: true,
dimension: true
}
}
},
orderBy: {
createdAt: "desc"
}
});
}
async function updateMitigation({ projectScope, mitigationId, actor, payload, request }) {
const before = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!before || before.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
const mitigation = await prisma.mitigation.update({
where: {
id: mitigationId
},
data: {
title: payload.title ?? before.title,
description: payload.description ?? before.description,
ownerDisplayName: payload.ownerDisplayName ?? payload.owner ?? before.ownerDisplayName,
status: payload.status !== undefined ? normalizeMitigationStatus(payload.status) : before.status,
progressPercent: payload.progressPercent !== undefined ? Number(payload.progressPercent) : before.progressPercent,
effectivenessPercent: payload.effectivenessPercent !== undefined ? Number(payload.effectivenessPercent) : before.effectivenessPercent,
dueDate: payload.dueDate !== undefined ? payload.dueDate ? new Date(payload.dueDate) : null : before.dueDate,
sequence: payload.sequence !== undefined ? Number(payload.sequence) : before.sequence
}
});
if (payload.evidenceTitle || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: before.riskId,
mitigationId: mitigation.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigation.id,
action: "update",
beforeJson: before,
afterJson: mitigation,
request
});
return mitigation;
}
async function deleteMitigation({ projectScope, mitigationId, actor, request }) {
const before = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!before || before.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
await prisma.mitigation.delete({
where: {
id: mitigationId
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigationId,
action: "delete",
beforeJson: before,
request
});
return {
deleted: true
};
}
async function addEvidenceToMitigation({ projectScope, mitigationId, actor, payload, request }) {
const mitigation = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!mitigation || mitigation.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
const evidence = await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: mitigation.riskId,
mitigationId: mitigation.id,
type: payload.type || "Review",
title: payload.title,
uri: payload.uri || null,
createdById: actor.id
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Evidence",
entityId: evidence.id,
action: "create",
afterJson: evidence,
request
});
return evidence;
}
module.exports = {
listRisks,
createRisk,
updateRisk,
deleteRisk,
createMitigation,
getMitigation,
listProjectMitigations,
updateMitigation,
deleteMitigation,
addEvidenceToMitigation,
normalizeRiskStatus,
normalizeApprovalStatus
};
012undefined3339__webpack_require__undefined415517964undefined8187__webpack_require__undefined8911155567undefined143149__webpack_require__undefined15116723518undefined
/***/ })9 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const { prisma } = __webpack_require__(17964);
const { scoreRisk } = __webpack_require__(55567);
const { writeAuditEvent } = __webpack_require__(23518);
function normalizeRiskStatus(value) {
if (value === "In mitigation" || value === "IN_MITIGATION") return "IN_MITIGATION";
if (value === "Accepted" || value === "ACCEPTED") return "ACCEPTED";
if (value === "Closed" || value === "CLOSED") return "CLOSED";
return "OPEN";
}
function normalizeApprovalStatus(value) {
if (value === "Approved" || value === "APPROVED") return "APPROVED";
if (value === "Rejected" || value === "REJECTED") return "REJECTED";
if (value === "Accepted" || value === "ACCEPTED") return "ACCEPTED";
return "PENDING";
}
function normalizeMitigationStatus(value) {
if (value === "In progress" || value === "IN_PROGRESS") return "IN_PROGRESS";
if (value === "Done" || value === "DONE") return "DONE";
if (value === "Rejected" || value === "REJECTED") return "REJECTED";
return "NOT_STARTED";
}
async function listRisks(projectId) {
const risks = await prisma.risk.findMany({
where: {
projectId
},
include: {
mitigations: true,
evidence: true
},
orderBy: {
createdAt: "asc"
}
});
return risks.map((risk)=>scoreRisk(Object.assign({}, risk, {
mitigationProgress: risk.mitigations.length ? Math.round(risk.mitigations.reduce((sum, item)=>sum + item.progressPercent, 0) / risk.mitigations.length) : 0,
mitigationEffectiveness: risk.mitigations.length ? Math.round(risk.mitigations.reduce((sum, item)=>sum + item.effectivenessPercent, 0) / risk.mitigations.length) : 0
})));
}
async function createRisk({ projectScope, actor, payload, request }) {
if (!payload.title) throw new Error("title is required");
const risk = await prisma.risk.create({
data: {
projectId: projectScope.project.id,
ownerDisplayName: payload.ownerDisplayName || payload.owner || actor.displayName,
title: payload.title,
description: payload.description || "",
dimension: payload.dimension || "Technical",
domain: payload.domain || "Technical risks",
lifecyclePhase: payload.lifecyclePhase || projectScope.project.currentLifecyclePhase || "Needs identification",
probability: Number(payload.probability || 3),
impact: Number(payload.impact || 3),
detectability: Number(payload.detectability || 3),
status: normalizeRiskStatus(payload.status),
approvalStatus: normalizeApprovalStatus(payload.approvalStatus),
dueDate: payload.dueDate ? new Date(payload.dueDate) : null,
evidenceSummary: payload.evidenceSummary || payload.evidence || ""
}
});
if (payload.evidenceTitle || payload.evidenceSummary || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: risk.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceSummary || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: risk.id,
action: "create",
afterJson: risk,
request
});
return scoreRisk(risk);
}
async function updateRisk({ projectScope, riskId, actor, payload, request }) {
const before = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!before || before.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
const risk = await prisma.risk.update({
where: {
id: riskId
},
data: {
title: payload.title ?? before.title,
description: payload.description ?? before.description,
dimension: payload.dimension ?? before.dimension,
domain: payload.domain ?? before.domain,
lifecyclePhase: payload.lifecyclePhase ?? before.lifecyclePhase,
probability: payload.probability !== undefined ? Number(payload.probability) : before.probability,
impact: payload.impact !== undefined ? Number(payload.impact) : before.impact,
detectability: payload.detectability !== undefined ? Number(payload.detectability) : before.detectability,
status: payload.status !== undefined ? normalizeRiskStatus(payload.status) : before.status,
approvalStatus: payload.approvalStatus !== undefined ? normalizeApprovalStatus(payload.approvalStatus) : before.approvalStatus,
dueDate: payload.dueDate !== undefined ? payload.dueDate ? new Date(payload.dueDate) : null : before.dueDate,
evidenceSummary: payload.evidenceSummary ?? before.evidenceSummary
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: risk.id,
action: "update",
beforeJson: before,
afterJson: risk,
request
});
return scoreRisk(risk);
}
async function deleteRisk({ projectScope, riskId, actor, request }) {
const before = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!before || before.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
await prisma.risk.delete({
where: {
id: riskId
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: riskId,
action: "delete",
beforeJson: before,
request
});
return {
deleted: true
};
}
async function createMitigation({ projectScope, riskId, actor, payload, request }) {
const risk = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!risk || risk.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
const mitigation = await prisma.mitigation.create({
data: {
riskId,
ownerDisplayName: payload.ownerDisplayName || payload.owner || actor.displayName,
title: payload.title,
description: payload.description || "",
status: normalizeMitigationStatus(payload.status),
progressPercent: Number(payload.progressPercent ?? payload.progress_percent ?? 0),
effectivenessPercent: Number(payload.effectivenessPercent ?? payload.effectiveness_percent ?? 0),
dueDate: payload.dueDate ? new Date(payload.dueDate) : null,
sequence: Number(payload.sequence || 1)
}
});
if (payload.evidenceTitle || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId,
mitigationId: mitigation.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigation.id,
action: "create",
afterJson: mitigation,
request
});
return mitigation;
}
async function getMitigation(mitigationId) {
const mitigation = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
evidence: true,
risk: {
select: {
id: true,
title: true,
dimension: true,
projectId: true
}
}
}
});
if (!mitigation) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
return mitigation;
}
async function listProjectMitigations(projectId) {
return prisma.mitigation.findMany({
where: {
risk: {
projectId
}
},
include: {
evidence: true,
risk: {
select: {
id: true,
title: true,
dimension: true
}
}
},
orderBy: {
createdAt: "desc"
}
});
}
async function updateMitigation({ projectScope, mitigationId, actor, payload, request }) {
const before = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!before || before.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
const mitigation = await prisma.mitigation.update({
where: {
id: mitigationId
},
data: {
title: payload.title ?? before.title,
description: payload.description ?? before.description,
ownerDisplayName: payload.ownerDisplayName ?? payload.owner ?? before.ownerDisplayName,
status: payload.status !== undefined ? normalizeMitigationStatus(payload.status) : before.status,
progressPercent: payload.progressPercent !== undefined ? Number(payload.progressPercent) : before.progressPercent,
effectivenessPercent: payload.effectivenessPercent !== undefined ? Number(payload.effectivenessPercent) : before.effectivenessPercent,
dueDate: payload.dueDate !== undefined ? payload.dueDate ? new Date(payload.dueDate) : null : before.dueDate,
sequence: payload.sequence !== undefined ? Number(payload.sequence) : before.sequence
}
});
if (payload.evidenceTitle || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: before.riskId,
mitigationId: mitigation.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigation.id,
action: "update",
beforeJson: before,
afterJson: mitigation,
request
});
return mitigation;
}
async function deleteMitigation({ projectScope, mitigationId, actor, request }) {
const before = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!before || before.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
await prisma.mitigation.delete({
where: {
id: mitigationId
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigationId,
action: "delete",
beforeJson: before,
request
});
return {
deleted: true
};
}
async function addEvidenceToMitigation({ projectScope, mitigationId, actor, payload, request }) {
const mitigation = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!mitigation || mitigation.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
const evidence = await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: mitigation.riskId,
mitigationId: mitigation.id,
type: payload.type || "Review",
title: payload.title,
uri: payload.uri || null,
createdById: actor.id
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Evidence",
entityId: evidence.id,
action: "create",
afterJson: evidence,
request
});
return evidence;
}
module.exports = {
listRisks,
createRisk,
updateRisk,
deleteRisk,
createMitigation,
getMitigation,
listProjectMitigations,
updateMitigation,
deleteMitigation,
addEvidenceToMitigation,
normalizeRiskStatus,
normalizeApprovalStatus
};
/***/ })K9 "use strict";
const { prisma } = require("../lib/prisma");
const { scoreRisk } = require("../domain/risk-engine");
const { writeAuditEvent } = require("./audit-service");
function normalizeRiskStatus(value) {
if (value === "In mitigation" || value === "IN_MITIGATION") return "IN_MITIGATION";
if (value === "Accepted" || value === "ACCEPTED") return "ACCEPTED";
if (value === "Closed" || value === "CLOSED") return "CLOSED";
return "OPEN";
}
function normalizeApprovalStatus(value) {
if (value === "Approved" || value === "APPROVED") return "APPROVED";
if (value === "Rejected" || value === "REJECTED") return "REJECTED";
if (value === "Accepted" || value === "ACCEPTED") return "ACCEPTED";
return "PENDING";
}
function normalizeMitigationStatus(value) {
if (value === "In progress" || value === "IN_PROGRESS") return "IN_PROGRESS";
if (value === "Done" || value === "DONE") return "DONE";
if (value === "Rejected" || value === "REJECTED") return "REJECTED";
return "NOT_STARTED";
}
async function listRisks(projectId) {
const risks = await prisma.risk.findMany({
where: {
projectId
},
include: {
mitigations: true,
evidence: true
},
orderBy: {
createdAt: "asc"
}
});
return risks.map((risk)=>scoreRisk(Object.assign({}, risk, {
mitigationProgress: risk.mitigations.length ? Math.round(risk.mitigations.reduce((sum, item)=>sum + item.progressPercent, 0) / risk.mitigations.length) : 0,
mitigationEffectiveness: risk.mitigations.length ? Math.round(risk.mitigations.reduce((sum, item)=>sum + item.effectivenessPercent, 0) / risk.mitigations.length) : 0
})));
}
async function createRisk({ projectScope, actor, payload, request }) {
if (!payload.title) throw new Error("title is required");
const risk = await prisma.risk.create({
data: {
projectId: projectScope.project.id,
ownerDisplayName: payload.ownerDisplayName || payload.owner || actor.displayName,
title: payload.title,
description: payload.description || "",
dimension: payload.dimension || "Technical",
domain: payload.domain || "Technical risks",
lifecyclePhase: payload.lifecyclePhase || projectScope.project.currentLifecyclePhase || "Needs identification",
probability: Number(payload.probability || 3),
impact: Number(payload.impact || 3),
detectability: Number(payload.detectability || 3),
status: normalizeRiskStatus(payload.status),
approvalStatus: normalizeApprovalStatus(payload.approvalStatus),
dueDate: payload.dueDate ? new Date(payload.dueDate) : null,
evidenceSummary: payload.evidenceSummary || payload.evidence || ""
}
});
if (payload.evidenceTitle || payload.evidenceSummary || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: risk.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceSummary || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: risk.id,
action: "create",
afterJson: risk,
request
});
return scoreRisk(risk);
}
async function updateRisk({ projectScope, riskId, actor, payload, request }) {
const before = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!before || before.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
const risk = await prisma.risk.update({
where: {
id: riskId
},
data: {
title: payload.title ?? before.title,
description: payload.description ?? before.description,
dimension: payload.dimension ?? before.dimension,
domain: payload.domain ?? before.domain,
lifecyclePhase: payload.lifecyclePhase ?? before.lifecyclePhase,
probability: payload.probability !== undefined ? Number(payload.probability) : before.probability,
impact: payload.impact !== undefined ? Number(payload.impact) : before.impact,
detectability: payload.detectability !== undefined ? Number(payload.detectability) : before.detectability,
status: payload.status !== undefined ? normalizeRiskStatus(payload.status) : before.status,
approvalStatus: payload.approvalStatus !== undefined ? normalizeApprovalStatus(payload.approvalStatus) : before.approvalStatus,
dueDate: payload.dueDate !== undefined ? payload.dueDate ? new Date(payload.dueDate) : null : before.dueDate,
evidenceSummary: payload.evidenceSummary ?? before.evidenceSummary
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: risk.id,
action: "update",
beforeJson: before,
afterJson: risk,
request
});
return scoreRisk(risk);
}
async function deleteRisk({ projectScope, riskId, actor, request }) {
const before = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!before || before.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
await prisma.risk.delete({
where: {
id: riskId
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: riskId,
action: "delete",
beforeJson: before,
request
});
return {
deleted: true
};
}
async function createMitigation({ projectScope, riskId, actor, payload, request }) {
const risk = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!risk || risk.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
const mitigation = await prisma.mitigation.create({
data: {
riskId,
ownerDisplayName: payload.ownerDisplayName || payload.owner || actor.displayName,
title: payload.title,
description: payload.description || "",
status: normalizeMitigationStatus(payload.status),
progressPercent: Number(payload.progressPercent ?? payload.progress_percent ?? 0),
effectivenessPercent: Number(payload.effectivenessPercent ?? payload.effectiveness_percent ?? 0),
dueDate: payload.dueDate ? new Date(payload.dueDate) : null,
sequence: Number(payload.sequence || 1)
}
});
if (payload.evidenceTitle || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId,
mitigationId: mitigation.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigation.id,
action: "create",
afterJson: mitigation,
request
});
return mitigation;
}
async function getMitigation(mitigationId) {
const mitigation = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
evidence: true,
risk: {
select: {
id: true,
title: true,
dimension: true,
projectId: true
}
}
}
});
if (!mitigation) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
return mitigation;
}
async function listProjectMitigations(projectId) {
return prisma.mitigation.findMany({
where: {
risk: {
projectId
}
},
include: {
evidence: true,
risk: {
select: {
id: true,
title: true,
dimension: true
}
}
},
orderBy: {
createdAt: "desc"
}
});
}
async function updateMitigation({ projectScope, mitigationId, actor, payload, request }) {
const before = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!before || before.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
const mitigation = await prisma.mitigation.update({
where: {
id: mitigationId
},
data: {
title: payload.title ?? before.title,
description: payload.description ?? before.description,
ownerDisplayName: payload.ownerDisplayName ?? payload.owner ?? before.ownerDisplayName,
status: payload.status !== undefined ? normalizeMitigationStatus(payload.status) : before.status,
progressPercent: payload.progressPercent !== undefined ? Number(payload.progressPercent) : before.progressPercent,
effectivenessPercent: payload.effectivenessPercent !== undefined ? Number(payload.effectivenessPercent) : before.effectivenessPercent,
dueDate: payload.dueDate !== undefined ? payload.dueDate ? new Date(payload.dueDate) : null : before.dueDate,
sequence: payload.sequence !== undefined ? Number(payload.sequence) : before.sequence
}
});
if (payload.evidenceTitle || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: before.riskId,
mitigationId: mitigation.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigation.id,
action: "update",
beforeJson: before,
afterJson: mitigation,
request
});
return mitigation;
}
async function deleteMitigation({ projectScope, mitigationId, actor, request }) {
const before = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!before || before.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
await prisma.mitigation.delete({
where: {
id: mitigationId
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigationId,
action: "delete",
beforeJson: before,
request
});
return {
deleted: true
};
}
async function addEvidenceToMitigation({ projectScope, mitigationId, actor, payload, request }) {
const mitigation = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!mitigation || mitigation.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
const evidence = await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: mitigation.riskId,
mitigationId: mitigation.id,
type: payload.type || "Review",
title: payload.title,
uri: payload.uri || null,
createdById: actor.id
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Evidence",
entityId: evidence.id,
action: "create",
afterJson: evidence,
request
});
return evidence;
}
module.exports = {
listRisks,
createRisk,
updateRisk,
deleteRisk,
createMitigation,
getMitigation,
listProjectMitigations,
updateMitigation,
deleteMitigation,
addEvidenceToMitigation,
normalizeRiskStatus,
normalizeApprovalStatus
};
012undefined3339__webpack_require__undefined415517964undefined8187__webpack_require__undefined8911155567undefined143149__webpack_require__undefined15116723518undefined
};
;T "use strict";
exports.id = 2622;
exports.ids = [2622];
exports.modules = {
/***/ 23518:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const { prisma } = __webpack_require__(17964);
async function writeAuditEvent({ organizationId, workspaceId = null, projectId = null, actorUserId = null, entityType, entityId, action, beforeJson = null, afterJson = null, request = null }) {
return prisma.auditEvent.create({
data: {
organizationId,
workspaceId,
projectId,
actorUserId,
entityType,
entityId,
action,
beforeJson,
afterJson,
ipAddress: request ? request.headers.get("x-forwarded-for") || null : null,
userAgent: request ? request.headers.get("user-agent") || null : null
}
});
}
module.exports = {
writeAuditEvent
};
/***/ }),
/***/ 54775:
/***/ ((module) => {
const counters = {
requests: 0,
errors: 0,
methods: {},
routes: {}
};
const timings = [];
function trackRequest(method, pathname, statusCode, durationMs) {
counters.requests++;
counters.methods[method] = (counters.methods[method] || 0) + 1;
const route = pathname.replace(/\/[a-z0-9]{20,}/gi, "/:id").replace(/\/[a-z0-9-]{20,}/gi, "/:id");
counters.routes[route] = (counters.routes[route] || 0) + 1;
if (statusCode >= 400) counters.errors++;
timings.push({
method,
pathname,
statusCode,
durationMs,
timestamp: Date.now()
});
if (timings.length > 1000) timings.splice(0, timings.length - 1000);
}
function getMetrics() {
const avgDuration = timings.length ? Math.round(timings.reduce((s, t)=>s + t.durationMs, 0) / timings.length) : 0;
return {
uptime: process.uptime(),
totalRequests: counters.requests,
totalErrors: counters.errors,
avgDurationMs: avgDuration,
methods: counters.methods,
routes: counters.routes,
recentTimings: timings.slice(-20)
};
}
module.exports = {
trackRequest,
getMetrics
};
/***/ }),
/***/ 62159:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
getIdempotencyKey: () => (/* binding */ getIdempotencyKey),
withIdempotency: () => (/* binding */ withIdempotency)
});
// EXTERNAL MODULE: ./node_modules/ioredis/built/index.js
var built = __webpack_require__(50453);
var built_default = /*#__PURE__*/__webpack_require__.n(built);
;// ./src/lib/redis.js
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
const ENABLED = process.env.COSMIC_REDIS_ENABLED !== 'false';
let redis = null;
let fallbackStore = new Map();
let fallbackTimers = new Map();
function createClient() {
if (!ENABLED) return null;
try {
const client = new (built_default())(REDIS_URL, {
maxRetriesPerRequest: 1,
retryStrategy (times) {
if (times > 3) return null;
return Math.min(times * 200, 2000);
},
lazyConnect: true,
enableOfflineQueue: false
});
client.on('error', ()=>{});
client.on('close', ()=>{});
return client;
} catch {
return null;
}
}
async function ensureConnected() {
if (redis === null) redis = createClient();
if (!redis || redis.status === 'ready') return redis;
if (redis.status === 'connecting' || redis.status === 'connect') return redis;
try {
await redis.connect();
return redis;
} catch {
return null;
}
}
function fallbackGet(key) {
const entry = fallbackStore.get(key);
if (!entry) return null;
if (entry.expiry && Date.now() > entry.expiry) {
fallbackStore.delete(key);
return null;
}
return entry.value;
}
function fallbackSet(key, value, ttlMs) {
fallbackStore.set(key, {
value,
expiry: ttlMs ? Date.now() + ttlMs : null
});
if (fallbackTimers.has(key)) clearTimeout(fallbackTimers.get(key));
if (ttlMs) {
const timer = setTimeout(()=>{
fallbackStore.delete(key);
fallbackTimers.delete(key);
}, ttlMs);
timer.unref();
fallbackTimers.set(key, timer);
}
}
function fallbackDel(key) {
fallbackStore.delete(key);
if (fallbackTimers.has(key)) {
clearTimeout(fallbackTimers.get(key));
fallbackTimers.delete(key);
}
}
async function redisGet(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.get(key);
} catch {
return null;
}
}
return fallbackGet(key);
}
async function redisSet(key, value, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
if (ttlMs) await client.set(key, value, 'PX', ttlMs);
else await client.set(key, value);
return;
} catch {}
}
fallbackSet(key, value, ttlMs);
}
async function redisDel(key) {
const client = await ensureConnected();
if (client) {
try {
await client.del(key);
return;
} catch {}
}
fallbackDel(key);
}
async function redisIncr(key, ttlMs) {
const client = await ensureConnected();
if (client) {
try {
const val = await client.incr(key);
if (ttlMs && val === 1) await client.pexpire(key, ttlMs);
return val;
} catch {}
}
const val = (parseInt(fallbackGet(key), 10) || 0) + 1;
fallbackSet(key, String(val), ttlMs);
return val;
}
async function redisTtl(key) {
const client = await ensureConnected();
if (client) {
try {
return await client.ttl(key);
} catch {
return -2;
}
}
const entry = fallbackStore.get(key);
if (!entry || !entry.expiry) return -1;
const remaining = Math.max(0, Math.floor((entry.expiry - Date.now()) / 1000));
return remaining > 0 ? remaining : -2;
}
async function redisFlush() {
const client = await ensureConnected();
if (client) {
try {
await client.flushdb();
return;
} catch {}
}
fallbackStore.clear();
for (const timer of fallbackTimers.values())clearTimeout(timer);
fallbackTimers.clear();
}
;// ./src/lib/idempotency.js
const TTL_MS = 86400000;
async function withIdempotency(key, handler) {
if (!key) return handler();
const existing = await redisGet(`idemp:${key}`);
if (existing) return JSON.parse(existing);
const result = await handler();
await redisSet(`idemp:${key}`, JSON.stringify(result), TTL_MS);
return result;
}
function getIdempotencyKey(request) {
return request.headers.get("Idempotency-Key") || request.headers.get("idempotency-key") || null;
}
/***/ }),
/***/ 69698:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const { prisma } = __webpack_require__(17964);
const { scoreRisk } = __webpack_require__(55567);
const { writeAuditEvent } = __webpack_require__(23518);
function normalizeRiskStatus(value) {
if (value === "In mitigation" || value === "IN_MITIGATION") return "IN_MITIGATION";
if (value === "Accepted" || value === "ACCEPTED") return "ACCEPTED";
if (value === "Closed" || value === "CLOSED") return "CLOSED";
return "OPEN";
}
function normalizeApprovalStatus(value) {
if (value === "Approved" || value === "APPROVED") return "APPROVED";
if (value === "Rejected" || value === "REJECTED") return "REJECTED";
if (value === "Accepted" || value === "ACCEPTED") return "ACCEPTED";
return "PENDING";
}
function normalizeMitigationStatus(value) {
if (value === "In progress" || value === "IN_PROGRESS") return "IN_PROGRESS";
if (value === "Done" || value === "DONE") return "DONE";
if (value === "Rejected" || value === "REJECTED") return "REJECTED";
return "NOT_STARTED";
}
async function listRisks(projectId) {
const risks = await prisma.risk.findMany({
where: {
projectId
},
include: {
mitigations: true,
evidence: true
},
orderBy: {
createdAt: "asc"
}
});
return risks.map((risk)=>scoreRisk(Object.assign({}, risk, {
mitigationProgress: risk.mitigations.length ? Math.round(risk.mitigations.reduce((sum, item)=>sum + item.progressPercent, 0) / risk.mitigations.length) : 0,
mitigationEffectiveness: risk.mitigations.length ? Math.round(risk.mitigations.reduce((sum, item)=>sum + item.effectivenessPercent, 0) / risk.mitigations.length) : 0
})));
}
async function createRisk({ projectScope, actor, payload, request }) {
if (!payload.title) throw new Error("title is required");
const risk = await prisma.risk.create({
data: {
projectId: projectScope.project.id,
ownerDisplayName: payload.ownerDisplayName || payload.owner || actor.displayName,
title: payload.title,
description: payload.description || "",
dimension: payload.dimension || "Technical",
domain: payload.domain || "Technical risks",
lifecyclePhase: payload.lifecyclePhase || projectScope.project.currentLifecyclePhase || "Needs identification",
probability: Number(payload.probability || 3),
impact: Number(payload.impact || 3),
detectability: Number(payload.detectability || 3),
status: normalizeRiskStatus(payload.status),
approvalStatus: normalizeApprovalStatus(payload.approvalStatus),
dueDate: payload.dueDate ? new Date(payload.dueDate) : null,
evidenceSummary: payload.evidenceSummary || payload.evidence || ""
}
});
if (payload.evidenceTitle || payload.evidenceSummary || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: risk.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceSummary || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: risk.id,
action: "create",
afterJson: risk,
request
});
return scoreRisk(risk);
}
async function updateRisk({ projectScope, riskId, actor, payload, request }) {
const before = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!before || before.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
const risk = await prisma.risk.update({
where: {
id: riskId
},
data: {
title: payload.title ?? before.title,
description: payload.description ?? before.description,
dimension: payload.dimension ?? before.dimension,
domain: payload.domain ?? before.domain,
lifecyclePhase: payload.lifecyclePhase ?? before.lifecyclePhase,
probability: payload.probability !== undefined ? Number(payload.probability) : before.probability,
impact: payload.impact !== undefined ? Number(payload.impact) : before.impact,
detectability: payload.detectability !== undefined ? Number(payload.detectability) : before.detectability,
status: payload.status !== undefined ? normalizeRiskStatus(payload.status) : before.status,
approvalStatus: payload.approvalStatus !== undefined ? normalizeApprovalStatus(payload.approvalStatus) : before.approvalStatus,
dueDate: payload.dueDate !== undefined ? payload.dueDate ? new Date(payload.dueDate) : null : before.dueDate,
evidenceSummary: payload.evidenceSummary ?? before.evidenceSummary
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: risk.id,
action: "update",
beforeJson: before,
afterJson: risk,
request
});
return scoreRisk(risk);
}
async function deleteRisk({ projectScope, riskId, actor, request }) {
const before = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!before || before.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
await prisma.risk.delete({
where: {
id: riskId
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: riskId,
action: "delete",
beforeJson: before,
request
});
return {
deleted: true
};
}
async function createMitigation({ projectScope, riskId, actor, payload, request }) {
const risk = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!risk || risk.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
const mitigation = await prisma.mitigation.create({
data: {
riskId,
ownerDisplayName: payload.ownerDisplayName || payload.owner || actor.displayName,
title: payload.title,
description: payload.description || "",
status: normalizeMitigationStatus(payload.status),
progressPercent: Number(payload.progressPercent ?? payload.progress_percent ?? 0),
effectivenessPercent: Number(payload.effectivenessPercent ?? payload.effectiveness_percent ?? 0),
dueDate: payload.dueDate ? new Date(payload.dueDate) : null,
sequence: Number(payload.sequence || 1)
}
});
if (payload.evidenceTitle || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId,
mitigationId: mitigation.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigation.id,
action: "create",
afterJson: mitigation,
request
});
return mitigation;
}
async function getMitigation(mitigationId) {
const mitigation = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
evidence: true,
risk: {
select: {
id: true,
title: true,
dimension: true,
projectId: true
}
}
}
});
if (!mitigation) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
return mitigation;
}
async function listProjectMitigations(projectId) {
return prisma.mitigation.findMany({
where: {
risk: {
projectId
}
},
include: {
evidence: true,
risk: {
select: {
id: true,
title: true,
dimension: true
}
}
},
orderBy: {
createdAt: "desc"
}
});
}
async function updateMitigation({ projectScope, mitigationId, actor, payload, request }) {
const before = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!before || before.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
const mitigation = await prisma.mitigation.update({
where: {
id: mitigationId
},
data: {
title: payload.title ?? before.title,
description: payload.description ?? before.description,
ownerDisplayName: payload.ownerDisplayName ?? payload.owner ?? before.ownerDisplayName,
status: payload.status !== undefined ? normalizeMitigationStatus(payload.status) : before.status,
progressPercent: payload.progressPercent !== undefined ? Number(payload.progressPercent) : before.progressPercent,
effectivenessPercent: payload.effectivenessPercent !== undefined ? Number(payload.effectivenessPercent) : before.effectivenessPercent,
dueDate: payload.dueDate !== undefined ? payload.dueDate ? new Date(payload.dueDate) : null : before.dueDate,
sequence: payload.sequence !== undefined ? Number(payload.sequence) : before.sequence
}
});
if (payload.evidenceTitle || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: before.riskId,
mitigationId: mitigation.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigation.id,
action: "update",
beforeJson: before,
afterJson: mitigation,
request
});
return mitigation;
}
async function deleteMitigation({ projectScope, mitigationId, actor, request }) {
const before = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!before || before.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
await prisma.mitigation.delete({
where: {
id: mitigationId
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigationId,
action: "delete",
beforeJson: before,
request
});
return {
deleted: true
};
}
async function addEvidenceToMitigation({ projectScope, mitigationId, actor, payload, request }) {
const mitigation = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!mitigation || mitigation.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
const evidence = await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: mitigation.riskId,
mitigationId: mitigation.id,
type: payload.type || "Review",
title: payload.title,
uri: payload.uri || null,
createdById: actor.id
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Evidence",
entityId: evidence.id,
action: "create",
afterJson: evidence,
request
});
return evidence;
}
module.exports = {
listRisks,
createRisk,
updateRisk,
deleteRisk,
createMitigation,
getMitigation,
listProjectMitigations,
updateMitigation,
deleteMitigation,
addEvidenceToMitigation,
normalizeRiskStatus,
normalizeApprovalStatus
};
/***/ })
};
;{}`0Y "use strict";
exports.id = 2622;
exports.ids = [2622];
exports.modules = {
/***/ 23518:
E /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
const { prisma } = require("../lib/prisma");
async function writeAuditEvent({ organizationId, workspaceId = null, projectId = null, actorUserId = null, entityType, entityId, action, beforeJson = null, afterJson = null, request = null }) {
return prisma.auditEvent.create({
data: {
organizationId,
workspaceId,
projectId,
actorUserId,
entityType,
entityId,
action,
beforeJson,
afterJson,
ipAddress: request ? request.headers.get("x-forwarded-for") || null : null,
userAgent: request ? request.headers.get("user-agent") || null : null
}
});
}
module.exports = {
writeAuditEvent
};
> 012undefined3339__webpack_require__undefined415517964undefined RawSource
/***/ }) ,
/***/ 54775:
/***/ ((module) => {
"use strict";
const counters = {
requests: 0,
errors: 0,
methods: {},
routes: {}
};
const timings = [];
function trackRequest(method, pathname, statusCode, durationMs) {
counters.requests++;
counters.methods[method] = (counters.methods[method] || 0) + 1;
const route = pathname.replace(/\/[a-z0-9]{20,}/gi, "/:id").replace(/\/[a-z0-9-]{20,}/gi, "/:id");
counters.routes[route] = (counters.routes[route] || 0) + 1;
if (statusCode >= 400) counters.errors++;
timings.push({
method,
pathname,
statusCode,
durationMs,
timestamp: Date.now()
});
if (timings.length > 1000) timings.splice(0, timings.length - 1000);
}
function getMetrics() {
const avgDuration = timings.length ? Math.round(timings.reduce((s, t)=>s + t.durationMs, 0) / timings.length) : 0;
return {
uptime: process.uptime(),
totalRequests: counters.requests,
totalErrors: counters.errors,
avgDurationMs: avgDuration,
methods: counters.methods,
routes: counters.routes,
recentTimings: timings.slice(-20)
};
}
module.exports = {
trackRequest,
getMetrics
};
012undefined ,
/***/ 62159:
Q /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
,
/***/ 69698:
K9 "use strict";
const { prisma } = require("../lib/prisma");
const { scoreRisk } = require("../domain/risk-engine");
const { writeAuditEvent } = require("./audit-service");
function normalizeRiskStatus(value) {
if (value === "In mitigation" || value === "IN_MITIGATION") return "IN_MITIGATION";
if (value === "Accepted" || value === "ACCEPTED") return "ACCEPTED";
if (value === "Closed" || value === "CLOSED") return "CLOSED";
return "OPEN";
}
function normalizeApprovalStatus(value) {
if (value === "Approved" || value === "APPROVED") return "APPROVED";
if (value === "Rejected" || value === "REJECTED") return "REJECTED";
if (value === "Accepted" || value === "ACCEPTED") return "ACCEPTED";
return "PENDING";
}
function normalizeMitigationStatus(value) {
if (value === "In progress" || value === "IN_PROGRESS") return "IN_PROGRESS";
if (value === "Done" || value === "DONE") return "DONE";
if (value === "Rejected" || value === "REJECTED") return "REJECTED";
return "NOT_STARTED";
}
async function listRisks(projectId) {
const risks = await prisma.risk.findMany({
where: {
projectId
},
include: {
mitigations: true,
evidence: true
},
orderBy: {
createdAt: "asc"
}
});
return risks.map((risk)=>scoreRisk(Object.assign({}, risk, {
mitigationProgress: risk.mitigations.length ? Math.round(risk.mitigations.reduce((sum, item)=>sum + item.progressPercent, 0) / risk.mitigations.length) : 0,
mitigationEffectiveness: risk.mitigations.length ? Math.round(risk.mitigations.reduce((sum, item)=>sum + item.effectivenessPercent, 0) / risk.mitigations.length) : 0
})));
}
async function createRisk({ projectScope, actor, payload, request }) {
if (!payload.title) throw new Error("title is required");
const risk = await prisma.risk.create({
data: {
projectId: projectScope.project.id,
ownerDisplayName: payload.ownerDisplayName || payload.owner || actor.displayName,
title: payload.title,
description: payload.description || "",
dimension: payload.dimension || "Technical",
domain: payload.domain || "Technical risks",
lifecyclePhase: payload.lifecyclePhase || projectScope.project.currentLifecyclePhase || "Needs identification",
probability: Number(payload.probability || 3),
impact: Number(payload.impact || 3),
detectability: Number(payload.detectability || 3),
status: normalizeRiskStatus(payload.status),
approvalStatus: normalizeApprovalStatus(payload.approvalStatus),
dueDate: payload.dueDate ? new Date(payload.dueDate) : null,
evidenceSummary: payload.evidenceSummary || payload.evidence || ""
}
});
if (payload.evidenceTitle || payload.evidenceSummary || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: risk.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceSummary || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: risk.id,
action: "create",
afterJson: risk,
request
});
return scoreRisk(risk);
}
async function updateRisk({ projectScope, riskId, actor, payload, request }) {
const before = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!before || before.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
const risk = await prisma.risk.update({
where: {
id: riskId
},
data: {
title: payload.title ?? before.title,
description: payload.description ?? before.description,
dimension: payload.dimension ?? before.dimension,
domain: payload.domain ?? before.domain,
lifecyclePhase: payload.lifecyclePhase ?? before.lifecyclePhase,
probability: payload.probability !== undefined ? Number(payload.probability) : before.probability,
impact: payload.impact !== undefined ? Number(payload.impact) : before.impact,
detectability: payload.detectability !== undefined ? Number(payload.detectability) : before.detectability,
status: payload.status !== undefined ? normalizeRiskStatus(payload.status) : before.status,
approvalStatus: payload.approvalStatus !== undefined ? normalizeApprovalStatus(payload.approvalStatus) : before.approvalStatus,
dueDate: payload.dueDate !== undefined ? payload.dueDate ? new Date(payload.dueDate) : null : before.dueDate,
evidenceSummary: payload.evidenceSummary ?? before.evidenceSummary
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: risk.id,
action: "update",
beforeJson: before,
afterJson: risk,
request
});
return scoreRisk(risk);
}
async function deleteRisk({ projectScope, riskId, actor, request }) {
const before = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!before || before.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
await prisma.risk.delete({
where: {
id: riskId
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Risk",
entityId: riskId,
action: "delete",
beforeJson: before,
request
});
return {
deleted: true
};
}
async function createMitigation({ projectScope, riskId, actor, payload, request }) {
const risk = await prisma.risk.findUnique({
where: {
id: riskId
}
});
if (!risk || risk.projectId !== projectScope.project.id) {
const error = new Error(`Risk not found: ${riskId}`);
error.status = 404;
throw error;
}
const mitigation = await prisma.mitigation.create({
data: {
riskId,
ownerDisplayName: payload.ownerDisplayName || payload.owner || actor.displayName,
title: payload.title,
description: payload.description || "",
status: normalizeMitigationStatus(payload.status),
progressPercent: Number(payload.progressPercent ?? payload.progress_percent ?? 0),
effectivenessPercent: Number(payload.effectivenessPercent ?? payload.effectiveness_percent ?? 0),
dueDate: payload.dueDate ? new Date(payload.dueDate) : null,
sequence: Number(payload.sequence || 1)
}
});
if (payload.evidenceTitle || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId,
mitigationId: mitigation.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigation.id,
action: "create",
afterJson: mitigation,
request
});
return mitigation;
}
async function getMitigation(mitigationId) {
const mitigation = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
evidence: true,
risk: {
select: {
id: true,
title: true,
dimension: true,
projectId: true
}
}
}
});
if (!mitigation) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
return mitigation;
}
async function listProjectMitigations(projectId) {
return prisma.mitigation.findMany({
where: {
risk: {
projectId
}
},
include: {
evidence: true,
risk: {
select: {
id: true,
title: true,
dimension: true
}
}
},
orderBy: {
createdAt: "desc"
}
});
}
async function updateMitigation({ projectScope, mitigationId, actor, payload, request }) {
const before = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!before || before.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
const mitigation = await prisma.mitigation.update({
where: {
id: mitigationId
},
data: {
title: payload.title ?? before.title,
description: payload.description ?? before.description,
ownerDisplayName: payload.ownerDisplayName ?? payload.owner ?? before.ownerDisplayName,
status: payload.status !== undefined ? normalizeMitigationStatus(payload.status) : before.status,
progressPercent: payload.progressPercent !== undefined ? Number(payload.progressPercent) : before.progressPercent,
effectivenessPercent: payload.effectivenessPercent !== undefined ? Number(payload.effectivenessPercent) : before.effectivenessPercent,
dueDate: payload.dueDate !== undefined ? payload.dueDate ? new Date(payload.dueDate) : null : before.dueDate,
sequence: payload.sequence !== undefined ? Number(payload.sequence) : before.sequence
}
});
if (payload.evidenceTitle || payload.evidenceUri) {
await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: before.riskId,
mitigationId: mitigation.id,
type: payload.evidenceType || "Review",
title: payload.evidenceTitle || payload.evidenceUri,
uri: payload.evidenceUri || null,
createdById: actor.id
}
});
}
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigation.id,
action: "update",
beforeJson: before,
afterJson: mitigation,
request
});
return mitigation;
}
async function deleteMitigation({ projectScope, mitigationId, actor, request }) {
const before = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!before || before.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
await prisma.mitigation.delete({
where: {
id: mitigationId
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Mitigation",
entityId: mitigationId,
action: "delete",
beforeJson: before,
request
});
return {
deleted: true
};
}
async function addEvidenceToMitigation({ projectScope, mitigationId, actor, payload, request }) {
const mitigation = await prisma.mitigation.findUnique({
where: {
id: mitigationId
},
include: {
risk: {
select: {
projectId: true
}
}
}
});
if (!mitigation || mitigation.risk.projectId !== projectScope.project.id) {
const error = new Error(`Mitigation not found: ${mitigationId}`);
error.status = 404;
throw error;
}
const evidence = await prisma.evidence.create({
data: {
projectId: projectScope.project.id,
riskId: mitigation.riskId,
mitigationId: mitigation.id,
type: payload.type || "Review",
title: payload.title,
uri: payload.uri || null,
createdById: actor.id
}
});
await writeAuditEvent({
organizationId: projectScope.organization.id,
workspaceId: projectScope.project.workspaceId,
projectId: projectScope.project.id,
actorUserId: actor.id,
entityType: "Evidence",
entityId: evidence.id,
action: "create",
afterJson: evidence,
request
});
return evidence;
}
module.exports = {
listRisks,
createRisk,
updateRisk,
deleteRisk,
createMitigation,
getMitigation,
listProjectMitigations,
updateMitigation,
deleteMitigation,
addEvidenceToMitigation,
normalizeRiskStatus,
normalizeApprovalStatus
};
012undefined3339__webpack_require__undefined415517964undefined8187__webpack_require__undefined8911155567undefined143149__webpack_require__undefined15116723518undefined
};
;webpack/lib/util/registerExternalSerializerwebpack-sources/RawSource( "use strict";exports.id=2622,exports.ids=[2622],exports.modules={23518:(a,b,c)=>{let{prisma:d}=c(17964);a.exports={writeAuditEvent:async function({organizationId:a,workspaceId:b=null,projectId:c=null,actorUserId:e=null,entityType:f,entityId:g,action:h,beforeJson:i=null,afterJson:j=null,request:k=null}){return d.auditEvent.create({data:{organizationId:a,workspaceId:b,projectId:c,actorUserId:e,entityType:f,entityId:g,action:h,beforeJson:i,afterJson:j,ipAddress:k&&k.headers.get("x-forwarded-for")||null,userAgent:k&&k.headers.get("user-agent")||null}})}}},54775:a=>{let b={requests:0,errors:0,methods:{},routes:{}},c=[];a.exports={trackRequest:function(a,d,e,f){b.requests++,b.methods[a]=(b.methods[a]||0)+1;let g=d.replace(/\/[a-z0-9]{20,}/gi,"/:id").replace(/\/[a-z0-9-]{20,}/gi,"/:id");b.routes[g]=(b.routes[g]||0)+1,e>=400&&b.errors++,c.push({method:a,pathname:d,statusCode:e,durationMs:f,timestamp:Date.now()}),c.length>1e3&&c.splice(0,c.length-1e3)},getMetrics:function(){let a=c.length?Math.round(c.reduce((a,b)=>a+b.durationMs,0)/c.length):0;return{uptime:process.uptime(),totalRequests:b.requests,totalErrors:b.errors,avgDurationMs:a,methods:b.methods,routes:b.routes,recentTimings:c.slice(-20)}}}},62159:(a,b,c)=>{c.r(b),c.d(b,{getIdempotencyKey:()=>o,withIdempotency:()=>n});var d=c(50453),e=c.n(d);let f=process.env.REDIS_URL||"redis://localhost:6379",g="false"!==process.env.COSMIC_REDIS_ENABLED,h=null,i=new Map,j=new Map;async function k(){if(null===h&&(h=function(){if(!g)return null;try{let a=new(e())(f,{maxRetriesPerRequest:1,retryStrategy:a=>a>3?null:Math.min(200*a,2e3),lazyConnect:!0,enableOfflineQueue:!1});return a.on("error",()=>{}),a.on("close",()=>{}),a}catch{return null}}()),!h||"ready"===h.status||"connecting"===h.status||"connect"===h.status)return h;try{return await h.connect(),h}catch{return null}}async function l(a){let b=await k();if(b)try{return await b.get(a)}catch{return null}let c=i.get(a);return c?c.expiry&&Date.now()>c.expiry?(i.delete(a),null):c.value:null}async function m(a,b,c){let d=await k();if(d)try{c?await d.set(a,b,"PX",c):await d.set(a,b);return}catch{}if(i.set(a,{value:b,expiry:c?Date.now()+c:null}),j.has(a)&&clearTimeout(j.get(a)),c){let b=setTimeout(()=>{i.delete(a),j.delete(a)},c);b.unref(),j.set(a,b)}}async function n(a,b){if(!a)return b();let c=await l(`idemp:${a}`);if(c)return JSON.parse(c);let d=await b();return await m(`idemp:${a}`,JSON.stringify(d),864e5),d}function o(a){return a.headers.get("Idempotency-Key")||a.headers.get("idempotency-key")||null}},69698:(a,b,c)=>{let{prisma:d}=c(17964),{scoreRisk:e}=c(55567),{writeAuditEvent:f}=c(23518);function g(a){return"In mitigation"===a||"IN_MITIGATION"===a?"IN_MITIGATION":"Accepted"===a||"ACCEPTED"===a?"ACCEPTED":"Closed"===a||"CLOSED"===a?"CLOSED":"OPEN"}function h(a){return"Approved"===a||"APPROVED"===a?"APPROVED":"Rejected"===a||"REJECTED"===a?"REJECTED":"Accepted"===a||"ACCEPTED"===a?"ACCEPTED":"PENDING"}function i(a){return"In progress"===a||"IN_PROGRESS"===a?"IN_PROGRESS":"Done"===a||"DONE"===a?"DONE":"Rejected"===a||"REJECTED"===a?"REJECTED":"NOT_STARTED"}a.exports={listRisks:async function(a){return(await d.risk.findMany({where:{projectId:a},include:{mitigations:!0,evidence:!0},orderBy:{createdAt:"asc"}})).map(a=>e(Object.assign({},a,{mitigationProgress:a.mitigations.length?Math.round(a.mitigations.reduce((a,b)=>a+b.progressPercent,0)/a.mitigations.length):0,mitigationEffectiveness:a.mitigations.length?Math.round(a.mitigations.reduce((a,b)=>a+b.effectivenessPercent,0)/a.mitigations.length):0})))},createRisk:async function({projectScope:a,actor:b,payload:c,request:i}){if(!c.title)throw Error("title is required");let j=await d.risk.create({data:{projectId:a.project.id,ownerDisplayName:c.ownerDisplayName||c.owner||b.displayName,title:c.title,description:c.description||"",dimension:c.dimension||"Technical",domain:c.domain||"Technical risks",lifecyclePhase:c.lifecyclePhase||a.project.currentLifecyclePhase||"Needs identification",probability:Number(c.probability||3),impact:Number(c.impact||3),detectability:Number(c.detectability||3),status:g(c.status),approvalStatus:h(c.approvalStatus),dueDate:c.dueDate?new Date(c.dueDate):null,evidenceSummary:c.evidenceSummary||c.evidence||""}});return(c.evidenceTitle||c.evidenceSummary||c.evidenceUri)&&await d.evidence.create({data:{projectId:a.project.id,riskId:j.id,type:c.evidenceType||"Review",title:c.evidenceTitle||c.evidenceSummary||c.evidenceUri,uri:c.evidenceUri||null,createdById:b.id}}),await f({organizationId:a.organization.id,workspaceId:a.project.workspaceId,projectId:a.project.id,actorUserId:b.id,entityType:"Risk",entityId:j.id,action:"create",afterJson:j,request:i}),e(j)},updateRisk:async function({projectScope:a,riskId:b,actor:c,payload:i,request:j}){let k=await d.risk.findUnique({where:{id:b}});if(!k||k.projectId!==a.project.id){let a=Error(`Risk not found: ${b}`);throw a.status=404,a}let l=await d.risk.update({where:{id:b},data:{title:i.title??k.title,description:i.description??k.description,dimension:i.dimension??k.dimension,domain:i.domain??k.domain,lifecyclePhase:i.lifecyclePhase??k.lifecyclePhase,probability:void 0!==i.probability?Number(i.probability):k.probability,impact:void 0!==i.impact?Number(i.impact):k.impact,detectability:void 0!==i.detectability?Number(i.detectability):k.detectability,status:void 0!==i.status?g(i.status):k.status,approvalStatus:void 0!==i.approvalStatus?h(i.approvalStatus):k.approvalStatus,dueDate:void 0!==i.dueDate?i.dueDate?new Date(i.dueDate):null:k.dueDate,evidenceSummary:i.evidenceSummary??k.evidenceSummary}});return await f({organizationId:a.organization.id,workspaceId:a.project.workspaceId,projectId:a.project.id,actorUserId:c.id,entityType:"Risk",entityId:l.id,action:"update",beforeJson:k,afterJson:l,request:j}),e(l)},deleteRisk:async function({projectScope:a,riskId:b,actor:c,request:e}){let g=await d.risk.findUnique({where:{id:b}});if(!g||g.projectId!==a.project.id){let a=Error(`Risk not found: ${b}`);throw a.status=404,a}return await d.risk.delete({where:{id:b}}),await f({organizationId:a.organization.id,workspaceId:a.project.workspaceId,projectId:a.project.id,actorUserId:c.id,entityType:"Risk",entityId:b,action:"delete",beforeJson:g,request:e}),{deleted:!0}},createMitigation:async function({projectScope:a,riskId:b,actor:c,payload:e,request:g}){let h=await d.risk.findUnique({where:{id:b}});if(!h||h.projectId!==a.project.id){let a=Error(`Risk not found: ${b}`);throw a.status=404,a}let j=await d.mitigation.create({data:{riskId:b,ownerDisplayName:e.ownerDisplayName||e.owner||c.displayName,title:e.title,description:e.description||"",status:i(e.status),progressPercent:Number(e.progressPercent??e.progress_percent??0),effectivenessPercent:Number(e.effectivenessPercent??e.effectiveness_percent??0),dueDate:e.dueDate?new Date(e.dueDate):null,sequence:Number(e.sequence||1)}});return(e.evidenceTitle||e.evidenceUri)&&await d.evidence.create({data:{projectId:a.project.id,riskId:b,mitigationId:j.id,type:e.evidenceType||"Review",title:e.evidenceTitle||e.evidenceUri,uri:e.evidenceUri||null,createdById:c.id}}),await f({organizationId:a.organization.id,workspaceId:a.project.workspaceId,projectId:a.project.id,actorUserId:c.id,entityType:"Mitigation",entityId:j.id,action:"create",afterJson:j,request:g}),j},getMitigation:async function(a){let b=await d.mitigation.findUnique({where:{id:a},include:{evidence:!0,risk:{select:{id:!0,title:!0,dimension:!0,projectId:!0}}}});if(!b){let b=Error(`Mitigation not found: ${a}`);throw b.status=404,b}return b},listProjectMitigations:async function(a){return d.mitigation.findMany({where:{risk:{projectId:a}},include:{evidence:!0,risk:{select:{id:!0,title:!0,dimension:!0}}},orderBy:{createdAt:"desc"}})},updateMitigation:async function({projectScope:a,mitigationId:b,actor:c,payload:e,request:g}){let h=await d.mitigation.findUnique({where:{id:b},include:{risk:{select:{projectId:!0}}}});if(!h||h.risk.projectId!==a.project.id){let a=Error(`Mitigation not found: ${b}`);throw a.status=404,a}let j=await d.mitigation.update({where:{id:b},data:{title:e.title??h.title,description:e.description??h.description,ownerDisplayName:e.ownerDisplayName??e.owner??h.ownerDisplayName,status:void 0!==e.status?i(e.status):h.status,progressPercent:void 0!==e.progressPercent?Number(e.progressPercent):h.progressPercent,effectivenessPercent:void 0!==e.effectivenessPercent?Number(e.effectivenessPercent):h.effectivenessPercent,dueDate:void 0!==e.dueDate?e.dueDate?new Date(e.dueDate):null:h.dueDate,sequence:void 0!==e.sequence?Number(e.sequence):h.sequence}});return(e.evidenceTitle||e.evidenceUri)&&await d.evidence.create({data:{projectId:a.project.id,riskId:h.riskId,mitigationId:j.id,type:e.evidenceType||"Review",title:e.evidenceTitle||e.evidenceUri,uri:e.evidenceUri||null,createdById:c.id}}),await f({organizationId:a.organization.id,workspaceId:a.project.workspaceId,projectId:a.project.id,actorUserId:c.id,entityType:"Mitigation",entityId:j.id,action:"update",beforeJson:h,afterJson:j,request:g}),j},deleteMitigation:async function({projectScope:a,mitigationId:b,actor:c,request:e}){let g=await d.mitigation.findUnique({where:{id:b},include:{risk:{select:{projectId:!0}}}});if(!g||g.risk.projectId!==a.project.id){let a=Error(`Mitigation not found: ${b}`);throw a.status=404,a}return await d.mitigation.delete({where:{id:b}}),await f({organizationId:a.organization.id,workspaceId:a.project.workspaceId,projectId:a.project.id,actorUserId:c.id,entityType:"Mitigation",entityId:b,action:"delete",beforeJson:g,request:e}),{deleted:!0}},addEvidenceToMitigation:async function({projectScope:a,mitigationId:b,actor:c,payload:e,request:g}){let h=await d.mitigation.findUnique({where:{id:b},include:{risk:{select:{projectId:!0}}}});if(!h||h.risk.projectId!==a.project.id){let a=Error(`Mitigation not found: ${b}`);throw a.status=404,a}let i=await d.evidence.create({data:{projectId:a.project.id,riskId:h.riskId,mitigationId:h.id,type:e.type||"Review",title:e.title,uri:e.uri||null,createdById:c.id}});return await f({organizationId:a.organization.id,workspaceId:a.project.workspaceId,projectId:a.project.id,actorUserId:c.id,entityType:"Evidence",entityId:i.id,action:"create",afterJson:i,request:g}),i},normalizeRiskStatus:g,normalizeApprovalStatus:h}}};