| 152 | * - mask: passes and returns masked text with PII replaced by `<ENTITY_TYPE>` |
| 153 | */ |
| 154 | export async function validatePII(input: PIIValidationInput): Promise<PIIValidationResult> { |
| 155 | const { text, entityTypes, mode, language = 'en', requestId } = input |
| 156 | |
| 157 | logger.info(`[${requestId}] Starting PII validation`, { |
| 158 | textLength: text.length, |
| 159 | entityTypes, |
| 160 | mode, |
| 161 | language, |
| 162 | }) |
| 163 | |
| 164 | try { |
| 165 | const spans = await analyze(text, entityTypes, language) |
| 166 | |
| 167 | const detectedEntities: DetectedPIIEntity[] = spans.map((s) => ({ |
| 168 | type: s.entity_type, |
| 169 | start: s.start, |
| 170 | end: s.end, |
| 171 | score: s.score, |
| 172 | text: text.slice(s.start, s.end), |
| 173 | })) |
| 174 | |
| 175 | if (spans.length === 0) { |
| 176 | logger.info(`[${requestId}] PII validation completed`, { passed: true, detectedCount: 0 }) |
| 177 | return { passed: true, detectedEntities: [], maskedText: mode === 'mask' ? text : undefined } |
| 178 | } |
| 179 | |
| 180 | if (mode === 'block') { |
| 181 | const counts = new Map<string, number>() |
| 182 | for (const e of detectedEntities) counts.set(e.type, (counts.get(e.type) ?? 0) + 1) |
| 183 | const summary = Array.from(counts.entries()) |
| 184 | .map(([type, count]) => `${count} ${type}`) |
| 185 | .join(', ') |
| 186 | logger.info(`[${requestId}] PII validation completed`, { |
| 187 | passed: false, |
| 188 | detectedCount: detectedEntities.length, |
| 189 | }) |
| 190 | return { passed: false, error: `PII detected: ${summary}`, detectedEntities } |
| 191 | } |
| 192 | |
| 193 | // mask mode: the anonymizer replaces every span with `<ENTITY_TYPE>`. |
| 194 | const maskedText = await anonymize(text, spans) |
| 195 | logger.info(`[${requestId}] PII validation completed`, { |
| 196 | passed: true, |
| 197 | detectedCount: detectedEntities.length, |
| 198 | hasMaskedText: true, |
| 199 | }) |
| 200 | return { passed: true, detectedEntities, maskedText } |
| 201 | } catch (error) { |
| 202 | logger.error(`[${requestId}] PII validation failed`, { error: getErrorMessage(error) }) |
| 203 | return { |
| 204 | passed: false, |
| 205 | error: `PII validation failed: ${getErrorMessage(error)}`, |
| 206 | detectedEntities: [], |
| 207 | } |
| 208 | } |
| 209 | } |
| 210 | |
| 211 | /** |