Skip to content

Senior Engineering Interview Handbook / Chapter 146

Customer-Facing and Forward-Deployed Engineering

A specialty-track chapter that follows one promised customer integration from ambiguous request through a bounded pilot, production hardening, truthful communication, and product learning.

Sales promised the pilot. What did engineering promise?

Suppose an interviewer gives you this engagement:

A large enterprise wants approval workflows from its internal system to appear
in your product. Its API is poorly documented. The customer can meet twice
before launch. Sales has promised a pilot in six weeks.

Walk through discovery, design, delivery, and customer communication.

The pressure invites a premature architecture. You could say webhooks, queue, retries, and mapping service before learning what an approval is. You could also retreat into process: gather requirements, align stakeholders, write a design, make a roadmap. Neither answer demonstrates the work.

The first engineering task is to turn “sync approval workflows” into a claim that can be tested. Does the customer need approvers to be visible, or must changes flow in both directions? Which system owns the decision? What happens when an approver disappears? Is six weeks tied to a contractual event, an executive demonstration, or a cohort that will perform real work?

Customer-facing engineering puts judgment where several kinds of pressure meet. The customer knows the operating pain. Sales knows the commercial stakes. Product knows the roadmap cost. Engineering can see failure modes that may be invisible to everyone else. A senior engineer does not choose one of those truths and dismiss the rest. The job is to make them precise enough for a decision.

Refuse the noun until you understand the work

“Approval,” “integration,” “real time,” and “pilot” sound concrete because they are familiar nouns. Each can conceal several incompatible systems.

Begin with the work the customer is trying to complete. Ask an operator to trace one approval from the moment it is requested to the moment someone may act on it. Identify who creates it, who changes it, who merely reads it, and which mistake would cause harm. Inspect the current path, including the CSV exports, scripts, spreadsheets, and manual checks that polite process diagrams often omit.

Then make the questions change the design:

  • If your product is only a consumer, a read-only import may be useful. If both systems can change approval state, you need conflict ownership rather than merely another endpoint.
  • If a nightly update is acceptable, a batch import with reconciliation may be safer than event infrastructure built against an undocumented API.
  • If employee email is the only apparent identity, test renames, contractors, duplicate addresses, and deactivated accounts before treating it as a key.
  • If the pilot succeeds only when operators abandon duplicate administration, a polished demo with no rejected-record workflow has not proved the outcome.
  • If the date is immovable but the scope is not, a smaller reliable slice may serve the customer better than a broad promise with hidden manual recovery.

Specific discovery is evidence of technical reasoning. “I would gather requirements” is not. “I would ask whether deletions must propagate before an operator can approve work, because the answer changes both the latency target and the safety model” gives the interviewer a decision they can inspect.

The two available customer meetings are themselves a design constraint. The first meeting should not attempt to settle every question verbally. Use it to obtain artifacts: representative payloads, identity rules, state-transition examples, failure exports, security requirements, and the names of people who will operate the pilot. Return for the second meeting with a concrete mapping, the unresolved cases exposed, and a decision to make. Scarce customer time should reduce uncertainty that cannot be resolved from code or documentation.

Make the first commitment smaller than the first request

Assume discovery reveals that the pilot group only needs to see the current approver in your product. The customer’s system remains authoritative. Its API can list approvals but offers no reliable change event and does not document deletion behavior.

A defensible first commitment is now possible: import one workflow type for one pilot group each night, leave approval changes in the source system, and give operators a report of records that could not be matched. This is not a timid version of bidirectional sync. It is a coherent product slice with a clear truth model.

Write the boundary as plainly as you would say it to the customer:

The pilot will show source-system approvers in our product for the selected
group after a nightly import. The source remains authoritative. Unmatched and
invalid records will appear in a review report; we will not guess identities.
The pilot will not write changes back or promise immediate propagation.

That statement prevents several classes of accidental commitment. It also gives design work a center: stable identities, lawful source states, import idempotency, rejected records, freshness, access, and recovery.

The right boundary will not always be a narrow import. Expected variation that administrators can safely understand may belong in configuration. Repeated variation behind a stable contract may deserve an extension point. A need shared across the target market may belong in the core product. A genuinely unique legacy system may justify a customer adapter with named ownership and a retirement decision. Low-volume work may remain a service or a documented manual path. Some requests should be deferred or declined because they violate security, supportability, or product strategy.

The senior move is not to declare custom work inherently bad. It is to make its cost and future visible. “This is our largest customer” changes the value side of the decision; it does not make maintenance, tenant isolation, or false commitments disappear.

Build the pilot as an argument

The pilot should answer the most dangerous unanswered questions, not merely produce an impressive screen. For the approval import, its argument is:

  1. the customer can supply identifiers and states that map without guesswork;
  2. the limited workflow is useful at nightly freshness;
  3. invalid data can be isolated without corrupting valid approvals;
  4. an operator can see what ran and repair or escalate rejected records; and
  5. the team can support this slice while deciding whether broader integration belongs in the product.

The adapter boundary keeps customer vocabulary from leaking through the core system. It should translate source records into a small internal contract, preserve the source identifier and observation time, and return explicit rejections instead of partial objects. If other customers arrive with similar workflows, they can implement the same contract. If they do not, the product has not paid for a speculative platform.

A practical coding round might ask you to implement the import. Clarify the input contract before touching the parser:

Input: a page of source approval records and an import cursor
Output: accepted mappings, rejected records with reasons, and the next cursor

Rules:
- source_approval_id is stable and required
- source_user_id must map to exactly one active tenant user
- duplicate delivery must not create duplicate approvals
- a changed source record may advance state but not move backward illegally
- one malformed record must not discard the rest of the page

Use a durable uniqueness boundary scoped to the tenant and source system. Keep validation separate from writes so the reasons remain testable. Commit the accepted page and its cursor consistently; otherwise a crash can either skip records or make replay ambiguous. If the source rate-limits midway through a run, retry from a known cursor and preserve the same import identity.

Tests should press on the places where customer data resists the model: duplicate pages, a source ID reused with different content, missing users, ambiguous identity matches, out-of-order states, malformed timestamps, partial database failure, expired credentials, rate limiting, and replay after a timeout. Clean code matters, but the distinctive signal is that rejected data remains visible and recoverable.

Production begins where the demo can lie

A demo can succeed with one curated file and an engineer watching the terminal. The pilot becomes production-shaped when people rely on its result without that engineer in the room.

Follow the nightly import through failure. The scheduler starts a run with a stable identity. The adapter authenticates with a tenant-scoped credential and fetches a page. Validation divides accepted records from rejections. Accepted changes commit with the cursor. Metrics record freshness, accepted and rejected counts, duration, and the reason for failure. The operator view reports the last successful observation, not merely the last attempted run.

Now the difference between infrastructure and customer trust becomes visible. Exponential backoff may protect the source API, but it does not tell an operator that twenty-three approvals are missing. A dead-letter queue may retain a record, but it does not explain whether the customer should retry, correct an identity, or wait. Logs may help the engineer, but they are not a support contract.

Make failure operable at the customer boundary. Provide a rejected-record report without leaking sensitive fields, stable error categories, a safe replay path, freshness and lag indicators, and an owner for alerts. Define what support may inspect, which action requires engineering, how credentials are rotated and revoked, and how the integration can be disabled without deleting the last known good state.

Before expanding the cohort, test tenant isolation, authorization, duplicate delivery, source schema drift, backfill, rollback, and a prolonged source outage. Decide what happens when a user is deleted or transferred, not just when one is created. Put customer data retention and diagnostic access under the same scrutiny as the main product. “It is only a pilot” does not exempt real identities from security and privacy obligations.

The prototype has done its job when it changes a decision. Perhaps nightly read-only import is enough. Perhaps operators need faster propagation. Perhaps the missing deletion event makes write-back unsafe. The next milestone should follow that evidence, not the emotional momentum of a successful demo.

Tell the customer exactly where reality ends

Customer communication is part of the engineering system because it determines which behavior people will rely on. Status should name the working capability, the remaining risk, the available choice, and the next decision point.

For the approval pilot, an executive update could be this short:

The nightly import is working in staging with the sample records. The remaining
risk is deactivated users: the source API does not expose a reliable deletion
event, so we cannot yet guarantee that removed approvers disappear safely.

We can keep the pilot date with read-only import and a daily exception review,
or move the date while we validate a broader synchronization contract. We
recommend the read-only pilot. We will review real tenant data Tuesday and make
the cohort decision Thursday.

This does not bury the customer in implementation detail, and it does not launder uncertainty into a green status. It explains the consequence of the unknown and gives the decision maker an honest choice.

The same form works when a customer is disappointed or an executive is angry. State what is known. Separate what is still unknown. Offer bounded options with their consequences. Name the owner and the next checkpoint. An apology may be appropriate, but apology without a changed plan is not recovery.

Commercial usefulness includes a disciplined refusal. If sales has promised bidirectional sync, do not answer with “engineering says no.” Explain that write-back without conflict and deletion semantics can silently reinstate an invalid approver. Offer the read-only pilot, describe the evidence needed to open write-back, and ask the accountable business owner to choose with the trade-off visible.

Do not leave a private product behind

After the pilot, inspect what was learned before celebrating delivery. Which parts belong to the customer’s legacy system? Which exposed a need shared by the target market? Which temporary operations are now recurring support work?

If several customers need approval imports, a versioned adapter contract, mapping configuration, conformance tests, and shared health model may now be earned. If only this customer needs the path, keep the exception explicit and price its ownership honestly. In either case, record who maintains it, how it is monitored, when it will be reviewed, and what event will retire or productize it.

Handoff is an engineering deliverable. A supported integration needs a runbook, diagnostic path, alert owner, credential procedure, customer escalation route, and a way for product to see recurring demand. Heroic delivery followed by permanent dependence on the original engineer is not ownership; it is concealed operational debt.

Carry the same engagement through the interview

This specialty appears in several rounds, but the underlying judgment stays the same.

In a practical coding round, expect messy exports, webhook consumers, mapping validation, migration scripts, or sync debugging. Make input contracts, partial failure, idempotency, rejected records, and diagnosis observable. A working happy path with silent data loss is a weak answer.

In system design, you may be asked for an integration platform, customer workflow engine, migration service, or embedded deployment. Establish source of truth, identity, direction, latency, tenancy, access, data mapping, retry semantics, observability, rollout, rollback, and support ownership. Let the customer outcome determine which components earn a place.

In product judgment, the pressure will often be commercial: a large account, a promised date, or a request that resembles the roadmap. Do not reduce the answer to build versus refuse. Compare a bounded configuration, extension, core change, customer adapter, service, manual path, deferment, or refusal, and make the maintenance consequence explicit.

For a project deep dive, choose an engagement where discovery changed the plan, a prototype encountered real data, or bespoke work became reusable or was deliberately retired. Bring artifacts: a sample data contract, decision record, mapping specification, launch gate, customer update, dashboard, runbook, or retirement plan. Make your own decision authority audible without claiming the work of sales, product, support, or the customer.

In a behavioral or senior-leadership round, expect pressure from a seller, a disappointed customer, an executive-visible delay, or a team inheriting fragile custom code. A credible story includes the business stake, the hidden technical uncertainty, the option you recommended, how you communicated it, who accepted residual risk, and what changed afterward.

Watch for the failure patterns that make a candidate sound busy rather than senior:

  • treating the requested mechanism as the customer’s actual need;
  • turning each account into a fork with no owner or retirement condition;
  • calling a demonstration complete before real-data and support failure modes have been exercised;
  • overpromising to protect momentum, then describing the date as someone else’s fault;
  • ignoring tenant boundaries, credential scope, retention, or diagnostic access because the work is temporary;
  • building retries and queues while leaving failure invisible to operators;
  • collecting customer patterns without changing product direction.

For each one, practice the repair, not merely the warning. Reconstruct the workflow. Narrow the promise. Expose rejected data. Give two truthful options. Name the support owner. Record the product decision.

Practice the promised approval sync until it resists you

Use the chapter’s prompt as one connected week of practice rather than a set of unrelated miniatures.

First, conduct discovery with a partner playing the customer. You get fifteen questions and one request for artifacts. Finish by writing the outcome, source of truth, success evidence, deadline source, and the three uncertainties that could invalidate your design.

Next, implement the paginated read-only importer. Include tenant-scoped stable IDs, validation, explicit rejections, idempotent replay, cursor recovery, and tests for duplicate and malformed records. Then let the source API change one field and rate-limit the backfill.

Third, design the move from demonstration to supported pilot. Add credential rotation, freshness metrics, customer-visible errors, cohort rollout, a disable path, support ownership, and deletion handling. Explain which properties you would verify before allowing bidirectional writes.

Finally, rehearse the executive conversation twice: once when the pilot can meet the date with read-only scope, and once when real data reveals that even read-only import is unsafe. Give a recommendation in plain language. Do not hide behind architecture vocabulary or promise confidence you do not have.

Preparation is adequate when the phrase “the customer needs a sync” no longer causes you to draw arrows immediately. You can discover the work beneath the noun, offer a smallest useful commitment, make failure visible to the people who operate it, tell the truth under commercial pressure, and decide what the product should learn.