A general-purpose data analysis platform

GPDAP

The world doesn't run on data. It runs on what you can do with it — and the only way to use data is to analyse it. There are four components, or layers, which are essential to any data analysis tool or platform, be it a generic tool or a custom-built platform for a very specific purpose.

The big 4

A data analysis platform primarily does four individual tasks. You can think of it as four different layers of processing. The four steps are extraction, curation, analysis, and presentation.

Below is how I imagine a data analysis platform — as a stack of the four layers I mentioned.

The platform

Four layers, stacked

Extraction, curation, analysis, presentation — one sitting on the next. Scroll and each layer lifts out to show what it's made of.

Layer 01

Extraction

Get the data, from wherever it lives.

Core

Ingestion core

Sessions, cookies, auth, captchas, headless browsers, workflows — anything a browser can do, given an instruction.

Built on top

Modality modules

Scraper, parser, media tap, fetcher — each holding its own homogeneous output shape.

Configuration

Source workflows

The steps for this site, the field map for that invoice. The part that changes weekly.

Layer 02

Curation

Filter, fix and enrich — the one place data changes.

Core

Structure operations

Generic manipulation of the machine-readable tree the layer above emits — cut, edit, merge.

Built on top

Helpers & reference joins

Helpers that know each modality's shape, plus lookups into datasets that already exist.

Configuration

Rules & enrichments

Drop the nav and tracking param; normalise; fold in the currency list or yesterday's numbers.

Layer 03

Analysis

The ALU. Where the thinking happens.

Core

Compute core

Arithmetic, logic, statistics, probability — the maths exposed as functions.

Built on top

Toolkits & API adapters

Adapters out to anything proprietary or absurd to rebuild — an LLM, as a call.

Configuration

Transaction logic

What this transaction needs computed, in what order, over which inputs.

Layer 04

Presentation

Put the human readability back.

Core

Renderer core

Writers for documents, sheets and decks; encoders for video, images and audio.

Built on top

Templates

Reusable shells above the renderers — the report, the deck, the sheet.

Configuration

Data mappers

Which value lands in which slot of which template. The part that grows forever.

Put back together

It all stacks up

Four layers, one clean contract between each. Stacked together they're not four bespoke tools — they're a single platform that can take on almost any data job.

General‑Purpose Data Analysis Platform GPDAP

The platform

Four layers, stacked

Extraction, curation, analysis, presentation — one sitting on the next. Tap a layer to open it and see the pieces it's made of.

Core

Ingestion core

Sessions, cookies, auth, captchas, headless browsers, workflows — anything a browser can do, given an instruction.

Built on top

Modality modules

Scraper, parser, media tap, fetcher — each holding its own homogeneous output shape.

Configuration

Source workflows

The steps for this site, the field map for that invoice. The part that changes weekly.

Core

Structure operations

Generic manipulation of the machine-readable tree the layer above emits — cut, edit, merge.

Built on top

Helpers & reference joins

Helpers that know each modality's shape, plus lookups into datasets that already exist.

Configuration

Rules & enrichments

Drop the nav and tracking param; normalise; fold in the currency list or yesterday's numbers.

Core

Compute core

Arithmetic, logic, statistics, probability — the maths exposed as functions.

Built on top

Toolkits & API adapters

Adapters out to anything proprietary or absurd to rebuild — an LLM, as a call.

Configuration

Transaction logic

What this transaction needs computed, in what order, over which inputs.

Core

Renderer core

Writers for documents, sheets and decks; encoders for video, images and audio.

Built on top

Templates

Reusable shells above the renderers — the report, the deck, the sheet.

Configuration

Data mappers

Which value lands in which slot of which template. The part that grows forever.

Put back together

It all stacks up

Four layers, one clean contract between each. Stacked together they're not four bespoke tools — they're a single platform that can take on almost any data job.

General‑Purpose Data Analysis Platform GPDAP

Notice that inside each layer are three distinct sub-components. The lowermost component is the core. This is akin to a kernel in an OS. It contains the actual capabilities of that layer — be it scraping for data extraction, a PDF generator for the presentation layer, and so on. Essentially, all the code we write for software is full of abstractions on top of code already written; similarly, the core capabilities are the very core here.

The second layer is for tools built on the core capabilities. These tools — consider them APIs to the core — are much easier to use than the core, just like assembly is fast but we mostly write software in high-level languages like Java and Python because they are an order of magnitude easier to write code in.

The point to remember: generic core and specific top.

The third layer is where we write application-specific code. If this is a platform for financial data analysis, we'd have financial models built in this layer for analysis; if it's a logistics platform, the topmost layer in presentation is about daily transportation reports. These components differ from company to company, depending on what business they are in.

This is what companies do when they build such a platform: they don't consider each layer as separate units, but try to build the entire layer — say, extraction — as a whole. There is a lot of abstraction going on still; however, the goal is not to make configurable platforms that take time, but to build a platform they can ship by the weekend.

However, with just a change in philosophy, one can build a general-purpose data analysis platform that would turn out to be far superior.

01 — The extraction layer

This layer has exactly one job: get the data, from wherever it resides. Starting from any type of digital document — an image, receipts, cards, recorded audio and video, websites — to physical documents, a live feed from sensors, or a camera. This layer's core is built to handle all types of data. It may be noisy, with a lot of gibberish, but it ingests it all. It scrapes websites and platforms that allow it, it integrates APIs, or connects with MCPs. It also exposes APIs for data to be pushed in, and this is the most common way this platform would be used. All for just one purpose: collect data.

Everything the extraction layer can ingest, as a graph. Tap a kind of input to see the sources under it — and the tidy record each one comes out as.

Sources

Comes out as — a document record

That's what "homogeneous" means — not one shape for everything (a video and an invoice share nothing), but every source under the same node producing an identical record. Two documents → the same record; a video → video's own record.

While building this, for example, we don't build a specific scraper for a website to begin with; what we build is a scraping core. The only job of this core is to scrape blindly. This, in conjunction with a sessions core and a login/auth core, would be able to log in to a page and scrape data from there. It's bare-bricks building, right from the very bottom.

The most important thing here — and I'll reiterate this philosophy several times later as well — is that all of this is built on extremely well-defined structures.

I am a sucker for structures.

In this case, when I refer to structures, I mean the output of this layer would be one from a defined set of structures. Say the output for a food bill receipt is a very well-defined JSON format, common for all the food bills that might be uploaded or fetched. It will have an exhaustive list of parameters, and in most cases a change in this structure would simply be an amendment, not an edit.

The reason for solid structures is that this makes the foundation of the system anti-fragile. Essentially, it fails to break, even on purpose.

Therefore these structures have to be thought through religiously from day one, because everything downstream is blindly built against them — and every version has to stay backwards compatible unless you've deliberately committed to a clean break, which would be the rarest of rare cases.

02 — The curation layer

Extraction is deliberately blind. It has no opinion about what matters, so it takes everything it can reach. This means it also took the navigation bar, the cookie banner, the ad slot, the tracking parameter, and the field that came back empty. Curation is where opinions, rules, and guides are applied for the first time with rigour (even extraction has rules, such as don't scrape a page when the response is an HTTP 500 — but those are more about common sense applied in code than about real analytics).

What extraction handed over

  • Page titleDaily FX rates
  • Navigation barHome · About · Contact
  • Cookie banner“We use cookies…”
  • USD rate 83.12
  • EUR rate90.44
  • GBP rate104.20
  • JPY rate0.56
  • USD rate83.12 (again)
  • CHF rate 91.80
  • Ad slot[ advert ]
  • Sponsor banner[ sponsored ]
  • Related linksNews · Markets · Help
  • Notes(empty)
  • Date updated19/07/2026
  • Timestamp19-07-2026 09:00
  • Tracking tagnewsletter
  • Session idsess_9f3a1c
  • Blank note(blank)

The curator's rules

Enrich from data on file · not re-fetched

What moves on to analysis

  • Page titleDaily FX rates
  • Navigation barHome · About · Contact
  • Cookie banner“We use cookies…”
  • USD rate83.12
  • EUR rate90.44
  • GBP rate104.20
  • JPY rate0.56
  • USD rate83.12 (again)
  • CHF rate91.80
  • Ad slot[ advert ]
  • Sponsor banner[ sponsored ]
  • Related linksNews · Markets · Help
  • Notes(empty)
  • Date updated2026-07-19
  • Timestamp2026-07-19 09:00
  • Tracking tagnewsletter
  • Session idsess_9f3a1c
  • Blank note(blank)
This is the one layer that changes the data. It cuts the noise and fixes the formats — but it also adds: reaching into datasets that already exist (a currency list, yesterday's rates, the issuing bank, a geo table) and folding that context in. Each is a separate join, and none of them are extracted per transaction — they were created once, to be looked up. Everything downstream builds on this output — none of it edits the data again.

All sorts of filters are applied here to remove noise and unwanted data, in certain cases intelligent masking, and also certain conversions (like currencies being converted to USD so that there is a standard for the next layer).

Curation is, frankly, an undersell here — because not only are filters and sorts done here, even the addition of data from static or live datasets is done here. Take the previous example of currency conversion: we'd need the currency rate for this. So curation also plugs into static or live data to handle this conversion.

Now, here one must ask: why not have this fed in from the extraction layer itself? The reason for not taking that road is the additional, useless effort. If for every transaction (defined as a process flowing through all data layers to generate an output) I need to get those rates from extraction, the extraction layer is overwhelmed with similar and predictable tasks. So rather, have that task performed only when required — and that too by curation. Also, currency is not raw data on which any process happens; it is a tool, an operator, whereas what we get from the extractor is the operand.

Lastly, this is the last place in the system where raw data is updated or changed, which becomes the only source of truth for the next layer.

03 — The analysis layer

This is the important one — i.e. the brain of the platform. Everything before it was mostly logistics; this is where a transaction actually gets thought about. The unit of analysis here is called a parameter.

A parameter is a self-contained logical unit that accepts inputs (from the previous layer or other parameters), does logical processing, and outputs a response in a fixed structure (the structure is specific for each parameter, and not the same for all parameters). Each parameter also has all possible error scenarios, such as an error in input, a logical error, or anything else — whatever can go wrong is already defined in a parameter. The last thing it has is a version. Anything about a parameter can essentially be updated with a new version of the parameter. Also, multiple versions may live in the same parameter at the same time, each one invoked by a configuration. Below is a depiction of a single parameter.

The unit of analysis — a parameter

ParameterDaily change %v2
InputsToday's rate · curationYesterday's rate · curation
Logic
  1. both rates present?
  2. today − yesterday
  3. ÷ yesterday × 100
may call out ↗
Output
data−0.34%
errornone
Error conditionsmissing input÷ by zeronot a numbera dependency errored

A parameter is one self-contained unit of analysis. It takes defined inputs, runs its own logic, guards every way it can fail, and hands back a strictly-structured output. Tap a part to see what it does.

The engine — find what to compute, then compute it in order

curated inputcomputedcarried onerrorednot needed

Run the analysis to watch the engine plan and compute.

Curated output

Today's rate
Yesterday's rate
Amount
30-day history
Peer rates

Layer 1

Daily change %
Amount in ₹
Volatility
30-day average
Peer gap

Layer 2

Trend
Risk score
Exposure
Momentum
Normal band

Layer 3

Plain-English summarycalls a model ↗
Go / no-go
Threshold alert

Output

To presentation — every parameter's output

First it traces the requested parameters back to everything they stand on — and skips the rest. Then it computes them layer by layer, each layer in parallel, and hands every parameter's output to presentation. If one errors, the parameters below it decide for themselves: carry on with what they have, or throw their own error.

A real transaction needs hundreds, if not thousands, of them. Also, as I mentioned earlier, a parameter may depend on other parameters. So we can visualise it like a node-based directional graph, where the direction is downwards and the root is the output of the curation layer. Because of dependencies, we can put parameters in layers, where a parameter in, say, layer 4 would depend on at least one parameter of layer 3 and no parameter of layer 4 or beyond. In simple words, all dependencies of a parameter are computed in the previous layer itself, and this is true for all parameters.

The way the analysis layer works is that it contains an engine which first identifies which parameters are to be computed (every transaction may require a different set of parameters). Once these parameters are identified, the engine then runs up the graph from these parameters, identifying dependencies and putting them in the same bag as the parameters that were requested. After this step, we know which parameters are to be computed. The engine then starts computing the parameters (in parallel) of each layer, one by one. Failures don't crash, because of the error conditions.

A parameter's logic can also call an API. Some computation is proprietary, or lives in a subsystem it'd be unnecessary to rebuild (the obvious being an LLM). It's all statistics underneath, but you don't assemble one inside your analysis layer when it's already sitting behind an API. The work happens outside, and the answer comes back into the unit to be used. In and out, the same discipline as everywhere else — standard structures both ways.

04 — The presentation layer

Each of the layers prior is operated on entirely by the system, where presentation does not matter — structure does. This is the last layer, where we bring presentation into the picture. Any analysis platform is meant to be used by a human in the end, and this is where we make output according to what makes sense to the human. It may be a PDF report, an HTML page, or a video — all are forms of output a human can make sense of, and therefore needed.

This layer contains three critical parts. The core is, of course, the fundamental builders, such as a PDF builder or an HTML renderer. The middle layer on top of this contains templates and data mappers: a template is essentially a prepared output structure, and a data mapper decides which data goes to which placeholder in the template. The topmost layer is the one that prepares the data for this process.

Template

Monthly volume review

Volume up 36% since January

Total across the period reached 4,356, averaging 544 per month.

⚑ May flagged as an outlier — excluded from the baseline.

None of these are different analyses — it's one result set, mapped into five templates. This is the layer that never stops growing, because every new use case wants its answer shaped a little differently.

This layer never really finishes. Every new use case wants the same answer shaped slightly differently, so the template library keeps growing. This would be one of the most worked-on components, because it deals with design — and designs ALWAYS keep changing.

Bringing it all together

Four layers, one continuous pipeline. Each takes the layer above it as input, fans that input out across its own node types, and folds the results back into a known shape, which is the exact input the next layer is waiting for. Here's the whole thing at once, extraction through to a delivered artefact.

Tap a layer to expand it and see every component ↓

Raw sources
Documents
Web pages
Media
Feeds & APIs
Databases
Email
Sensors
Structured records
Drop empty
Page furniture
Deduplicate
Tracking tags
Tidy spacing
Fix dates & numbers
Currency names
Yesterday's rates
Issuing bank
Region & timezone
Convert currency
Clean, enriched records
Daily change %
Amount in ₹
Volatility
30-day average
Peer gap
Trend
Risk score
Exposure
Momentum
Normal band
Plain-English summary
Go / no-go
Threshold alert
Analysis results
Report
Spreadsheet
Workbook
Slide deck
Chart
Document
Video
Audio brief
Delivered artefacts
One pipeline. Each layer takes the handoff above it, fans it across its own components, and folds the results back into a known shape — the exact input the next layer expects. Expand any layer to see everything inside it; add a component and nothing downstream has to change.

Why this wins

None of this is for its own sake. Because every node is an independent unit built on the foundation — and nothing else — the whole thing gets easy exactly where big systems get hard: building it, scaling it across teams, debugging it, and keeping it alive. Four big wins, and that too with simple, piecemeal components.

Monolith · coupled
Pricing featureScraperAuthParserRates
reaches into everything → touch one, retest all
Build up · on the core
Scraping coregeneric engine · used by allSession + authbuilt on the coreRetailer login flowbuilt on that+ Retailer pricing pagepure config · one sourcespecificgeneric
new node = one more level on the core

A monolith reaches sideways — pulling pieces from everywhere until one change means retesting the lot. Our platform does the opposite: every node builds straight up on the fundamental core, each level narrower than the one below, until the top is pure config for a single source. Nothing is pulled in from unrelated peers, so there's no web of dependencies — you add a level at the top, never reopen the floor.

What adds weight to it is that each new component is an addition to the whole system, not an isolated piece. It's as close to open source as possible, and wonders can be created with this. I've got some ideas already. Would you like to chat about it?

Click here to contact me →

← All work