AstroBaaS

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

proposalsizewhy it earns money
6Abandoned-cart recovery — the sweep already exists; add a scheduled email with a signed resume link and a one-off codeMThe single highest-ROI feature in e-commerce. Pays for the module in a month on any real volume.
7Subscriptions / repeat orders — contact lenses are a recurring purchase and the two live shops sell themLTurns a one-off sale into an annuity, for the shop and therefore for the module.
8Multi-currency and per-market pricing — price lists per market, not a live FX conversionMUnlocks selling beyond Greece, which is where the i18n work already points.
9B2B: accounts, price lists, quotes, invoices — an optician chain buying wholesale is a different customer to a consumerLB2B customers pay for software; consumers pay for products.
10A real returns/RMA flow — request, approve, label, restock, refund, with the Directive’s withdrawal window wired inMThe legal texts are already generated; this is the workflow around them.
11Bundles and kits — frame + lenses + coating as one sellable item with its own stock rulesMThis is how opticians actually sell, and today it is faked with variants.
12Loyalty and store credit — a ledger, not a discount codeS–MCheap 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]

proposalsizenote
13A plugin marketplace / registry — signed packages, a manifest, install from the adminLThe thing that turns a CMS into an ecosystem. Do not start it before the plugin API has been stable for two releases.
14Scheduled publishing for products, not just postsSThe scheduler exists; products do not use it. Sales campaigns need it.
15Content preview links for unpublished work, shareable with a clientSSigned, expiring, no session. Small, and asked for by everyone with a client.
16Webhook replay and a delivery inspector in the adminSDeliveries are stored and redeliverable via the API; the admin cannot see them.
17Structured logging + an OpenTelemetry exporterMLOG_REQUESTS and /metrics exist. Traces are what turn “the shop is slow” into an answer.
18Backup to S3-compatible storage, on a scheduleMThe backup endpoints exist and are lowdb-only. This is the gap between “there is a backup feature” and “there is a backup”.
19A CLI that talks to a remote instanceastrobaas deploy, astrobaas backup, astrobaas healthMdeploy.sh and the deep health check are already the hard parts.
20Uploads to S3/R2 instead of local diskMThe one thing standing between this and a multi-node deployment, now that media has a clean URL layer.

Editor and admin

proposalsizenote
21Reusable content blocks — edit once, updates everywhere it is usedMSections and patterns exist; they are copies.
22A media picker that can crop and set a focal pointMDerivatives are generated; a focal point would make them crop intelligently rather than centre-cropping a face out of frame.
23Bulk edit for products — price, category, status across a filtered selectionSA 436-product shop does this weekly, currently one product at a time.
24Drafts and revisions for products, matching postsSRevisions exist for posts. A price change has no undo.
25A dashboard that answers a question — today’s orders, stock about to run out, dead URLs costing moneyMThe 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

  1. Sessions in the database (#1) — unblocks everything multi-process and removes the most visible rough edge.
  2. A storefront starter kit (#2) — turns the positioning into something a developer can run in fifteen minutes.
  3. Abandoned-cart recovery (#6) — the paid module’s clearest return, on infrastructure that mostly exists.