feat(01-04): CASL permission definitions and ability factory

- Install @casl/ability for role-based access control
- Create src/lib/casl/types.ts with AppAbility, AppSubjects, AppActions types
- Create src/lib/casl/permissions.ts with permission matrix for all 5 roles
- Create src/lib/casl/ability.ts with defineAbilityFor() factory function
- Support multi-role users via additive union of permissions
- Super-admin bypasses all permission checks via can("manage", "all")
This commit is contained in:
kevin-asprec
2026-03-04 18:52:39 +08:00
parent 36729343cc
commit 67bb6cc95c
5 changed files with 307 additions and 0 deletions

48
package-lock.json generated
View File

@@ -8,6 +8,7 @@
"name": "netforge",
"version": "0.1.0",
"dependencies": {
"@casl/ability": "^6.8.0",
"@prisma/client": "^6.19.2",
"bcryptjs": "^3.0.3",
"next": "16.1.6",
@@ -336,6 +337,18 @@
"node": ">=6.9.0"
}
},
"node_modules/@casl/ability": {
"version": "6.8.0",
"resolved": "https://registry.npmjs.org/@casl/ability/-/ability-6.8.0.tgz",
"integrity": "sha512-Ipt4mzI4gSgnomFdaPjaLgY2MWuXqAEZLrU6qqWBB7khGiBBuuEp6ytYDnq09bRXqcjaeeHiaCvCGFbBA2SpvA==",
"license": "MIT",
"dependencies": {
"@ucast/mongo2js": "^1.3.0"
},
"funding": {
"url": "https://github.com/stalniy/casl/blob/master/BACKERS.md"
}
},
"node_modules/@emnapi/core": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz",
@@ -3076,6 +3089,41 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/@ucast/core": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/@ucast/core/-/core-1.10.2.tgz",
"integrity": "sha512-ons5CwXZ/51wrUPfoduC+cO7AS1/wRb0ybpQJ9RrssossDxVy4t49QxWoWgfBDvVKsz9VXzBk9z0wqTdZ+Cq8g==",
"license": "Apache-2.0"
},
"node_modules/@ucast/js": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@ucast/js/-/js-3.1.0.tgz",
"integrity": "sha512-eJ7yQeYtMK85UZjxoxBEbTWx6UMxEXKbjVyp+NlzrT5oMKV5Gpo/9bjTl3r7msaXTVC8iD9NJacqJ8yp7joX+Q==",
"license": "Apache-2.0",
"dependencies": {
"@ucast/core": "1.10.2"
}
},
"node_modules/@ucast/mongo": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/@ucast/mongo/-/mongo-2.4.3.tgz",
"integrity": "sha512-XcI8LclrHWP83H+7H2anGCEeDq0n+12FU2mXCTz6/Tva9/9ddK/iacvvhCyW6cijAAOILmt0tWplRyRhVyZLsA==",
"license": "Apache-2.0",
"dependencies": {
"@ucast/core": "^1.4.1"
}
},
"node_modules/@ucast/mongo2js": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/@ucast/mongo2js/-/mongo2js-1.4.1.tgz",
"integrity": "sha512-9aeg5cmqwRQnKCXHN6I17wk83Rcm487bHelaG8T4vfpWneAI469wSI3Srnbu+PuZ5znWRbnwtVq9RgPL+bN6CA==",
"license": "Apache-2.0",
"dependencies": {
"@ucast/core": "1.10.2",
"@ucast/js": "3.1.0",
"@ucast/mongo": "2.4.3"
}
},
"node_modules/@unrs/resolver-binding-android-arm-eabi": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz",