Signperu
Electronic signing for PDF documents: the sender builds an envelope, signers sign from a link with an emailed code, and the final PDF is sealed and can be verified publicly.

The problem
A contract sent by message leaves each party waiting blind, with no versions and no clear close, and nothing stops the file from changing after it is signed.
What I built
I built a modular monolith (Spring Boot 4, Java 21, hexagonal DDD) with an Angular 22 frontend. Signers get in without an account through a link and an emailed code; on completion the system stamps the signatures, adds an evidence page and seals the PDF with PAdES and a time stamp.
Outcome
An own product with private access, covering the full cycle: envelope, signing, sealing and public verification.
Decisions that mattered
- 01
Evidence, not just an image
Each signature records the verified email, IP, browser, time, PDF hash and the consent version accepted. The audit log is hash-chained: altering one record breaks the chain.
- 02
The final PDF proves itself
It is sealed with PAdES B-T: a signature with its own certificate plus an RFC 3161 time stamp from an external authority, with a backup one. Without a stamp the envelope stays in SELLANDO and retries.
- 03
The link is not enough
The token travels in the URL fragment, only its hash is stored, and a 6-digit code is required, with at most 5 attempts.
- 04
Events with an outbox
Every state change writes its events to an outbox table in the same transaction. Background tasks use FOR UPDATE SKIP LOCKED and can also be triggered from Cloud Scheduler.
- 05
A monolith, on purpose
No microservices, Kafka or Redis: cost with no benefit at this volume. Contexts (envelopes, documents, identity, notifications, audit) talk through facades and events.
- 06
Built for Cloud Run
A non-root Docker image, PDFs in a private bucket, the sealing key in Secret Manager and Cloud Scheduler triggering background tasks.
Technologies
- Java 21
- Spring Boot 4
- PostgreSQL
- Angular 22
- PDFBox
- BouncyCastle
- Resend
- Cloud Run
- Cloud Storage
C4 model. The pulsing line is the main path of a request.
Level 1 · who uses the system and what it connects to
Level 2 · the applications and data stores it is made of
Level 3 · the components inside the API
- Person
- System
- Container
- Database
- External
- Main path
- 01Sender uploads the PDF
- 02Envelope and fields
- 03Link and code
- 04Signature with evidence
- 05PAdES sealing
- 06Public verification