Files
projectmycelium/docs/dev/design/archive/marketplace-todo.md
2025-09-01 21:37:01 -04:00

55 KiB
Raw Permalink Blame History

Project Mycelium - Comprehensive TODO List

Last Updated: 2025-08-15 12:41
Priority System: 🔥 Critical | High | 📋 Medium | 💡 Enhancement


Service Requests & Bookings: Persistence, Sync, and UI — IN PROGRESS 2025-08-14

  • Context: Provider-side status changes not reflecting on buyer bookings; inconsistent API envelopes; UI rows disappearing after updates.
  • Implemented:
    • Provider lookup fallback in OrderService::find_service_provider() to fixtures/global catalog (ensures correct provider email resolution).
    • Integration test for instant purchase persistence verifying service_requests (provider) and service_bookings (buyer).
    • Test robustness: relaxed SLA assertions (assert ≥1 and presence by ID) to match current fixture data.
    • Atomic JSON saves and structured logging in UserPersistence::save_user_data(); logging added around add/save for requests/bookings.
  • Backend TODO:
    • Sync provider service_requests status/progress to buyer service_bookings by request.id on update (set completed_date when Completed).
    • Complete UserPersistence::update_service_request_progress() to persist hours/notes and update priority; add logs and error bubbling.
    • Normalize update endpoints in src/controllers/dashboard.rs to return consistent ResponseBuilder envelopes:
      • Success: include { updated_request, total_requests } for provider; consider returning updated booking on buyer flows.
      • Decline+remove: return { removed: true } with 200.
    • Bubble persistence errors; avoid any fallback to mocks in update paths.
  • Frontend TODO:
    • Always unwrap API payloads: const data = result.data || result; and guard null/undefined.
    • After status change, re-render/migrate rows between tabs (Pending → In Progress → Completed) instead of removing.
    • Improve booking details in dashboard-user.js: provider, product, status, and progress timeline.
    • Add error handling and structured logging around update flows.
  • Testing & Observability:
    • API contract tests for update endpoints (field names/envelopes) and tab migration logic.
    • E2E verifying provider update reflects on buyer bookings within same session.
    • Structured logs: include path, emails, IDs, counts; grepable tags user_persistence, dashboard_controller.
  • Acceptance:
    • Provider accepts/updates a request; buyer sees synchronized status in My Service Bookings without reload; rows migrate tabs correctly; no console errors.

Progress Update — 2025-08-14 13:35

  • Removed inline mock client_requests arrays in src/models/user.rs (replaced with Vec::new()) to align with persistentdataonly policy and fix compile errors caused by new fields.
  • Confirmed ServiceRequest now includes hours_worked: Option<f64> and notes: Option<String> with #[serde(default)] to preserve backward compatibility.
  • Order path: src/services/order.rs constructs ServiceRequest with these fields set to None, persists provider request via UserPersistence::add_user_service_request, and creates buyer booking via create_service_booking_from_request.
  • Controllers: DashboardController::update_service_request and ...::update_service_request_progress normalize responses via ResponseBuilder, reload the updated request, and synchronize buyer service_bookings with provider service_requests; added structured logging and error bubbling.
  • Persistence: UserPersistence persists hours_worked, notes, and sets completed_date when status is Completed or progress ≥ 100.
  • Build status: cargo check passes; only warnings remain (unrelated to this flow).

Next:

  • Remove remaining inline mocks (e.g., revenue_history) and wire reads to persistent storage.
  • Ensure prod runs with APP_ENABLE_MOCKS=0; verify update paths have zero mock fallbacks.

Progress Update — 2025-08-15 10:30

  • Dashboard Overview: Fixed Tera render by mapping activities to date/action/status/details in src/controllers/dashboard.rs (context now matches src/views/dashboard/index.html). No template changes; persistent-only.
  • App Provider Dashboard: Removed legacy monthly_revenue fallbacks and sessionStorage merges; now using persistent *_usd fields only. Treated "Running" as "Active". Exposed window.__appProviderDashboard for modal helpers. GET /api/dashboard/deployment/{id} returns proper JSON via ResponseBuilder. json_to_app reads monthly_revenue_usd with fallback.
  • Verification: UI/API tested under APP_ENABLE_MOCKS=0; frontend unwrap pattern enforced (const data = result.data || result;).

Progress Update — 2025-08-15 12:41

  • Mock Gating: src/controllers/gitea_auth.rs now attaches MockUserData::new_user() only when APP_ENABLE_MOCKS is enabled via get_app_config().enable_mock_data(). Prevents mock data in production OAuth callback.
  • Status Normalization: Updated deployment status terminology to “Active”:
    • src/services/slice_calculator.rs comment now lists "Provisioning", "Active", "Stopped", "Failed".
    • Recent related: src/models/user.rs mock DeploymentStat sample changed from "Running" → "Active"; src/static/js/demo-workflow.js now emits "Active" in simulated deployment events.
  • Build: cargo check passing (warnings only).

Next:

  • Gate any remaining unconditional mock usage behind APP_ENABLE_MOCKS (e.g., src/controllers/dashboard.rs).
  • Normalize any remaining "Running" → "Active" across:
    • Rust: src/models/builders.rs (DeploymentStatBuilder default), other comments/docs.
    • Frontend: src/static/js/marketplace-integration.js, src/static/js/dashboard-user.js.
    • Templates: status badge renderers.
  • Run cargo test; fix any failures from normalization.
  • Manual UI verification with APP_ENABLE_MOCKS=0 (dashboards and flows use only persisted data).

User Data Loading & Scan Hardening — COMPLETED 2025-08-14

What changed

  • Hardened all user_data/ directory scans to only process real per-user JSON files, preventing serde errors from non-user fixtures (carts, sessions, aggregated files).

Filtering criteria

  • Filename ends with .json
  • Contains _at_ (email encoding)
  • Does not contain _cart
  • Not equal to session_data.json

Affected files

  • src/services/node_marketplace.rsget_all_marketplace_nodes(), get_all_slice_combinations()
  • src/services/node_rental.rsfind_node_owner()
  • src/services/order.rsfind_app_provider(), find_service_provider()
  • src/controllers/dashboard.rs → cross-user deployment counting
  • src/utils/data_cleanup.rsDataCleanup::cleanup_all_users()
  • src/utils/data_validator.rsDataValidator::validate_all_user_files()
  • Confirmed src/services/user_persistence.rs aggregators already filter accordingly.

Outcome

  • Non-user fixture files are ignored; no more deserialization crashes from broad scans.
  • Persistence-only architecture enforced in prod mode (APP_ENABLE_MOCKS=0).
  • cargo check passed post-changes.

Follow-ups

  • Add unit tests for scan helpers and a regression test covering session_data.json and cart files.
  • Audit future contributions to ensure new scans reuse the strict filter.

Roadmap to Final Marketplace (2025-08-10)

Phases are incremental and shippable; each has crisp acceptance criteria.

Phase 0: Polish fixtures/dev mode (nowshort)

  • Catalog dev cache: Optional generated user_data/catalog.products.json from aggregator; documented as generated-only.
  • Acceptance: cold-start marketplace loads ≥300 ms faster locally; cache invalidation documented.
  • Mock cleanup: Ensure prod path never touches mock data/services; annotate remaining dev-only templates (e.g., mock timeline) and gate behind config.
  • Acceptance: production run with APP_ENABLE_MOCKS=0 has zero mock reads/writes.
  • Tests:
  • Invoices: ownership checks, 403/404, print view loads.
  • Cart badge/events: add/remove/clear flows consistent after reload.
  • Marketplace dashboard loads with mocks disabled (HTTP 200).
  • Rental endpoints return 404 when mocks are disabled and resource is missing.
  • Acceptance: tests green in CI; fixtures-run smoke passes.

Quick .env for Phase 0 (fixtures/dev):

APP_DATA_SOURCE=fixtures
APP_FIXTURES_PATH=./user_data
APP_ENABLE_MOCKS=0
APP_CATALOG_CACHE=true
APP_CATALOG_CACHE_TTL_SECS=5

CSP-Compliant Frontend with JSON Hydration — COMPLETED 2025-08-11

What changed

  • Externalized scripts: All base/page scripts move to src/static/js/ (e.g., base.js, wallet.js, statistics.js). src/views/base.html exposes {% block scripts %} for page-specific includes only.
  • JSON hydration: Pages now pass data via <script type="application/json" id="..."> blocks. JS parses this block to initialize page behavior.
  • Wallet hydration fix: src/views/wallet/index.html hydration now uses json_encode and named-arg default to produce valid JSON under CSP:
    <script type="application/json" id="wallet-hydration">
      {"currency_symbol": {{ currency_symbol | default(value='$') | json_encode() }}}
    </script>
    
  • Startup diagnostics: src/main.rs now prints Tera template init errors (Tera initialization error: ...) before exit. This revealed the hydration parsing issue and prevents silent exits.

Benefits

  • Security: Strict CSP (no inline scripts/handlers) reduces XSS risk.
  • Maintainability: Clean separation of HTML structure, JSON data, and JS behavior.
  • Performance: External JS is cacheable; smaller HTML payloads.
  • Testability: Deterministic hydration JSON is easy to mock in tests.
  • Consistency: One binding pattern via DOMContentLoaded, IDs/data-attributes; no scattered inline handlers.

Affected files

  • src/static/js/base.js, src/static/js/wallet.js, src/static/js/statistics.js, src/static/js/checkout.js, src/static/js/services.js
  • src/views/base.html, src/views/wallet/index.html, src/views/marketplace/checkout.html, src/views/marketplace/services.html
  • src/main.rs

Next steps to complete externalization

  • Phase 1: Cart + Checkout
    • Externalize inline handlers in src/views/marketplace/cart.html, cart_full.html, checkout.html (e.g., edit/remove/save/share, processPayment) to src/static/js/cart.js and checkout.js.
    • Add hydration blocks for totals, currency labels, and endpoint URLs.
  • Phase 2: Orders + Services
    • orders.html (exportOrders, clearAllFilters) → orders.js with hydration.
    • services.html Completed 2025-08-11 → externalized to src/static/js/services.js with CSP-safe hydration (#services-data) and stable grid id (#services-grid).
  • Phase 3: Dashboard pages
    • dashboard/cart.html (qty +/-/remove/save/share), dashboard/orders.html (viewOrderDetails/viewInvoice/contactSupport), dashboard/pools.html (handle* actions), dashboard/user.html, dashboard/farmer.html, dashboard/service_provider.html.
  • Phase 4: Print utilities
    • Replace inline onclick="window.print()" in order_invoice.html, service_request_report.html, service_request_invoice.html with a shared print-utils.js and [data-action="print"] binding.
  • Global hygiene
    • Audit all hydration blocks to use json_encode and provide {} where no data needed.
    • Add a template lint/test to fail CI on inline on*= attributes and verify hydration JSON parses.

Services Page Externalization — COMPLETED 2025-08-11

What changed

  • Removed inline JS and handlers from src/views/marketplace/services.html.
  • Added CSP-safe hydration: <script type="application/json" id="services-data">{}</script>.
  • Stabilized DOM hooks: added id="services-grid" to the services container.
  • Created external script: src/static/js/services.js which:
    • Binds .add-to-cart-btn click events without inline attributes.
    • Shows an authentication modal when 401 or auth-required responses occur.
    • Listens for serviceCreated events to refresh displayed services.
    • Loads services from API with session fallback and renders cards with no inline handlers.
    • Uses globals from base.js when available (updateCartCount, emitCartUpdated).

Affected files

  • src/views/marketplace/services.html
  • src/static/js/services.js

Outcome

  • Services page is CSP-compliant: zero inline scripts/handlers, deterministic hydration, external JS only.

CSP Externalization COMPLETE — 2025-08-12

🎉 ACHIEVEMENT: The entire Project Mycelium is now 100% CSP-compliant with zero inline handlers across all templates.

Dashboard: Service Provider CSP Externalization — COMPLETED

  • Availability UI wiring moved to delegation in src/static/js/dashboard-service-provider.js:
    • data-action="availability.toggle"toggleAvailability() (no API write; user feedback only).
    • data-action="availability.update"updateAvailability() performs PUT /api/dashboard/availability with validation and notifications.
  • Initialization on load: loadAvailabilitySettings() runs on DOMContentLoaded to hydrate checkbox and hours safely.
  • Service creation flow centralized:
    • data-action="services.create" bound to createNewService() which opens modal, validates, calls API, and refreshes UI.
  • Save changes button externalized: [data-action="services.saveChanges"] is handled via delegation and calls existing saveServiceChanges() (no inline JS).
  • Hydration present: CSP-safe JSON block #sp-dashboard-hydration included in template and consumed on init.
  • Tera parse error fixed: moved page styles to top-level {% block head %} and hydration/external scripts to top-level {% block scripts %}; dashboard_content now contains only markup/modals.
  • Build status: cargo check/build passing as of 2025-08-12; Dashboard controller ResponseBuilder return patterns fixed.

Final CSP Cleanup — COMPLETED 2025-08-12

  • src/views/cart.html — Converted editCartItem() & removeCartItem() to data-action="cart.edit" & data-action="cart.remove"
  • src/views/dashboard/user.html — Converted viewBookingDetails() & contactProvider() to data-action="booking.view" & data-action="provider.contact"
  • src/views/dashboard/farmer.html — Converted 6 inline handlers to data-action patterns:
    • refreshSliceCalculations()data-action="slice.refresh"
    • syncWithGrid()data-action="grid.sync"
    • viewNodeSlices()data-action="node.view"
    • setMaintenanceMode()data-action="node.maintenance"
    • restartNode()data-action="node.restart"

CSP Verification Results — 2025-08-12

  • Zero inline handlers found across all templates (confirmed via comprehensive audit)
  • All external JS files exist and properly structured

Phase 1: Unified insufficient balance contract

  • Backend: Standardize on 402 Payment Required and canonical ResponseBuilder error payload across src/controllers/order.rs, src/services/order.rs, src/services/instant_purchase.rs and wallet-related controllers.
  • Frontend: One renderer consumes error.details ("Insufficient balance. Need $X more.").
  • Acceptance: Each major purchase flow has one insufficient-funds behavior; e2e verified.
  • Reference: See section below "🔥 Critical: Insufficient Balance Unified Error Contract" for JSON envelope and acceptance details.

Phase 2: Orders API enrichment — COMPLETED 2025-08-13

  • Add invoice_available and invoice_url in /api/orders and /api/orders/{id}.
  • UI enables/disables invoice CTAs from payload.
  • Acceptance: No dead CTAs; invoices open consistently from both list and detail.

Phase 3: Provider and catalog readiness

  • Minimal “publishing status” on products (draft/published) respected by aggregator (fixtures treat all as published).
  • Featured curation source-of-truth file (config JSON) for Featured Items, decoupled from categories.
  • Acceptance: Only published items appear; Featured fully driven by config.

Phase 4: Search, filters, and category UX

  • Add keyword search and common filters (category, price range, availability).
  • Acceptance: Search/filters consistent across overview and category pages; no duplicates with Featured on overview.

Phase 5: Database migration (PostgreSQL + PostgREST)

  • Implement schema and public_products view with RLS as per blueprint in the guide.
  • Wire ProductService reads to PostgREST in “db mode”; keep fixtures mode intact for demos.
  • Migration scripts + seed path for demo data.
  • Acceptance: App runs in db mode with same UX; fixtures mode remains supported for demos.

Phase 6: Payments and wallet top-up

  • Stripe integration to purchase TFC credits; lock rates at checkout; record payment method.
  • Commission logic applied to marketplace orders.
  • Acceptance: Successful top-up flows; orders complete with correct balances and auditable records.

Phase 7: Security and reliability

  • CSRF, rate limiting, session hardening; structured logging where appropriate; metrics & health endpoints.
  • Acceptance: Security checklist green; basic SLOs monitored.

Phase 8: Launch readiness

  • CI/CD, load testing, PWA/performance polish, accessibility, documentation/runbooks.
  • Acceptance: Go-live checklist complete; rollback plan defined.

🔥 CRITICAL PRIORITIES (Immediate - Next 1-2 weeks)

1. Currency System Enhancement COMPLETE

Summary: Multi-currency display with USD settlement; fixed duplicate USD, added TFC & CAD support, EUR already supported.

  • UI Fix: Removed duplicate USD and added TFC in dashboard settings dropdown.
    • File: src/views/dashboard/settings.html
  • Backend Support: Added TFC and CAD to supported currencies; USD remains base/default, EUR and TFT already present.
    • File: src/services/currency.rs::CurrencyService::get_supported_currencies()
    • TFC: Custom("credits"), exchange_rate_to_base 1.0, decimals 2
    • CAD: Fiat, placeholder exchange_rate_to_base 1.35, decimals 2
    • EUR: already present
  • Controller Compatibility: Preference endpoint validates/accepts new currencies.
  • Design Decision: Display prices in user-selected currency (USD/TFC/CAD/EUR/…); settle payments in USD (Stripe) later.
  • Store canonical base_usd_amount and also persist display_currency, display_amount, rate_used, timestamp at checkout.
  • Dashboard overview wallet: label and amount now dynamic via navbar dropdown API (/api/navbar/dropdown-data).
    • JS updates #dashboardWalletBalance and #dashboardCurrencyCode with wallet_balance_formatted and display_currency using const data = result.data || result;.
    • File: src/views/dashboard/index.html
  • Consistency verified across Navbar, Wallet, Orders, Cart pages; all use server-formatted currency strings and preferred currency code.

Follow-ups (optional):

  • Render dropdown options dynamically from /api/currency/supported to avoid drift between UI and backend.
  • Implement rate locking at checkout and show “final charge in USD; conversions approximate.”

2. Authentication Flow UX Improvements COMPLETE

Issue: Buy-now button when logged out should provide clearer guidance

  • Root Cause: Generic message and redirect to /register instead of /dashboard
  • Solution Implemented:
    • Updated Message: Changed to "Please log in or register to make purchases. Would you like to go to the dashboard to continue?"
    • Improved Redirect: Now redirects to /dashboard where users can both log in or register
    • Better UX: Clear call-to-action with appropriate destination
  • Technical Details:
    • Modified showAuthRequired() method in BuyNowManager class (fallback confirm dialog)
    • Updated showAuthRequired() method in ModalSystem class (primary modal system)
    • Redirect destination changed from /register to /dashboard in both implementations
    • Message content updated for clarity and inclusiveness
    • Button text changed from "Go to Registration" to "Go to Dashboard"
  • Files Modified:
    • src/static/js/buy-now.js - Enhanced fallback authentication flow messaging
    • src/static/js/modal-system.js - Enhanced modal system authentication flow

3. Order Management Integration COMPLETE

Issue: Items added to cart or purchased via buy-now are not appearing in orders

  • Root Cause: Frontend JavaScript accessing wrong API response structure due to ResponseBuilder wrapping
  • Architectural Decision: User-Centric Data Storage Pattern
    • Orders are stored as part of user's persistent data (UserPersistence) rather than separate OrderStorage
    • This creates a localized source of truth where each user owns their complete data set
    • Follows industry standards for user-centric data management and GDPR compliance
    • Enables easier data portability and user account management
  • Solution Implemented:
    • Backend: Orders correctly saved via UserPersistence::save_user_data() in instant purchase flow
    • API Layer: ResponseBuilder automatically wraps responses in {"data": {...}, "success": true} structure
    • Frontend Fix: Updated JavaScript to access data.data.orders instead of data.orders
    • UX Enhancement: Added order sorting by creation date (latest first)
  • Technical Implementation:
    • instant_purchase.rs: Orders pushed to persistent_data.orders vector
    • order.rs: get_user_orders() reads from UserPersistence, sorts by created_at DESC
    • orders.html: Frontend handles nested ResponseBuilder JSON structure
    • Data Flow: Purchase → UserPersistence → API → ResponseBuilder → Frontend
  • Files Modified:
    • src/views/dashboard/orders.html - Fixed JavaScript data access pattern
    • src/services/order.rs - Added descending order sorting by creation date

Implemented Service-Provider → Marketplace → Consumer Flow — COMPLETED 2025-08-12

  • Creation (Provider)

    • Service/App creation via dashboard APIs:
      • Services: POST /api/dashboard/services, PUT /api/dashboard/services/{id}, DELETE /api/dashboard/services/{id}
      • Apps: POST /api/dashboard/apps, PUT /api/dashboard/apps/{id}, DELETE /api/dashboard/apps/{id}
      • Generic products: GET/POST /api/dashboard/products
    • Data persists in user_data/{email}.json under products.
  • Aggregation (Marketplace)

    • projectmycelium/src/services/product.rs::ProductService::get_all_products() aggregates fixtures + user products (+ optional slice products) and applies category normalization via canonical_category_id.
    • Dev cache: optional TTL cache controlled by APP_CATALOG_CACHE and APP_CATALOG_CACHE_TTL_SECS.
  • Visibility (Marketplace → Consumer)

    • src/controllers/marketplace.rs::services() filters products where category_id is service or application, converts prices to the user's currency, and injects service_products into the template.
    • src/views/marketplace/services.html renders service_products expecting objects of the form { product, price, formatted_price }.
  • Purchase Flows

    • Add to cart: POST /api/cart/addOrderController::add_to_cart.
    • Buy now: src/static/js/buy-now.js calls
      • Affordability: GET /api/wallet/check-affordability?amount=<Decimal> → returns { can_afford: bool, shortfall_info?: {...} } in ResponseBuilder envelope.
      • Instant purchase: POST /api/wallet/instant-purchase with InstantPurchaseRequest → creates order and persists via UserPersistence.
    • Related wallet endpoints: GET /api/wallet/balance, GET /api/wallet/transactions, POST /api/wallet/quick-topup.
  • Frontend Integration

    • Response pattern: APIs return a ResponseBuilder envelope { success, data }; frontend unwraps with const data = result.data || result;.
    • CSP-compliant hydration: pages pass JSON via <script type="application/json" id="..."> blocks; all JS external (e.g., src/static/js/services.js, buy-now.js, dashboard_cart.js).
  • Generalization

    • App providers follow the same flow. Canonical category application is normalized and displayed on /marketplace/applications with equivalent filtering, pricing, and purchase behavior.

Dashboard TODOs (Consolidated — 2025-08-15)

  • Deprecation: docs/dev/design/current/marketplace-todo-dashboard.md is deprecated; update this file instead.
  • Open items:
    • /dashboard/user — My Services (Purchased): implement GET /api/dashboard/user/services/purchased?product_type=service|app|bundle|any, render in src/views/dashboard/user.html. Acceptance: items/empty state; currency formatting; no console errors.
    • /dashboard/service-provider — Service Requests: implement GET /api/dashboard/service-provider/requests?product_type=service|app|bundle|any, render in src/views/dashboard/service_provider.html. Acceptance: list/empty state; no console errors.
    • /dashboard/farmer: guard 404s from /api/dashboard/slice-statistics and handle non-JSON; fix averageDiscount ReferenceError; guard undefined .length; avoid duplicate listeners with init guard.
    • /dashboard/app-provider: avoid duplicate dashboard-app-provider.js inclusion to prevent "Identifier 'AppProviderDashboard' has already been declared".
    • Cross-product Types Extension: support product_type param across dashboards; reuse ProductService::get_all_products() normalization.
  • Manual testing (brief):
    • Start server and open relevant dashboards.
    • Verify creation, persistence, and marketplace visibility for a new app/service.
    • Check ResponseBuilder unwrap usage: const data = result.data || result;.
    • Confirm invoice CTAs honor invoice_available and use invoice_url.
    • Watch console/network for 404s and JSON parse errors; fix guards.

🚨 New User-Reported TODOs (2025-08-07)

  • Service Provider: Creating a new service causes modal flicker — FIXED 2025-08-12 (root-cause; fade preserved). Background hover transitions on cards/rows/items caused repaints during modal fade. Tightened transitions; suppressed hover transitions under body.modal-open; restored .modal.fade; added GPU hints to modal buttons. Files: src/static/css/styles.css, src/views/dashboard/service_provider.html.
  • SLA: New SLA is saved under user_data/ but does not appear in the list. Ensure frontend fetches from persistent API (/api/dashboard/slas) and unwraps ResponseBuilder via const data = result.data || result;. Refresh list after create/save/delete. Confirm mocks disabled for SLA in config. Files: src/static/js/dashboard-service-provider.js, src/controllers/dashboard.rs.
  • Persistent data only: audit and remove any remaining mock/fixture/stub data from runtime paths. Search src/ for "mock", "fixture", "stub". Verify all reads/writes go through user_data/ and UserPersistence.
  • Service Provider Dashboard: remove all user.mock_data references and align JS/template with persistent service_provider_data using *_usd fields. COMPLETED 2025-08-15
  • App Provider Dashboard: remove any user.mock_data references; inject and bind persistent app_provider_data with *_usd fields; update dashboard-app-provider.js accordingly. COMPLETED 2025-08-15
  • User Dashboard: ensure template/JS use only persistent user_dashboard_data; remove mock fallbacks and align currency fields.
  • Navbar cart counter not updating after delete: ensure delete-from-cart updates count. Implemented event-driven update and fresh fetch with cache: 'no-store'. FIXED 2025-08-08
  • Proceed-to-cart shows "Insufficient USD credits. Need $0.00 more." even with sufficient wallet: audit wallet check in cart flow for ResponseBuilder wrapping and TFC vs USD logic; fix Decimal math and messaging.
  • Add to cart should not check wallet funds: remove funds check on add-to-cart; enforce funds check only at checkout. Align with buy-now logic which already deducts correctly and creates orders.
  • Orders: "Download invoice" not working: Implemented marketplace order invoice HTML view and UI wiring. FIXED 2025-08-09
  • Orders page: remove "Reorder" option from src/views/dashboard/orders.html. FIXED 2025-08-08
  • Orders page: "Contact support" link uses ThreeFold support URL consistently. FIXED 2025-08-08

Note: Add tests for the above, and ensure all frontend API parsing uses const data = result.data || result;.

🧩 New Findings & TODOs (2025-08-09)

🔥 Critical: Marketplace Order Invoices COMPLETED 2025-08-09

  • Backend: Implemented GET /orders/{id}/invoice → HTML view (Tera) for print in browser.
    • Deliberately not implemented now: direct download API (/api/orders/{id}/invoice).
      • Rationale: "View Invoice" + browser Print → Save as PDF is sufficient for current UX; avoids extra complexity and PDF/file generation. No immediate need for programmatic downloads. Can be added later if integrations require it.
  • Controller: Implemented OrderController::get_order_invoice in src/controllers/order.rs with:
    • Ownership check using session["user_email"] when available.
    • Dual-source lookup: try in-memory OrderStorage; if not found, fallback to UserPersistence (email-based). Fixes buy-now invoices not found.
  • Template: Created src/views/marketplace/order_invoice.html (order id, date, items, qty, unit price, line totals, subtotal/total, payment method, billing email, print button).
  • Frontend: Wired src/views/dashboard/orders.html to open /orders/{id}/invoice in a new tab.
    • CTA text updated to "View Invoice" with eye icon.
    • JS handlers renamed: downloadInvoiceviewInvoice, downloadInvoiceFromModalviewInvoiceFromModal.
  • API enrichment (optional): add invoice_available and invoice_url in /api/orders and /api/orders/{id}.
  • Acceptance: Invoice view renders for owned orders; 404 if not found; 403 if access denied. Achieved for HTML view.
  • Behavior: "Popular Applications" excludes any products already shown in "Featured Items" on /marketplace.
  • Implementation: src/controllers/marketplace.rs builds a set of featured product IDs and filters the popular applications list before price conversion/render.
  • Rationale: Avoid duplicate cards on the overview while keeping "Featured" as a curated, source-agnostic section.
  • Acceptance: WireGuard VPN (featured) no longer appears again under Popular; verified in fixtures and mock modes.

Marketplace Dashboard 500 Fix (Tera parsing + test setup) — COMPLETED 2025-08-10

  • Issue: Dashboard returned HTTP 500 when mocks were disabled due to a Tera parsing error and missing Tera initialization in tests.
  • Root Causes:
    • Tera condition syntax: parenthesized filter expressions like (collection | length) > 0 cause a parse error. Correct form is collection | length > 0 without parentheses.
    • Tests not registering custom Tera functions, so templates failed in the test environment.
  • Fixes:
    • Template: Updated src/views/marketplace/dashboard.html to remove parentheses around | length checks and guard nested field access.
    • Tests: Initialized Tera and registered custom functions in tests/mock_gating.rs before configuring routes.
  • Tests Added:
    • test_marketplace_dashboard_loads_with_mocks_disabled → expects HTTP 200
    • test_rent_product_returns_404_when_mocks_disabled → expects HTTP 404
  • Test Setup Pattern (Actix + Tera):
    use actix_web::{App, test, web};
    use tera::Tera;
    use threefold_marketplace::utils; // register_tera_functions
    
    #[actix_web::test]
    async fn test_marketplace_dashboard_loads_with_mocks_disabled() {
        let mut tera = Tera::new("src/views/**/*.html").expect("init tera");
        utils::register_tera_functions(&mut tera);
    
        let app = test::init_service(
            App::new()
                .app_data(web::Data::new(tera))
                .configure(threefold_marketplace::routes::configure_routes),
        ).await;
    
        let req = test::TestRequest::get().uri("/marketplace").to_request();
        let resp = test::call_service(&app, req).await;
        assert!(resp.status().is_success());
    }
    
    Notes:
    • Mirror production Tera setup in tests (template glob + custom functions).
    • Avoid parentheses around filter expressions in Tera conditions.

Category ID Normalization (Fixtures) — COMPLETED 2025-08-10

  • Implementation: src/services/product.rs::ProductService normalizes plural/alias category IDs to canonical singulars during fixtures load.
    • Examples: "applications" → "application", "gateways" → "gateway".
    • Data: user_data/products.json uses singular category_id values.
    • Outcome: Category pages and filters align; products appear under the correct categories.

Category Normalization (User Products) — COMPLETED 2025-08-12

  • Implemented mapping of professional service subcategories (Consulting, Deployment, Support, Training, Development, Maintenance) to canonical service in projectmycelium/src/services/product.rs::canonical_category_id.
  • Ensures user-created services stored under user_data/{email}.json with legacy subcategory IDs are visible on the marketplace.
  • src/controllers/marketplace.rs::services() includes both service and application for backward compatibility while normalization propagates.

Catalog Dev Cache (Development) — COMPLETED 2025-08-10

  • Purpose: Speed up local dev by caching the aggregated catalog (fixtures + user-owned + optional slices).
  • Implementation: In-memory TTL cache in ProductService keyed by slice toggle (include_slice_products).
    • Static: OnceLock<Mutex<CatalogCache>> with buckets for with/without slices.
    • get_all_products() uses TTL; miss/expiry recomputes via aggregate_all_products_uncached() and updates cache.
    • Dedupe semantics and category normalization remain intact.
  • Config:
    • Flags: APP_CATALOG_CACHE (true/false), APP_CATALOG_CACHE_TTL_SECS (u64).
    • Defaults: Dev/Test enabled, TTL=5s. Prod disabled unless explicitly enabled.
    • Accessors: AppConfiguration::is_catalog_cache_enabled(), catalog_cache_ttl_secs().
  • Acceptance:
    • Catalog updates reflect after TTL; no duplicates; category pages correct.
    • Build passes (cargo check).
  • Phase Roadmap:
    • Phase 0 (now): Simple in-memory TTL cache.
    • Phase 1: Optional dev-only cache-bust.
    • Phase 2: Optional finer-grained or Redis-backed cache toggle for prod.

Runtime Modes & Commands

  • Fixtures mode (recommended): make fixtures-run or APP_DATA_SOURCE=fixtures APP_FIXTURES_PATH=./user_data APP_ENABLE_MOCKS=0 cargo run --bin projectmycelium
  • Mock mode (dev-only): APP_DATA_SOURCE=mock APP_ENABLE_MOCKS=1 cargo run --bin projectmycelium to visualize legacy mock data.
  • Notes: Production builds must not enable mocks; fixtures are seed/demo-only and not write targets.

DevX: Rust Error-Only Compilation Logs — COMPLETED 2025-08-12

To speed up debugging and keep logs readable, we added an error-only workflow for cargo check.

  • Script: scripts/dev/cargo-errors.sh
  • Make targets:
    • make check-errors
    • make fixtures-errors (runs with fixtures env)
  • Output: /tmp/cargo_errors_only.log (override with OUT=/path/to/file.log)
  • Behavior: warnings are fully suppressed; only errors are logged. Exit code mirrors cargo check.

Usage:

make check-errors
OUT=/tmp/my_errors.log make check-errors
make fixtures-errors

Quick helpers:

grep -c '^error' /tmp/cargo_errors_only.log
sed -n '1,80p' /tmp/cargo_errors_only.log

🔥 Critical: Insufficient Balance Unified Error Contract

  • Decide and document single status code for insufficient funds responses.
    • Recommendation: 402 Payment Required.
  • Define canonical error JSON shape (via ResponseBuilder), e.g.:
    {
      "success": false,
      "error": {
        "code": "INSUFFICIENT_FUNDS",
        "message": "Insufficient balance",
        "details": {
          "currency": "USD",
          "wallet_balance_usd": 0,
          "required_usd": 0,
          "deficit_usd": 0
        }
      }
    }
    
  • Audit and update flows to emit the canonical contract:
    • src/controllers/order.rs, src/services/order.rs, src/services/instant_purchase.rs
    • Wallet-dependent controllers: wallet.rs, pool.rs, rental.rs
  • Frontend: consume error.details and show a single consistent message:
    • "Insufficient balance. Need $ more." (currency-aware)
    • Avoid hardcoding numbers; read from details.
    • Keep const data = result.data || result; for wrapper safety.
  • Tests:
    • API tests verify status code and JSON shape for each flow (checkout, buy-now, cart quantity validations if applicable).
    • Frontend tests/steps verify rendering and CTA behavior (e.g., "Add Funds").
  • Compatibility/migration notes:
    • Document any legacy shapes temporarily supported and plan a removal date.

Acceptance Criteria:

  • Single status code across insufficient funds responses.
  • Identical JSON structure across all emitting endpoints.
  • Frontend shows a unified message and uses numeric values from error.details everywhere.
  • Tests cover at least one success and one insufficient-funds path per major flow.

High: Buyer My Services & Provider Service Requests — NEW 2025-08-13

  • Goal: complete the post-purchase dashboard flows for services, then extend to all product types (param-driven product_type).
  • Backend endpoints (ResponseBuilder):
    • GET /api/dashboard/user/services/purchased?product_type=service|app|bundle|any — items bought by current user.
    • GET /api/dashboard/service-provider/requests?product_type=service|app|bundle|any — orders where current user is seller/provider.
  • Frontend bindings:
    • /dashboard/user → render “My Services (purchased)” in src/views/dashboard/user.html using src/static/js/dashboard-user.js.
    • /dashboard/service-provider → render “Service Requests” in src/views/dashboard/service_provider.html using src/static/js/dashboard-service-provider.js.
    • Unwrap API responses with const data = result.data || result;. Reads { cache: 'no-store' }, mutations { credentials: 'same-origin' }.
  • Error contract: any related mutations must use the unified insufficient balance envelope.
  • Acceptance:
    • Buyer sees purchased services list; Provider sees incoming requests; empty states handled; currency-formatted display consistent.
    • Same flow works for apps/bundles via product_type.

High: Cart Events, Cache, Credentials Standardization COMPLETED 2025-08-09

  • Implemented across views:
    • src/views/dashboard/cart.html
    • src/views/marketplace/cart.html
    • src/views/marketplace/cart_full.html
    • src/views/marketplace/cart_standalone.html
    • src/views/cart.html (guest)
  • Event emission unified: all flows call window.emitCartUpdated(cartCount?) instead of dispatching CustomEvent directly.
  • Reads standardized: all fetch('/api/cart') include { cache: 'no-store', credentials: 'same-origin' } to prevent stale data and ensure session cookies.
  • Mutations standardized: all POST/PUT/DELETE to /api/cart and /api/cart/item/{id} include { credentials: 'same-origin' }.
  • Robustness: tolerant JSON parsing for 204/no-body responses where applicable.
  • Verification: Manual tests across guest and logged-in flows confirm consistent navbar badge updates and UI state.

📋 Medium: Mock/Fixture Gating for Production

  • Introduce AppConfig.enable_mock_data (default false in production) to guard any legacy dev-only readers/writers (e.g., MockDataService, certain session_manager.rs paths).
  • Enforce persistent-only sources (user_data/ via UserPersistence) in production.
  • Acceptance: production runtime has zero mock reads/writes; dev-only paths documented.

📋 Medium: Orders API Contract Improvements — COMPLETED 2025-08-13

  • Added invoice_available and invoice_url fields to order payloads to drive UI state.
  • Acceptance: orders UI enables/disables invoice actions based on payload.

💡 Tests

  • Integration tests: invoice endpoints (auth/ownership, headers), insufficient balance contract, cart event → badge update.
  • Unit tests: currency shortfall formatting.
  • Acceptance: tests pass in CI.

📦 Fixtures Mode: Seeded Products + Manual Checklist COMPLETED 2025-08-09

  • Seeded user_data/products.json with three products (WireGuard VPN, Public Gateway Bundle, Object Storage 100GB).
  • Added manual checklist: docs/dev/design/current/ux/manual_fixture_test_checklist.md.
  • Personas doc updated with seeded products: docs/dev/design/current/ux/current_personas.md.
  • Make targets: make fixtures-run, make fixtures-check.

🧭 Decision: User-Owned Products & Derived Catalog (No Dual Writes) — 2025-08-09

  • Single Source of Truth (SOT): product is owned by creator (user). Writes go to user persistence (now) / products table (DB).
  • Global catalog is a derived read model built from all user-owned products (and seeds in fixtures). Do NOT write to both.
  • In fixtures mode, user_data/products.json is seed/demo-only; not a write target.
  • Next tasks:
    • 2025-08-10: Added id-based dedupe in ProductService::get_all_products(); later sources override earlier ones. get_product_by_id() now searches the aggregated, deduped list.
    • Optional dev cache: generate user_data/catalog.products.json from aggregator (marked generated).
    • Plan DB/PostgREST (see Architecture Guide update): tables, public_products view, RLS.

HIGH PRIORITY (Next 2-4 weeks)

4. Continue Builder Pattern Migration COMPLETE

Status: Dashboard Controller 331/331 patterns complete (100% done)

4.1 Utils Module ResponseBuilder Migration COMPLETE

  • Target: src/utils/mod.rs:32 - render_template function
  • Status: COMPLETED - Successfully migrated with HTML support added to ResponseBuilder
  • Impact: All template rendering now uses ResponseBuilder pattern
  • Testing: Verified - All HTML pages render correctly
  • Pattern Count: 1/1 HttpResponse pattern complete

4.2 Dashboard Controller Completion COMPLETE

  • Final Progress: 331/331 patterns migrated (100% complete)
  • Migration Completed: All 17 HttpResponse patterns successfully migrated to ResponseBuilder
  • Patterns Migrated: Redirect (3), JSON Success (6), JSON Error (5), Unauthorized (1), Internal Error (1), Plain Text (1)
  • Verification: Zero compilation errors maintained, full functional testing completed
  • Testing: Dashboard application runs successfully with all features working

4. Payment Method Persistence Enhancement COMPLETE

Issue: Payment method dropdown should remember and display last used payment method

  • Root Cause: ResponseBuilder wrapping responses in data field, frontend not handling correctly
  • Solution Implemented:
    • ResponseBuilder Compatibility: Fixed API response handling with const data = result.data || result;
    • UI Enhancement: Label updates to show "Payment Method: Credit Card" instead of generic text
    • Event-Driven Updates: Programmatic change events ensure UI updates correctly
    • Debug Implementation: Added comprehensive logging for troubleshooting
  • Technical Details:
    • Backend: WalletController::get_last_payment_method() returns ResponseBuilder-wrapped JSON
    • Frontend: loadLastPaymentMethod() handles both wrapped and unwrapped responses
    • UX: Dropdown pre-selects saved method, hides placeholder, updates label dynamically
  • Files Modified:
    • src/views/dashboard/wallet.html - Enhanced payment method loading and UI updates

5. Frontend-Backend Integration Standardization

Based on Recent Session Learnings:

  • Issue: ResponseBuilder pattern creates nested responses {data: {...}, success: true}
  • Critical Pattern: All API calls must use const data = result.data || result; for compatibility
  • Action: Audit all frontend API calls for ResponseBuilder compatibility
  • Files to Review:
    • All JavaScript files in src/static/js/
    • Ensure consistent handling of nested response format
    • Add fallback logic where needed: response.data || response
  • Documentation: Added comprehensive ResponseBuilder guide in MASTER-ARCHITECTURE-GUIDE.md

📋 MEDIUM PRIORITY (Next 1-2 months)

6. Authentication & Security Enhancements

Based on Recent Session Fixes:

  • Middleware Audit: Review all route exclusions for security gaps
  • Session Validation: Enhance multi-factor session validation across all endpoints
  • CSRF Protection: Implement comprehensive CSRF protection
  • Rate Limiting: Add rate limiting to authentication endpoints

7. Payment Integration Implementation

  • Stripe Integration: TFC credit purchases via credit card
  • TFC → TFT Conversion: Service for ThreeFold Grid deployment
  • Commission System: Marketplace commission calculation (5-15%)
  • Payment Flow: Complete end-to-end payment processing

8. Database Migration Planning

  • Current: JSON file-based storage (user_data/ directory)
  • Target: PostgreSQL with Supabase
  • Phase 1: Local development environment setup
  • Phase 2: Schema design and migration scripts
  • Phase 3: Production deployment strategy

💡 ENHANCEMENT PRIORITIES (Next 3-6 months)

9. Complete Marketplace Ecosystem

  • Deployment Automation: ThreeFold Grid integration pipeline
  • Real-time Status: WebSocket-based deployment status updates
  • Provider Dashboard: Tools for service providers
  • Analytics Dashboard: Usage and revenue analytics

10. User Experience Improvements

  • Mobile Responsiveness: Optimize for mobile devices
  • Progressive Web App: PWA capabilities for better mobile experience
  • Internationalization: Multi-language support
  • Accessibility: WCAG 2.1 compliance

11. Performance Optimization

  • Caching Strategy: Redis integration for session and data caching
  • CDN Integration: Static asset delivery optimization
  • Database Optimization: Query optimization and indexing
  • Load Testing: Performance benchmarking and optimization

🔧 TECHNICAL DEBT & MAINTENANCE

12. Code Quality Improvements

  • Warning Cleanup: Address remaining unused variable warnings
  • Documentation: Complete API documentation with examples
  • Testing: Comprehensive test suite implementation
  • CI/CD: Automated testing and deployment pipeline

13. Monitoring & Observability

  • Logging Strategy: Structured logging for production (while maintaining log-free development)
  • Metrics Collection: Application performance metrics
  • Error Tracking: Comprehensive error monitoring
  • Health Checks: Service health monitoring endpoints

14. Security Hardening

  • Dependency Audit: Regular security vulnerability scanning
  • Input Validation: Comprehensive input sanitization
  • API Security: Rate limiting, authentication, and authorization
  • Data Encryption: Encryption at rest and in transit

📊 PROGRESS TRACKING

Builder Pattern Migration Status

  • Auth Controller: 10/10 patterns complete
  • Wallet Controller: 49/49 patterns complete
  • Product Controller: 7/7 patterns complete
  • Currency Controller: 12/12 patterns complete
  • Marketplace Controller: 44/44 patterns complete
  • Rental Controller: 24/24 patterns complete
  • Pool Controller: 13/13 patterns complete
  • Order Controller: 26/26 patterns complete
  • Debug Controller: 1/1 patterns complete
  • Gitea Auth Controller: 2/2 patterns complete
  • Public Controller: Uses render_template utility (no direct patterns)
  • Dashboard Controller: 331/331 patterns complete (100% complete) 🎉
  • Utils Module: 1/1 patterns complete (render_template function with HTML support)

Total Progress: 521/521 patterns complete (100% overall) 🎉

Recent Accomplishments (2025-08-08)

  • Dashboard Controller Migration Complete: Successfully migrated all 331/331 HttpResponse patterns to ResponseBuilder

  • 17 Pattern Types Migrated: Redirect (3), JSON Success (6), JSON Error (5), Unauthorized (1), Internal Error (1), Plain Text (1)

  • Full Functional Testing: Dashboard application runs successfully with all features working

  • 100% Builder Pattern Coverage: All controllers now use ResponseBuilder architecture

  • Zero Compilation Errors: Maintained clean build throughout entire migration process

  • Architecture Milestone: Complete ResponseBuilder pattern implementation across entire codebase

  • Cart Count Consistency & Persistence Cleanup: Fixed stale navbar cart count after restart/build.

    • Backend: src/services/order.rs::get_cart_with_details() now:
      • Cleans orphaned cart items whose product_id no longer exists
      • Recomputes item_count from valid items only
      • Persists cleaned cart to session and user_data/*_cart.json
    • Frontend:
      • Global updateCartCount() in src/views/base.html fetches /api/cart with cache: 'no-store'
      • src/views/marketplace/cart.html dispatches cartUpdated on remove/clear and calls window.updateCartCount()
      • src/views/marketplace/dashboard.html avoids overriding global by renaming to updateCartCountLocal() and using window.updateCartCount()
    • Result: Navbar badge always reflects true backend state, including after app restarts.
  • Checkout & Orders Flow Alignment (2025-08-08)

    • Checkout redirect fix: In src/views/marketplace/checkout.html processPayment() now unwraps the ResponseBuilder envelope, extracts order_id and confirmation_number from data, and builds a valid confirmation URL.
    • Post-purchase cart clear: DELETE /api/cart includes { credentials: 'same-origin' } to ensure session consistency after order placement.
    • Order status alignment: Successful wallet/cart checkout is now marked Completed both in-memory and when persisted to user data.
      • Backend: src/services/order.rs::process_payment() updates to OrderStatus::Completed and attaches payment details.
      • Persistence: Wallet flow persists the order as Completed with payment details in UserPersistence.
      • Buy Now already sets Completed; both flows are now consistent.
    • Dashboard display hardening: src/views/dashboard/orders.html maps confirmed/completed to green and lowercases status before color mapping for robustness.
  • Cart Clear UX: Post-Reload Success Toast (2025-08-08)

    • Behavior: After successful clear, we reload the page for state consistency and show a success toast after reload.
    • Mechanism: Set sessionStorage.setItem('cartCleared','1') before window.location.reload(). On DOMContentLoaded, check the flag, show toast, then remove it.

Previous Accomplishments (2025-08-07)

  • Critical Authentication Fix: Resolved wallet balance issue affecting buy-now flow
  • ResponseBuilder Integration: Fixed frontend-backend response format compatibility
  • Middleware Security: Enhanced authentication validation and route protection
  • Debug Infrastructure: Added comprehensive debugging for troubleshooting

🎯 SUCCESS METRICS

Code Quality Metrics

  • Compilation Errors: Maintain 0 errors
  • Log Statements: Maintain 0 in production code
  • Test Coverage: Target 80%+ coverage
  • Performance: Sub-200ms API response times

User Experience Metrics

  • Authentication Success Rate: >99%
  • Purchase Completion Rate: >95%
  • Page Load Times: <2 seconds
  • Mobile Usability: 100% responsive

Business Metrics

  • Transaction Success Rate: >99%
  • Payment Processing: <5 second completion
  • Service Deployment: <30 second initiation
  • User Satisfaction: >4.5/5 rating

📋 IMPLEMENTATION GUIDELINES

Development Standards

  • Zero Compilation Errors: All changes must maintain clean builds
  • Builder Pattern Usage: Mandatory for complex object construction
  • ResponseBuilder Consistency: All HTTP responses use ResponseBuilder pattern
  • Log-Free Code: No log:: statements in main/development branches
  • Persistent Data Only: No mock data in production code

Testing Requirements

  • Unit Tests: All new functions require unit tests
  • Integration Tests: API endpoints require integration tests
  • Manual Testing: UI changes require manual verification
  • Performance Testing: Critical paths require performance validation

Documentation Requirements

  • Code Comments: Complex logic requires inline documentation
  • API Documentation: All endpoints documented with examples
  • Architecture Updates: Changes require architecture guide updates
  • Change Log: All user-facing changes documented

Document Maintainer: Development Team
Review Cycle: Weekly sprint planning
Priority Updates: Based on user feedback and business requirements
Completion Tracking: Updated with each completed task


Appendix: Marketplace Currency Refactor Work Done

Summary

  • Refactored dashboard Orders UI and server to use the user's preferred currency dynamically, aligning with Wallet and Cart.
  • Eliminated hardcoded symbols by injecting currency_symbol and display_currency into templates and formatting amounts server-side where possible.

Code Changes

  • orders template: src/views/dashboard/orders.html

    • Added formatCurrencyAmount() helper to place symbol correctly (prefix for , €, C, etc.; suffix for alphabetic symbols like TFC/TFT).
    • Updated aggregated "Total Spent" to use the helper instead of a hardcoded prefix.
    • Continued using server-injected currency_symbol/display_currency.
  • dashboard controller: src/controllers/dashboard.rs

    • Injected currency_symbol and display_currency into Tera context for:
      • cart_section()
      • orders_section()
  • orders controller: src/controllers/order.rs

    • Fixed compile error (E0425) in view_order_history_legacy() by defining display_currency before using it for conversions/formatting.
    • Updated get_orders_json() to convert/format item and order totals in the preferred display_currency using CurrencyService::convert_amount + format_price, and to return the preferred currency code in currency.

Rationale

  • Centralize currency conversion/formatting in backend (CurrencyService) to reduce JS complexity and ensure consistency across Orders, Cart, Wallet, and Navbar.
  • Ensure all user-facing totals and labels reflect the preferred currency and appropriate symbol placement.

Build/Status

  • Addressed E0425: cannot find value display_currency in Orders legacy view.
  • There are many warnings (mostly unused variables); non-blocking for functionality and can be cleaned later.

Frontend Externalization & JSON Hydration

  • Externalized dashboard scripts from src/views/dashboard/index.html into static/js/dashboard.js.
  • Added a JSON data block in index.html using <script type="application/json" id="dashboard-chart-data"> to safely hydrate chart data (no inline template directives inside JS).
  • Dashboard JS reads hydrated data, initializes all charts, and updates wallet balance/currency via /api/navbar/dropdown-data using the ResponseBuilder-safe unwrap pattern.
  • Benefits: CSP-friendly, caching for JS, reduced template lints, clearer separation of concerns.

Next Steps

  • Adjust src/views/dashboard/orders.html JS to rely solely on server-provided formatted fields for item/unit/subtotal/total where available.
  • Verify that Dashboard main page and Navbar still display wallet balance and labels in the preferred currency.
  • Run cargo build and targeted tests to confirm no regressions.