feat(assets): 去掉企业资产范围 256 条规则上限
逐个 IP / 域名录范围的企业很容易撞上这个上限,撞上之后只能拆成多个企业, 而范围本身并不因为条数多就更慢。 - db:删掉 MaxCompanyScopeRules 常量、请求条数校验与 ensureCompanyScopeCapacityTx(每企业持久化总数的事务内校验) - 前端:去掉 MAX_COMPANY_SCOPE_RULES 与「剩余额度」计算,追加范围弹窗不再 按剩余条数报错;demo mock 的两处上限一并移除 - 单条规则仍限 1024 字符;请求正文 2 MiB(maxCompanyMutationBodyBytes)保留 作兜底,约合四五万条规则 测试:原先断言「超容量被拒」的两个用例翻转为「超过旧上限也能写入」—— db 侧批量写 300 条 + 追加 1 条,server 侧一次创建带 300 条范围的企业。 新用例先注册清理再断言,避免断言失败把企业留在共享开发库里。
This commit is contained in:
1 parent
48e14e8cf2
commit
acd1ac29d7
7 files changed
+41
-64
No files matched your search
@@ -59,7 +59,7 @@ import {
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { api } from "@/lib/api";
|
||||
import { MAX_COMPANY_SCOPE_RULES, parseCompanyScopeText } from "@/lib/company-scope";
|
||||
import { parseCompanyScopeText } from "@/lib/company-scope";
|
||||
import type { Asset, Company, CompanyScopeRule } from "@/lib/types";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@@ -1510,11 +1510,7 @@ function AppendScopeDialog({ company, onSaved }: { company: Company; onSaved: ()
|
||||
const [scopeText, setScopeText] = React.useState("");
|
||||
const [reason, setReason] = React.useState("");
|
||||
const [busy, setBusy] = React.useState(false);
|
||||
const remainingScopeRules = Math.max(0, MAX_COMPANY_SCOPE_RULES - (company.scope?.length || 0));
|
||||
const parsedScope = React.useMemo(
|
||||
() => parseCompanyScopeText(scopeText, { maxRules: remainingScopeRules }),
|
||||
[remainingScopeRules, scopeText],
|
||||
);
|
||||
const parsedScope = React.useMemo(() => parseCompanyScopeText(scopeText), [scopeText]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!open) return;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { CompanyScopeKind, CompanyScopeRule } from "@/lib/types";
|
||||
|
||||
export const MAX_COMPANY_SCOPE_RULES = 256;
|
||||
export const MAX_COMPANY_SCOPE_VALUE_LENGTH = 1024;
|
||||
|
||||
export type CompanyScopeTextIssue = {
|
||||
@@ -173,7 +172,7 @@ export function classifyCompanyScopeLine(
|
||||
|
||||
export function parseCompanyScopeText(
|
||||
value: string,
|
||||
options: { preservedRules?: CompanyScopeRule[]; maxRules?: number } = {},
|
||||
options: { preservedRules?: CompanyScopeRule[] } = {},
|
||||
): ParsedCompanyScopeText {
|
||||
const nonEmpty = value
|
||||
.split(/\r?\n/)
|
||||
@@ -190,13 +189,6 @@ export function parseCompanyScopeText(
|
||||
const preservedRule = queue?.shift();
|
||||
return classifyCompanyScopeLine(raw, line, preservedRule);
|
||||
});
|
||||
const maxRules = options.maxRules ?? MAX_COMPANY_SCOPE_RULES;
|
||||
if (nonEmpty.length > maxRules) {
|
||||
issues.push({
|
||||
line: nonEmpty[Math.max(0, maxRules)]?.line ?? 1,
|
||||
error: `最多允许 ${maxRules} 条范围,当前 ${nonEmpty.length} 条`,
|
||||
});
|
||||
}
|
||||
return {
|
||||
rules: issues.flatMap((item) => (item.rule ? [item.rule] : [])),
|
||||
errors: issues.flatMap((item) => (item.error ? [{ line: item.line, error: item.error }] : [])),
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
classifyCompanyScopeLine,
|
||||
companyScopeRuleError,
|
||||
isCompanyScopeKind,
|
||||
MAX_COMPANY_SCOPE_RULES,
|
||||
normalizeCompanyScopeValue,
|
||||
} from "../company-scope";
|
||||
import type {
|
||||
@@ -599,7 +598,6 @@ function mockScopeRows(
|
||||
existing: ScopeRow[] = [],
|
||||
): { rows: ScopeRow[]; invalid: number; skipped: number } {
|
||||
if (!Array.isArray(input)) return { rows: [], invalid: 0, skipped: 0 };
|
||||
if (input.length > MAX_COMPANY_SCOPE_RULES) throw new Error(`企业范围最多支持 ${MAX_COMPANY_SCOPE_RULES} 条`);
|
||||
let nextID =
|
||||
mockCompanies.flatMap((company) => company.scope ?? []).reduce((max, row) => Math.max(max, row.id), 0) + 1;
|
||||
const rows: ScopeRow[] = [];
|
||||
@@ -636,9 +634,6 @@ function mockScopeRows(
|
||||
keys.add(key);
|
||||
rows.push(row);
|
||||
}
|
||||
if (existing.length + rows.length > MAX_COMPANY_SCOPE_RULES) {
|
||||
throw new Error(`企业范围规则过多:每个企业最多 ${MAX_COMPANY_SCOPE_RULES} 条`);
|
||||
}
|
||||
return { rows, invalid, skipped };
|
||||
}
|
||||
|
||||
@@ -1438,7 +1433,7 @@ function route(m: string, path: string, seg: string[], q: URLSearchParams, b: Re
|
||||
const numericTaskID = mockTaskAssetID(seg[1]);
|
||||
if (!task || numericTaskID === undefined) throw new Error("任务不存在");
|
||||
if (Array.isArray(b.scope)) {
|
||||
if (b.scope.length === 0 || b.scope.length > MAX_COMPANY_SCOPE_RULES) throw new Error("请填写有效测试范围");
|
||||
if (b.scope.length === 0) throw new Error("请填写有效测试范围");
|
||||
const rules: CompanyScopeRule[] = b.scope.map((candidate, index) => {
|
||||
if (typeof candidate === "string") {
|
||||
const issue = classifyCompanyScopeLine(candidate, index + 1);
|
||||
|
||||
Reference in new issue
Block a user