init projectmycelium

This commit is contained in:
mik-tf
2025-09-01 21:37:01 -04:00
commit b41efb0e99
319 changed files with 128160 additions and 0 deletions

View File

@@ -0,0 +1,859 @@
# 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.rs``get_all_marketplace_nodes()`, `get_all_slice_combinations()`
- `src/services/node_rental.rs``find_node_owner()`
- `src/services/order.rs``find_app_provider()`, `find_service_provider()`
- `src/controllers/dashboard.rs` → cross-user deployment counting
- `src/utils/data_cleanup.rs``DataCleanup::cleanup_all_users()`
- `src/utils/data_validator.rs``DataValidator::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):
```dotenv
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:
```html
<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/add` → `OrderController::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)
- [x] 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`.
- [x] 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
- [x] 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.
- [x] 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.
- [x] Orders: "Download invoice" not working: Implemented marketplace order invoice HTML view and UI wiring. ✅ FIXED 2025-08-09
- [x] Orders page: remove "Reorder" option from `src/views/dashboard/orders.html`. ✅ FIXED 2025-08-08
- [x] 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: `downloadInvoice` → `viewInvoice`, `downloadInvoiceFromModal` → `viewInvoiceFromModal`.
- 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.
### ✅ Marketplace Overview De-duplication (Featured vs Popular) — COMPLETED 2025-08-10
- 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):
```rust
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:
```bash
make check-errors
OUT=/tmp/my_errors.log make check-errors
make fixtures-errors
```
Quick helpers:
```bash
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.:
```json
{
"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 $<deficit> 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`](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.