This is the twentieth post on this blog. It feels appropriate to write something different — not a detailed breakdown of one feature, but an honest status report on where the product is, what shipped, what didn't, and where we're steering next.
What shipped this year The AI document importer is the standout. It replaced a rigid Excel-only importer that had been in place since the earliest versions of the platform. The old importer worked only if the supplier's spreadsheet exactly matched the expected column layout — any deviation, any extra column, any slightly different header name, and the import failed with a cryptic error. The AI importer accepts PDF, XLSX, XLS, and CSV, handles whatever layout the supplier uses, and classifies every line as exact match, AI decision, or not found. The first real customer imports validated the core bet: that an LLM-augmented pipeline could handle the messiness of real-world supplier documents without requiring the supplier to change their format.
Alongside the importer, we completed trilingual UI coverage for every new surface. The platform now serves en-US, pt-BR, and es-US across all pages — not just the core quote and inventory workflows, but every settings screen, every error message, every confirmation dialog, and every email template. The translation system runs as CI infrastructure: a build step verifies that every locale file has every key present in the en-US base, and missing keys fail the build. No more 'this string is only in English because we forgot to add it to the other files.'
The stock-movement ledger shipped as a foundational piece of the inventory system. Every change to stock — reserve, release, ship, return, receive, adjustment — is recorded as a typed movement with a signed delta, a source document FK, a timestamp, and the user who initiated it. The ledger is append-only: rows are never edited, never deleted. The cache stores the running total; the ledger is the durable record. Any team can audit the full history of any product at any location without asking engineering to run a query.
Three fulfillment documents — DeliveryNote, ReturnNote, and StockReceipt — now share a single posting flow. Posting a delivery moves stock from reserved to shipped. Posting a return moves it from shipped back to on-hand. Posting a receipt books incoming inventory from a supplier. All three create stock movements with the document's ID in the source FK, all three update the same cache, and all three respect the same permission boundaries. The shared flow means warehouse teams learn one pattern, not three.
The permission matrix held up to scrutiny. Four groups — admin, manager, commercial, warehouse — with a documented matrix showing who can CRUD what. No per-tenant overrides, no per-user ACLs, no custom permission classes scattered across views. New features start by adding a row to the matrix, then wiring the check. The simplicity is the feature: when a customer asks 'who can approve a return?' the answer is in a single markdown table, not spread across six files.
The blog you're reading now launched alongside the redesign of the marketing site. Twenty posts covering the technical decisions behind the product — not marketing copy, but honest explanations of why the platform works the way it does. The blog is both an SEO surface and a technical credibility signal: a prospective customer who reads three posts knows more about how Quotery handles inventory than they'd learn from a dozen competitor demos.
What didn't ship We wanted to ship a reporting module — dashboards with sales trends, inventory turnover, quote conversion rates. It didn't happen. The importer consumed more engineering time than planned, and we made the deliberate choice to ship one thing well rather than two things halfway. The reporting data model is designed and the queries are written; the missing piece is the frontend surface. It's the top priority for the next cycle.
Accounting integrations remain on the roadmap. The platform can export data in formats that accounting tools can consume, but there's no direct API integration with any accounting package. This is partly technical — accounting APIs are notoriously inconsistent — and partly a sequencing choice: integration with a tool you don't yet use daily is premature. Now that the core workflows are solid and customers are live, integrations become the natural next layer.
Mobile optimization for warehouse workflows is partial. The platform is responsive and works on a phone, but the warehouse experience — scanning, picking, posting deliveries — was designed for a desktop browser. A dedicated mobile-first warehouse view, optimized for barcode scanning and one-handed operation, is the third major item on the roadmap.
What's next The reporting module comes first. The goal is not a generic analytics dashboard with a dozen widgets nobody uses. It's three focused views: sales performance (quote volume, conversion rate, revenue by customer and product), inventory health (turnover, dead stock, stockout frequency), and team activity (quotes created, deliveries posted, returns processed per user). Each view has a primary chart, a summary table, and an export button. The design principle is the same one we applied to the importer: answer the most important question first, then get out of the way.
Accounting integrations follow. We're evaluating which package to integrate with first based on customer demand and API quality. The integration will be one-directional at first — Quotery pushes invoices and stock valuations to the accounting system, but doesn't pull data back. Bidirectional sync is a harder problem (conflict resolution, data ownership, reconciliation) and we'd rather ship a reliable one-way integration than an unreliable two-way one.
The mobile warehouse view is the third major item. It's not a mobile app — it's a responsive web view optimized for the specific ergonomics of warehouse work. Large touch targets for gloved hands, barcode scanning via the device camera, one-thumb navigation, and offline-tolerant posting (queue the post, sync when connectivity returns). The desktop warehouse view remains for back-office work; the mobile view is for people on their feet.
Beyond the big three, there's a long tail of polish. Scroll position restoration across navigation. Keyboard shortcuts for power users — close quote, post delivery, approve return, all from the keyboard. Better error messages in edge cases that are hard to hit but confusing when you do. Loading skeletons that match the shape of the content they're replacing. These are not roadmap items with deadlines; they're ongoing work that happens between features. The quiet details that separate software you tolerate from software you trust.
What we learned The biggest lesson of the year: AI features succeed or fail on their review UX, not on their model accuracy. The LLM in our importer is good — it classifies roughly 90% of the lines it attempts correctly. But if confirming those 90% felt like work, the feature would have failed. The review UI — inline comparison, single-tap confirm, clear visual hierarchy — is what makes the accuracy usable. A 95% accurate model with a bad review experience is worse than an 85% accurate model with a good one, because the user spends more time fighting the UI than correcting the model.
The second lesson: append-only data models are worth the upfront complexity. The stock movement ledger took longer to design and implement than a simple running-total approach would have. But every audit question, every discrepancy investigation, every 'why was this number different last Tuesday?' is answerable with a query instead of a guess. The ledger has already paid for its complexity in avoided debugging sessions and confident answers to customer questions.
The third lesson: trilingual support is not three times the work. Once the translation infrastructure is in place — key-based lookups, CI enforcement, locale-aware formatting for dates and numbers — adding a third language is mostly translation labor, not engineering labor. The first language after English required building the infrastructure. The third required writing Spanish strings. The marginal cost drops sharply.
A thank-you To the early teams who pushed real supplier PDFs through the importer and told us exactly what broke: thank you. Your willingness to try a new tool on live documents — not test data, not sanitized samples, but the actual messy PDFs your suppliers send — is what made the importer good. Every edge case we handle today (the password-protected PDF, the image-only scan, the supplier who uses six different SKU formats on the same page) exists because someone hit it and told us.
To everyone who read these blog posts and sent feedback: thank you. Writing about technical decisions in public is a forcing function for clarity. Several posts in this series started as notes-to-self and turned into explanations we now use in sales conversations and onboarding sessions. The blog has become an asset we didn't anticipate.
There's a lot more to build. The reporting module, the accounting integrations, the mobile warehouse view, and the quiet polish that makes everything feel a little more solid. But the foundation is real: the importer works, the ledger is append-only, the permissions are simple, and the translations are complete. Year three starts from a good place.
