Skip to main content

Known Issues and Edge Cases

Last updated: 2026-03-19 Jira ticket: DEV-4 Purpose: Reference document for QA team. Catalogs known issues, edge cases, incomplete features, and testing recommendations across the Pyra codebase.


1. Critical Issues​

These must be fixed before production deployment.

1.1 No Rate Limiting on SMS Sends​

  • File: server/src/services/twilio/TwilioSmsService.ts:284-286
  • Description: No proactive rate limiting before Twilio API calls. System can exceed account limits or trigger unexpected billing.
  • Impact: Potential for massive SMS costs, service abuse, or hitting Twilio platform rate limits.
  • Test: Simulate 50+ concurrent SMS sends; verify rate limiting prevents excessive API calls.

1.2 A2P 10DLC Regulatory Compliance Missing​

  • File: server/src/services/communications/ComplianceService.ts
  • Description: No validation that an A2P brand is approved before SMS/MMS sends. System can send SMS without proper regulatory registration.
  • Impact: Legal and compliance violations (TCPA), potential FCC fines.
  • Test: Attempt SMS send without A2P registration; verify system blocks the send.

1.3 SMS Cost Calculation Precision Error​

  • File: server/src/services/communications/UsageTrackingService.ts:164
  • Description: Falls back to smsOutbound count when smsSegments is missing. Multi-segment SMS not properly charged (Twilio charges per segment, not per message).
  • Impact: Revenue loss on multi-segment messages; billing inaccuracy.
  • Test: Send a 200-character SMS (2+ segments); verify cost reflects segment count, not message count.

2. Security Edge Cases​

2.1 Soft Authorization Checks Return Null​

  • File: server/src/graphql/resolvers/sharedInventoryResolvers.ts:36-55
  • Description: Many resolvers return null on unauthorized access instead of throwing a FORBIDDEN error. Client can't distinguish "not found" from "forbidden".
  • Impact: Information leakage (existence of resource revealed by null vs error).
  • Test: Query shared inventory as unauthorized user; verify proper 403 response, not null.

2.2 calculateSmsSegments Missing Auth Check​

  • File: server/src/graphql/resolvers/communicationResolvers.ts:770-775
  • Description: The calculateSmsSegments query has no authentication check — it directly calls the service without validating the caller. Note: canSendMessage (line 804) does have auth via getOrganizationId.
  • Impact: Unauthenticated users can probe SMS segment calculation.
  • Test: Call calculateSmsSegments without auth token; verify it's rejected.

2.3 Test Mode Webhook Validation Bypass​

  • File: server/src/routes/twilioWebhookRoutes.ts:18-20
  • Description: Webhook signature validation disabled in test mode without additional safeguards.
  • Impact: Unauthenticated webhooks possible in staging environments.
  • Test: Verify production environment always validates webhook signatures.

2.4 Phone Numbers Logged Without Masking​

  • File: server/src/services/twilio/TwilioSmsService.ts:288
  • Description: Phone numbers logged in plaintext.
  • Impact: PII exposure in logs; compliance risk.
  • Test: Check server logs after SMS operations; verify phone numbers are masked.

3. Data Integrity Concerns​

3.1 Missing Cascade Delete Rules​

  • File: server/prisma/schema.prisma
  • Description: 6 relations missing onDelete: Cascade or onDelete: SetNull:
    1. Message -> MessageTemplate
    2. ScheduledMessage -> Conversation
    3. ScheduledMessage -> MessageTemplate
    4. TwilioMessageLog -> Message
    5. DeadLetterMessage -> Message
    6. VoiceCallLog -> Message
  • Impact: Orphaned records in database after parent deletion.
  • Test: Delete a conversation with messages; verify no orphaned TwilioMessageLog or DeadLetterMessage records.

3.2 Duplicate Affiliate Programs Possible​

  • File: server/src/services/affiliateService.ts:126-128
  • Description: Database lacks unique constraints to prevent duplicate MAIN or ORGANIZATION programs per org.
  • Impact: Duplicate affiliate programs silently created; data inconsistency.
  • Test: Create two MAIN affiliate programs for the same org; verify the second is rejected.

3.3 Missing Database Indexes​

  • File: server/prisma/schema.prisma
  • Description: Missing composite indexes for high-frequency queries:
    • [organizationId, customerId, status] on Conversation
    • messageId on TwilioMessageLog, TwilioVoiceCallLog
    • originalMessageId on DeadLetterMessage
  • Impact: Query performance degradation as data grows.
  • Test: Load test with 10K+ messages; measure query latency on these tables.

4. Business Logic Edge Cases​

4.1 Delivery Fee Not Implemented​

  • File: server/src/services/CheckoutService.ts:423
  • Description: Delivery fee calculation is hardcoded to 0. Feature not implemented.
  • Impact: All delivery orders have $0 delivery fee.
  • Test: Create order with delivery option; verify delivery fee is $0 (expected current behavior).

4.2 Shared Inventory Date-Range Filtering Not Working​

  • File: server/src/graphql/resolvers/sharedInventoryResolvers.ts:477-479
  • Description: startDate/endDate parameters accepted but not used to filter holds. Returns point-in-time availability.
  • Impact: Incorrect availability for date-range queries; potential double-booking of shared inventory.
  • Test: Query shared inventory with date range; verify availability reflects holds within that range (currently broken).

4.3 Concurrent Coupon Over-Redemption​

  • File: server/src/services/couponService.ts:82-90
  • Description: Coupon max uses (maxUses, maxUsesPerCustomer) checked without transaction locking.
  • Impact: Two concurrent redemptions can exceed coupon limits.
  • Test: Simultaneously redeem a coupon with maxUses: 1 from two sessions; verify only one succeeds.

4.4 Inventory Hold Expiry — Theoretical Edge Case​

  • File: server/src/services/inventoryHoldService.ts:88-140
  • Description: Row-level locking (FOR UPDATE) is properly implemented, but expired holds are filtered by expiresAt > now(). At the exact millisecond boundary of expiry, concurrent requests could theoretically see different availability. The transaction isolation makes exploitation very unlikely.
  • Impact: Extremely low risk — locking mitigates most scenarios.
  • Test: Stress test hold creation with rapid concurrent requests near expiry boundary (likely passes).

4.5 Trial Expiry Notification Not Retry-Safe​

  • File: server/src/jobs/trialExpiryWorker.ts:208-212
  • Description: trialExpiredNotified flag is set before confirming email delivery. If email send fails, flag is already set and retry won't fire.
  • Impact: Some organizations don't receive trial expiry notifications.
  • Test: Simulate email failure during trial expiry; verify notification is retried.

4.6 Daily Spend Tracking Inaccurate​

  • File: server/src/services/communications/FinancialCircuitBreaker.ts:594-627
  • Description: Daily spend approximated by dividing monthly spend by days elapsed. Inaccurate after server restarts or mid-day resets.
  • Impact: Spending limits may be over or under-enforced.
  • Test: Verify spend tracking accuracy after a server restart mid-billing-cycle.

4.7 International SMS Rate Hardcoded​

  • File: server/src/services/communications/UsageTrackingService.ts:425
  • Description: International SMS uses hardcoded 2x multiplier vs actual Twilio rates.
  • Impact: Billing inaccuracy for international SMS.
  • Test: Send international SMS; verify cost matches actual Twilio rate, not 2x domestic.

5. Race Conditions and Concurrency​

5.1 Voice Webhook Idempotency Not Atomic​

  • File: server/src/routes/twilioWebhookRoutes.ts:227-241
  • Description: Idempotency check in voice webhook is not atomic. Concurrent duplicate webhooks can process the same event twice.
  • Impact: Double-booking, duplicate charges, or duplicate notifications.
  • Test: Send duplicate voice webhook payloads simultaneously; verify only one is processed.

5.2 Apollo Cache Race on Rapid Mutations​

  • File: client/src/pages/v2/invite-codes.tsx:100-107
  • Description: Multiple refetch() calls in succession after mutations. Second mutation can fire before first refetch completes.
  • Impact: Stale data displayed; UI shows outdated state.
  • Test: Rapidly create/delete invite codes; verify list stays consistent.

5.3 Stale Response Guard Inconsistency​

  • Files: Various v2 pages
  • Description: Some pages use cancellation flag pattern for stale async responses (register.tsx, scheduling hooks), but this pattern is not consistently applied across all async operations.
  • Impact: Data inconsistency in pages without the guard.
  • Test: Rapidly switch filters/tabs on pages like scheduling, inventory; verify displayed data matches current selection.

6. Frontend / UX Issues​

6.1 Silent Error Handling (80+ instances)​

  • Files: useNLBSProducts.js, useFileCenter.js, useSharedInventoryGrid.ts, useInventoryHolds.js, usePageSections.js, useThemeManager.js
  • Description: Errors logged to console only; user gets no visual feedback for operation failures.
  • Impact: Users unaware when file uploads, inventory operations, theme saves, etc. fail.
  • Test: Simulate network failure during file upload; verify user sees an error message (not just console).

6.2 Production Blockers in Communication Module​

  • Files:
    • components/Communication/tabs/InboxView.jsx:131 — File upload not implemented
    • components/Communication/tabs/WorkflowManagement.jsx:18 — Migration from localStorage to backend incomplete
    • components/Communication/tabs/AnalyticsView.jsx:236, 293 — Mock data instead of real queries
    • components/Communication/settings/DiagnosticsPanel.jsx:14 — SIMULATION_MODE should be false in production
  • Impact: Communication module partially functional; some features show fake data.
  • Test: Navigate to Communication module; verify each tab loads real data.

6.3 Incomplete V2 Network Pages​

  • Files: client/src/pages/v2/network/
  • Description: Several network sub-pages have unimplemented features:
    • Backlinks: directory page, export, settings persistence not wired
    • Analytics: period selector uses mock constants
    • Affiliate manage: detail view, commission editor, messaging, bulk ops not wired
    • Affiliate settings: not persisted via mutation
    • Sponsored content: create flow and marketplace view not wired
  • Impact: Network center pages partially functional.
  • Test: Navigate to each network sub-page; verify CRUD operations work end-to-end.

6.4 Accessibility Gaps​

  • Files:
    • client/src/pages/v2/file-center.tsx:208 — <div> with onClick but no role or keyboard support
    • client/src/pages/v2/organizations.tsx:395 — role="button" without onKeyDown
    • client/src/pages/v2/customers.tsx:376 — role="button" without keyboard support
    • client/src/pages/v2/admin-feedback.tsx:236 — role="button" on div without keyboard handler
  • Impact: Keyboard-only users cannot interact with these elements.
  • Test: Navigate each page using only keyboard (Tab, Enter, Space); verify all interactive elements are reachable and activatable.

6.5 V2 Payment Method Migration Incomplete​

  • File: client/src/pages/v2/settings/account.tsx:283
  • Description: Stripe card entry component not migrated to v2.
  • Impact: Payment method UI may not function correctly in v2 settings.
  • Test: Navigate to v2 account settings; attempt to add/update payment method.

6.6 Order Delivery Tracking — Image Integration Pending​

  • File: client/src/pages/v2/order-delivery-tracking.tsx:525
  • Description: Cloudflare Images fileId integration pending for delivery photo uploads.
  • Impact: Delivery proof photos may not persist correctly.
  • Test: Upload delivery photo; verify it saves and displays correctly.

7. Form Validation Gaps​

7.1 Customer Form​

  • File: client/src/pages/v2/add-customer.tsx
  • Description: Billing address validation is client-side only. Service address validation missing when sameAsBilling=true. Email format validation not visible.
  • Test: Submit customer form with invalid email, missing ZIP code, very long name; verify appropriate validation errors.

7.2 Inventory Form​

  • File: client/src/pages/v2/inventory-form.tsx
  • Description: No max-length validation on name/description fields. Custom duration input accepts strings.
  • Test: Submit inventory item with 10,000-character name; verify server-side validation catches it.

7.3 Online Store Page Form​

  • File: client/src/pages/v2/online-store-page-form.tsx
  • Description: Title validation only checks trim(), no length limits.
  • Test: Create page with very long title (500+ chars); verify behavior.

7.4 Number Input Edge Cases (All Financial Forms)​

  • Description: Risk of integer overflow, decimal precision issues, and negative values across pricing forms.
  • Test: Enter 99999999.999, -1, 0.001, and NaN in all price/quantity fields; verify correct handling.

8. Testing Gaps​

8.1 Inventory Management Test Suite Disabled​

  • File: client/src/tests/pages/InventoryManagement.test.jsx:70
  • Description: Entire test suite skipped with describe.skip() due to JavaScript heap OOM crashes.
  • Impact: No automated regression testing for inventory operations.
  • Action: Investigate OOM root cause (likely test fixture bloat); re-enable tests.

8.2 No V2 Page Unit Tests​

  • Description: Only auth pages (login, forgot-password, reset-password, not-authorized) have v2 test files. The other 70+ v2 pages have zero test coverage.
  • Impact: No automated regression safety for migrated pages.
  • Action: Create smoke tests for top 10 v2 pages (dashboard, inventory-list, orders, scheduling, customers, categories, employee-app, file-center, reports, settings).

8.3 Missing Error Boundary Coverage​

  • Description: Only 6 error boundaries exist across the entire app. Large v2 pages (category-form, order-detail, file-center, inventory-list, express-checkout) have no error boundaries.
  • Impact: A single component crash can take down an entire page with no recovery option.
  • Action: Add error boundaries wrapping top-level v2 page content.

8.4 Large V2 Pages Approaching 1000-Line Limit​

  • Description: Several pages are near the ESLint max-lines limit:
    • category-form.tsx (997 lines)
    • order-detail.tsx (970 lines)
    • file-center.tsx (966 lines)
    • inventory-list.tsx (963 lines)
    • order-charges.tsx (960 lines)
    • express-checkout.tsx (944 lines)
  • Impact: Future changes may trigger ESLint failures. Maintenance burden.
  • Action: Refactor into smaller sub-components.

9. Incomplete Features​

9.1 Voice Channel​

  • File: server/src/graphql/resolvers/communicationResolvers.ts:1201-1202
  • Description: sendMessage throws at runtime if channel === 'VOICE'. Transcription webhook endpoint not implemented.
  • Test: Verify VOICE option is hidden from UI, or that error is handled gracefully.

9.2 BYO Provider Config​

  • File: server/src/services/communications/MessageClassificationService.ts:170-172
  • Description: "Bring Your Own" SMS provider support is stubbed; always returns false.
  • Test: Verify BYO provider option is hidden from UI.

9.3 PDF Report Export​

  • File: server/src/services/reportExportService.ts:73-75
  • Description: PDF generation not implemented; returns HTML instead of PDF.
  • Test: Export a report as PDF; verify file format and content.

9.4 WhatsApp Channel​

  • File: server/src/graphql/resolvers/communicationResolvers.ts:2463-2466
  • Description: WhatsApp fields return hardcoded false or null values.
  • Test: Verify WhatsApp features are hidden from UI if not supported.

9.5 Usage Alert Notifications​

  • File: server/src/services/communications/UsageTrackingService.ts:417-418
  • Description: Alerts are computed but only logged to console; never delivered to users.
  • Test: Exceed a usage threshold; verify no alert notification is received (expected current behavior).

9.6 Sandbox Usage Cache Not Production-Ready​

  • File: server/src/services/communications/ComplianceService.ts:122-123
  • Description: Sandbox SMS usage tracked in-memory Map; doesn't survive restarts or multi-instance deployments.
  • Test: Restart server during sandbox testing; verify usage limits reset (known bug).

10. Caching Issues​

10.1 Twilio Client Cache Never Expires​

  • File: server/src/services/twilio/TwilioClientFactory.ts:77-79
  • Description: In-memory client cache has no expiry. Credential rotation not reflected.
  • Impact: Long-running server instances can use stale Twilio credentials.
  • Test: Rotate Twilio credentials; verify new credentials take effect without restart.

11. Compliance Gaps​

  • File: server/src/services/communications/ComplianceService.ts
  • Description: No tracking of express written consent documentation or proof. Only tracks opt-in flag.
  • Impact: Can't prove consent if audited.
  • Test: Check consent audit log after customer opt-in; verify proof documentation is captured.

11.2 Voice Opt-In IP Not Captured​

  • File: server/src/services/communications/ComplianceService.ts:851-856
  • Description: Voice channel doesn't capture consent IP address (SMS does at line 841, EMAIL at line 848, but VOICE omits it).
  • Impact: Incomplete audit trail for voice consent compliance.
  • Test: Opt in to voice communications; verify IP is logged.
  • File: server/src/services/communications/ComplianceService.ts:225-244
  • Description: Any ConsentSource value accepted without validation against enum.
  • Impact: Invalid consent source strings persist in database.
  • Test: Submit consent with invalid source value; verify rejection.

12. Stripe / Payment Edge Cases​

12.1 Minimum Amount Validation Missing Stripe's $0.50 Floor​

  • File: server/src/services/StripeCheckoutService.ts:63-64
  • Description: Amount validation checks for positive integers but doesn't enforce Stripe's minimum charge amount ($0.50 USD). Orders with tiny amounts (e.g., $0.01) will fail at the Stripe API with an opaque error.
  • Impact: Checkout fails with unhelpful error for small orders.
  • Test: Submit checkout with $0.01 subtotal; verify user-friendly error about minimum amount.

12.2 Platform Fee Rounds to $0 for Small Orders​

  • File: server/src/services/StripeCheckoutService.ts:67-69
  • Description: Math.floor((amountCents * feeBasisPoints) / 10000) rounds down. For small orders, platform fee can be $0. No validation that fee doesn't exceed order amount. No cap on fee percentage.
  • Impact: Revenue loss on small orders. Misconfigured fee percentage (>100%) causes Stripe rejection.
  • Test: Create $1.00 order with 10% fee; verify fee is 10 cents, not $0. Try 150% fee; verify rejection.
  • File: server/src/services/StripeConnectService.ts:121-124
  • Description: Account links expire after 24 hours. No client-side expiry warning, no server-side refresh mechanism. If a user bookmarks the link or returns the next day, they see a Stripe error page.
  • Impact: Poor UX for Stripe Connect onboarding; users may abandon setup.
  • Test: Generate onboarding link, wait >24 hours, attempt to use link; verify error handling.

12.4 Stripe Account Deletion Doesn't Check Liabilities​

  • File: server/src/services/StripeConnectService.ts:216-246
  • Description: deleteConnectedAccount() deletes from Stripe then clears database. No check for active payouts, disputes, or non-zero balance. Stripe may reject deletion.
  • Impact: Partial deletion leaves orphaned account in Stripe. Account funds may be trapped.
  • Test: Attempt to delete account with pending payout or dispute; verify error handling.

12.5 Webhook Processing Failures Not Retried​

  • File: server/src/routes/webhookRoutes.ts:160-174
  • Description: Failed webhook events are logged but not retried or dead-lettered. Returns 500, causing Stripe to retry and potentially duplicate-process. No alert to ops about persistent failures.
  • Impact: Failed payments may be double-processed on Stripe retry. No monitoring of webhook health.
  • Test: Simulate handler error during webhook; verify second attempt doesn't duplicate work.

12.6 Payment Intent Idempotency Key Issue​

  • File: server/src/services/StripeCheckoutService.ts:88-90
  • Description: Idempotency key uses orderId, not cartId. If an order is deleted and recreated with the same ID, Stripe returns the old PaymentIntent.
  • Impact: Cart retry logic can attach to wrong previous PaymentIntent.
  • Test: Create order, delete it, recreate with same ID; verify new PaymentIntent is created.

13. Email / Notification Edge Cases​

13.1 No Production Guard for Missing RESEND_API_KEY​

  • File: server/src/services/ResendEmailService.ts:27-30
  • Description: If RESEND_API_KEY is not set, the service logs a warning but doesn't prevent startup. All email sends silently fail in production if the env var is missing.
  • Impact: Users never receive verification codes, password resets, or booking confirmations.
  • Test: Run server without RESEND_API_KEY; verify app either refuses to start or gracefully degrades with clear error messages.

14. Image Upload Edge Cases​

14.1 No File Size Limits for Cloudflare Uploads​

  • File: server/src/services/cloudflareImageService.ts:125-226
  • Description: uploadBase64Image() and uploadBuffer() don't validate image file size or MIME type. No limit on base64 string length. Cloudflare Images has a 10MB limit, but the server doesn't enforce it before sending.
  • Impact: Users can attempt to upload very large images, causing OOM on server, slow/stalled requests, and unhelpful errors. Potential DoS vector.
  • Test: Upload base64 image >10MB; verify helpful error message before it reaches Cloudflare.

Testing Recommendations​

Priority 1 — Security​

  1. Authorization bypass attempts on all resolver queries/mutations
  2. Webhook signature validation in production mode
  3. Unauthenticated access to calculateSmsSegments query

Priority 2 — Financial Accuracy​

  1. Multi-segment SMS cost calculation accuracy
  2. Coupon over-redemption with concurrent checkout requests
  3. International SMS billing vs actual Twilio rates
  4. Negative and zero values in all pricing fields
  5. Stripe minimum amount enforcement ($0.50 floor)
  6. Platform fee calculation for small orders (rounding to $0)
  7. Payment Intent idempotency with reused order IDs

Priority 3 — Data Integrity​

  1. Concurrent inventory operations (create, share, unshare)
  2. Cascade deletes on conversations with messages
  3. Webhook failure retry and duplicate-processing prevention

Priority 4 — User Experience​

  1. File upload failures with user feedback
  2. Navigation between v1 and v2 routes (session preservation)
  3. Mobile responsive testing on all v2 pages
  4. Keyboard-only navigation audit
  5. Stripe Connect onboarding with expired account links
  6. Email delivery when RESEND_API_KEY is missing

Priority 5 — Reliability​

  1. Server restart during active operations (trial expiry, sandbox limits)
  2. Webhook idempotency under concurrent Twilio callbacks
  3. Error boundary coverage for large v2 pages
  4. Image upload size limits (>10MB files)