I could not log in. The credentials in .env (last known working 13 Mar 2026) were rejected — "Please check your username and password." I stopped after a single attempt rather than risk locking the account. Most likely a forced password rotation or a deactivated user.
So this review rests on three things I could verify directly: the unauthenticated login page, the 813 order lines exported in March, and the scraper source — which is itself unusually good evidence, because every workaround in it documents something the portal refused to do. I have not directly observed the authenticated UI. Findings about grid behaviour are inferred from code that demonstrably worked against it, and are marked as such.
D-STAR is a competent 2018 portal. It is a place to look things up, and it's built on the assumption that a human will do the looking. In 2026 the bar is that a supplier portal is a data interface first and a web page second — and by that bar it doesn't clear. The single most damning artefact is the scraper sitting in this repo: a customer had to drive a headless browser and fake mouse coordinates to get their own purchase orders out.
| Dimension | Grade | Reading |
|---|---|---|
| Machine access / API | F | No usable programmatic path. Export-and-scrape is the sanctioned workflow. |
| Data completeness | D | Downstream milestones collapse to 11–20% fill. The grid promises a pipeline it doesn't populate. |
| Information architecture | D+ | 45 undifferentiated columns, no role scoping, 9 permanently blank. |
| Derived intelligence | F | Ships raw dates. No ETA, no variance, no exception surfacing — the customer built all of it. |
| Authentication | C− | Password-only, no SSO, no visible MFA. Rotation silently breaks integrations. |
| Transport security | B+ | Genuinely fine. HSTS 2yr + preload-grade, CSP frame-ancestors none, XFO DENY, nosniff. |
| Front-end weight | B | Login page is lean — 53 KB, 10 requests, 2.4 s to networkidle. |
| Accessibility | C− | No h1, unlabelled submit, missing alt text, autocomplete="off" on password. |
The portal exposes data through a RaySheet grid embedded in an iframe. To extract it, the scraper cannot use ordinary automation — it has to compute the iframe's bounding box and issue real mouse events at absolute page coordinates, because a synthetic .click() doesn't fire the grid's custom handlers.
It gets worse: the Export control is a <span>, not a button. The dialog's submit has to be located by scanning every <button> for one whose text is "Export" and whose getBoundingClientRect() is non-zero. And there is no event to wait on, so the code just sleeps three seconds and hopes.
Why this matters beyond inconvenience: this integration is pinned to pixel positions and render timing. Any cosmetic change GlobeRide ships — a toolbar reorder, a slower dialog, a different grid version — breaks it silently and produces no data rather than an error. That is the worst possible failure mode for a supply-chain feed.
Fairness note
Salesforce does provide REST, Bulk and Pub/Sub APIs. This is almost certainly a GlobeRide licensing and configuration choice — Experience Cloud community licences typically exclude API access — not a platform limitation. That makes it a decision someone can reverse, which is the good news buried in the bad.
The export carries a full logistics milestone chain. Measured across all 813 rows, it decays hard:
| Milestone | Filled | % |
|---|---|---|
| PI Sailing On Or About Date | 664 | 82% |
| Factory Invoice Issued Date | 161 | 20% |
| CI Sailing On Or About Date | 161 | 20% |
| Commercial Invoice No. | 162 | 20% |
| B/L Received Date | 87 | 11% |
| Sales Confirmed Date | 87 | 11% |
Some of this is legitimate — an order that hasn't shipped has no bill of lading. But the customer cannot tell "not yet" from "nobody entered it", because an empty cell means both. A 2026 portal distinguishes these: a milestone is pending, confirmed, or overdue against its own plan, and the last of those raises a flag rather than rendering as whitespace.
Nine columns are blank across every single row — Adj. Alert, Adjusted Special Price, Cancel Date, Cancellation Reason, Note1, Note2, Note for Factory, Remarks, Factory Interface Co. On page one alone, 20 of 45 columns were empty. Those are fields the schema advertises and the process never fills.
D-STAR provides five separate date columns and no answer to the only question that matters: when does this actually arrive, and is that late? The scraper reconstructs it — cascading through the milestone chain to find the most authoritative date available, then adding a per-factory lead time:
That logic lives on one analyst's laptop. It is business-critical, undocumented, unversioned, and unknown to GlobeRide — who are the only party that actually knows the true lead times and could keep them current.
Caveat, stated plainly: running that heuristic over the March export yields 577 of 813 lines late (median 26 days, worst 88). Do not quote that figure to GlobeRide. It is the output of an assumption GlobeRide never validated, applied to a dataset where 80% of rows lack a confirmed shipping milestone. It is a useful smoke signal and nothing more. The real finding is that a customer had to guess at all.
The login page offers username, password, "remember me", and a forgotten-password link. Probing the unauthenticated DOM: no SSO affordance, no SAML, no MFA step, no IdP hand-off. For a portal carrying purchase orders, FOB pricing and factory relationships across a supplier network, that is below 2026 baseline — SSO with SCIM provisioning is table stakes, and phishing-resistant MFA is close behind.
This review is itself the proof of the operational cost: an unannounced credential change turned a working data feed into a silent failure, and nobody found out until someone went looking. Machine identities need service accounts with rotating tokens, not a human password that expires on a human schedule.
Two smaller things in the same area — the generic "check your username and password" error is correct practice and deserves credit for not leaking account existence. But autocomplete="off" on the password field is a 2010 habit that modern guidance rejects: it fights password managers, which pushes users toward weaker, memorable, reused passwords.
Data leaves the portal exclusively as Excel files, one page at a time, filenames like DITS Order List _ C_page001.xlsx. The consequences compound:
Orig. _x000A_Qty, Commercial _x000A_Invoice No. — leaking the rendering layer into the data contract and forcing downstream renames.The recorded 500 + 313 = 813 split is internally consistent, so the March run appears to have captured its view completely. Worth noting that earlier notes reference 1,342 records across three pages — this export is a narrower slice (every row is factory DVN, shipping method Boat), consistent with a filtered list view rather than a failed run.
Measured on the login page, which is the only surface I could reach:
| Check | Result |
|---|---|
Document has an h1 | None — 0 headings on the page |
| Images have alt text | 1 of 4 missing |
| Submit button accessible name | No text, no aria-label, no title |
| Password autocomplete | off — blocks password managers |
| Form inputs labelled | Yes, real <label> associations |
| Document language | en-us |
| Mobile reflow at 390 px | No horizontal scroll |
The mobile result carries an asterisk: the login page reflows fine, but a 45-column RaySheet grid inside an iframe is not going to. I could not verify that, and I'd expect it to be the portal's weakest surface.
An honest review has to say this: the security headers are properly configured, and better than plenty of production systems.
The login page is also genuinely lean — 53 KB across 10 requests, 596 ms TTFB, 1.6 s to load event. No tracker sprawl, no third-party hosts beyond Salesforce itself. Whoever configured the edge did their job.
And the underlying data model is rich. Adjusted FOB, currency, incoterms, COO, lot numbers, per-shipment scheduling — the schema knows a great deal. The failure is in delivery and completeness, not in domain modelling. That's a much cheaper problem to fix.
What a supplier portal is expected to provide today, and where D-STAR sits against each.
| Expectation | 2026 standard | D-STAR |
|---|---|---|
| Machine access | REST/GraphQL with OAuth service accounts; bulk export for backfill | Absent |
| Change notification | Webhooks or event subscriptions; consumer never polls | Absent |
| Incremental sync | modifiedSince cursors, stable surrogate keys | Absent |
| Identity | SSO/SAML + SCIM, phishing-resistant MFA, separate machine credentials | Password only |
| Derived signal | Predicted ETA, variance vs commitment, exception alerts pushed to the customer | Raw dates only |
| Data quality | Explicit pending/confirmed/overdue states; no permanently-blank fields | Blank means everything |
| Role-scoped views | Views shaped per persona, not one 45-column table | One grid for all |
| Accessibility | WCAG 2.2 AA, keyboard-operable data grid | Below AA on basics |
| Transport security | HSTS, CSP, modern headers | Meets standard |
Split by who can act. The first three you control; the rest require GlobeRide.
Get the credentials reset, then ask GlobeRide for a dedicated integration user — not a shared human login. If they'll only issue a human account, at minimum document the rotation date and set a calendar alarm ahead of it.
The current failure mode is the dangerous one: a broken selector yields an empty file, not an alarm. Add an expected-row-count assertion, compare against the grid's own record counter, and exit non-zero on mismatch. Replace the blind time.sleep(3) with a wait on the dialog's actual presence.
The factory lead-time table is real business logic living in a Python dict. Put it in a config file with an owner and a review date, and send the assumptions to GlobeRide for confirmation. Their answer is more valuable than the estimate.
The highest-leverage ask by a wide margin, and the cheapest for them — DITS_Order__c already exists as a Salesforce object. This is a licence and permission-set change, not a build. Lead with this.
If API access is refused, a date-filtered list view still converts a full re-pull into a delta and makes the weekly question answerable.
Ask that empty dates carry a status — pending, confirmed, or overdue. This is the fix that turns the grid from a record into a signal, and it costs them nothing in data they don't already hold.
Frame it as risk reduction on their side, not convenience on yours. A supplier portal holding FOB pricing and factory relationships behind a single reusable password is their exposure as much as it is yours.
If any of this goes to them, lead with recommendation 4 and drop the grades. The scorecard is a working tool for deciding where to push — it is not a diplomatic document, and a vendor who reads "F" stops reading. The strongest thing you can put in front of them is the scraper itself: this is what we had to build to read our own purchase orders. That argument doesn't need a grade attached.