If an assistant remembers everything about a business, you had better be sure it never mixes that memory with another business.
What the system does
MSME-360 is a single dashboard for small and medium businesses. It has a chat assistant, a unified inbox for WhatsApp, Instagram, Facebook and Gmail, GST invoice generation, receipt scanning, and a live link to Google Sheets. The assistant uses Hindsight agent memory (https://github.com/vectorize-io/hindsight) so it can remember past decisions and instructions across sessions.
Hindsight documentation: https://hindsight.vectorize.io/
Agent memory explainer: https://vectorize.io/what-is-agent-memory
I built the backend: Node.js, Express, MongoDB with Mongoose, JWT authentication, encryption for stored credentials, PDF invoices and billing.
The through-line: one rule for every record
The rule is simple. Every record belongs to a userId, and every query is filtered by it. That covers vendors, customers, inventory, inbox threads, vector records and Google Sheet IDs.
A business owner who asks "who is my most reliable vendor?" must only ever get an answer built from their own data and their own memory. A mix up here would not be a small bug. It would end the product.
So I put the check in one place. Every protected route reads the JWT bearer token, finds the user, and passes userId down into the controllers and services. Nothing below that layer is allowed to query without it. When we later added memory and search, the same rule carried over without any new thinking.
Keeping secrets safe
Connecting WhatsApp, Instagram, Facebook and Gmail means storing access tokens for other people's accounts. We never store those as plain text. I wrapped them in AES-256-GCM encryption using Node's built in crypto module, so a leaked database row is useless without the server key. The secret box decrypts only when a message actually needs to be sent.
The write path: fast first, sync later
When someone adds a vendor, customer or inventory item, the API does two things.
POST /api/vendors (JWT bearer token)
1. Save to MongoDB, filtered by userId.
2. Append to Google Sheets in the background.
3. Return 201 right away.
The user gets an answer straight from MongoDB. The Google Sheets update happens without blocking them. If Sheets is slow or fails, the app still feels instant, and the record is already safe.
Invoices from a sentence
The chat can create invoices from messages such as "Create an invoice for Acme Corp for ₹25,000". I used PDFKit to generate the file on the fly, with the company name, GSTIN, PAN and tax rate coming from the user's settings.
This is where memory shows its value. After the owner tells the assistant once to always add 18 percent GST and use 15 day payment terms, Hindsight recalls that instruction and the invoice route receives the right values without asking again.
Billing and uploads
New accounts start on a trial subscription, and the billing controller tracks the plan. For uploads I used Multer to handle receipts and PDFs, then passed the files to the OCR service my teammate built. Keeping uploads, billing and auth in clear separate controllers kept the codebase easy for five people to work in at the same time.
What went wrong
My first version of the user filter lived inside each controller. Two controllers drifted apart and one forgot a check during testing. I caught it, but it scared me enough to move the logic into shared middleware. If a rule has to be true everywhere, put it in one place and make it impossible to skip.
Lessons I would reuse
1. Make tenant isolation a rule of the framework, not a habit of the developers.
2. Return fast, sync later. Slow third party calls should never sit in the user's click path.
3. Encrypt third party tokens at rest from day one. It is much harder to add later.
4. Treat memory as user data. Anything an agent remembers deserves the same access rules as a database row.
5. Split controllers early. Auth, billing, uploads and search are easier to debug apart.
We used Hindsight Cloud for memory, redeeming the promo code MEMHACK99 in the billing section after we registered to get the free credits. We worked with the Band AI desktop app, and the Hindsight community Slack was where we asked our questions. Language model calls go through Groq.
Memory is only a feature when it is safe. Once it is safe, it becomes the reason people trust the product.
Top comments (0)