All Case Studies
Foreverkids system at a glance
The main facts of the Foreverkids system build and migration.
| Item | Detail |
|---|---|
| Client and industry | Foreverkids, multi-brand kidswear retailer with a physical shop |
| Market and audience | India; parents buying children's clothing in store and online |
| Engagement period | Mar 2026 to Aug 2026, from repository history |
| Our scope | Online store, in-store POS, accounting, GST and payroll, and migration from Marg ERP |
| Platform and stack | Laravel 12, Blade, Alpine.js, Tailwind CSS 4, MySQL, Redis, Electron POS shell, Shiprocket, PayU, AWS |
Challenge
Foreverkids is a multi-brand kidswear retailer whose shop ran on Marg ERP billing software. Dcrayon built one Laravel system for its online store, shop counter and accounts, and moved the Marg catalogue across.
A kidswear shop that billed every sale through Marg
Foreverkids sells children's clothing from hundreds of labels, in sizes from newborn up to 2XL. The shop billed its sales through Marg, a desktop billing and ERP (enterprise resource planning) package, and Marg's stock report listed 10,460 products. Running a website with its own stock count beside Marg would have meant two stock records for the same shelves, so the project built a single system: storefront, point of sale (POS) and accounting on one database, with the Marg history brought across.
Ten thousand products locked inside an encrypted billing system
Marg's main data files are encrypted in a proprietary format. Its standard exports gave product names, codes and prices, but not the size and colour detail behind each item, so a straight export would have produced a catalogue without variants.
Shelf labels the new till had to read
Every garment in the shop carried a printed Marg label. The barcode field in Marg's product master was empty in every year of data, so nobody knew what number the labels actually encoded. Without that answer, every piece in the shop would have needed relabelling before the new POS could sell it.
Size and colour hidden inside a batch field
Marg stored size and colour together in a single 12-character batch number, such as "9-12M GREY" or "XXL PINK", with colours cut short at seven letters. Those values had to become proper size and colour variants, each with its own stock and price.
Money leaving the drawer by the wrong route
A till handles cash, card, UPI, store credit and returns every day. Returns, credit notes and discounts need rules that the cashier cannot bypass by accident: a bill cannot be refunded twice, a refund in cash cannot exceed the cash taken, and a large discount needs a manager.
Accounts and GST the owner already relied on
The shop's books, GST returns and supplier ledgers ran through Marg and Tally. A replacement had to keep producing the same outputs, or the owner would end up running two systems side by side.
Why a straight Marg export was not enough for Foreverkids
The data problems behind the migration, who they affected and what they would have cost.
| Issue | Who it affected | Business impact |
|---|---|---|
| Marg tables encrypted; exports lacked size and colour | Owner and online shoppers | A catalogue without variants or per-size stock |
| Label barcode field empty in Marg | Cashiers | Every piece in the shop would need relabelling |
| Size and colour packed into one batch field | Stock team and shoppers | No size or colour filters, no per-size stock |
| Accounts and GST in Marg and Tally | Owner and accountant | Two systems running side by side |
Solution
Reading Marg's unencrypted FoxPro indexes
The project's analysis on 2 Jul 2026 looked at every source on hand: a copy of the Marg data folder, the installed Marg program, screenshots of Marg screens and the work already done in the new system. Marg's tables were encrypted, but its FoxPro index files (the .cdx files that make lookups fast) were stored in plain text, and every index entry carried its record number. Two options were rejected. Relabelling the whole shop would have meant printing a new tag for every piece before the first sale. Waiting for a fresh, complete export from Marg would have left the variant data incomplete, because Marg's exports did not include it. Dcrayon instead wrote a parser for the compact B-tree format of those index files and joined the indexes back together.
The recovery produced 44,855 size and colour variants across 10,334 products, with 44,850 of them (99.99 per cent) matched to a product code and name. It traced the number printed on shelf labels to a six-digit serial that Marg assigns to each item and batch, giving 44,745 distinct barcodes mapped to item, size, colour and MRP. It found 168 distinct size values and 1,547 colour values; where text in the size field was not a size, it was moved to a colour guess rather than dropped. The same analysis found Tally-format exports the shop had already produced: a master file with about 9,968 stock items carrying HSN codes and GST rates, and a day book with about 12,000 vouchers for 2025-26, which gave a source for tax codes and supplier ledgers. This work sits within our database design and system integration services.
How shelf labels became barcodes in the new POS
Recovered label serials were loaded into a product barcodes table, which links each barcode to a variant and records its type, its pack unit and a label price, the price printed on the tag for that purchase batch. Billing follows the printed tag: since August 2026 the tag price wins at the counter, which matches how the shop priced stock in Marg. New variants get a barcode automatically when they are created, and a scheduled job at 2.30 am fills in any variant still missing one. If a scan ever opens the wrong article, the cashier can remap that label on the spot. New labels print on a TSC thermal label printer through a service that writes TSPL, the command language those printers use, with a small print agent that sends the labels to the Windows printer.
One stock ledger for the counter and the website
About 9,290 products were imported, and size and colour variants were rebuilt from roughly 37,500 purchase lines across three financial years. Clean-up commands merged duplicate product codes, removed junk rows such as "BALANCED" entries and re-pointed history to the surviving product when two were merged.
Every stock movement is a row in a stock ledger table, with quantity in, quantity out and the running balance, and a transaction type: purchase, purchase return, sale, sale return, adjustment, transfer in, transfer out, opening or scrap. Each row points back to the document that caused it. A stock snapshots table holds the current, reserved and available quantity with a weighted average cost. Because the shop counter and the online store write to the same ledger, a sale in either place reduces the same stock. Reconcile commands rebuild per-variant stock from Marg purchase files when the shop supplies a fresh export, and a stock drift-guard command checks for mismatches between them.
The Foreverkids till: billing, returns and credit notes
The POS bills by barcode scan and shows a size-by-colour grid for each article. Bills can be held and resumed, and held bills expire. Payment can be cash, card, UPI, wallet, store credit or a split across them, and the receipt and daily report show each part of a split. Each sale carries a unique idempotency key, so if the same sale is sent twice, the second request replays the original bill instead of creating a duplicate. Cash drawer movements and staff shifts are recorded, and a salesperson can be attached to each bill.
Returns and exchanges run inside a database transaction that locks the sale. The system works out how much of each line is still returnable, after earlier returns, and refuses anything above it with a message that states what was sold and what has already come back. Credit notes carry an amount, a used amount, a remaining balance, a secure code and an expiry date, and they can be redeemed at the counter or cashed out; a nightly job at 1 am expires old notes. A unique index means one bill can produce only one credit note.
The counter runs in a browser or inside an Electron desktop shell, a kiosk window with a tray icon and automatic updates that prints receipts on USB or network receipt printers. A written POS user guide covers daily use.
Marg-style accounts, GST returns and Tally export
Every POS sale posts a sales invoice, a double-entry journal and a stock ledger entry. Journal entries carry a type (receipt, payment, journal, contra, sales, purchase, credit note, debit note, adjustment or opening), and their lines hold debits and credits against a chart of accounts. Parties are customers, suppliers, both or employees, each with a credit limit. Purchase invoices record GST totals and the balance due, and a unique index on supplier and bill number stops the same supplier bill being entered twice. Purchase returns, debit notes, delivery challans and a cheque register (issued or received; pending, cleared, bounced, cancelled or in hand) complete the books.
For tax and the accountant, a GSTR export service produces GSTR-1 and GSTR-3B files, and a set of Tally services export masters, purchases and the company's books in Tally's XML and tabular formats. Payroll covers attendance, leave, holidays and salary payments, with a profit-share option that pays staff a percentage of monthly POS sales profit.
The online store on the same catalogue
The storefront sells from the same catalogue and stock. Shoppers can filter by size, colour and price, browse brand pages, open a quick view, use a size guide, track an order and read the blog. Product pages show the brand's own Instagram reels: a scheduled job pulls media from Instagram's official API at 3.30 am, matches posts to products and mirrors the thumbnails locally at 4 am, so product pages do not depend on Instagram's servers. A WhatsApp chat button sits on every page, abandoned-cart reminders go out each morning, and back-in-stock notices are sent every two hours.
Checkout runs through Shiprocket's checkout, which the store opens with a signed session and a hashed cart reference; Shiprocket's order webhook is authenticated, de-duplicated on Shiprocket's order ID and only creates an order when the payment succeeded. Card and UPI payments can also run through PayU. Requests to PayU are signed with SHA-512, and on the way back the store checks the reverse hash with a constant-time comparison, confirms that a pending payment exists for that transaction and order, and checks that the amount matches the order total before marking it paid. A failed-payment callback is also hash-checked, and stock is returned only if the order and payment are still pending. This is part of our e-commerce solutions work.
AI help for product names and customer messages
Marg's item names were written for a billing screen, such as "11/144 FROCK WITH PAJAMI". A product enrichment service and console commands use an AI model, through the system's Claude service, to draft readable display names, descriptions and categories for the website, while the POS keeps the original Marg name searchable at the counter. A messaging assistant also answers customer messages from Instagram, Messenger and WhatsApp; incoming messages are processed on a separate supervised queue, so slow replies do not hold up the store or the till.
Blade components and layouts behind every screen
The interface is server-rendered Blade with Alpine.js for interactive parts and Tailwind CSS 4, built with Vite; Alpine components are used in 95 views. Reusable Blade components are grouped from small to large: inputs, alerts, modals, the logo and breadcrumbs at the bottom; the product card, the product schema block and the Shiprocket buy button in the middle; and widgets such as recently viewed, similar products, recommended products, the Instagram reel strip, the cookie consent banner and the chat widget at the top. Partials provide the header, footer, mobile navigation and the product and category filter panels. Separate layouts serve the storefront, the admin panel, the seller area, the delivery partner area, guest pages and the POS.
Roles, sections and the manager PIN
Access depends on who is signed in. Customers, sellers, staff, delivery partners and a read-only product viewer are user roles; administrators are super admin, admin or moderator; and staff carry a role such as manager, cashier, salesperson, support, warehouse or accountant, each mapped to the admin sections it may open. Middleware enforces this on every route group: owner-only pages, admin sections such as catalogue, orders and Tally, an audit log for admin actions, POS sign-in, an open shift before selling, and manager-only actions at the till.
The manager PIN is stored as a bcrypt hash. When a bill discount goes above a percentage or value the store sets, the sale cannot be completed until an active manager or admin in the same store enters their PIN; line-item discounts have their own threshold, discount rules can carry their own PIN, and returns above a set value also need manager approval. Every POS sale stores its idempotency key, every credit note is tied to one source bill, and supplier bills are unique per supplier.
Search, structured data and the Merchant feed
Product search runs through Laravel Scout on the product model, backed by full-text indexes. A sitemap controller publishes an index with separate sitemaps for pages, products, categories and blog posts, and the robots file is generated by the application. A feed controller produces a Google Merchant Center product feed, with product IDs, prices and sale prices in rupees. Pages publish structured data for products, breadcrumbs, the clothing store, the website and its search, the organisation, blog posts and FAQs. Google Analytics and the Meta Pixel load only after the visitor accepts cookies, with their IDs managed from the admin settings. Our technical SEO service covers this layer of the build.
From commit to counter: CI, ratchet and deploy
The code lives in a Git repository with 256 commits between March and August 2026. On every change, a CI pipeline (continuous integration, which runs checks automatically) starts MySQL 8 and Redis 7, installs the application, runs the migrations, checks code style on the changed files with Pint and runs the PHPUnit unit and feature tests. A ratchet step then compares the results with a recorded baseline of 102 passing tests and fails the build if any of them stops passing, so new work cannot quietly break something that already worked. A second job builds the production assets, and a third scans the repository for secrets with gitleaks. Deployment runs only after CI passes and ends with a smoke test.
A production-readiness audit on 2 Jul 2026 confirmed 27 findings across the POS and website, and the nine critical ones, including the return, credit-note and refund rules described above, were fixed in the same session. A QA checklist and a tester brief followed on 17 Jul 2026. Since August 2026 a scheduled guard checks every 30 minutes for code changed directly on the server and records any change in the repository, so the live system and Git cannot drift apart unnoticed. The system is hosted on AWS, with Redis for caching and a supervised queue worker for messages.
Foreverkids stock, POS and accounting tables
The real tables that hold the shop's stock, sales and books.
| Entity | Table or file | What it holds |
|---|---|---|
| Variant | product_variants | Size and colour rows, each with its own MRP, price and cost |
| Barcode | product_barcodes | Barcode, type, pack unit and the label price of its batch |
| Stock movement | stock_ledger | Quantity in and out, running balance, transaction type and source document |
| POS sale | pos_sales | Totals, paid and change amounts, unique idempotency key, salesperson |
| Credit note | credit_notes | Amount, used and remaining balance, secure code, source bill and expiry |
| Journal | journal_entries and journal_lines | Double-entry postings by type, with debits and credits |
Money controls at the Foreverkids till
The rules that protect the cash drawer and the books, and how each was checked.
| Control | Where it applies | How it was checked |
|---|---|---|
| Return limited to sold minus already returned, under a row lock | POS returns | Audit of 2 Jul 2026 and code inspection |
| One credit note per bill, by unique index and locked re-check | Admin credit notes | Audit of 2 Jul 2026 and code inspection |
| Cash refund capped at the cash collected on the bill | POS returns | Audit of 2 Jul 2026 |
| Manager PIN above a store-set discount | POS sale and line discounts | Code inspection |
| Unique idempotency key replays a repeated sale | POS sale | Code inspection |
| PayU reverse-hash and amount check before marking paid | Online checkout | Code inspection |
Results
What the Foreverkids counter, website and accounts do now
At the counter, the recovered Marg label serials are loaded as barcodes, so existing shelf labels can be scanned at the new till, and the cashier can remap a label on the spot if a scan opens the wrong article. Returns, credit notes, refunds and discounts follow rules the till enforces rather than rules staff must remember. Online, customers browse the same catalogue the shop sells from, filter by size and colour, and check out through Shiprocket. For the owner, one system now produces the GST files, the Tally export, payroll and the day's stock position.
The data recovery has measured results, shown in the table below. Commercial figures for the store are not published.
Marg recovery results for Foreverkids
What the index recovery produced, measured against what Marg's own data showed.
| Metric | Baseline | Final | Period | Source |
|---|---|---|---|---|
| Label barcodes linked to an item | 0 (barcode field empty in Marg) | 44,745 distinct barcodes | Three financial years of Marg data | Recovery report |
| Size and colour variants | Not in Marg exports | 44,855 across 10,334 products | Three financial years of Marg data | Recovery report |
| Variants matched to a product code and name | Not applicable | 44,850 of 44,855 (99.99 per cent) | Recovery run, 2 Jul 2026 | Recovery report |
| Distinct size and colour values | Packed in one batch field | 168 sizes and 1,547 colours | Recovery run, 2 Jul 2026 | Recovery report |
Key takeaways
Why the data, not the code, decided this migration
Retail software migrations are usually blocked by data, not code. Here the decisive step was finding that the old system's index files were readable when its tables were not, which turned a relabelling job for the whole shop into an import. The second lesson is that a shop and its website should share one stock ledger from the start; two systems kept in sync by hand drift apart. The third is that money rules belong on the server, with locks and unique keys, because limits on returns, refunds and credit notes are only reliable when the till cannot override them.
For more on Indian tax automation, read our guide to GST billing automation for D2C brands, and for managing large catalogues, our article on product information management for multi-marketplace brands. The Daddy of Tastes case study covers another Laravel build that joins online orders with staff tools.
If you run a shop on desktop billing software and want an online store that shares its stock, talk to our team.
More work













