A Shared Drive Full of Contracts
A medium Pipeline Design interview practice problem on DataDriven. Design the pipeline on the canvas: sources, transforms, storage and checks, then get feedback on it.
- Domain
- Pipeline Design
- Difficulty
- medium
- Seniority
- L5
Problem
Thousands of contracts land on a shared drive every month in PDF and scanned image format, and legal must be able to produce any original exactly as received years later. Design the pipeline, from the drive to legal's search, that the legal operations analyst who owns the drive needs to extract key terms like party names, dates, and obligations.
Buried in PDFs. The data is in there somewhere.
Business requirements
- Today every contract sits on a shared drive and finding anything means opening files manually; legal needs to be able to search.
- Paralegals search for contracts by counterparty, by clauses like 'auto-renewal', and by expiry date; full-text alone doesn't let them filter by structured fields.
- Each contract is highly sensitive; only the legal team and the right account manager may see it, however they search.
Worked solution and explanation
Why this problem exists in real interviews
Legal can't search a shared drive. Two ways to fix that go wrong differently. Pure full-text search lets them grep but not filter by counterparty or expiry. A warehouse with structured fields lets them filter but doesn't search the body of the document. The actual answer is both, fed by an extraction pipeline, with the originals preserved and per-document access enforced by the platform.
Most candidates upload everything to a search index, run OCR on the scans, and call it done. Paralegals can grep text now, which is better than the shared drive, but they can't ask 'all contracts with auto-renewal expiring next quarter' because expiry isn't a column anywhere; it's a phrase buried in the text. Meanwhile, the search index has every contract indexed equally and an account manager from one team can search and find a contract that belongs to another. Two of the three requirements are unmet.
Walk the requirements
Step 1: Move documents through extraction into a search layer
Uploads land in immutable object storage; an extraction stage OCRs scans, pulls the text, and indexes it in a search engine. Legal queries the search engine and gets back document hits with snippets. The originals stay in object storage and the search index references them by id; legal opens the original from the search result. Without a cold-storage tier the originals have nowhere defensible to live; without a search layer 'I need this contract' is still a manual hunt.
Step 2: Expose both full-text and structured filters
Paralegals search by counterparty, by clauses like 'auto-renewal,' and by expiry date. The extraction stage pulls these as structured fields and writes them to a warehouse table keyed on document id. The paralegal's UI queries the search index for full-text and joins the warehouse for the structured filter. A query like 'auto-renewal contracts expiring next quarter with counterparty Acme' becomes a structured filter on the warehouse plus a full-text intersect on the index. Without a warehouse the structured filters have nowhere to live; full-text alone leaves expiry as a phrase, not a column.
Step 3: Per-document access enforced by the platform
Each contract is sensitive. Per-document permissions live on the document id and propagate to both the search index and the warehouse: the search query returns only documents the user is allowed to see, the warehouse filter excludes the rest, the storage layer denies direct retrieval without permission. A 'we'll filter in the UI' approach is one bypass away from an account manager seeing a contract from another team. The policy is on the document and enforced at retrieval, not at the screen.
The shape that fits
- document_upload (source, API)
- original_archive (storage, object storage)
- ocr_term_extraction (transform, Spark)
- search_index (storage, PostgreSQL)
- metadata_warehouse (storage, warehouse)
- per_document_access_check (quality gate, custom)
- legal_search_ui (consumer)
- document_upload -> original_archive
- original_archive -> ocr_term_extraction
- ocr_term_extraction -> search_index
- ocr_term_extraction -> metadata_warehouse
- search_index -> per_document_access_check
- metadata_warehouse -> per_document_access_check
- per_document_access_check -> legal_search_ui
- Ingest + archive: document_upload, original_archive
- Extraction: ocr_term_extraction
- Search + structured: search_index, metadata_warehouse
- Access + UI: per_document_access_check, legal_search_ui
Common follow-up questions
- Legal asks for an audit log of who searched for which contract. What in this design captures that, and where does it live? (Tests whether the candidate sees that the access-check layer is the right place to log retrievals: every authorised hit is a log entry referencing user, document id, and time. Logging at the search index alone misses retrievals that come straight from object storage.)
- A new clause type ('change-of-control') becomes important and legal wants to filter on it. What changes in this design, and what doesn't? (Tests whether the candidate sees the extraction stage as the extension point: a new structured field in the warehouse, a new extraction rule, and a backfill of historical documents through the same pipeline. The search index, the original archive, and the access check are unchanged.)