Synthetic Industry

Job legacy-extract-one-module-behind-interface · revised 11 October 2026

Pull one self-contained module out of a monolith behind a tested interface

One module of a monolith gets a documented interface that every caller uses, a contract test passing on the current code and on a separate copy, and a switch that selects which answers.

You might be seeing

  • Changes to one area need a full-application release and a full regression run
  • Other code reaches into the module's internals and tables, so nobody can change it safely
  • An earlier attempt to split the application stalled because the boundary was never defined

No passwords, keys, card details or admin invites needed to start.

What usually happened

A module inside a monolith is rarely as separate as its folder suggests. Other code calls its internal functions directly, reads its database tables and relies on shared state, so moving it out breaks callers nobody knew about. Extracting the module in one move, as a new service with a new database, replaces an invisible dependency with a network call and a data-ownership problem at the same time. The safer first move is to make the boundary real inside the monolith, prove it with tests, and only then run the module separately.

Who it’s for: An engineering lead whose monolith has one part that changes often, scales differently or needs a different runtime, and who wants to separate that part without rewriting the rest.

Usually starts when: One module forces the whole application to be released together, a team wants to own a part independently, or a part needs a newer runtime than the rest of the code can use.

The result: One agreed module is reachable only through a documented interface. A contract test suite passes against the module in its current place and against a separately running copy, a configuration switch chooses which one answers, and no code outside the module reads its internals or writes its tables.

Check whether this job fits

Five short questions. Your answers stay on this page unless you choose to email them.

How big is the module you want to separate?
How many places elsewhere in the code call the module?
Does the module have its own database tables?
Are there tests for the module?
Can your team host and operate a separate process?

Answer the questions to see whether this job fits.

Nothing is sent anywhere until you choose to email us.

Send an enquiry about this outcome

Checks you can run yourself

  1. Count the places that use the module

    Ask a developer to run this read-only search in a copy of the project folder, replacing the module name and the module's folder name, and send the number. It skips installed dependencies and the module's own folder.

    grep -rn "YOUR_MODULE_NAME" --include='*.rb' --include='*.py' --include='*.php' --include='*.js' --include='*.ts' --exclude-dir=node_modules --exclude-dir=vendor --exclude-dir=YOUR_MODULE_FOLDER . | wc -l

    Look for: A count of references outside the module itself. The fixed scope covers up to 40 call sites.

  2. List the database tables the module touches

    Ask a developer to search the module's code for table names and send the list, not the code.

    Look for: Table names. Then search the rest of the code for the same names: any hit is an access to be routed through the interface.

What you get

  • The interface description and the contract test suite
  • The changed callers and the separately running module as pull requests
  • A map of what the module reads and writes, including database tables, with each access routed through the interface or listed as an exception
  • A runbook for the switch and for switching back

Included

  • One module of up to 15 source files whose behaviour can be described as a small set of operations, in an application with a runnable test suite
  • A written interface for the module: its operations, inputs, outputs and errors, agreed with you before any code moves
  • Moving every caller, up to 40 call sites, onto that interface so that no code outside the module touches its internals
  • A contract test suite of up to 25 cases, run against the module in the application
  • A second implementation of the same interface running as a separate process that you can host, using the same database and the module's own tables (no data is moved or split), passing the same contract tests, with a configuration switch between the two

Not included

  • Hosting, deploying or operating the separate module in production, which stay with your team
  • Splitting the database into a separate one, or distributed transactions across the boundary
  • Rewriting the module in another language, or adding features to it
  • Extracting more than one module, which is a separate job for each
  • Changing how the rest of the application is built or deployed

How we know it’s done

Agreed with you before work starts. Each check produces evidence you keep.

  1. A search of the code outside the module finds no import or call of the module's internal functions and no query against its tables; every use goes through the interface

    Evidence: The search output before and after, and the map of the module's data access with each access routed through the interface or listed as an accepted exception

  2. The contract test suite of up to 25 cases passes against the module in the application, and passes unchanged against the separately running copy

    Evidence: Two test run logs listing the same cases

  3. With the switch set to each implementation in turn on staging, the application's existing tests and the agreed flows pass

    Evidence: Test output and flow results for both settings

  4. Switching from the separate copy back to the in-application module restores the same results for the agreed flows, rehearsed on staging

    Evidence: The rehearsal log with before and after results

Sign-off. You review the interface, the contract tests and the data map, then merge and deploy under your own gates. Passing contract tests cover the behaviours agreed, not every possible use of the module.

If it fails. If the agreed acceptance checks do not pass, you do not pay and you keep the interface, the tests and the map of accesses.

When it fits, and when we stop

It fits when

  • The module has up to 15 files, an owner who can describe what it does and a test suite that exercises it or a list of behaviours you can agree
  • No more than 40 call sites outside the module use it, and they can be found by searching the code
  • The module's own data is read and written only by the module, or the exceptions can be routed through the interface
  • The application runs on a copy with test data and no live customers or payments
  • Your team can host a separate process for the module on staging, and in production if you choose to switch, and operate it

We stop and tell you if

  • The module shares in-memory state or database transactions with the rest of the application in a way that cannot be put behind an interface
  • Other code reads or writes the module's tables in many places that cannot be listed and changed
  • The module's behaviour cannot be exercised without production data or live external effects
  • The call sites are generated dynamically and cannot be found by searching
  • Nobody on your side can host and operate a separate process, even on staging: the seam alone is not covered by this fixed-price outcome, so ask for a quote

What could go wrong

Every change is a pull request your team merges, so it can be reverted. The configuration switch defaults to the module in its current place; switching back to it from the separate copy restores the earlier behaviour. No data is moved in this job: the separate process reads and writes the same database and the module's own tables, only through the interface, so there is nothing to reconcile when you switch back.

Scroll the table sideways to read it all.

RiskHow we handle it
A caller or data access is missed and breaks when the module runs separatelyCallers are found by search and then proved by moving them one at a time with the tests re-run, and the reviewer repeats the search independently.
The contract tests are weaker than the behaviour people rely onThe list of behaviours is agreed with a named person before tests are written, and each test is traced to an item on the list.
A network call adds failure modes the in-process call did not haveThe interface states its errors explicitly, the contract tests include failure cases, and the switch lets you run the in-process version until you are satisfied.

A second reviewer re-searches the code for any remaining access to the module's internals and its tables, checks that the contract tests are not weaker than the behaviour agreed, and re-runs both settings of the switch from the handover notes alone.

How we deliver

We arrange the work and independent review, then show you the result against the agreed checks. You keep authority over your systems.

  • Agree the module, the list of its operations and the definition of done, then run the application's tests on a copy and record the baseline
  • Find every caller and every data access of the module by searching the code, and write the map of what it reads and writes
  • Write the interface and the contract tests against the module as it is, so the tests pass before anything moves
  • Move each caller onto the interface one at a time, re-running the tests after each, until nothing outside the module touches its internals
  • Build the separately running copy of the module against the same interface and run the same contract tests, then add the switch and test both settings
  • Independent review of the interface, the caller changes and the data map, then hand over the pull requests, the evidence and the runbook for switching and switching back

This is a one-off job, not emergency cover or a subscription. We confirm eligibility, the total price, a start window and a delivery date before you accept. Work starts only after agreed inputs, secure access, any licences and necessary permissions are in place. Hosting, platform and supplier charges are excluded unless the written quote includes them. No charge or booking is created by an enquiry.

Need to keep it working?

Discuss a follow-on to extract the next module, or a monthly service that keeps the application's dependencies on supported versions.

Ongoing work is separately scoped and quoted: no monitoring, response-time guarantee or automatic subscription is included in this job.

Explore an ongoing engineering lane, or mention the responsibility you need in your enquiry.

What you can check

This is a new service. We have not delivered this job for a client yet.

Other ways to get this done

  • Stopping after the seam, with the module still inside the application behind its interface, already removes most of the risk. That smaller scope is quoted separately from this job, which also builds the separately running copy; whether you switch to the copy is your decision after you see the tests.
  • If the module is rarely changed and shares most of its data with the rest of the code, leaving it where it is and improving its tests may be the better investment.

Questions

Why not extract it straight into a new service?

Because most failures come from callers and data access that nobody listed. Making the boundary real first, with tests, finds them while everything is still in one place.

Do I have to run the module separately?

No. Whether you switch to the separate copy is your decision. The copy is part of this fixed job, so it needs somewhere to run, even if only on staging. The seam and contract tests alone are quoted separately.

Does the separate module get its own database?

Not in this job. The separate process uses the same database and the module's own tables, reached only through the interface. Splitting the database needs a data-ownership plan and is quoted separately.

Send an enquiry

Send us

  • The language and framework, and the module you want separated and what it does
  • The approximate number of files in it, and how many places call it
  • Whether the module has its own database tables, and whether other code uses them
  • Why you want it separate and how you would host it

Later, once you agree

  • A controlled copy of the source with secrets removed, through the agreed company-controlled secure handoff
  • How to run the application and its tests locally, with synthetic fixtures
  • A named person who can confirm the module's intended behaviour
  • A company-controlled secure handoff agreed before access: no live passwords, keys, private code or customer records by ordinary email.

You own the code, hosting and data. We work from an authorised copy with secrets removed and return pull requests that your team reviews, merges and deploys. We never ask for passwords or tokens in the first enquiry.

A public HTTPS link only, without login details, query strings or fragments. No code or logs.

Sending emails your enquiry and contact address to our team through our mail provider (Resend). It is not kept in a website database. Do not send passwords, keys, recovery links, confidential code or customer records. Your contact email is unverified; nothing is ordered, charged or reserved. Privacy notice.

Email fallback: open your mail app

If website submission is unavailable, review and send the fallback email yourself. An email fallback is not a website receipt. Or write to hello@syntheticindustry.ai with “legacy-extract-one-module-behind-interface” as the subject.