Commit Graph

1 Commits

Author SHA1 Message Date
diegosouzapw
fc9f8d91f7 feat(providers): bulk add API keys with Single/Bulk tabs
Mirrors the 9router UX (one textarea, name|apiKey per line) but goes
further: dedicated server-side endpoint with Zod validation, partial-
failure semantics, audit log, and provider whitelist.

UI (src/app/(dashboard)/dashboard/providers/[id]/page.tsx):
- AddApiKeyModal now switches between Single (existing behaviour) and
  Bulk Add via tab strip. Tabs hide for providers that don't support
  bulk (Vertex, web-session, OAuth, multi-field).
- Bulk pane: textarea, shared Priority + "validate each key" checkbox,
  result panel with per-line errors (truncated at 10).

Backend:
- POST /api/providers/bulk: iterates entries through createProviderConnection
  with the same provider-specific normalization as the single endpoint.
  Returns {success, failed, total, created, errors[]}. Optional pre-save
  validation via /api/providers/validate when validateKeys=true. Each
  entry succeeds/fails independently — no transaction rollback.
- Bulk audit event logged once per request plus per-entry success events.

Schemas:
- bulkCreateProviderSchema (src/shared/validation/schemas.ts): max 200
  entries, mandatory name+apiKey per entry, google-pse-search cx guard.
- supportsBulkApiKey() helper (src/shared/constants/providers.ts) with
  explicit deny-list for OAuth/web-session/multi-field providers.

Parser:
- parseBulkApiKeys() (src/shared/utils/bulkApiKeyParser.ts) handles
  CRLF, # comments, blank lines, pipe inside apiKey, empty-name fallback,
  and caps input at BULK_API_KEY_MAX_LINES (200) with a warning.

Tests:
- tests/unit/bulkApiKeyParser.test.ts: 12 cases (format, edge cases, cap)
- tests/unit/providers-bulk-route.test.ts: 12 cases (schema, whitelist,
  response shape, apiKey leak guard)

i18n:
- en.json: bulkTabSingle, bulkTabBulkAdd, bulkAddFormatHint,
  bulkValidateKeys, bulkAddAllKeys, bulkAddedCount, bulkFailedCount,
  adding
2026-05-17 11:30:49 -03:00