feat: add new page and migration scripts for access rules and collections

- Introduced new page component for library topics with type checks.
- Added migration scripts to update access rules for various collections including badges, curriculum versions, and themes.
- Implemented PocketBase integration for managing collection access rules dynamically.
- Ensured proper type validation for page props and metadata generation functions.
This commit is contained in:
RaymondVerhoef
2026-05-23 22:26:40 +02:00
parent 14286d6cb1
commit 8684ffa35b
109 changed files with 2065 additions and 114 deletions

View File

@@ -66,6 +66,11 @@
"static/chunks/main-app.js",
"static/chunks/app/app/profile/page.js"
],
"/app/library/[topicId]/page": [
"static/chunks/webpack.js",
"static/chunks/main-app.js",
"static/chunks/app/app/library/[topicId]/page.js"
],
"/_not-found/page": [
"static/chunks/webpack.js",
"static/chunks/main-app.js",

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -2,9 +2,9 @@
"/_not-found/page": "app/_not-found/page.js",
"/auth/page": "app/auth/page.js",
"/page": "app/page.js",
"/app/session/page": "app/app/session/page.js",
"/admin/page": "app/admin/page.js",
"/app/profile/page": "app/app/profile/page.js",
"/app/library/page": "app/app/library/page.js",
"/admin/documents/page": "app/admin/documents/page.js"
"/admin/documents/page": "app/admin/documents/page.js",
"/app/session/page": "app/app/session/page.js",
"/app/library/[topicId]/page": "app/app/library/[topicId]/page.js",
"/app/page": "app/app/page.js"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -125,7 +125,7 @@
/******/
/******/ /* webpack/runtime/getFullHash */
/******/ (() => {
/******/ __webpack_require__.h = () => ("51e1c2914ed1ba13")
/******/ __webpack_require__.h = () => ("5fc192207423a534")
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -25,7 +25,7 @@ eval(__webpack_require__.ts("Promise.resolve(/*! import() eager */).then(__webpa
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (\"b88116e9ef0b\");\nif (true) { module.hot.accept() }\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKGFwcC1wYWdlcy1icm93c2VyKS8uL3NyYy9hcHAvZ2xvYmFscy5jc3MiLCJtYXBwaW5ncyI6IjtBQUFBLCtEQUFlLGNBQWM7QUFDN0IsSUFBSSxJQUFVLElBQUksaUJBQWlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vX05fRS8uL3NyYy9hcHAvZ2xvYmFscy5jc3M/ZjYwMSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBcImI4ODExNmU5ZWYwYlwiXG5pZiAobW9kdWxlLmhvdCkgeyBtb2R1bGUuaG90LmFjY2VwdCgpIH1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(app-pages-browser)/./src/app/globals.css\n"));
eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (\"faba7d6da641\");\nif (true) { module.hot.accept() }\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKGFwcC1wYWdlcy1icm93c2VyKS8uL3NyYy9hcHAvZ2xvYmFscy5jc3MiLCJtYXBwaW5ncyI6IjtBQUFBLCtEQUFlLGNBQWM7QUFDN0IsSUFBSSxJQUFVLElBQUksaUJBQWlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vX05fRS8uL3NyYy9hcHAvZ2xvYmFscy5jc3M/ZjYwMSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBcImZhYmE3ZDZkYTY0MVwiXG5pZiAobW9kdWxlLmhvdCkgeyBtb2R1bGUuaG90LmFjY2VwdCgpIH1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(app-pages-browser)/./src/app/globals.css\n"));
/***/ }),

View File

@@ -192,7 +192,7 @@
/******/
/******/ /* webpack/runtime/getFullHash */
/******/ !function() {
/******/ __webpack_require__.h = function() { return "f0b0b64480e0ded4"; }
/******/ __webpack_require__.h = function() { return "a7ccb1bd8466330b"; }
/******/ }();
/******/
/******/ /* webpack/runtime/global */

View File

@@ -0,0 +1 @@
{"c":["app/layout","webpack"],"r":[],"m":[]}

View File

@@ -0,0 +1 @@
{"c":["app/layout","webpack"],"r":[],"m":[]}

View File

@@ -0,0 +1 @@
{"c":["app/layout","app/admin/documents/page","webpack"],"r":[],"m":[]}

View File

@@ -0,0 +1 @@
{"c":["webpack"],"r":["app/_not-found/page"],"m":["(app-pages-browser)/./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=C%3A%5CUsers%5CRaymondVerhoef%5CGitea%5Clearning-platform%5Capp%5Cfrontend%5Cnode_modules%5Cnext%5Cdist%5Cclient%5Ccomponents%5Cnot-found-error.js&page=%2F_not-found%2Fpage!","(app-pages-browser)/./node_modules/next/dist/client/components/not-found-error.js"]}

View File

@@ -0,0 +1 @@
{"c":["app/layout","webpack"],"r":[],"m":[]}

View File

@@ -0,0 +1 @@
{"c":["app/layout","webpack"],"r":[],"m":[]}

View File

@@ -0,0 +1 @@
{"c":["webpack"],"r":[],"m":[]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,22 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("app/layout",{
/***/ "(app-pages-browser)/./src/app/globals.css":
/*!*****************************!*\
!*** ./src/app/globals.css ***!
\*****************************/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (\"faba7d6da641\");\nif (true) { module.hot.accept() }\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKGFwcC1wYWdlcy1icm93c2VyKS8uL3NyYy9hcHAvZ2xvYmFscy5jc3MiLCJtYXBwaW5ncyI6IjtBQUFBLCtEQUFlLGNBQWM7QUFDN0IsSUFBSSxJQUFVLElBQUksaUJBQWlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vX05fRS8uL3NyYy9hcHAvZ2xvYmFscy5jc3M/ZjYwMSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBcImZhYmE3ZDZkYTY0MVwiXG5pZiAobW9kdWxlLmhvdCkgeyBtb2R1bGUuaG90LmFjY2VwdCgpIH1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(app-pages-browser)/./src/app/globals.css\n"));
/***/ })
});

View File

@@ -0,0 +1,22 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("app/layout",{
/***/ "(app-pages-browser)/./src/app/globals.css":
/*!*****************************!*\
!*** ./src/app/globals.css ***!
\*****************************/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (\"4d1be2fbc1d5\");\nif (true) { module.hot.accept() }\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKGFwcC1wYWdlcy1icm93c2VyKS8uL3NyYy9hcHAvZ2xvYmFscy5jc3MiLCJtYXBwaW5ncyI6IjtBQUFBLCtEQUFlLGNBQWM7QUFDN0IsSUFBSSxJQUFVLElBQUksaUJBQWlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vX05fRS8uL3NyYy9hcHAvZ2xvYmFscy5jc3M/ZjYwMSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBcIjRkMWJlMmZiYzFkNVwiXG5pZiAobW9kdWxlLmhvdCkgeyBtb2R1bGUuaG90LmFjY2VwdCgpIH1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(app-pages-browser)/./src/app/globals.css\n"));
/***/ })
});

View File

@@ -0,0 +1,22 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("app/layout",{
/***/ "(app-pages-browser)/./src/app/globals.css":
/*!*****************************!*\
!*** ./src/app/globals.css ***!
\*****************************/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (\"823f19c267ee\");\nif (true) { module.hot.accept() }\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKGFwcC1wYWdlcy1icm93c2VyKS8uL3NyYy9hcHAvZ2xvYmFscy5jc3MiLCJtYXBwaW5ncyI6IjtBQUFBLCtEQUFlLGNBQWM7QUFDN0IsSUFBSSxJQUFVLElBQUksaUJBQWlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vX05fRS8uL3NyYy9hcHAvZ2xvYmFscy5jc3M/ZjYwMSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBcIjgyM2YxOWMyNjdlZVwiXG5pZiAobW9kdWxlLmhvdCkgeyBtb2R1bGUuaG90LmFjY2VwdCgpIH1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(app-pages-browser)/./src/app/globals.css\n"));
/***/ })
});

View File

@@ -0,0 +1,22 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("app/layout",{
/***/ "(app-pages-browser)/./src/app/globals.css":
/*!*****************************!*\
!*** ./src/app/globals.css ***!
\*****************************/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (\"25d949e1ff47\");\nif (true) { module.hot.accept() }\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKGFwcC1wYWdlcy1icm93c2VyKS8uL3NyYy9hcHAvZ2xvYmFscy5jc3MiLCJtYXBwaW5ncyI6IjtBQUFBLCtEQUFlLGNBQWM7QUFDN0IsSUFBSSxJQUFVLElBQUksaUJBQWlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vX05fRS8uL3NyYy9hcHAvZ2xvYmFscy5jc3M/ZjYwMSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBcIjI1ZDk0OWUxZmY0N1wiXG5pZiAobW9kdWxlLmhvdCkgeyBtb2R1bGUuaG90LmFjY2VwdCgpIH1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(app-pages-browser)/./src/app/globals.css\n"));
/***/ })
});

View File

@@ -0,0 +1,22 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("app/layout",{
/***/ "(app-pages-browser)/./src/app/globals.css":
/*!*****************************!*\
!*** ./src/app/globals.css ***!
\*****************************/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (\"39ba7864e079\");\nif (true) { module.hot.accept() }\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKGFwcC1wYWdlcy1icm93c2VyKS8uL3NyYy9hcHAvZ2xvYmFscy5jc3MiLCJtYXBwaW5ncyI6IjtBQUFBLCtEQUFlLGNBQWM7QUFDN0IsSUFBSSxJQUFVLElBQUksaUJBQWlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vX05fRS8uL3NyYy9hcHAvZ2xvYmFscy5jc3M/ZjYwMSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBcIjM5YmE3ODY0ZTA3OVwiXG5pZiAobW9kdWxlLmhvdCkgeyBtb2R1bGUuaG90LmFjY2VwdCgpIH1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(app-pages-browser)/./src/app/globals.css\n"));
/***/ })
});

View File

@@ -0,0 +1,22 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("app/layout",{
/***/ "(app-pages-browser)/./src/app/globals.css":
/*!*****************************!*\
!*** ./src/app/globals.css ***!
\*****************************/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (\"a49431f69319\");\nif (true) { module.hot.accept() }\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKGFwcC1wYWdlcy1icm93c2VyKS8uL3NyYy9hcHAvZ2xvYmFscy5jc3MiLCJtYXBwaW5ncyI6IjtBQUFBLCtEQUFlLGNBQWM7QUFDN0IsSUFBSSxJQUFVLElBQUksaUJBQWlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vX05fRS8uL3NyYy9hcHAvZ2xvYmFscy5jc3M/ZjYwMSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBcImE0OTQzMWY2OTMxOVwiXG5pZiAobW9kdWxlLmhvdCkgeyBtb2R1bGUuaG90LmFjY2VwdCgpIH1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(app-pages-browser)/./src/app/globals.css\n"));
/***/ })
});

View File

@@ -0,0 +1,22 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("app/layout",{
/***/ "(app-pages-browser)/./src/app/globals.css":
/*!*****************************!*\
!*** ./src/app/globals.css ***!
\*****************************/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (\"f963c24539ed\");\nif (true) { module.hot.accept() }\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKGFwcC1wYWdlcy1icm93c2VyKS8uL3NyYy9hcHAvZ2xvYmFscy5jc3MiLCJtYXBwaW5ncyI6IjtBQUFBLCtEQUFlLGNBQWM7QUFDN0IsSUFBSSxJQUFVLElBQUksaUJBQWlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vX05fRS8uL3NyYy9hcHAvZ2xvYmFscy5jc3M/ZjYwMSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBcImY5NjNjMjQ1MzllZFwiXG5pZiAobW9kdWxlLmhvdCkgeyBtb2R1bGUuaG90LmFjY2VwdCgpIH1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(app-pages-browser)/./src/app/globals.css\n"));
/***/ })
});

View File

@@ -0,0 +1 @@
{"c":["app/layout","webpack"],"r":[],"m":[]}

View File

@@ -0,0 +1 @@
{"c":["app/layout","app/admin/knowledge/page","webpack"],"r":[],"m":[]}

View File

@@ -0,0 +1 @@
{"c":["app/admin/documents/page","app/admin/knowledge/page","app/admin/curriculum/page","app/app/session/page","app/app/profile/page","webpack"],"r":["app/_not-found/page"],"m":["(app-pages-browser)/./node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?absolutePagePath=C%3A%5CUsers%5CRaymondVerhoef%5CGitea%5Clearning-platform%5Capp%5Cfrontend%5Cnode_modules%5Cnext%5Cdist%5Cclient%5Ccomponents%5Cnot-found-error.js&page=%2F_not-found%2Fpage!","(app-pages-browser)/./node_modules/next/dist/client/components/not-found-error.js"]}

View File

@@ -0,0 +1 @@
{"c":["webpack"],"r":[],"m":[]}

View File

@@ -0,0 +1,18 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ !function() {
/******/ __webpack_require__.h = function() { return "a7ccb1bd8466330b"; }
/******/ }();
/******/
/******/ }
);

View File

@@ -0,0 +1,18 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ !function() {
/******/ __webpack_require__.h = function() { return "2eb37301afdeda1e"; }
/******/ }();
/******/
/******/ }
);

View File

@@ -0,0 +1,18 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ !function() {
/******/ __webpack_require__.h = function() { return "ff5e88d2dcebc726"; }
/******/ }();
/******/
/******/ }
);

View File

@@ -0,0 +1,18 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ !function() {
/******/ __webpack_require__.h = function() { return "e803e77acd202a08"; }
/******/ }();
/******/
/******/ }
);

View File

@@ -0,0 +1,18 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ !function() {
/******/ __webpack_require__.h = function() { return "b156fa60016c21cf"; }
/******/ }();
/******/
/******/ }
);

View File

@@ -0,0 +1,18 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ !function() {
/******/ __webpack_require__.h = function() { return "4907ba520745328f"; }
/******/ }();
/******/
/******/ }
);

View File

@@ -0,0 +1,18 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ !function() {
/******/ __webpack_require__.h = function() { return "5c4f3d7b80335c82"; }
/******/ }();
/******/
/******/ }
);

View File

@@ -0,0 +1,18 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ !function() {
/******/ __webpack_require__.h = function() { return "14b62dbaa8275210"; }
/******/ }();
/******/
/******/ }
);

View File

@@ -0,0 +1,18 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ !function() {
/******/ __webpack_require__.h = function() { return "994e7beecd42381b"; }
/******/ }();
/******/
/******/ }
);

View File

@@ -0,0 +1,18 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ !function() {
/******/ __webpack_require__.h = function() { return "28206c700b782558"; }
/******/ }();
/******/
/******/ }
);

View File

@@ -0,0 +1,18 @@
"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ !function() {
/******/ __webpack_require__.h = function() { return "402d7af51f69ed0f"; }
/******/ }();
/******/
/******/ }
);

View File

@@ -0,0 +1,79 @@
// File: C:\Users\RaymondVerhoef\Gitea\learning-platform\app\frontend\src\app\app\library\[topicId]\page.tsx
import * as entry from '../../../../../../src/app/app/library/[topicId]/page.js'
import type { ResolvingMetadata, ResolvingViewport } from 'next/dist/lib/metadata/types/metadata-interface.js'
type TEntry = typeof import('../../../../../../src/app/app/library/[topicId]/page.js')
// Check that the entry is a valid entry
checkFields<Diff<{
default: Function
config?: {}
generateStaticParams?: Function
revalidate?: RevalidateRange<TEntry> | false
dynamic?: 'auto' | 'force-dynamic' | 'error' | 'force-static'
dynamicParams?: boolean
fetchCache?: 'auto' | 'force-no-store' | 'only-no-store' | 'default-no-store' | 'default-cache' | 'only-cache' | 'force-cache'
preferredRegion?: 'auto' | 'global' | 'home' | string | string[]
runtime?: 'nodejs' | 'experimental-edge' | 'edge'
maxDuration?: number
metadata?: any
generateMetadata?: Function
viewport?: any
generateViewport?: Function
}, TEntry, ''>>()
// Check the prop type of the entry function
checkFields<Diff<PageProps, FirstArg<TEntry['default']>, 'default'>>()
// Check the arguments and return type of the generateMetadata function
if ('generateMetadata' in entry) {
checkFields<Diff<PageProps, FirstArg<MaybeField<TEntry, 'generateMetadata'>>, 'generateMetadata'>>()
checkFields<Diff<ResolvingMetadata, SecondArg<MaybeField<TEntry, 'generateMetadata'>>, 'generateMetadata'>>()
}
// Check the arguments and return type of the generateViewport function
if ('generateViewport' in entry) {
checkFields<Diff<PageProps, FirstArg<MaybeField<TEntry, 'generateViewport'>>, 'generateViewport'>>()
checkFields<Diff<ResolvingViewport, SecondArg<MaybeField<TEntry, 'generateViewport'>>, 'generateViewport'>>()
}
// Check the arguments and return type of the generateStaticParams function
if ('generateStaticParams' in entry) {
checkFields<Diff<{ params: PageParams }, FirstArg<MaybeField<TEntry, 'generateStaticParams'>>, 'generateStaticParams'>>()
checkFields<Diff<{ __tag__: 'generateStaticParams', __return_type__: any[] | Promise<any[]> }, { __tag__: 'generateStaticParams', __return_type__: ReturnType<MaybeField<TEntry, 'generateStaticParams'>> }>>()
}
type PageParams = any
export interface PageProps {
params?: any
searchParams?: any
}
export interface LayoutProps {
children?: React.ReactNode
params?: any
}
// =============
// Utility types
type RevalidateRange<T> = T extends { revalidate: any } ? NonNegative<T['revalidate']> : never
// If T is unknown or any, it will be an empty {} type. Otherwise, it will be the same as Omit<T, keyof Base>.
type OmitWithTag<T, K extends keyof any, _M> = Omit<T, K>
type Diff<Base, T extends Base, Message extends string = ''> = 0 extends (1 & T) ? {} : OmitWithTag<T, keyof Base, Message>
type FirstArg<T extends Function> = T extends (...args: [infer T, any]) => any ? unknown extends T ? any : T : never
type SecondArg<T extends Function> = T extends (...args: [any, infer T]) => any ? unknown extends T ? any : T : never
type MaybeField<T, K extends string> = T extends { [k in K]: infer G } ? G extends Function ? G : never : never
function checkFields<_ extends { [k in keyof any]: never }>() {}
// https://github.com/sindresorhus/type-fest
type Numeric = number | bigint
type Zero = 0 | 0n
type Negative<T extends Numeric> = T extends Zero ? never : `${T}` extends `-${string}` ? T : never
type NonNegative<T extends Numeric> = T extends Zero ? T : Negative<T> extends never ? T : '__invalid_negative_number__'

View File

@@ -3,6 +3,7 @@ import React, { useEffect, useState } from 'react'
import { useParams } from 'next/navigation'
import Link from 'next/link'
import { pb } from '@/lib/pocketbase'
import { postGenerateAll } from '@/lib/services'
import { TopicEditCard } from '@/components/admin/TopicEditCard'
import { Button } from '@/components/ui/Button'
import { StatusBadge } from '@/components/ui/StatusBadge'
@@ -17,6 +18,7 @@ export default function ThemeDetailPage() {
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
const [publishingAll, setPublishingAll] = useState(false)
const [approveToast, setApproveToast] = useState<string | null>(null)
async function load() {
setLoading(true)
@@ -43,17 +45,24 @@ export default function ThemeDetailPage() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [themeId])
async function handlePublishAll() {
async function handleApproveBatch() {
setPublishingAll(true)
setApproveToast(null)
try {
// Publish all draft topics
await Promise.all(
topics
.filter((t) => t.status === 'draft')
.map((t) => pb.collection('topics').update(t.id, { status: 'published' })),
)
// Publish the theme
await pb.collection('themes').update(themeId, { status: 'published' })
// Trigger generation
const { queued } = await postGenerateAll(themeId)
setApproveToast(`Approved. Generation queued for ${queued} micro-learnings.`)
void load()
} catch {
// refresh anyway
} catch (err) {
setApproveToast(err instanceof Error ? err.message : 'Approval failed')
void load()
} finally {
setPublishingAll(false)
@@ -134,16 +143,21 @@ export default function ThemeDetailPage() {
<span style={{ fontSize: 'var(--t-body)', color: 'var(--fg-muted)' }}>
{publishedCount} published · {draftCount} draft
</span>
{draftCount > 0 && (
{theme.status !== 'published' && (
<Button
variant="primary"
size="sm"
onClick={() => void handlePublishAll()}
onClick={() => void handleApproveBatch()}
loading={publishingAll}
>
Publish all drafts ({draftCount})
Approve batch{draftCount > 0 ? ` (${draftCount} draft${draftCount !== 1 ? 's' : ''})` : ''}
</Button>
)}
{approveToast && (
<span style={{ fontSize: 'var(--t-small)', color: 'var(--teal)', fontWeight: 500 }}>
{approveToast}
</span>
)}
</div>
{/* Topics list */}

View File

@@ -38,19 +38,26 @@ export function DocumentUpload({ onSuccess }: DocumentUploadProps) {
try {
// Create record in PocketBase
const format = ext.slice(1) as 'pdf' | 'md' | 'txt'
const fd = new FormData()
fd.append('file', file)
fd.append('filename', file.name)
fd.append('format', ext.slice(1) as 'pdf' | 'md' | 'txt')
fd.append('format', format)
fd.append('status', 'processing')
const doc = await pb.collection('source_documents').create<{ id: string }>(fd)
const doc = await pb.collection('source_documents').create<{ id: string; file: string }>(fd)
// Build PocketBase file download URL
const pbUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL ?? 'http://localhost:8090'
const fileUrl = `${pbUrl}/api/files/source_documents/${doc.id}/${doc.file}`
// Kick off ingestion
const ingestFd = new FormData()
ingestFd.append('documentId', doc.id)
const { jobId: jId } = await postIngest(ingestFd)
const { jobId: jId } = await postIngest({
documentId: doc.id,
filename: file.name,
format,
fileUrl,
})
setJobId(jId)
} catch (err) {
setUploadError(err instanceof Error ? err.message : 'Upload failed')

View File

@@ -4,6 +4,7 @@ import Link from 'next/link'
import type { Theme } from '@/types'
import { StatusBadge } from '@/components/ui/StatusBadge'
import { Button } from '@/components/ui/Button'
import { pb } from '@/lib/pocketbase'
import { postGenerateAll } from '@/lib/services'
interface ThemeCardProps {
@@ -12,24 +13,57 @@ interface ThemeCardProps {
}
export function ThemeCard({ theme, onUpdate }: ThemeCardProps) {
const [generating, setGenerating] = useState(false)
const [approving, setApproving] = useState(false)
const [rejecting, setRejecting] = useState(false)
const [toast, setToast] = useState<string | null>(null)
const [error, setError] = useState<string | null>(null)
const [queued, setQueued] = useState<number | null>(null)
async function handleGenerate() {
setGenerating(true)
async function handleApprove() {
setApproving(true)
setError(null)
setToast(null)
try {
const { queued: q } = await postGenerateAll(theme.id)
setQueued(q)
// 1. Fetch all topics in this theme
const topics = await pb.collection('topics').getFullList<{ id: string }>({
filter: `theme="${theme.id}"`,
fields: 'id',
})
// 2. Publish all topics
await Promise.all(
topics.map((t) => pb.collection('topics').update(t.id, { status: 'published' }))
)
// 3. Publish the theme
await pb.collection('themes').update(theme.id, { status: 'published' })
// 4. Trigger generation service
const { queued } = await postGenerateAll(theme.id)
setToast(`Generation queued for ${queued} micro-learnings`)
onUpdate()
} catch (err) {
setError(err instanceof Error ? err.message : 'Generation failed')
setError(err instanceof Error ? err.message : 'Approval failed')
} finally {
setGenerating(false)
setApproving(false)
}
}
async function handleReject() {
setRejecting(true)
setError(null)
try {
await pb.collection('themes').update(theme.id, { status: 'rejected' })
onUpdate()
} catch (err) {
setError(err instanceof Error ? err.message : 'Rejection failed')
} finally {
setRejecting(false)
}
}
const isPublished = theme.status === 'published'
const isRejected = theme.status === 'rejected'
return (
<div
style={{
@@ -40,28 +74,15 @@ export function ThemeCard({ theme, onUpdate }: ThemeCardProps) {
display: 'flex',
flexDirection: 'column',
gap: 'var(--s-3)',
opacity: isRejected ? 0.6 : 1,
}}
>
<div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 'var(--s-3)' }}>
<div style={{ flex: 1, minWidth: 0 }}>
<h3
style={{
margin: '0 0 var(--s-1)',
fontSize: 'var(--t-body)',
fontWeight: 700,
color: 'var(--fg)',
}}
>
<h3 style={{ margin: '0 0 var(--s-1)', fontSize: 'var(--t-body)', fontWeight: 700, color: 'var(--fg)' }}>
{theme.title}
</h3>
<p
style={{
margin: 0,
fontSize: 'var(--t-small)',
color: 'var(--fg-muted)',
lineHeight: 1.5,
}}
>
<p style={{ margin: 0, fontSize: 'var(--t-small)', color: 'var(--fg-muted)', lineHeight: 1.5 }}>
{theme.description}
</p>
</div>
@@ -80,49 +101,34 @@ export function ThemeCard({ theme, onUpdate }: ThemeCardProps) {
{theme.source_documents.length} source doc{theme.source_documents.length !== 1 ? 's' : ''}
</div>
{queued !== null && (
<div
style={{
background: 'var(--success)',
color: 'var(--teal-900)',
borderRadius: 'var(--r-sm)',
padding: 'var(--s-2) var(--s-3)',
fontSize: 'var(--t-small)',
fontWeight: 500,
}}
>
{queued} micro-learnings queued for generation
{toast && (
<div style={{ background: 'var(--success)', color: 'var(--teal-900)', borderRadius: 'var(--r-sm)', padding: 'var(--s-2) var(--s-3)', fontSize: 'var(--t-small)', fontWeight: 500 }}>
{toast}
</div>
)}
{error && (
<div
style={{
background: '#f8d7da',
color: '#c0392b',
borderRadius: 'var(--r-sm)',
padding: 'var(--s-2) var(--s-3)',
fontSize: 'var(--t-small)',
}}
>
<div style={{ background: '#f8d7da', color: '#c0392b', borderRadius: 'var(--r-sm)', padding: 'var(--s-2) var(--s-3)', fontSize: 'var(--t-small)' }}>
{error}
</div>
)}
<div style={{ display: 'flex', gap: 'var(--s-2)', flexWrap: 'wrap' }}>
{!isRejected && (
<Link href={`/admin/knowledge/${theme.id}`} style={{ textDecoration: 'none' }}>
<Button variant="secondary" size="sm">
View topics
</Button>
<Button variant="secondary" size="sm">Edit topics</Button>
</Link>
<Button
variant="primary"
size="sm"
onClick={() => void handleGenerate()}
loading={generating}
>
Generate micro-learnings
)}
{!isPublished && !isRejected && (
<>
<Button variant="primary" size="sm" onClick={() => void handleApprove()} loading={approving}>
Approve batch
</Button>
<Button variant="danger" size="sm" onClick={() => void handleReject()} loading={rejecting}>
Reject
</Button>
</>
)}
</div>
</div>
)

View File

@@ -19,16 +19,22 @@ async function handleResponse<T>(res: Response): Promise<T> {
return res.json() as Promise<T>
}
export async function postIngest(formData: FormData): Promise<{ jobId: string }> {
export async function postIngest(payload: {
documentId: string
filename: string
format: 'pdf' | 'md' | 'txt'
fileUrl: string
}): Promise<{ jobId: string }> {
const res = await fetch(`${INGESTION_URL}/ingest`, {
method: 'POST',
body: formData,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
})
return handleResponse<{ jobId: string }>(res)
}
export async function getIngestionStatus(jobId: string): Promise<IngestionJobStatus> {
const res = await fetch(`${INGESTION_URL}/ingest/${encodeURIComponent(jobId)}/status`)
const res = await fetch(`${INGESTION_URL}/ingest/status/${encodeURIComponent(jobId)}`)
return handleResponse<IngestionJobStatus>(res)
}

View File

@@ -0,0 +1,24 @@
/// <reference path="../pb_data/types.d.ts" />
migrate((db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("5gl7qj7aky6wjl9")
collection.listRule = "@request.auth.id != \"\""
collection.viewRule = "@request.auth.id != \"\""
collection.createRule = "@request.auth.role = \"admin\""
collection.updateRule = "@request.auth.role = \"admin\""
collection.deleteRule = "@request.auth.role = \"admin\""
return dao.saveCollection(collection)
}, (db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("5gl7qj7aky6wjl9")
collection.listRule = null
collection.viewRule = null
collection.createRule = null
collection.updateRule = null
collection.deleteRule = null
return dao.saveCollection(collection)
})

View File

@@ -0,0 +1,24 @@
/// <reference path="../pb_data/types.d.ts" />
migrate((db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("1cbepol4z1jxb20")
collection.listRule = "@request.auth.id != \"\""
collection.viewRule = "@request.auth.id != \"\""
collection.createRule = "@request.auth.role = \"admin\""
collection.updateRule = "@request.auth.role = \"admin\""
collection.deleteRule = "@request.auth.role = \"admin\""
return dao.saveCollection(collection)
}, (db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("1cbepol4z1jxb20")
collection.listRule = null
collection.viewRule = null
collection.createRule = null
collection.updateRule = null
collection.deleteRule = null
return dao.saveCollection(collection)
})

View File

@@ -0,0 +1,24 @@
/// <reference path="../pb_data/types.d.ts" />
migrate((db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("9ivwlfc584lp63w")
collection.listRule = "@request.auth.id != \"\""
collection.viewRule = "@request.auth.id != \"\""
collection.createRule = "@request.auth.role = \"admin\""
collection.updateRule = "@request.auth.role = \"admin\""
collection.deleteRule = "@request.auth.role = \"admin\""
return dao.saveCollection(collection)
}, (db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("9ivwlfc584lp63w")
collection.listRule = null
collection.viewRule = null
collection.createRule = null
collection.updateRule = null
collection.deleteRule = null
return dao.saveCollection(collection)
})

View File

@@ -0,0 +1,24 @@
/// <reference path="../pb_data/types.d.ts" />
migrate((db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("52xqp11w4t0y68u")
collection.listRule = "@request.auth.id != \"\""
collection.viewRule = "@request.auth.id != \"\""
collection.createRule = "@request.auth.role = \"admin\""
collection.updateRule = "@request.auth.role = \"admin\""
collection.deleteRule = "@request.auth.role = \"admin\""
return dao.saveCollection(collection)
}, (db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("52xqp11w4t0y68u")
collection.listRule = null
collection.viewRule = null
collection.createRule = null
collection.updateRule = null
collection.deleteRule = null
return dao.saveCollection(collection)
})

View File

@@ -0,0 +1,24 @@
/// <reference path="../pb_data/types.d.ts" />
migrate((db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("516qnoxsmeomkte")
collection.listRule = "@request.auth.id != \"\""
collection.viewRule = "@request.auth.id != \"\""
collection.createRule = "@request.auth.id != \"\""
collection.updateRule = "@request.auth.id = user"
collection.deleteRule = "@request.auth.role = \"admin\""
return dao.saveCollection(collection)
}, (db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("516qnoxsmeomkte")
collection.listRule = null
collection.viewRule = null
collection.createRule = null
collection.updateRule = null
collection.deleteRule = null
return dao.saveCollection(collection)
})

View File

@@ -0,0 +1,24 @@
/// <reference path="../pb_data/types.d.ts" />
migrate((db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("o9gcrudod9g510u")
collection.listRule = "@request.auth.id != \"\""
collection.viewRule = "@request.auth.id != \"\""
collection.createRule = "@request.auth.role = \"admin\""
collection.updateRule = "@request.auth.role = \"admin\""
collection.deleteRule = "@request.auth.role = \"admin\""
return dao.saveCollection(collection)
}, (db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("o9gcrudod9g510u")
collection.listRule = null
collection.viewRule = null
collection.createRule = null
collection.updateRule = null
collection.deleteRule = null
return dao.saveCollection(collection)
})

View File

@@ -0,0 +1,24 @@
/// <reference path="../pb_data/types.d.ts" />
migrate((db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("li75ivkr87g3r94")
collection.listRule = "@request.auth.id != \"\""
collection.viewRule = "@request.auth.id != \"\""
collection.createRule = "@request.auth.role = \"admin\""
collection.updateRule = "@request.auth.role = \"admin\""
collection.deleteRule = "@request.auth.role = \"admin\""
return dao.saveCollection(collection)
}, (db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("li75ivkr87g3r94")
collection.listRule = null
collection.viewRule = null
collection.createRule = null
collection.updateRule = null
collection.deleteRule = null
return dao.saveCollection(collection)
})

View File

@@ -0,0 +1,24 @@
/// <reference path="../pb_data/types.d.ts" />
migrate((db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("ilkfmv9xibmekna")
collection.listRule = "@request.auth.id != \"\""
collection.viewRule = "@request.auth.id != \"\""
collection.createRule = "@request.auth.role = \"admin\""
collection.updateRule = "@request.auth.role = \"admin\""
collection.deleteRule = "@request.auth.role = \"admin\""
return dao.saveCollection(collection)
}, (db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("ilkfmv9xibmekna")
collection.listRule = null
collection.viewRule = null
collection.createRule = null
collection.updateRule = null
collection.deleteRule = null
return dao.saveCollection(collection)
})

View File

@@ -0,0 +1,24 @@
/// <reference path="../pb_data/types.d.ts" />
migrate((db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("57kc85afcdkjlje")
collection.listRule = "@request.auth.id != \"\""
collection.viewRule = "@request.auth.id != \"\""
collection.createRule = "@request.auth.id != \"\""
collection.updateRule = ""
collection.deleteRule = ""
return dao.saveCollection(collection)
}, (db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("57kc85afcdkjlje")
collection.listRule = null
collection.viewRule = null
collection.createRule = null
collection.updateRule = null
collection.deleteRule = null
return dao.saveCollection(collection)
})

View File

@@ -0,0 +1,24 @@
/// <reference path="../pb_data/types.d.ts" />
migrate((db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("0lr0nf3rzh5tdq3")
collection.listRule = "@request.auth.role = \"admin\""
collection.viewRule = "@request.auth.role = \"admin\""
collection.createRule = "@request.auth.role = \"admin\""
collection.updateRule = "@request.auth.role = \"admin\""
collection.deleteRule = "@request.auth.role = \"admin\""
return dao.saveCollection(collection)
}, (db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("0lr0nf3rzh5tdq3")
collection.listRule = null
collection.viewRule = null
collection.createRule = null
collection.updateRule = null
collection.deleteRule = null
return dao.saveCollection(collection)
})

Some files were not shown because too many files have changed in this diff Show More