Where it is going
Proposals
Generated from docs/ROADMAP.md in the AstroBaaS repository. The repository is the source of truth; this page is a copy of it.
Proposals, not commitments. Each one says what it is, who asks for it, roughly what it costs, and — the part that usually decides — what breaks or gets harder if it is built badly.
Ordered by what would make the most difference, not by what is easiest.
Legend: [core] free and GPL · [paid] commercial module · [either] a free core hook with a paid implementation on top.
The five that matter most
1. Sessions that survive a restart · [core] · S
Sessions are held in memory. A deploy signs every editor out mid-edit, and on two nodes a session made on one is not recognised by the other. It is the single most visible rough edge for anyone running this seriously, and everything below that involves more than one process assumes it is fixed.
Cost: small. A sessions table on the existing storage interface, a
last_seen sweep, and the cookie already carries what is needed.
Trap: a sessions table that is read on every request without an in-process
cache turns one memory lookup into one database round trip per request. Cache
with a short TTL and invalidate on logout — the media base memo is the pattern.
2. A storefront starter kit · [core] · M
The pitch is “works with any vibe-coded frontend”, and the honest gap is that
someone still has to work out what to call and in what order. A Next.js and an
Astro starter that render a real catalogue against a live AstroBaaS — cart,
checkout, an account page, srcset from variants, media_base resolved
properly — turn a claim into a fifteen-minute demonstration.
Cost: medium, mostly design. Trap: a starter that drifts from the API is worse than none. It has to be built in this repository and exercised by the same smoke suite, or it becomes a museum piece within two releases.
3. Stock that cannot oversell · [core] · M
Inventory is a number on a product. Two shoppers buying the last frame in the same second both succeed, because nothing reserves anything. Rare at current volume, unforgettable when it happens — the shop sells something it does not have and has to phone a customer.
Cost: medium. Reservation rows with a TTL, taken at checkout and released on
abandonment, plus a conditional decrement.
Trap: the three storage drivers do not all offer the same atomicity. The
relational driver can do a conditional update; the document drivers need the
existing mutex. This has to be one rule with three implementations, tested
differentially — the same discipline post-query already uses.
4. Order editing and partial refunds · [paid, commerce] · M
Shops change orders constantly: wrong lens index, a frame swapped, a part-refund for a delayed item. Today that is a status change and a phone call. This is the feature that makes the commerce module worth paying for on its own, because the alternative is a spreadsheet.
Cost: medium. An order-revision trail, a refund ledger that reconciles
against the PSP, and an audit entry per change.
Trap: money must never be derived from two places. There is already a
REFUND_ISSUED / REFUND_FAILED audit pair — the ledger has to be the single
source, and the PSP the thing reconciled against it, never the reverse.
5. Search that understands Greek · [core] · S–M
foldForSearch and transliterate already handle Greek↔Latin, and legacy-URL
recovery proves the matching works. Product search does not use it in earnest:
no typo tolerance, no synonyms, no ranking beyond substring position.
Cost: small to medium if it stays in-process (trigram index over folded
text). Large if it becomes a search service, which it should not.
Trap: relevance you cannot explain is relevance you cannot debug. Keep the
score decomposable — matchPath already returns which tokens matched, and a
shop owner asking “why is this product third?” deserves an answer.
Commerce module — the paid surface
| proposal | size | why it earns money | |
|---|---|---|---|
| 6 | Abandoned-cart recovery — the sweep already exists; add a scheduled email with a signed resume link and a one-off code | M | The single highest-ROI feature in e-commerce. Pays for the module in a month on any real volume. |
| 7 | Subscriptions / repeat orders — contact lenses are a recurring purchase and the two live shops sell them | L | Turns a one-off sale into an annuity, for the shop and therefore for the module. |
| 8 | Multi-currency and per-market pricing — price lists per market, not a live FX conversion | M | Unlocks selling beyond Greece, which is where the i18n work already points. |
| 9 | B2B: accounts, price lists, quotes, invoices — an optician chain buying wholesale is a different customer to a consumer | L | B2B customers pay for software; consumers pay for products. |
| 10 | A real returns/RMA flow — request, approve, label, restock, refund, with the Directive’s withdrawal window wired in | M | The legal texts are already generated; this is the workflow around them. |
| 11 | Bundles and kits — frame + lenses + coating as one sellable item with its own stock rules | M | This is how opticians actually sell, and today it is faked with variants. |
| 12 | Loyalty and store credit — a ledger, not a discount code | S–M | Cheap to build on the refund ledger from #4, and shops ask for it constantly. |
Trap that applies to all of them: every one of these touches money. The rule that has held so far — money is computed in one place, in integer cents, and audited — is the reason there has not been a pricing incident. A feature that introduces a second place where a total is computed will eventually disagree with the first.
Verticals beyond optical · [paid]
The optical module proved the plugin platform can carry a whole domain: prescriptions, frame geometry, fit tolerance, its own admin screens and its own schema endpoints. The same shape fits other trades where the product has structured, validated attributes that a generic catalogue cannot express:
- Pharmacy / para-pharmacy — batch numbers, expiry, restricted categories
- Automotive parts — fitment by make/model/year, the classic reason people leave a generic shop platform
- Jewellery — engraving, sizing, hallmark and materials
- Wine and spirits — vintage, region, age verification at checkout
- Made-to-measure — anything with a measurement form and a validation rule
Cost: each one is smaller than optical was, because the platform now exists. Trap: every vertical that reaches into core is a vertical that makes the next one harder. Optical is the proof that a vertical can live entirely behind the plugin API — keep it that way, and say no to the first “just one small core change” request.
Platform and operations · [core]
| proposal | size | note | |
|---|---|---|---|
| 13 | A plugin marketplace / registry — signed packages, a manifest, install from the admin | L | The thing that turns a CMS into an ecosystem. Do not start it before the plugin API has been stable for two releases. |
| 14 | Scheduled publishing for products, not just posts | S | The scheduler exists; products do not use it. Sales campaigns need it. |
| 15 | Content preview links for unpublished work, shareable with a client | S | Signed, expiring, no session. Small, and asked for by everyone with a client. |
| 16 | Webhook replay and a delivery inspector in the admin | S | Deliveries are stored and redeliverable via the API; the admin cannot see them. |
| 17 | Structured logging + an OpenTelemetry exporter | M | LOG_REQUESTS and /metrics exist. Traces are what turn “the shop is slow” into an answer. |
| 18 | Backup to S3-compatible storage, on a schedule | M | The backup endpoints exist and are lowdb-only. This is the gap between “there is a backup feature” and “there is a backup”. |
| 19 | A CLI that talks to a remote instance — astrobaas deploy, astrobaas backup, astrobaas health | M | deploy.sh and the deep health check are already the hard parts. |
| 20 | Uploads to S3/R2 instead of local disk | M | The one thing standing between this and a multi-node deployment, now that media has a clean URL layer. |
Editor and admin
| proposal | size | note | |
|---|---|---|---|
| 21 | Reusable content blocks — edit once, updates everywhere it is used | M | Sections and patterns exist; they are copies. |
| 22 | A media picker that can crop and set a focal point | M | Derivatives are generated; a focal point would make them crop intelligently rather than centre-cropping a face out of frame. |
| 23 | Bulk edit for products — price, category, status across a filtered selection | S | A 436-product shop does this weekly, currently one product at a time. |
| 24 | Drafts and revisions for products, matching posts | S | Revisions exist for posts. A price change has no undo. |
| 25 | A dashboard that answers a question — today’s orders, stock about to run out, dead URLs costing money | M | The data all exists now, including the paid-click 404 report. |
AI, where it is honest
The assistant proxy already exists and keeps the key server-side. Everything here is a bounded use where a wrong answer is visible and cheap:
- Alt text and product descriptions from an image — a draft a human edits. Directly useful: this shop has ~436 products and alt text is mostly empty.
- Translation drafts for the catalogue — the i18n field structure is there; a machine draft that a human approves is exactly the right division of labour.
- Natural-language search over the catalogue, falling back to the real search.
Trap: nothing here should write to the catalogue without a human pressing a button. An AI feature that silently edits a shop’s own product data is the fastest way to lose a shop’s trust, and it is very hard to earn back.
Deliberately not proposed
Worth writing down, because each of these looks attractive:
- A page builder with a block tree. Content is an HTML string that every downstream consumer already reads. A parallel block model would break that, and the sections approach was chosen for exactly this reason.
- Multi-tenancy in core. One database per shop is simpler, safer, and the deployment story already supports it. Tenancy in core would touch every query in the codebase forever.
- A GraphQL API. The REST surface is documented, contract-tested and stable. A second API is a second thing to keep true.
- A visual workflow builder. Webhooks plus plugins already cover the real cases, and the last 20% of a workflow builder is where they all die.
If you only did three things
- Sessions in the database (#1) — unblocks everything multi-process and removes the most visible rough edge.
- A storefront starter kit (#2) — turns the positioning into something a developer can run in fifteen minutes.
- Abandoned-cart recovery (#6) — the paid module’s clearest return, on infrastructure that mostly exists.