Commit 52dafd0
authored
Fix import/export API endpoints and improve CSV upload reliability (#458)
* refactor(shared): fix zod schemas for partial clusters and lint errors
Changes:
- Replace z.record with z.object for zodPolisClusters and zodPolisClustersMetadata
to allow partial clusters (z.record with enum key requires ALL values present,
but conversations can have fewer than 6 clusters)
- Wrap numeric constants in String() for template literal error messages to fix
TypeScript lint errors about implicit string coercion
- Remove unused imports (zodConversationBodyOutput, zodOpinionContentOutput) from dto.ts
Deploy: agora, api, math-updater
* refactor(api): convert import/export endpoints from GET/DELETE to POST
Standardize all API endpoints to use POST method following the codebase's
JSON-RPC-like pattern. This ensures consistent UCAN authentication handling
and prevents issues with URL parameter limitations.
Backend changes:
- Convert GET /conversation/import/active to POST
- Convert GET /conversation/import/status/:importSlugId to POST with body
- Convert GET /conversation/export/status/:exportSlugId to POST with body
- Convert GET /conversation/export/history/:conversationSlugId to POST with body
- Convert GET /conversation/export/readiness/:conversationSlugId to POST with body
- Convert DELETE /conversation/export/:exportSlugId to POST /export/delete with body
- Fix verifyUcanAndKnownDeviceStatus to properly spread expectedKnownDeviceStatus
Frontend changes:
- Update all API wrapper functions to use new POST endpoints with body params
- Add file-upload timeout profile (90s) for large CSV uploads
- Add configurable UCAN lifetime for file uploads (120s vs default 30s)
- Update generated OpenAPI client to match new endpoints
Deploy: agora, api
* fix(nginx): increase client_max_body_size for CSV import uploads
Set client_max_body_size to 150M on /api location to support importing
3 CSV files (summary, comments, votes) up to 50MB each.
Deploy: nginx
* fix(agora): continue polling import status on 404 for read replica lag
When using database read replicas, newly created import records may not
be immediately visible due to replication lag. This causes the import
status query to return 404 briefly after creating an import.
Continue polling on 404 errors instead of showing an error state, giving
the read replica time to catch up with the primary.
Deploy: agora
* chore: remove debug logging and reduce import noise
- Remove console.log debug statements from PreLoginIntentionDialog
- Reduce noise in comment import logging by treating null vote counts as 0
(only log warnings when Polis provides a non-null value that differs
from calculated)
Deploy: agora, api
* fix(agora): improve AsyncStateHandler and ImportStatusView components
AsyncStateHandler:
- Fix error message priority: show config.error.message before errorMessage
- Add bottom padding to asyncStateMessage for better visual spacing
ImportStatusView:
- Use computed statusData accessor for cleaner template bindings
- Remove redundant isEmpty prop (AsyncStateHandler handles empty state)
- Simplify enabled condition (isGuestOrLoggedIn implies auth initialized)
Deploy: agora
* feat(agora): improve CSV upload error formatting and display
Add comprehensive error formatting for CSV upload failures:
- Format Axios errors with HTTP status, response body, and stack trace
- Handle both string and JSON response bodies (nginx HTML vs API JSON)
- Include full error object for debugging
- Better error details for generic Error instances
This helps users report and debug upload failures more effectively.
Deploy: agora
* feat(api): add unique constraint on conversation_import.conversationId
Add unique constraint to prevent duplicate conversation references in the
import table. The constraint allows multiple NULL values (imports in progress
or failed) while ensuring each completed import points to a unique conversation.
Includes Drizzle schema update and Flyway migration script.
Deploy: api (requires migration)
* docs: document POST-only API pattern in CLAUDE.md
Add comprehensive documentation for the codebase's POST-only API design pattern:
- All endpoints use POST (never GET, PUT, PATCH, DELETE)
- Request data goes in body, never URL parameters
- All "delete" operations are soft-deletes
- SSE endpoints are the only exception (must use GET)
Include code examples showing correct vs incorrect patterns.
Deploy: none
* fix(agora): fix export enabled check for undefined env var
The VITE_EXPORT_CONVOS_ENABLED env var was using .default("true") in the
Zod schema, but defaults only apply during Zod parsing. Since processEnv
is a direct type cast of import.meta.env without runtime parsing, the
default never applied when the var was unset.
Changes:
- Make VITE_EXPORT_CONVOS_ENABLED optional instead of using .default()
- Change visibility check from === "true" to !== "false" so export is
enabled by default when the env var is not set
Deploy: agora1 parent 1c73503 commit 52dafd0
35 files changed
Lines changed: 7520 additions & 929 deletions
File tree
- script/vhosts
- services
- agora/src
- api
- components
- authentication/intention
- conversation/import
- newConversation/import/csv
- ui
- utils
- actions/definitions
- api
- conversationExport
- conversationImport
- post
- crypto/ucan
- api
- database/flyway
- drizzle
- meta
- src
- service
- load-testing/src
- api
- math-updater/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
254 | 254 | | |
255 | 255 | | |
256 | 256 | | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
257 | 318 | | |
258 | 319 | | |
259 | 320 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
96 | 96 | | |
97 | 97 | | |
98 | 98 | | |
| 99 | + | |
99 | 100 | | |
100 | 101 | | |
101 | 102 | | |
| |||
0 commit comments