feat(scheduling): enable department/personal permission filtering
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
- Disable BYPASS_AUTH (was true, now false) — backend enforces JWT auth - Scheduling suggestions filtered by department/manager permissions: - full: see all suggestions - department: see only own department's vehicles - personal: see only own managed vehicles - Candidate vehicles (inventory) remain fully visible to all - Summary recalculated after permission filtering - Consistent with mileage module permission model Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ import type { JwtPayload, AuthUser } from './types.js';
|
|||||||
const JWT_SECRET = process.env.JWT_SECRET || 'ln-bi-default-secret';
|
const JWT_SECRET = process.env.JWT_SECRET || 'ln-bi-default-secret';
|
||||||
|
|
||||||
// 临时:跳过所有认证(保留完整逻辑便于快速恢复)
|
// 临时:跳过所有认证(保留完整逻辑便于快速恢复)
|
||||||
const BYPASS_AUTH = true;
|
const BYPASS_AUTH = false;
|
||||||
|
|
||||||
export async function authMiddleware(c: Context, next: Next) {
|
export async function authMiddleware(c: Context, next: Next) {
|
||||||
const path = c.req.path;
|
const path = c.req.path;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { fetchVehicleInfoMap } from '../mileage/vehicle-info.js';
|
|||||||
import { mapRegion } from '../vehicles.js';
|
import { mapRegion } from '../vehicles.js';
|
||||||
import { filterByPermission, maskCustomerNames } from '../../auth/permissions.js';
|
import { filterByPermission, maskCustomerNames } from '../../auth/permissions.js';
|
||||||
import { classifyVehicle, generateSuggestions } from './algorithm.js';
|
import { classifyVehicle, generateSuggestions } from './algorithm.js';
|
||||||
import type { EnrichedVehicle, InventoryVehicle, SchedulingResponse } from './types.js';
|
import type { EnrichedVehicle, InventoryVehicle, SchedulingResponse, SchedulingSummary } from './types.js';
|
||||||
import type { AuthUser } from '../../auth/types.js';
|
import type { AuthUser } from '../../auth/types.js';
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -305,8 +305,20 @@ app.get('/', async (c) => {
|
|||||||
vehicleCount: targetVehicleCounts.get(t.id) || 0,
|
vehicleCount: targetVehicleCounts.get(t.id) || 0,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// Recalculate summary based on permission-filtered results
|
||||||
|
const filteredQualified = masked.filter((s: any) => s.type === 'replace_qualified').length;
|
||||||
|
const filteredHopeless = masked.filter((s: any) => s.type === 'rescue_hopeless').length;
|
||||||
|
const filteredSummary: SchedulingSummary = {
|
||||||
|
qualifiedCount: summary.qualifiedCount,
|
||||||
|
hopelessCount: summary.hopelessCount,
|
||||||
|
suggestionCount: masked.length,
|
||||||
|
estimatedGain: masked.filter((s: any) =>
|
||||||
|
s.candidates?.some((c: any) => c.canQualifyAfterSwap)
|
||||||
|
).length,
|
||||||
|
};
|
||||||
|
|
||||||
const response: SchedulingResponse = {
|
const response: SchedulingResponse = {
|
||||||
summary,
|
summary: filteredSummary,
|
||||||
suggestions: masked,
|
suggestions: masked,
|
||||||
targets: targetOptions,
|
targets: targetOptions,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user