Back

The Journey of the Japan Goods Decision Chain

Japan Goods Decision Chain

The text below was written in July 2026, when the three tools still operated separately. The original has been preserved without changes.

Three questions keep returning when I run this small second-hand goods business in Japan:

  • Where are the underpriced items online?
  • Standing in the shop, what is the most I can pay for this?
  • Once it sells, how should the transaction be recorded?

So I made three tools, one for each question.

None of them is a commercial product. They are production tools built for my own real use. Each one handles discovery, judgment, or record-keeping; together they form a complete path from online market prices to the final entry in the books.

Chain overview

  1. Japan Goods Radar

    Find items priced below the market

  2. In-Store Decision

    Calculate the highest in-store offer

  3. Sales Records

    Record trades and final profit

Japan Goods Radar

Find items priced below the market

What it is

A desktop collection of radars that runs on a Mac.

Its first active module is the Yahoo! Auctions Japan radar. It monitors three verticals on Yahoo!オークション: cameras and lenses, figures and models, and watches.

When the system finds an item clearly below its recent market range, it pushes an alert straight to my phone.

How I use it

  1. Build the market baseline automatically

    At a fixed time every night, it collects the day’s completed-auction prices and writes them to a local database, gradually building a baseline for what each item normally sells for.

  2. Scan live listings during the day

    It scans active listings in several rounds each day. When a buy-it-now price is clearly below recent completed sales, it filters the candidate further before sending it to my phone.

  3. Instant notification when a match is found

    Through ntfy, I can receive alerts in real time while I am out, open the pushed listing link at any time, and decide whether to act.

  4. Review the local overview

    When I need the full picture, a local web panel shows market percentiles, monitored keywords, and low-price candidates on one screen.

How it works

The core arrangement is simple: the computer works at home; I receive the results outside.

  1. Collection

    Rate-limited Python scripts collect public pages while respecting robots rules. Completed-sale data and live-listing data are stored separately in SQLite and inform each other’s judgments.

  2. Scheduling

    macOS launchd runs the jobs on a schedule, with no cloud server involved. Completed-sale data runs nightly; listing alerts run several times a day. The Mac itself is the server.

  3. Decision

    The baseline uses a cleaned low percentile of completed prices from the previous six months. A candidate must clear both a percentage-drop threshold and an absolute-value threshold.

    Items with unverified condition are logged but not pushed. After the first pass, the system reads the listing detail and adds a second-stage judgment for condition and seller risk.

  4. Delivery

    Alerts are sent through ntfy. Installing the ntfy App and subscribing is enough to receive them; there is no relay server to build and no developer account to request.

In-Store Decision

Calculate the highest in-store offer

What it is

A mobile-first web tool.

Standing inside a second-hand shop in Japan, I enter a model number and immediately get the maximum price I can pay in yen.

It compresses Xianyu market prices, exchange rates, costs, and target gross margin into a judgment I can make within seconds of taking out my phone.

How I use it

  1. In-store calculator

    I enter a model number in the home-page search field and filter to the right product.

    After selection, the maximum purchase price appears in large type alongside inspection points for that model.

    The price is calculated in real time from:

    • Xianyu median price
    • Channel fees
    • Target gross margin
    • Carry-back cost
    • The day’s exchange rate

    The result is rounded down.

    If the shop price is higher, I can put the item back immediately.

  2. Purchase ledger

    I record a purchase on the spot. The tool calculates expected gross margin automatically, making it possible to review the quality of each buying batch later.

  3. Shop library and routes

    Shop lists are grouped by the routes I use when visiting them.

    Each shop can be marked “visited this week” with one tap and resets every Monday, matching the rhythm of early-week restocking.

    Apple Maps or Google Maps navigation can be opened directly.

  4. Nearby shop radar

    If I decide to look while already outside, location access lets me search within a few kilometres for second-hand shops and the target retail chains.

How it works

The defining requirement is that it must work in a shop with nothing more than mobile data.

  1. Deployment

    The application runs on a Hong Kong cloud server with Flask, SQLite, an nginx reverse proxy, and systemd supervision, reached through an HTTPS domain.

    The phone only needs to open a web page.

    Hong Kong gives reasonable access from both Japan and mainland China.

  2. Experience

    On first use, an access token is authenticated and written to a Cookie; later visits open directly.

    Adding it to the Safari home screen lets it run full-screen, close to a native App experience without store submission, signing, or review.

  3. Data

    Exchange rates are cached daily from a public API.

    If they have not updated for more than 48 hours, the page warns me so I do not set an offer using a stale rate.

    Nearby-shop data comes from the OpenStreetMap Overpass API, with Apple Maps and Google Maps search available as supplements.

  4. Sync

    The data lives on the server.

    Anything entered on the phone in a shop remains available when I open the same URL on a computer at home, giving the tool natural cross-device continuity.

Sales Records

Record trades and final profit

What it is

A locally run sales-recording and analysis tool for multiple products and multiple sales channels.

It brings product profiles, every purchase and sale, different costs, and sales paths into one place. From individual items to categories to the business as a whole, I can see revenue, profit, and margin whenever I need them.

How I use it

  1. Product profiles

    I can create categories such as sneakers, hiking equipment, and desktop storage, then assign a unique product code to every item.

    Each product can store:

    • Object photographs
    • Sales photographs
    • Chinese product name
    • Japanese product name
    • English product name
    • Product description
    • Sales copy

    When the same product is listed across several platforms, the existing material can be reused directly.

  2. Record every transaction

    The same product can accumulate multiple separate transactions.

    Each record can include:

    • Sale price
    • Quantity
    • Purchase cost
    • Other costs
    • Sales platform
    • Sales path

    The system calculates revenue and final profit for each transaction from the entered data.

    A product is not reduced to one fixed price or one sales record.

  3. Analyse at three levels

    The data can be read at three levels:

    • Product: how many units a particular item sold and how much it earned.
    • Category: which product categories perform better.
    • Overall: total revenue, total profit, margin, and channel performance.
  4. Search and review

    A search by product code or name on the home page retrieves the product profile quickly.

    Together with past transaction records, it helps me review pricing, restocking, and sales-channel choices for the next round.

How it works

  1. Local use

    This is personal software built for my day-to-day buying and selling. Its purpose is to record and review real sales whenever needed, not to provide a service to outside users.

  2. Products and transactions stay separate

    Product profiles hold long-lived or reusable information; sales records hold each real transaction.

    One product can be linked to many sales records.

  3. Automatic totals

    Revenue, costs, profit, and margin are aggregated automatically from real transaction records, without re-entering totals by hand.

  4. Media and multilingual material

    Product images, names in three languages, and sales copy are tied to the product code so they can be reused across different sales platforms.

Together, the three tools form one complete Japan Goods Decision Chain:

  1. Japan Goods Radar finds the opportunity
  2. In-Store Decision sets the highest offer
  3. Sales Records closes the purchase, sale, and final entry

Data accumulates as it moves through the chain, and each link makes the next decision a little more accurate.

From three tools to one chain

The three tools above were not built together, or even for the same purpose.

Japan Goods Radar began because I did not want to check Yahoo! manually every day. In-Store Decision came from the time I stared at a camera in a shop for more than ten minutes, did not dare buy it, then discovered at home that the price had actually been excellent. Sales Records was older still; it was originally made to keep track of trainers.

Each had its own origin. While writing any one of them, I gave no thought to the others. I only realised they formed one chain after I began using them—

If I saw a price on Yahoo!, I opened a second tool to find out what I could pay for that model. Once I brought the item home, I opened a third to enter the transaction. To answer “have I bought this camera before, and what did the last one sell for?”, I had to move back and forth across all three interfaces. The same object left one incomplete record in each of three places, and none knew the others existed.

Standing in a shop with a camera in my hands, that back-and-forth was the part that mattered most.

Discovery, judgement, accounting—their ends had always met. I was simply living them as three separate steps.

What happened next is written below.

The 2.0 development story

  1. The hardest part was not writing the interface, but agreeing what the data meant

    The three tools were written three different ways, and their data formats did not recognise one another. Yet the real blockage was not format. It was definition.

    The radar has a long filtering chain before it calculates a price baseline: remove accessories, remove unrelated models, remove listings whose condition is unclear. At first, to save time, I queried the raw table and inspected that distribution. The result bore no resemblance to the numbers the system actually used. I thought the data was polluted by accessories; in reality, it was not.

    I made a rule after that: before drawing a conclusion from any number, first confirm that it is the number the system truly uses. That rule has saved me many times since.

  2. An error that had been hiding for a long time

    The watch category once had a ¥50,000 price ceiling. Any completed listing above it was excluded from the baseline. I had added it casually long ago, intending only to block absurd data.

    When I removed it, one model’s median jumped from ¥8,650 to ¥89,000—tenfold. Its baseline had always been wrong, and spectacularly so. Most transactions for that model were naturally above ¥50,000; the cap cut off the entire upper half and left only the scraps.

    Worse, the error was not obvious. The median is naturally insensitive to clipping, so everything appeared normal. The two values pulled out of shape were precisely the percentiles used to judge a purchase—the two I actually looked at.

    The final method trims 5% from each end of the price range for each model. There is no fixed monetary cap, so the range rises with the market. I recalculated every model under the new definition.

    Now, opening any model’s market section reveals an “historical baseline” row further down, with the old method labelled “includes ¥50,000 cap”. It is not there as a souvenir. Once a number has changed, I need to know what it looked like before.

  3. The data did not move house

    The easiest way for one panel to read three datasets would have been to copy them into its own database. I did not do that.

    The cost of copying is greater than it looks. Two copies will eventually diverge, and on that day it will be impossible to know which one is correct. The panel therefore copied not one row. Every read is relayed to the original source. It is a little slower, but there is only ever one truth.

    The Sales Records database had another complication: it was made for purely local personal use and never had authentication. To use it from the panel, its port had to remain entirely on localhost. Every request passes through the panel backend, and the outside world never touches it. I retested this after every later change because one missed opening would put those product photographs directly on the public internet.

  4. Those thirty seconds in the shop

    The panel is made for use in a shop. That sentence determined many details that appear unrelated.

    There is no jargon in the interface: percentiles are called “low, middle, high”, with the test written beside them in plain language. All data is sent once and filtering happens locally on the phone, so a tap does not introduce a wait. The gate uses a passphrase I wrote and a six-month Cookie rather than a more orthodox enterprise login; the latter requires an email verification code whenever it expires. Standing in a shop with a camera in my hands and a member of staff watching, I cannot spare that half-minute.

  5. Seventeen batches of changes

    The panel was not finished in one pass. It was worn into shape batch by batch: connect the data first, bring the functions across one at a time, then compare the original three interfaces line by line to see what was still missing.

    That final comparison found eleven omissions, seven of them in the same place: transaction records. The reason was straightforward. I used that part the most, so I built it first, before I knew what the whole thing would eventually become.

  6. Ending

    The chain now runs from beginning to end.

    It has not made me earn more money—it has only let me know a little more before I take out my wallet in a shop.