Skip to content

customer-portal — feature queue ​

Repo: Adalen-Truck/customer-portal · Path: /Users/Shared/moltis/repos/customer-portal Audit branch: develop (⚠️ the remote default is main — never fall back to origin/HEAD) Stack: Vue 3 + <script setup>, PrimeVue, Tailwind 4 (ÅDALEN semantic tokens), TanStack Query/DB, CASL abilities, vue-i18n (en/nb), Capacitor mobile wrapper

✅ Inventory built from develop @ 693a76c on 2026-07-30, after fast-forwarding one commit (#24, "Improve sidebar navigation and mobile tab bar") that rewrote router/index.ts and added admin/SyncPage.vue.

Derived from apps/web/src/router/index.ts (59 page components). This is the post-consolidation "One App": the former web, internal and admin apps now share one router, one AppLayout and one guard, with sections gated by CASL abilities and role names. Grouping follows the app's own sidebar sections (AppLayout.vue menuItems) rather than an invented taxonomy.

Redirect-only routes are excluded: bookings → service-overview, locations-contacts → locations, admin/access-denied → forbidden.

Ordered by user impact: public and auth paths first, then money paths (marketplace/bids/trade-in), then core customer work, then internal, then admin.

#FeatureRoutesPatternsStatus
1Warranty submission (public)warranty.submitforms/form-validation, forms/file-input, media/image-upload, user-feedback/notificationdrafted
2Sign inauth.sign-inauthentication/login, forms/password, forms/form-validationdrafted
3Sign upauth.sign-upauthentication/signup, forms/password, forms/form-validationdrafted
4Password resetauth.forgot-password, auth.reset-passwordauthentication/password-reset, forms/passworddrafted
5Email verificationverify-emailauthentication/signup, user-feedback/notification, user-feedback/empty-statesdrafted
6Onboardingonboardadvanced/wizard, user-feedback/progress-indicator, forms/form-validationdrafted
7Account selectionselect-accountforms/selection-input, data-display/list-viewdrafted
8Landing pagehome.indexnavigation/link, forms/buttondrafted
9Marketplacemarketplace.index, marketplace.detaildata-display/card-grid, e-commerce/product-card, data-display/filter-paneldrafted
10Bidsmarketplace.bids, bids.detailforms/currency-input, data-display/table, user-feedback/notificationdrafted
11Trade-in machinestrade-in-machines.index, trade-in-machines.create, trade-in-machines.detailadvanced/wizard, media/image-upload, forms/form-validationdrafted
12Catalogcatalog.products.index, catalog.products.detaildata-display/card-grid, e-commerce/product-card, forms/search-fielddrafted
13Dashboarddashboarddata-display/dashboard, data-display/statistics, user-feedback/skeletondrafted
14Customer assetscustomer-assets.index, customer-assets.detail, live-trackingdata-display/table, data-display/card-grid, user-feedback/empty-statesdrafted
15Service overviewservice-overview, bookings.detaildata-display/timeline, data-display/table, data-display/filter-paneldrafted
16Book servicebook-serviceadvanced/wizard, forms/date-picker, forms/form-validationdrafted
17Service plans & checklist builderservice-plans, checklist-builder.new, checklist-builder.editcontent-management/drag-and-drop, forms/form-validation, advanced/wizarddrafted
18Work ordersorders, orders.detaildata-display/table, data-display/timeline, data-display/filter-paneldrafted
19Partner service orderspartner-orders.index, partner-orders.detaildata-display/table, data-display/filter-paneldrafted
20Locationslocationsdata-display/table, user-feedback/empty-statesdrafted
21Contactscontactsdata-display/table, forms/phone-number, user-feedback/empty-statesdrafted
22Skills & employeesskills, skills.employeedata-display/table, authentication/user-profiledrafted
23Termstermscontent-management/accordion, content-management/expandable-textdrafted
24Profileprofileauthentication/user-profile, authentication/account-settingsdrafted
25Contact Aadalencontactforms/form-validation, forms/textarea, user-feedback/notificationdrafted
26Orders logistics (internal)orders.logistics, orders.logistics.sandboxeddata-display/kanban-board, data-display/table, content-management/drag-and-dropdrafted
27Shipping orders (internal)shipping-orders, shipping-orders.detaildata-display/table, forms/signature-paddrafted
28Warehouse take-out (internal)warehouse.take-outforms/search-field, forms/multi-select-input, data-display/list-viewdrafted
29Charging (internal)chargingforms/form-validation, data-display/list-viewdrafted
30Admin analyticsadmin.analyticsdata-display/dashboard, data-display/chart, data-display/statisticsdrafted
31Sync monitoring (admin)admin.sync, admin.sync-runs, admin.sync-events, admin.sync-failuresnavigation/tabs, data-display/table, data-display/filter-paneldrafted
32Commands (admin)admin.commandsdata-display/table, user-feedback/notificationdrafted
33Emails (admin)admin.emailsdata-display/table, user-feedback/empty-statesdrafted
34User administration (admin)admin.users, admin.user-linksdata-display/table, forms/search-field, authentication/user-profiledrafted
35Roles & permissions (admin)admin.permissions, admin.permissions.detaildata-display/table, forms/checkbox, data-display/tree-viewdrafted
36Admin configurationadmin.settings, admin.standards, admin.termsauthentication/account-settings, forms/form-validation, forms/rich-text-editordrafted
37Error statesforbiddenuser-feedback/empty-states, navigation/linkdrafted

37 features to audit. None started.

Inventory-level observations ​

Recorded here, not as findings — they need a proper audit run to confirm against the baseline. Flagged now so the relevant audits look for them.

  • No catch-all 404 route. router/index.ts has no /:pathMatch(.*)* record and there is no NotFoundPage.vue (grep confirms zero hits for pathMatch, NotFound or 404 in router/ and pages/). An unmatched URL therefore matches no record and renders an empty layout rather than a recoverable error page. Belongs to #37 Error states; playout has this covered via not-found, so it is likely a cross-project inconsistency.
  • live-tracking is a hidden feature. The route resolves and is ability-gated, but its sidebar entry is hardcoded visible: false (AppLayout.vue:122) pending release. Audit it as reachable-by-deep-link only, and do not report the missing nav entry as a defect.
  • Account selection reads localStorage. The guard keys multi-account selection off localStorage.getItem("admin-selected-account") (router/index.ts:683, :700). Not a token, so it does not breach the repo's own "no tokens in localStorage" rule, but the persistence and clear-on-sign-out behaviour is worth checking in #7.
  • Ability failures are deliberately fail-open on a transient /me error (router/index.ts:722-729, with a comment explaining the trade-off). Backend enforces authorization, so this is UX-only by design — do not file it as a security finding without reading that comment first.

Suggested next: #1 Warranty submission — the only fully public, token-gated route in the app, so it is the one surface where frontend UX failures have no authenticated fallback and no sidebar to escape to. It also exercises file upload and validation, which seeds rules reusable across the other three projects.