Repository navigation
Release v0.4.25 - #119
Merged
Merged
Release v0.4.25#119
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #119 +/- ##
=============================================
Coverage 100.00% 100.00%
- Complexity 2283 3853 +1570
=============================================
Files 182 222 +40
Lines 9086 13841 +4755
=============================================
+ Hits 9086 13841 +4755
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
feat(promotions): store attribution, shareable code and availability on public promotions
…-chat # Conflicts: # server/tests/Unit/Routes/StorefrontRoutesTest.php
feat(chat): customer chat with the driver delivering their order
feat(products): expose add-on category limits on public product payloads
…the testing seeders - Network seeder: a "Home & Wellness" category and two service stores tagged `services` (Lion City Cleaning, Tiong Bahru Wellness) with bookable products that carry a duration (`meta.duration`, 45 to 360 minutes), options, add-ons and a sale price. - Promotions for the network and individual stores, covering every type (percentage, fixed amount, free delivery, buy 2 get 1) and state (live, weekly schedule, weekends only, code only, first order only, upcoming, ended, draft), with codes WELCOME15, FIRSTCLEAN, MARKET5 and VIPPREVIEW. They target categories, products or stores. - Customer segments (loyal, recent, lapsed, never ordered, push enabled) and sent, scheduled and draft campaigns that deep-link to a promotion, store or product. Scheduled campaigns are due days ahead, so the scheduler doesn't send them straight away. - Single-store seeder: a smaller set of promotions, segments and campaigns. - Re-running purges seeded campaigns, promotions with their codes and redemptions, and segments. - Fix: re-running failed with "A customer with this email already exists". Both seeders used the same customer emails and phones in one company, and Fleet-Ops allows one customer profile per account there. The store seeder's customers now use `+market` emails and `+65 9101` phones.
- Reviews sorted ascending whatever was asked: applySort set sort_direction,
which core's query builder never reads. It now sends the columns core
understands ("-rating", "-created_at"), with the newest review first on equal
ratings, so "highest" and "newest" come back in the right order.
- Payment methods: creating the Stripe customer ran outside the try/catch, so a
gateway whose key Stripe refuses (such as the seeded placeholder key) threw
and came back as a bare 401 "Unauthenticated.". It now returns the Stripe
error as a 400, like the other Stripe failures there.
Re-seeding purged and recreated the network and stores, and the models generate a new key on every create, so each run changed the storefront key and forced an app rebuild. The seeder now remembers the uuid, public id and key of every store and network it created before purging, recreates them with the same uuid, and writes the old public id and key back after the insert. New ones get new keys as before.
- No service rate had the storefront service type, so every delivery quote failed with "No service rates available!" and checkout showed delivery as unavailable for any address. Both seeders now create a "Storefront Delivery" rate (base fee plus a per-km fee, no service area) for the storefront order config, purged and recreated like their other fixtures. - Re-seeding replaced the seeded Stripe gateways' keys with placeholders. A gateway now keeps the real keys it already had (set in the console), unless SEED_STRIPE_SECRET_KEY / SEED_STRIPE_PUBLISHABLE_KEY are given.
The test stores, network, products, promotions, seeded orders and the seeded delivery rate now use Singapore dollars. Service rates only quote carts in their own currency, so the delivery rate follows the seeded owner's currency.
…hen it is updated
Choosing another payment method calls stripe-update-payment-intent, which
updated the PaymentIntent and then created a new checkout without its
PaymentIntent id. The app captured with that checkout's token and capture
refused it ('Stripe PaymentIntent is not linked to this checkout').
The checkout that started the PaymentIntent is now updated in place (a
PaymentIntent belongs to one checkout), and its promotion reservations are
released before being reserved again at the new price. A PaymentIntent on
another customer's checkout is refused. With no existing checkout, the new
one is linked to the PaymentIntent.
…ampaign text The seeded stores and network sell in SGD, but promotion names, descriptions and campaign copy wrote amounts as "$40", while the app formats the amounts it calculates as "S$40".
GET storefront/v1/orders/{id}/activity-flow returns the signed-in customer's
order as a line of steps from its order config, so apps can show custom flows
(e.g. Created > Dispatched > Started > Enroute > Completed) instead of guessing
from status codes.
Steps are the activities the order has been through (tracking history, first
time each was reached), its current activity, then the path it is expected to
take. At a branch, Fleet-Ops' own activity conditions decide: an activity whose
conditions this order meets (pickup's 'ready for pickup') wins over an
unconditional one, cancellation branches are never projected, and a looping
flow is capped. Unknown statuses still appear, labelled from tracking history.
Labels and details come from the config, with {storefront.name}-style
placeholders filled.
Seeded store hours used "monday", while the console writes "Monday" and clients such as the storefront SDK match on that, so the app's store info screen crashed on seeded stores.
…river-assigned notice per driver
…urns them; the console serializers handle place types
…t its own notification
…oducts brought to the earliest appointment
…work review setting is enforced
…ulti-store order; otherwise the tip goes to the network
…translations build again c8af413 inserted the split-tips label between the two lines of the enable-multi-cart-checkout value, which js-yaml reads as a bad mapping entry and the engine build fails.
…h the shared identity cells, pills and select options The orders, network orders, customers and network customers tables use table/cell/identity typed for the shared fleetops-data descriptors, reading the loaded relation or an identity stub named after the row, so a row shows the right tile and name before the relation loads. Clicking a customer opens the storefront customer page; a driver or place opens its FleetOps panel, loading the engine only then. The order details, fulfillment and customer panels, the incoming-order modal, the orders and customers widgets and the food-truck cards use Customer::Pill, Driver::Pill and Vehicle::Pill in place of hand-rolled avatar blocks, whose styles are removed. Driver, vehicle, customer, user and category selects render SelectOption rows with compact selected items. The fleetops-data range moves to ^0.2.3, the version the workspace links.
feat(identity): render drivers, customers, vehicles and places through the shared identity components
…ore anything is created and a failed attempt is undone
… from the queue, not during checkout
…oof of delivery
"Mark as ready" dispatches a delivery order and sets it to `preparing`, which
the panel showed as still confirmed, with no way on: the quick actions knew
only created, accepted and ready.
The panel now follows the order's own order config, the default Storefront
flow or a custom one:
- The flow endpoint adds `next` (the activities the current one leads to whose
conditions hold, the expected one first) and `completion` (the activity that
finishes this order).
- The step strip is the config's steps; the default Storefront flow keeps its
five store steps, each standing for the statuses it covers (Ready: preparing,
dispatched, started, driver en route to the store; Dispatched: driver picked
up, en route), so "Mark as ready" lands on Ready.
- After accepting and marking ready, the bar moves the order to its expected
next step; a menu offers the other allowed steps and completing it now.
- `PATCH orders/update-activity/{id}` takes the activity from the order's
config by code (status, details, proof rules are the config's), bypasses
proof the console cannot capture (the dialog says so), and an order finished
this way without a driver is still finished (cash settled, customer told).
- The bar and banners look up the panel's refresh when they run; they held an
empty one bound before the panel loaded, so nothing refreshed after a step.
Proof of delivery: the overview lists the order's proofs (`delivery.proof_items`:
photos, signatures, scanned codes, with time and remarks) and the panel shows
them under the delivery; the delivered banner's View proof scrolls to them and
says how early or late in days, hours or minutes.
…tomers told about unavailable items, paid balances and moved bookings - New booking form: a week of the service's free days and start times, at the customer's or at the store, travel fee from the store's delivery rates, and a provider (a driver assigned once the booking is placed) - Order panel: the booking's time and steps, Provider and Service address, products to bring to the job, and Reschedule - Reschedule opens a modal with the week strip; the move goes through the order edit, which keeps meta.booking, booking_at and the service line's time and checks the time is still free - Edit form: "Booked for" with the same slot picker - Contacts are looked up by uuid once loaded (utils/find-contact): asking for a public id the store already re-keyed threw, so Edit did nothing right after creating a booking - The orders list carries meta.booking, so a list refresh keeps the end time - Customer notifications (push, inbox, email): an item marked unavailable, a balance paid by link, and a moved booking in the store's time - Edit summaries show times in the store's time zone
…e booked time, header buttons aligned and tighter, badges on one row
…an action - A list counted a child panel's own query params (booking, for_customer) as list changes, and Ember then refreshed it for its re-sent page/sort: New order and New booking reloaded the orders list behind the form - A reload of the page on screen (same filters) keeps it, and any panel open over it, until the new data arrives instead of swapping it for the loading skeleton; first visits and real filter, search or page changes still show it - The order panel and the edit form refresh only the orders list, not the whole console; a sent message reloads only the panel's summary
- The panel listens on each of the order's threads (chat.{uuid}) and on the
company channel for threads the order did not have: a message shows in the
open thread, or counts as unread with a toast; the drawer no longer polls
- Opening a thread marks it read for the store even when the staff member had
not joined it; what the viewer sent never counts as unread to them (the
owner can be the driver too)
- Sending no longer hangs when the message's own live reload arrives first,
and a sent message cannot show twice
- The overview's chat summary carries each thread's channel ids
…address or at the store) and the provider; a store can set its own with options.booking_quick_replies
chore(deps): ember-ui 0.4.6, ember-core 0.3.26 and fleetops-data 0.2.3
The suite never ran against the real core until it was tagged: PHP CI could not resolve ^1.6.69. Against it, four tests in CustomerControllerContractsTest fail: - codes sent by SMS are stored hashed and used up when accepted, so the test reads the plain code from the text the provider was handed instead of the row, gives the customer a phone on file so that text exists, checks the accepted code is marked used, and asks for a fresh closure code after the deletion that fails burned the first one - two local verification_codes tables lacked the uuid and status columns that consume() writes - verifyCode() builds a form request from a plain request and validates it; the bootstrap's FormRequest stub gains setContainer(), setRedirector() and validateResolved(), deferring to the request's own failedValidation() so the usual 422 response is attached, and illuminate/validation (a core dev dependency, not a runtime one) is now a dev dependency here too
…gs skeletons match the pages - Order messages section in store settings: quick replies for orders and for bookings, one per line, the defaults as placeholders; empty keeps the defaults - Picking a timezone marks the page changed (the select fires no form event), and the console now gets timezone and pod_method back from the Store and Network resources (internal requests only), so a save no longer looks lost; the network model declares pod_method so network settings send it - Opening Settings shows a skeleton of the settings shell and the General page instead of the dashboard's; gateways and notification channels show their section and item
test: run the customer controller tests against core-api 1.6.69
…ands no longer pile up - The Store and Network APIs return the store's timezone (else its company's) and its current utc_offset; food trucks' and cart items' store carry them too - The console reads store times with that offset instead of the browser's timezone data (some browsers format every zone as UTC): the dashboard's open state, every time in the order panel, the edit and new order forms, the reschedule modal, the booking day strip, and order times in lists (utils/store-time, the store-time helper) - Every scheduled command skips a run while the last is still going, with a lock that expires in minutes: every-minute runs that took longer stacked up and starved the server
…QPay token reuse and customer order stores (cherry picked from commit b9dd0dac0f11dd7d020c63d126033059b67c2f43)
…promotion hub, redemptions, attention, reviews off and store memberships (cherry picked from commit 33a756a436b8cac4dcb505247d23ae38f0df2863)
…log assignment, food trucks and filters (cherry picked from commit 1175a839f87d51a7bb0bef923a3c460e02322b37)
… gaps (cherry picked from commit bc178e712513cb98466c54ae708beea29a246bdd)
…otes and redemptions (cherry picked from commit e51fe5425760f13c14f61d73500d1fbb0a5e91ee)
…er filter and order edit exception (cherry picked from commit f01ce8989761fc44d83a854bae9b22eb5d4025f7)
…uites both declared catalogCoverageSchema)
…ty observer and step notifications (cherry picked from commit bc7503775f97e0785ce1044a8c6c0d5b930c92a0)
…; the test runner gets 1G - The customer verification fallbacks for cores without findActiveFor(), findActiveForSubject() and consume() can never run: Storefront requires fleetbase/core-api ^1.6.69, which has all three - The full suite, and the coverage run on top of it, needs more than PHP's default 128M; the runner gives the Pest process 1G
…one per process Fleet-Ops keys a new order config by its slugged name (storefront-booking), so the lookup by key missed the config it had just made and every process made another. The config is now found by company and namespace, the oldest of any duplicates is used, and its key is set back to storefront_booking.
The preview built an unsaved place for a typed address, and the delivery quote reads the drop-off by id, so the fee could not be quoted. The address is now saved for the quote inside a transaction that is rolled back, leaving nothing behind. A drop-off saved by the edit itself now belongs to the order's company, which the quote needs to find it.
…tions Core hides expired invites from every query, so an expired network invitation disappeared from the list and overview, and could not be resent or revoked. Those queries now include expired invitations; accepting and declining still refuse them.
requestPhoneVerification texted the number on file, so a customer changing their number got the code on the old one, and a customer with none got nothing while the endpoint reported success. It now passes the new number with core's phone option (fleetbase/core-api#310), so composer requires core-api ^1.6.70.
The contract now runs against fleetbase/fleetbase main with socket auth left off (#719) and fleetbase/postman main expecting the 404 (#71); a re-run of the earlier pull_request run kept the workflow snapshot from before #719. A dispatched run on this branch (38540245475) passed every assertion.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release branch for v0.4.25, cut from
main. Versions are bumped incomposer.json,extension.jsonandpackage.json, andRELEASE.mdhas the notes.This branch collects:
reviews.subject_uuidindex.reviews.order_uuid.Before merging
fleetbase/core-api^1.6.69.Merging this tags
v0.4.25. The version comes from the branch name and is checked against the version files and the first line ofRELEASE.md.