Known limitations
Source of truth for this page: static audit report.md (dated 2026-11-02; cleanup pass notes from 2026-11-03). Do not treat this as a live bug tracker — re-verify against code before relying on severity. The audit did not cover full test/CI runs, production env/webhook verification, SSE load tests, or deep XSS/CSRF.
Payments & inventory (high)
| Issue | Where | Behavior |
|---|---|---|
| Paid Razorpay orders without stock | ecommerce/checkout_orders.py (backend-main/ecommerce/checkout_orders.py) _create_order_from_pending / _decrement_snapshot_stock | After payment, stock decrement failures are swallowed. Order is still PAYMENT_STATUS_VERIFIED; system comment notes stock could not be reserved. Customer charged; inventory wrong. |
| No stock hold for open Razorpay checkouts | EcommerceCheckoutView + start_razorpay_checkout | COD decrements in the same atomic request. Razorpay only creates PendingRazorpayCheckout + Razorpay order; stock touched on completion. Two buyers can pay for the last unit; one/both hit the “stock missing but order created” path. |
| Custom / design ecommerce lines skip stock | ecommerce/views.py (backend-main/ecommerce/views.py) EcommerceCheckoutView | For is_custom: quantity hardcoded to 1 (client qty ignored); no get_product_stock check; not added to stock_items. Blank/customizable SKUs can be oversold. |
| POS orders never decrement warehouse stock | pos/serializers.py (backend-main/pos/serializers.py) POSOrderCreateSerializer.create | Creates POSOrder / items but never updates WarehouseStock. Catalog requires stock to show products; selling does not reduce it → ecommerce vs POS inventory diverge unless adjusted elsewhere. |
| Client-controlled POS unit prices | POSOrderCreateSerializer / _create_pos_order_product_item | unit_price from client trusted (item_data.get('unit_price') or product.default_price); same for service charges. Valid POS access_key can submit arbitrary prices (may be intentional for discounts; no server catalog price lock). |
Suggested directions in the audit (not implemented by this doc): fail closed / refund on stock miss; reserve or soft-hold at Razorpay start with expiry; explicit custom-SKU stock policy; decrement or allocate on POS create; harden POS pricing rules.
Security (from audit)
| Severity | Issue | Where |
|---|---|---|
| High | POS passwords hashed with unsalted SHA-256 | pos/views.py (backend-main/pos/views.py), pos/serializers.py (backend-main/pos/serializers.py) — ecommerce customers use Django hashers; POS does not |
| High (if shared machine) | Deploy / SSH keys on disk next to source | nova-print-deploy.pem, nova-print-github (+ .pub); gitignored but risky for backups/scans |
| High (misconfigured prod) | DEBUG defaults True; SECRET_KEY falls back to insecure string | config/settings.py (backend-main/config/settings.py) |
| Medium | JWT refresh rotation without blacklist | ROTATE_REFRESH_TOKENS=True, BLACKLIST_AFTER_ROTATION=False; token_blacklist not enabled |
| Medium | POS access keys in SSE query strings | Frontend POS / checkout SSE hooks (?access_key=…) |
| Low–Medium | Ecommerce forgot-password user enumeration | EcommerceForgotPasswordView returns 404 / USER_NOT_FOUND_MESSAGE when email missing |
| Controlled | SQL editor powerful despite guards | Superuser-only; blocks DDL/multi-statement; still allows UPDATE/DELETE; keyword filters ≠ full SQL parser |
Other logic smells
| Severity | Issue |
|---|---|
| Medium | COD stock pre-check unlocked (get_product_stock) then later select_for_update in allocate_and_decrement_stock — TOCTOU under concurrency |
| Medium | PendingRazorpayCheckout has no expiry / cleanup job; abandoned intents accumulate; no auto-cancel of unpaid Razorpay orders |
| Medium | Custom checkout quantity forced to 1 while cart/UI can show other quantities |
| Low | Broad except Exception: pass on SSE fan-out (pos/workflows.py _notify_customer_link_workflow_change) |
| Low | Leftover console.log in SSE / auth refresh paths |
| Info | Track-order public with order_id + email — acceptable if IDs hard to guess |
Cleanup already done (2026-11-03)
Per report §5: dead Gemini checkout integration removed; nested empty frontend-pos/frontend-pos/ deleted; stale admin integration markdown removed; AGENTS.md updated for frontend-ecommerce/; root node_modules removed and gitignored. Blueprint/plan docs kept as historical archives. Payment / stock / auth issues above were explicitly left unchanged by that cleanup.
Audit priority order (still open)
- Fail closed (or refund/hold) when Razorpay fulfillment cannot reserve stock
- Reserve/soft-hold stock at Razorpay start; expire abandoned pendings
- Decide custom SKU stock policy and align UI
- Align POS with warehouse decrement/allocate
- Replace POS SHA-256 with Django password hashers (migrate carefully)
- Force
DEBUG=False+ realSECRET_KEYin prod; enable refresh blacklist if rotating - Move deploy keys out of the project folder; rotate if needed