- API client: switch from /api/v3/document-types to /api/document-types,
replace group_ids with ruleSetIds, add getEntryModules/getRuleSets
- List page: simplified to code/name/entry_module/rule_sets/status columns
- New/Edit page: code + name + description + entry_module dropdown +
rule_set multi-select checklist
- Fix DocumentType type import collision in documents.ts
- getDocumentTypes: switch from PostgREST /document_types to
GET /api/document-types
- getTodayDocuments: switch from PostgREST /documents to
GET /api/documents/list with userId + dateFrom params
- getQueueStatus: gracefully handle 404 (endpoint not yet migrated)
by returning empty queue state instead of erroring
Replace the old nested upload_info JSON approach with flat
multipart fields (typeId, region, fileRole, createdBy, autoRun,
speed) matching the new leaudit-platform backend.
- uploadDocumentToServer: POST ${API_BASE_URL}/api/upload
- handleFileUpload: pass region from userInfo.area, derive speed
from priority enum, pass createdBy from JWT user_id
- UploadResult replaces FileUploadResponse with documentId/fileId
replacing the old nested result.id/result.file_name pattern
The axios response interceptor was discarding the server's
permission-denied message (e.g. "缺少「用户列表」权限") and
replacing it with a generic "无权限". Now it reads the server
response body and surfaces the exact permission that's missing.
Previously only provincial_admin could edit roles/permissions in
the UI. Now admin (city-level admin) role can also edit. The
backend already enforces fine-grained permission checks, so the
UI gate just needs to match can_manage semantics.
If the API returns a non-string error (e.g. numeric HTTP status code),
calling .includes() directly on it throws "N.includes is not a function".
Convert to string via JSON.stringify first.
Fixes save button crash on rules/new page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Multiple locations in ReviewSettings.tsx call .includes() or .filter()
on variables that could theoretically be non-arrays:
1. availableFields.filter/.includes - added safeAvailableFields guard
2. newFields.map field.includes('_') - added typeof===string guard + filter
3. (prior fix) cfgAvailableFields includes/every in renderRuleConfig
4. (prior fix) selectedFields includes in renderFieldTags
These prevent TypeError crashes when config objects contain unexpected
types (e.g. {} instead of []) from stale API data.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
config.availableFields may be undefined or a non-array value (e.g. {}),
causing TypeError when calling .includes/.every directly on it.
Precompute cfgAvailableFields with Array.isArray guard before use.
Fixes: N.includes is not a function on rules/new page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>