Files
Edu/apps/portal-shell/eslint.config.js
SpecialX cfb7b005fd feat(portal-shell): v2.1 P0 auth + middleware + login + graphql proxy
- 新增 ARCHITECTURE.md v3.0:portal-shell 架构权威文档
  涵盖 §3.4 V3-A2/A3 认证链、§4 GraphQL 联邦、§5 安全、
  §6 部署、§10 P0-P3 验收清单
- 新增 middleware.ts:认证 + 路由门禁
  httpOnly cookie edu_session(JWT)读取
  DEV_MODE 合成 dev-user/teacher 身份(NODE_ENV!=production &&
  NEXT_PUBLIC_DEV_MODE=true)
  生产模式 jose JWKS RS256 验签(iss/aud 校验)
  路由权限位图注入 x-user-id/x-user-role/x-user-permissions 头
  /shell/** 强制 checkRoutePermission,拒绝跳 /shell/forbidden
- 新增 instrumentation.ts:生产环境 DEV_MODE 强制 false
  防止生产环境误开 DEV_MODE 合成身份
- 新增 app/api/auth/login/route.ts + logout/route.ts
  登录走 api-gateway /v1/iam/login
  设置 httpOnly + Secure + SameSite=Strict cookie
- 新增 app/api/graphql/route.ts:同域 GraphQL 代理
  转发到 apollo-router,注入 router-authorization 头
- 新增 app/login/page.tsx + login-form.tsx
  zod 表单校验,next 参数支持
- 新增 app/shell/forbidden/page.tsx:403 页面
- 更新 route-permissions.ts:补全 P0 路由权限映射
- 更新 permission-bitmap.ts(shared-ts):位图编码/解码
- 更新 apollo-client.ts:DEV_MODE APQ 关闭,错误处理
- 更新 config-fetcher.ts:config-service 直连降级
- 更新 ApolloProvider.tsx:SSR/RSC 兼容
- 更新 eslint.config.js:design-tokens/no-hardcoded-fonts
  白名单调整
2026-07-22 11:35:36 +08:00

149 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* portal-shell ESLint flat config (ESM)
*
* 包含设计令牌强制规则project_rules §3.10
* - 禁止 #hex 颜色字面量
* - 禁止 'Inter'/'Fraunces'/'JetBrains Mono' 字体名字面量
*
* P0-7补 no-restricted-importsARCHITECTURE.md §3.4 V3-A3 / §8.3 铁律)
* - 禁 widget/页面 直接 import sonner统一走 @/shared/lib/notify
* - 禁 widget/页面 绕过 lib/api 直接 import @apollo/client
* - 禁 widget 跨目录 import 其他 widget插件隔离
*
* 关联project_rules §3.10、portal-shell ARCHITECTURE.md §8.3、§11.7
*/
import js from "@eslint/js";
import tseslint from "typescript-eslint";
import prettierConfig from "eslint-config-prettier";
export default tseslint.config(
{
ignores: [
"**/dist/**",
"**/node_modules/**",
"**/.next/**",
"**/coverage/**",
"**/*.config.js",
"**/*.config.mjs",
],
},
js.configs.recommended,
...tseslint.configs.recommended,
{
languageOptions: {
ecmaVersion: 2024,
sourceType: "module",
},
rules: {
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": [
"error",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
},
],
"no-console": "off",
},
},
// 设计令牌强制规则project_rules §3.10
{
files: ["**/*.{ts,tsx,js,jsx}"],
rules: {
"no-restricted-syntax": [
"error",
{
// 禁止 #hex 颜色字面量(如 "#fff"、"#000000"
selector: "Literal[value=/^#[0-9a-fA-F]{3,8}$/]",
message:
"禁止硬编码颜色 #hex使用 var(--*) 或 Tailwind bg-* 类project_rules §3.10",
},
{
// 禁止字体名字面量next/font 的 import 标识符不受影响)
selector: "Literal[value=/^(Inter|Fraunces|JetBrains Mono)$/]",
message:
"禁止硬编码字体名字面量,使用 var(--font-family-sans/serif/mono)project_rules §3.10",
},
],
},
},
// P0-7no-restricted-imports 强制ARCHITECTURE.md §8.3 / §11.7 红线)
// - 禁直接 import sonner统一走 @/shared/lib/notify 封装)
// - 禁页面/widget 绕过 lib/api 直接 import @apollo/client
// - 禁 widget 跨目录 import 其他 widget插件隔离铁律
// 白名单:
// - notify 封装本体src/shared/lib/notify.ts+ 其测试__tests__/notify.test.ts+ Toaster 容器src/shared/components/ui/sonner.tsx
// - 数据层src/lib/apollo-client.ts、useWidgetQuery.ts、useWidgetMutation.ts、config-fetcher.ts、src/lib/api/**、src/providers/ApolloProvider.tsx
// - widget 注册中心src/shell/Registry.tsx必须 import 各 widget 的 plugin.manifest是唯一例外
{
files: ["src/**/*.{ts,tsx}"],
ignores: [
"src/shared/lib/notify.ts",
"src/shared/lib/__tests__/notify.test.ts",
"src/shared/components/ui/sonner.tsx",
"src/lib/apollo-client.ts",
"src/lib/useWidgetQuery.ts",
"src/lib/useWidgetMutation.ts",
"src/lib/config-fetcher.ts",
"src/lib/api/**",
"src/providers/ApolloProvider.tsx",
"src/shell/Registry.tsx",
],
rules: {
"no-restricted-imports": [
"error",
{
paths: [
{
name: "sonner",
message:
"禁止直接 import sonner统一使用 @/shared/lib/notifyARCHITECTURE.md §8.3",
},
{
name: "@apollo/client",
message:
"禁止绕过 lib/api 直接 import @apollo/client使用 useWidgetQuery/useWidgetMutationARCHITECTURE.md §11.7",
},
],
patterns: [
{
group: ["@/widgets/*", "../widgets/*", "../../widgets/*"],
message:
"禁止 widget 跨目录 import 其他 widget插件隔离铁律ARCHITECTURE.md §11.7",
},
],
},
],
},
},
// 白名单令牌原始定义、PWA manifest
{
files: ["**/primitive.css", "**/manifest.ts"],
rules: {
"no-restricted-syntax": "off",
},
},
// 测试文件放宽规则
{
files: [
"**/*.test.ts",
"**/*.test.tsx",
"**/*.spec.ts",
"**/*.spec.tsx",
"**/__tests__/**",
],
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-non-null-assertion": "off",
},
},
prettierConfig,
);