Platen PDF
A multi-repository document platform that separates the web workspace, Go API, and Python processing boundary.
- Role
- Full-stack developer
- Period
- 2025 – Present
- Sources
- 4 grouped repositories
Processing model
One API, multiple legitimate response modes
The browser workspace talks to the Go API. Each operation uses a direct, async, or preview mode.
Browser / workspace
Workspace ownership
Tool selection, file state, preview, and local results remain in the web workspace.
Request boundary
Go API
Owns the application/file boundary and selects the operation-dependent path.
Alternative modes, not sequential stages
Direct response
Immediate document operation / Direct OCR response
A binary response is returned to the browser and the frontend owns the local result state. Text or a searchable PDF is streamed back for the request, with temporary input/output cleanup in the request lifecycle.
Async task / worker
Long-running processing job
The API registers a task, persists or references the source, dispatches a named worker actor, and returns while the worker claims capacity, reports progress, and writes an artifact. The client receives an accepted submission and later uses status and owner-scoped download paths for the terminal result.
Preview mode
Page preview
The backend hashes the prepared PDF for an owner-scoped session, asks the worker for only the requested page, and recreates a failed cached session before retrying the render. A page image is returned for workspace preview; it is not treated as the final downloadable processing artifact.
Optional local engine
Optional local document engine. Explicit adapter; not a required service.
These are alternative operation-dependent modes, not phases of every request.
Problem
Coordinate browser workflows and document processing without turning every PDF operation into a separate, inconsistent implementation.
Constraints
- The web application, API, and worker have separate responsibilities and release surfaces.
- Uploads, validation, processing, and downloads need reusable boundaries across document workflows.
- PDF edge cases, OCR, and long-running processing require explicit failure and resource-handling decisions.
- The public product is Platen PDF while the web, API, and worker repositories retain their historical PDFNest-era names.
Architecture
Web application
Provide the Next.js/React/TypeScript document workspace, tool routes, shared UI, and browser-side workflow.
Backend/API
Expose the Go/Fiber API and modular document, authentication, upload, and persistence boundaries.
Processing worker
Handle Python/FastAPI and Dramatiq/Redis processing work that should not be owned by the browser shell.
Related document SDK
Provide the local-first, separately published document-processing SDK extracted from the earlier PDFNest OCR work; it can integrate through explicit engine selectors without being required by the Platen PDF runtime.
Evidence record
Mixed classificationsHow the system is split, synchronized, and tested
Platen PDF is documented here as a multi-service document product: the web workspace owns browser interaction, the Go API owns application and file boundaries, the Python worker owns selected processing jobs, and platen-document remains a related local-first engine rather than a required application service.
Ownership boundaries
The system is easier to reason about when authority, policy, processing, and presentation state have explicit owners.
Web workspace
IMPLEMENTEDpdfnest web application
Own tool selection, browser-side file/workspace state, configured API requests, preview presentation, and local result/download state.
Application and file boundary
IMPLEMENTEDpdfnest-backend
Own HTTP routes, identity and quota checks, PDF/upload validation, temporary staging, worker dispatch, task state, artifact access, and cleanup coordination.
Processing boundary
IMPLEMENTEDpdfnest-worker
Own selected Python/FastAPI processing routes, Dramatiq actors, Redis-backed job state, OCR/document engines, progress, cancellation, and worker-side artifacts.
Related local engine
IMPLEMENTEDplaten-document SDK
Provide independently importable local PDF/OCR/document APIs. It does not own Platen PDF authentication, queues, durable storage, billing, or HTTP application routing.
Each boundary is shown with its owner and classification. The arrows describe the evidence-oriented relationship, not a claim that every message moves in one direction.
Transport and boundary contracts
Each boundary describes how data, identity, state, or work crosses between owned parts of the system.
Browser to Go API
IMPLEMENTEDThe web application posts FormData or JSON to the configured API origin. Immediate operations return a binary response; job-oriented operations return a submission/task reference rather than exposing the worker to the browser.
Go API to worker
IMPLEMENTEDThe backend calls the worker over an authenticated HTTP boundary, using signed requests and streaming multipart bodies where a local file is sent; the browser does not call the worker directly.
Job state and artifact boundary
IMPLEMENTEDWorker jobs use queued/running/terminal states and artifact references; the worker mirrors canonical state into the legacy Go task shape so existing status/download routes can continue to serve owner-scoped results.
Preview session boundary
IMPLEMENTEDThe backend prepares a temporary preview input, creates or reuses an owner-and-content-keyed worker render session, requests a page image, and recreates the worker session once when a cached render session fails.
Workflow modes
The product keeps immediate responses, queued processing, and page previews as distinct contracts.
| Workflow | Mode | Entry point / owner | Processing and result | Evidence |
|---|---|---|---|---|
| Immediate document operation | SynchronousIMPLEMENTED | Browser multipart request to short-form structure, optimization, or security routes Owner: Go API and the selected document handler | The API validates and stages the upload, then the route either completes within the backend or delegates a specialized operation before returning the response body. Result: A binary response is returned to the browser and the frontend owns the local result state. | frontend-api, backend-main, backend-validation |
| Direct OCR response | SynchronousIMPLEMENTED | POST /api/ocr/extract-text or /api/ocr/to-text-pdf Owner: Go API with the worker OCR boundary | The API validates the PDF or image set, calls the worker-backed OCR service, and keeps the response tied to the request context; direct worker OCR uses a bounded in-process admission gate. Result: Text or a searchable PDF is streamed back for the request, with temporary input/output cleanup in the request lifecycle. | backend-ocr, worker-ocr |
| Long-running processing job | AsynchronousIMPLEMENTED | Async OCR, editor, markup, and PDF-to-Markdown routes Owner: Go task boundary and Python worker actors | The API registers a task, persists or references the source, dispatches a named worker actor, and returns while the worker claims capacity, reports progress, and writes an artifact. Result: The client receives an accepted submission and later uses status and owner-scoped download paths for the terminal result. | frontend-jobs, backend-markdown, backend-ocr, worker-router, worker-actors |
| Page preview | PreviewIMPLEMENTED | Preview session creation and page-render requests Owner: Go preview service and worker render session | The backend hashes the prepared PDF for an owner-scoped session, asks the worker for only the requested page, and recreates a failed cached session before retrying the render. Result: A page image is returned for workspace preview; it is not treated as the final downloadable processing artifact. | backend-preview |
| Optional local document engine | SynchronousACCEPTED | Explicit internal/sdk engine selectors at the worker/application boundary Owner: Application adapter and platen-document SDK | The application may select the standalone SDK for supported consumers; the SDK processes local paths with native/scanned routing, OCR, structured extraction, rendering, and cooperative callbacks. Result: The application keeps the job, storage, authorization, and lifecycle contract outside the SDK; explicit SDK selection has no implicit runtime fallback. | sdk-api, sdk-architecture |
Architecture decisions
Each decision records the boundary it protects and the alternative that was deliberately not chosen.
Keep the browser at the Go API boundary
ACCEPTED- Decision
- The web application talks to the configured backend origin and never treats the worker as a public browser dependency.
- Why
- Identity, validation, storage, quotas, and worker credentials remain server-owned while the browser keeps a simple tool/workspace contract.
- Alternative considered
- Direct browser-to-worker calls were not chosen because they would expose a processing boundary and bypass the application-owned file/task controls.
Use response mode per workload
IMPLEMENTED- Decision
- Keep direct responses for bounded request work, queued jobs for long-running/progress-bearing operations, and a separate preview path for page inspection.
- Why
- The user experience and resource lifetime differ between a returned blob, a cancellable job, and a page image preview.
- Alternative considered
- Queueing every operation was not treated as the current design because several routes intentionally return synchronously.
Separate async artifacts from local worker paths
IMPLEMENTED- Decision
- Async jobs use job-scoped source/result references and owner-aware download routes rather than returning worker filesystem paths to the client.
- Why
- The job can outlive the request while storage, authorization, cleanup, and artifact expiry stay explicit.
- Alternative considered
- Returning a local temp path to the browser was rejected by the server-owned file boundary.
Keep platen-document optional and standalone
ACCEPTED- Decision
- Treat platen-document as a related local-first SDK selected through explicit application adapters, not as a required Platen PDF web/API/worker service.
- Why
- The SDK can be tested and used locally while the application retains jobs, queues, storage, auth, billing, and UI concerns.
- Alternative considered
- Merging the SDK into the product runtime or presenting it as a mandatory service would misstate its documented architecture.
Publish guardrails, not capacity claims
ACCEPTED- Decision
- Expose implemented byte/page/concurrency/retention guardrails and keep throughput, latency, scalability, and production-capacity claims deferred until controlled evidence exists.
- Why
- Source defaults demonstrate boundaries and failure behavior, but they are not a substitute for a repeatable workload benchmark or production measurement.
- Alternative considered
- Turning configuration limits into a universal capacity claim was rejected as unsupported.
Primary lifecycle
The primary sequence follows input, ownership, processing, result, and cleanup transitions without collapsing synchronous and queued work into one claim.
Receive and validate
IMPLEMENTEDReceive and validate
Go API
Accept the multipart upload, stage it in the dedicated temporary workspace, validate the PDF signature and operation-specific page limit, and resolve the request identity.
Result: Malformed, empty, unreadable, or over-limit input is rejected before processing begins.
Choose response mode
IMPLEMENTEDChoose response mode
Route and application policy
Select an immediate response, a queued task, or a page-scoped preview based on the operation rather than forcing every route through the same job path.
Result: Short request work can return directly while long-running or progress-bearing work receives a durable job boundary.
Persist and dispatch
IMPLEMENTEDPersist and dispatch
Go API
For async work, write the source to an application-controlled storage key, create task state and download capability data, then submit the named worker actor.
Result: The request returns an accepted task reference, or marks the task failed and releases the reservation when dispatch/storage setup fails.
Claim and process
IMPLEMENTEDClaim and process
Worker actor
Claim the queued job, acquire the configured execution lease, download the source into a temporary path, run the selected engine, report progress, and observe cancellation.
Result: The worker records a terminal success, cancellation, or failure with an artifact reference and bounded diagnostic fields.
Serve and clean up
IMPLEMENTEDServe and clean up
Go API and worker storage boundaries
Mirror terminal state, authorize completed-artifact download by owner or capability token, stream the artifact through a temporary download path when needed, and remove request/job temporary files.
Result: The result is available only through the intended completion and ownership boundary; expired or removed artifacts return an explicit unavailable response.
Synchronous request file
Immediate routes keep the upload in a private request workspace and remove temporary input/output files when the handler returns or fails.
Stage
IMPLEMENTEDStage
Go upload middleware
Copy the multipart file into the dedicated temp directory using a UUID-prefixed name and restrictive file permissions.
Result: The handler receives a server-owned path rather than trusting a caller-controlled path.
Process
IMPLEMENTEDProcess
Go handler and worker boundary
Validate the PDF, run the selected operation, and keep worker multipart transfer streamed where delegation is required.
Result: The response is produced without making the browser responsible for backend filesystem state.
Return and remove
IMPLEMENTEDReturn and remove
Request cleanup
Send the result body or file response and remove staged input and temporary output paths in deferred/finally cleanup.
Result: Synchronous artifacts are not represented as durable portfolio-level project files.
Asynchronous source and result
Queued work separates durable job references from local worker paths and uses object-storage keys for the source/result boundary where configured.
Upload to source key
IMPLEMENTEDUpload to source key
Go API storage boundary
Validate the staged upload and persist the source under an application-controlled job key before actor dispatch.
Result: The worker can retrieve the source without receiving a browser filesystem path.
Materialize locally
IMPLEMENTEDMaterialize locally
Python worker
Download the source object into a worker-owned temporary path, process it, and upload the output artifact under a job-scoped key.
Result: Job state references an artifact key rather than exposing the worker's local path.
Download and expire
IMPLEMENTEDDownload and expire
Go task/download boundary
Require terminal completion and owner/token authorization, materialize an object-storage artifact into a temporary download path when necessary, and remove that path after response handling.
Result: Expired, missing, or unauthorized results do not become anonymous file reads.
Preview derivative
Preview rendering uses a temporary derivative and an owner/content-keyed worker session instead of treating a preview image as the final document artifact.
Prepare and fingerprint
IMPLEMENTEDPrepare and fingerprint
Go preview service
Write the upload to a temporary PDF path, hash it with the requesting identity, and reuse an existing preview session when available.
Result: The same owner and source can reuse a render session without sharing it across identities.
Render page
IMPLEMENTEDRender page
Worker render session
Request the selected page at the requested scale and touch the session on success.
Result: The browser receives a page image for inspection while the source remains application-owned.
Recover and clean
IMPLEMENTEDRecover and clean
Go preview service
Delete a failed cached session, recreate it once, retry the page render, and run temporary-file cleanup after the request.
Result: A stale worker render session does not permanently poison the current preview request.
Processing paths
Processing choices are shown with their boundary and limits instead of being collapsed into one generic pipeline claim.
Native/scanned OCR routing
IMPLEMENTEDplaten-document engine and worker OCR adapter
The default route preserves validated native text when appropriate and uses OCR when required; FORCE_OCR is an explicit policy rather than the default.
Limits
- The reviewed source establishes routing behavior, not a universal accuracy or latency number.
Searchable PDF rendering
IMPLEMENTEDOCR result to searchable-PDF renderer
An existing OCR result can be passed into the searchable-PDF renderer, avoiding a second OCR pass; the output is independently validated by the SDK renderer boundary.
Limits
- No cross-device rendering or throughput measurement is published here.
Page-scoped OCR preview
IMPLEMENTEDWorker OCR V2 preview route
Preview input can be reduced to one selected page, with request-byte and page-count guards, then projected back to the original page index in the response.
Limits
- This is a bounded preview path, not evidence that full-document OCR is cheap or universally fast.
Explicit SDK integration selector
ACCEPTEDApplication consumer adapter to platen-document
Supported consumers can select the SDK through explicit engine selectors; the standalone SDK remains independently usable and does not import application jobs, queues, or storage.
Limits
- Selector coverage differs by consumer; the reviewed architecture documents some application paths as internal-only.
Focused code excerpts
Short, source-pinned excerpts make one engineering boundary concrete without reproducing a source file.
Release state when worker dispatch fails
goreq.Header.Set("Content-Type", "application/json")
resp, err := worker.Do(req)
if err != nil || resp.StatusCode >= 400 {
releaseReservation()
tasks.Registry.Set(taskId, "FAILED", 0, "", "Failed to submit job to worker")
idempotency.Release(c, nil)
errMsg := "Failed to submit job to worker"
if err != nil {
errMsg += ": " + err.Error()
} else if resp != nil {
errMsg += fmt.Sprintf(" (HTTP %d)", resp.StatusCode)
}
return c.Status(fiber.StatusBadGateway).JSON(fiber.Map{
"code": "WORKER_DISPATCH_ERR",
"message": errMsg,
})
}This async conversion boundary delegates to the worker and releases reservation, task, and idempotency state when submission fails.
Limit: This is one representative asynchronous route; it is not a throughput, retry-rate, or universal PDF-processing claim.
View exact sourcecommit 9faae1a42155843e0e5a6e472d6a4109ccaa25a8
Failure boundaries
Failure handling is attached to the boundary that owns the response, cleanup, retry, or user-visible state transition.
Input validation
IMPLEMENTED- Trigger
- Empty/non-PDF upload, unreadable document, unsupported content type, or operation-specific page/byte limit exceeded
- Behavior
- The API or worker rejects the input with an explicit client error before processing or removes a partially staged file on failure.
Worker unavailable or dispatch failure
IMPLEMENTED- Trigger
- The backend cannot reach the worker or the worker rejects a submitted actor
- Behavior
- The request receives a deliberate gateway/error response; async setup marks the task failed and releases the reservation rather than leaving an apparently successful job without a processor.
Cancellation and stalled execution
IMPLEMENTED- Trigger
- Client disconnect, user cancellation, actor cancellation request, or worker progress exceeding the configured stale-job window
- Behavior
- Cancellation is propagated where supported, terminal cancellation/failure is recorded, leases are released, and stale jobs transition to failure with an explicit reason.
Artifact access and expiry
IMPLEMENTED- Trigger
- Download requested before completion, by the wrong owner, without a valid capability token, or after the backing object has been removed
- Behavior
- The download boundary returns not-found, forbidden, or gone responses and only serves completed artifacts through the owner/token check.
Engine configuration and availability
ACCEPTED- Trigger
- Selected OCR/document engine is unavailable or explicitly configured with an invalid selector
- Behavior
- Worker/API error codes describe engine unavailability or invalid configuration; the SDK architecture does not imply an invisible fallback when the SDK is explicitly selected.
Evidence, measurements, and limits
Values retain their context, sample, method, and limits so an implementation detail is not mistaken for universal capacity or outcome evidence.
| Evidence | Classification | Result and context | Method / environment / sample | Limitations |
|---|---|---|---|---|
| Request and document guardrails | IMPLEMENTED | The reviewed defaults include a 100 MB Go API body limit; OCR/convert routes commonly default to 150 pages; worker OCR V2 defaults to 100 MB and 150 pages. These are implemented admission boundaries, not throughput or maximum-capacity measurements. | Method: Default-branch source and configuration inspection. Environment: Verified remote default-branch source for the web/API/worker repositories. Sample: Deterministic configured defaults at the audited commits; no workload sample. |
|
| Job retention and stale-job windows | IMPLEMENTED | Worker jobs default to a 24-hour Redis TTL and a 180-second stale-running transition; the legacy Go task mirror uses a one-hour TTL and a 15-minute stale-task default. Retention and stale-state behavior are part of the job contract and may be overridden by environment configuration. | Method: Source/config inspection of worker job storage and Go task registry. Environment: Verified remote default-branch source; configured defaults rather than deployed environment values. Sample: Static configuration values; no production expiration experiment. |
|
| Execution admission bounds | IMPLEMENTED | Worker defaults include four global heavy executions, two per identity, and a 600-second heavy lease; direct OCR routes use a default in-process semaphore of two. These settings make resource admission explicit but are not a tested concurrency capacity guarantee. | Method: Source/config inspection. Environment: Verified remote default-branch defaults; no production load environment. Sample: Static configuration values; no load-test run used for this portfolio record. |
|
| Quantitative capacity and throughput | NOT TESTED | No portable benchmark output, production throughput number, or repeatable end-to-end latency figure was found in the reviewed default-branch material, so no numeric performance claim is published. The evidence boundary is deliberate: configuration guardrails are shown separately from measured workload results. | Method: Bounded search of the four default-branch repositories for benchmark output, profiling captures, timing logs, and load-test results suitable for portfolio publication. Environment: Remote default branches audited at their recorded commits; no shared deployment or controlled benchmark environment. Sample: Source/docs/test inventory only; no quantitative workload sample. |
|
Failure and recovery stories
Each story connects a symptom to an owned boundary and keeps verification limits visible.
Recovering a stale preview render session
IMPLEMENTED- Symptom
- A cached worker preview session can fail when the worker-side session is no longer usable while the backend still has an owner/content mapping.
- Root cause
- The backend preview cache can outlive the worker render session it points to.
- Correction
- Delete the failed mapping, create a fresh worker preview session, store the new owner/content association, and retry the requested page once.
- Verification
- The recovery path is explicit in the audited preview service source; no browser screenshot or deployed failure injection is claimed.
Limitations
- Source inspection does not establish how often this happens in production.
- No end-to-end visual regression run was used as evidence here.
Failing an async dispatch without orphaning the task
IMPLEMENTED- Symptom
- A document has been staged and a task/reservation has been prepared, but worker submission or storage setup can fail before processing starts.
- Root cause
- The application crosses storage, task, billing, and worker boundaries before the actor can claim work.
- Correction
- Release the reservation, mark the task failed where it exists, release idempotency state, and return an explicit storage/worker dispatch error.
- Verification
- The audited PDF-to-Markdown async path contains explicit failure branches; a live fault-injection run was not performed.
Limitations
- This is an implementation boundary, not proof that every failure combination has been exercised.
- No production retry-rate or recovery-time claim is made.
Limitations and deferred evidence
- Evidence is based on the remote default branches audited at the recorded commits: pdfnest main 70db8e8a5a1466ddb154112ed1ddecee6e6cb57e, pdfnest-backend master 9faae1a42155843e0e5a6e472d6a4109ccaa25a8, pdfnest-worker main 9d38852e7ca1e7b657f7f644823d400553886ff0, and platen-document main a5a14413ded0daa93a5839b86554f1fe67d92a93.
- The source confirms implemented boundaries and defaults, not a deployed production topology, operational SLO, or universal capacity result.
- No numeric throughput, latency, memory, or horizontal-scaling claim is promoted because no controlled, portable measurement was found in the audited material.
- Some route families process locally in Go while others delegate to the worker; the evidence intentionally describes representative boundaries rather than claiming every PDF operation follows one path.
- The worker and Go task layers retain compatibility state shapes with different default retention windows; this is documented rather than collapsed into one invented lifecycle number.
- Focused code excerpts and technical screenshots remain deferred; the source links identify the exact evidence commits for later review.
Source evidence
Links point to the commits inspected for this page. The classification attached to each claim is more important than the existence of a link alone.
- Platen PDF frontend API boundary
Configured API origin, multipart blob requests, error/health handling, and download-origin checks.
commit 70db8e8a5a1466ddb154112ed1ddecee6e6cb57e · 2026-09-21
- Platen PDF frontend job client
Editor job submission, status polling, terminal states, cancellation, and stall timeout behavior.
commit 70db8e8a5a1466ddb154112ed1ddecee6e6cb57e · 2026-09-21
- Platen PDF workspace route
Shared tool workspace selection and backend availability boundary.
commit 70db8e8a5a1466ddb154112ed1ddecee6e6cb57e · 2026-09-21
- Platen PDF Go API composition root
API body/time limits, database/Redis startup, route registration, cleanup workers, and service composition.
commit 9faae1a42155843e0e5a6e472d6a4109ccaa25a8 · 2026-09-20
- Go upload validation
PDF magic-header, page-count, and operation-specific limit checks.
commit 9faae1a42155843e0e5a6e472d6a4109ccaa25a8 · 2026-09-20
- Go upload staging and cleanup
Private staged upload paths, restrictive permissions, failure cleanup, and request cleanup.
commit 9faae1a42155843e0e5a6e472d6a4109ccaa25a8 · 2026-09-20
- Go task registry
Task state, TTL, stale transitions, cancellation, owner identity, and download-token fields.
commit 9faae1a42155843e0e5a6e472d6a4109ccaa25a8 · 2026-09-20
- Go task artifact download
Completed-only, owner/token-authorized artifact serving and temporary cloud-download cleanup.
commit 9faae1a42155843e0e5a6e472d6a4109ccaa25a8 · 2026-09-20
- Go worker HTTP client
Signed worker requests, long operation timeout, and streaming multipart request construction.
commit 9faae1a42155843e0e5a6e472d6a4109ccaa25a8 · 2026-09-20
- Go OCR controller
Synchronous and asynchronous OCR paths, cancellation polling, admission, result storage, billing release, and cleanup.
commit 9faae1a42155843e0e5a6e472d6a4109ccaa25a8 · 2026-09-20
- Go async PDF-to-Markdown route
Validation, source-object staging, task registration, worker actor dispatch, and explicit dispatch failure handling.
commit 9faae1a42155843e0e5a6e472d6a4109ccaa25a8 · 2026-09-20
- Go preview session service
Owner/content-keyed preview sessions, page rendering, session touch, recreation, and temporary PDF cleanup.
commit 9faae1a42155843e0e5a6e472d6a4109ccaa25a8 · 2026-09-20
- Go editor worker adapter
Editor extraction/compile job submission, status, cancellation, and download boundary.
commit 9faae1a42155843e0e5a6e472d6a4109ccaa25a8 · 2026-09-20
- Go storage boundary
Application-controlled object/local storage abstraction used by async artifacts.
commit 9faae1a42155843e0e5a6e472d6a4109ccaa25a8 · 2026-09-20
- Platen PDF worker application
FastAPI composition, worker authentication middleware, readiness checks, janitor, render pool, and route registration.
commit 9d38852e7ca1e7b657f7f644823d400553886ff0 · 2026-09-16
- Worker runtime guardrails
Storage mode, job TTL, stale timeout, heavy-execution limits, lease settings, and managed-environment validation.
commit 9d38852e7ca1e7b657f7f644823d400553886ff0 · 2026-09-16
- Worker job model
Queue names, queued/running/cancelled/terminal states, progress, artifacts, errors, ownership, and page status.
commit 9d38852e7ca1e7b657f7f644823d400553886ff0 · 2026-09-16
- Worker job store and task mirror
Redis persistence, optimistic updates, sticky cancellation/terminal state, stale-job transition, and Go task mirror.
commit 9d38852e7ca1e7b657f7f644823d400553886ff0 · 2026-09-16
- Worker job submission routes
Worker job status/cancellation and named actor submission boundary.
commit 9d38852e7ca1e7b657f7f644823d400553886ff0 · 2026-09-16
- Worker processing actors
OCR, searchable PDF, editor, markup, and PDF-to-Markdown queue actors with cancellation, retries, artifacts, and cleanup.
commit 9d38852e7ca1e7b657f7f644823d400553886ff0 · 2026-09-16
- Worker direct OCR routes
Synchronous OCR routes, temporary files, direct OCR admission, disconnect cancellation, and response cleanup.
commit 9d38852e7ca1e7b657f7f644823d400553886ff0 · 2026-09-16
- Worker OCR V2 boundary
Private authenticated OCR V2 input staging, byte/page validation, page-scoped preview derivative, capability reporting, and safe error mapping.
commit 9d38852e7ca1e7b657f7f644823d400553886ff0 · 2026-09-16
- Worker storage boundary
Local/remote artifact storage abstraction, object-key handling, and worker-side materialization boundary.
commit 9d38852e7ca1e7b657f7f644823d400553886ff0 · 2026-09-16
- platen-document public API
DocumentProcessor API, native/scanned routing, callbacks, searchable-PDF result reuse, markup, and local capability boundary.
commit a5a14413ded0daa93a5839b86554f1fe67d92a93 · 2026-09-18
- platen-document architecture
Explicit SDK/application boundary, supported consumer selectors, and excluded auth/job/storage concerns.
commit a5a14413ded0daa93a5839b86554f1fe67d92a93 · 2026-09-18
Repository enrichment
Mutable public facts are optional; the project identity above is portfolio-owned.
pdfnest
Frontend/web application and document workspace
- Updated
- 8 Oct 2026
- Language
- TypeScript
- Stars
- 0
- Forks
- 0
pdfnest-backend
Go backend/API and document service boundary
- Updated
- 16 Oct 2026
- Language
- Go
- Stars
- 0
- Forks
- 0
pdfnest-worker
Python/FastAPI processing worker
- Updated
- 16 Sept 2026
- Language
- Python
- Stars
- 0
- Forks
- 0
platen-document
Related standalone local-first document/OCR SDK and optional processing engine
- Updated
- 18 Sept 2026
- Language
- Python
- Stars
- 0
- Forks
- 0
Related case studies
Related Engineering Decisions
See the selected constraints, alternatives, and evidence behind this project's key boundaries.
Explore Platen PDF decisionsContent notes
- The existing static screenshot paths are not tracked in this repository, so they are not promoted into the canonical model.
- Platen PDF is the public product/display name; the stable portfolio route remains /projects/pdfnest.
- The web, API, and worker repositories retain their historical PDFNest-era names, while platen-document remains an independent local-first SDK.