technomiles-portal

Technomiles Accounts Hub

Internal web app for Technomiles (owners: Aamir Masood and Imran Anwar Awan, 50/50 partners). It pulls orders and marketplace fees from client stores every day and produces month-end statements showing what each client owes Technomiles under their contract.

Today this is done by hand: downloading order files from every platform and calculating in Excel. The goal is to remove that work.

Scope

In scope:

In scope since Sep 2026 (owner’s decision): an internal Company section in the same portal, see “Company accounts” below.

Current clients

Client Stores Currency Agreement
Kensingtons (Mr. Qasim), UK bedding Shopify: Kensingtons Bedding (kensingtonsbedding.co.uk), Raymat Textiles (raymattextile.co.uk); Amazon UK: 1 account; eBay UK: 4 accounts (Kensingtons Bedding kensingtons-uk, Raymat Home raymathome, Online Bedding 4U onlinebedding4u, Duvets Online) GBP 10% of net sale after all online selling expenses (marketplace charges, Shopify fees incl. plan and apps, shipping service charges, ad costs)
Jawa Jewelers, US jewelry Shopify: jawajewelers.com; Amazon US: 1 account; eBay US: 2 accounts (Jawa Fashion goldntime2013, Ask4Fashion) USD 50% of net profit after all expenses

New clients must be addable from the UI with their own terms.

Business decisions (confirmed by the owner, Sep 2026)

These apply to every client, current and future.

Tech stack and hosting

Data model (suggested)

Store money as integer minor units (pence/cents) to avoid rounding errors.

Ledger categories and sign convention

Amounts are signed from the seller’s point of view: money in is positive, costs are negative.

SALES, SHIPPING_CHARGED, TAX_COLLECTED, TAX_WITHHELD, REFUNDS, MARKETPLACE_FEES, FULFILLMENT_FEES, PAYMENT_FEES, SHIPPING_LABELS, ADVERTISING, SUBSCRIPTION, OTHER_FEES, REIMBURSEMENTS, ADJUSTMENTS

Payouts/transfers/withdrawals are money movement, not P&L: do not record them.

Contract terms and calculation

Each client can have one or more terms, each with:

Calculation for a client and month:

  1. Gross = SALES (+ SHIPPING_CHARGED) (+ tax, if included), converted to the client currency at order-date rates
  2. Base = Gross − each selected deduction group (as a positive cost)
  3. Base −= loss carried forward from the previous month; += adjustments carried in from changes to closed months
  4. If Base < 0: share = 0 and the loss carries forward. Otherwise Share = Base × rate + fixed fee
  5. Group everything by currency; never mix GBP and USD.

Kensingtons’ term = 10%, deducting refunds, marketplace, payment, shipping (platform labels + Parcelforce/EVRI), advertising, subscriptions (incl. Shopify plan/apps), other platform fees. Base = “Total net sales” after shipping labels. Jawa’s term = 50%, deducting all of those plus COGS (per-order costs), purchases and other manual expenses (e.g. ShipStation).

Manual expenses are tagged with a deduction group, so they fall into the same checkboxes. A manual expense with no store applies only to terms covering all stores.

COGS = sum of per-order cost entries (item cost + handling) for orders in the month. List orders with no cost entry; they block closing the month.

Month boundaries use the client’s timezone. Lines are assigned to a month by their posted/transaction date.

Statements: view live (draft), then Close to save a snapshot and assign an invoice number. A closed month can still be edited, but its invoiced amount stays fixed; the difference is carried into the next open month as an adjustment. Export CSV and a PDF (print-friendly page) with two parts:

  1. Invoice: Technomiles logo, business details, bank details, invoice number/date, client, month, amount due.
  2. Monthly summary: sales per platform/store, shipping charged, expenses by category, external shipping costs, loss/adjustments carried in, base, share. Per-store and per-category breakdown so the client can check it.

Statement rules as implemented

Platform connectors

Each connector: test connection, then fetch orders and ledger lines for a date range. Every sync re-fetches from (last sync − 3 days) to catch late fees; upserts make this safe. Handle rate limits with retries and backoff. Write a sync log per run.

Keep the mapping from raw API data to orders/ledger lines in pure functions and unit-test them with sample payloads.

Shopify

eBay

Amazon (SP-API)

Screens

Left menu: Dashboard, Clients (dropdown listing every client, plus “All clients” and “Add client”), Settings.

Users and access

Client types

MARKETPLACE (ongoing store management, monthly profit sheet), SERVICE (web development / hosting / website management billed monthly or yearly), PROJECT (one-time work). Service and project clients are billed through invoices (below) rather than statements.

Company accounts

Decided with the owner (Sep 2026):

Demo data (remove before go-live)

npm run demo -- add loads the owner’s Aug 2026 Excel figures (scripts/demo/august-2026.json, no buyer personal data) as orders, ledger lines and expenses tagged DEMO- / [DEMO], and moves the contract terms to start 2026-08 so the profit sheet shows them. npm run demo -- remove deletes all of it, any statements closed for months before 2026-10, and restores the terms to start 2026-10. Run remove before going live.

Rollout

  1. Build Shopify and eBay first (easy access); Amazon once the Seller Central registrations are approved.
  2. Run the first month (October 2026) in parallel with the Excel method and reconcile totals per store and category before relying on it (differences from the old Excel’s missing fees/refunds are expected).
  3. Walmart later, as a new connector.

@AGENTS.md