A clean backend infrastructure clone inspired by the core workflow concepts behind digital signature platforms such as DocuSign.
This backend engine orchestrates multi-party document signing workflows through stateless authentication, sequential and parallel signing state machines, event-driven audit logging, and decoupled notification processing.
The project focuses on modeling real-world business workflows, enforcing authorization boundaries, maintaining auditability, and structuring backend systems using clean separation of concerns within a Spring Boot ecosystem.
- Tech Stack
- System Architecture
- Domain Model
- Project Structure
- Security & Defenses
- Signing Workflows
- Audit & Notification System
- Controller & API Design
- Service Layer Design
- Production Gap Analysis & Planned Upgrades
- Getting Started
| Technology | Purpose | Selection Rationale |
|---|---|---|
| Java 17 | Core Language | Long-Term Support (LTS) release offering modern language features and strong type safety. |
| Spring Boot | Application Framework | Production-oriented framework providing dependency injection, configuration management, and rapid application development. |
| Spring Security + JWT | Stateless Authentication | Enables token-based authentication without maintaining server-side sessions. |
| Spring Data JPA | Object-Relational Mapping | Simplifies persistence through repository abstractions and transaction support. |
| PostgreSQL | Relational Database | Provides ACID guarantees and strong referential integrity for workflow state management. |
| Lombok | Boilerplate Reduction | Reduces repetitive code through compile-time generation of common methods. |
| Spring Events | Event-Driven Communication | Decouples auxiliary concerns such as auditing and notifications from core workflow execution. |
The application follows a layered architecture designed to separate responsibilities and keep business workflows predictable and maintainable.
[ HTTP Controller Layer ] --> Handles request parsing and authentication context.
β
[ Service Layer ] --> Orchestrates business workflows and validation rules.
β
[ Repository Layer ] --> Encapsulates persistence operations.
β
[ Domain Layer ] --> Entities, enums, and workflow state boundaries.
β
[ Event Layer ] --> Handles audit and notification events.
Core workflow services publish application events whenever important business state transitions occur. Audit logging and notification creation subscribe to these events, allowing auxiliary concerns to remain decoupled from the primary signing workflow.
This design keeps business services focused on workflow execution while allowing supporting functionality to evolve independently.
The primary actor within the system.
Implements Spring Security's "UserDetails" interface to integrate directly with the authentication layer.
A single account may act as both:
- Document Sender
- Document Signer
reflecting real-world usage where users can create and participate in signature workflows simultaneously.
Represents uploaded document metadata.
The Document entity tracks ownership and storage metadata while remaining independent from workflow participation logic.
Lifecycle States:
DRAFT β PENDING β COMPLETED
The central workflow aggregate responsible for coordinating document signing activities.
It associates a document with one or more signers while tracking the overall completion state of the workflow.
Lifecycle States:
PENDING β COMPLETED PENDING β DECLINED
Represents an individual's participation slot within a workflow.
Encapsulates signer-specific metadata such as:
- Signing Order
- Signing Status
- Signature Timestamp
This separation prevents workflow-specific state from polluting the global User entity.
Captures forensic evidence associated with a completed signature action.
Stores:
- Global UTC timestamp
- Client IP address
to provide an immutable record of signature execution.
An append-only historical ledger that records significant system events.
Designed to support operational traceability and lifecycle reconstruction.
Represents user-facing alerts generated by workflow state transitions.
Notifications maintain their own lifecycle and read/unread state independent of workflow execution.
To mitigate Broken Object-Level Authorization vulnerabilities, protected endpoints enforce ownership validation using Spring Security expressions and a custom evaluation component.
@PreAuthorize("@documentSecurityEvaluator.isParticipant(#requestId, principal.username)")This validation ensures that only authorized participants associated with a workflow may access protected resources.
All audit and transactional timestamps use "java.time.Instant" rather than server-local time representations.
Benefits include:
- Consistent global timestamps
- Elimination of timezone ambiguity
- Improved audit reliability
Business workflows enforce explicit state transitions to prevent duplicate actions and invalid lifecycle progression.
Example:
if (signer.getStatus() == SignerStatus.DECLINED) {
throw new IllegalStateException(
"Business Logic Violation: This request has already been declined."
);
}This prevents repeated workflow execution caused by duplicate submissions or invalid state mutations.
Persistence rules enforce structural consistency beneath the application layer.
Example:
@Table(
name = "signers",
uniqueConstraints = {
@UniqueConstraint(
columnNames = {
"signature_request_id",
"signing_order"
}
)
}
)This prevents invalid workflow configurations containing duplicate signing positions.
All designated signers receive the request simultaneously.
Each signer may complete their action independently without waiting for others.
Suitable for:
- Board approvals
- Internal acknowledgements
- Multi-party consent forms
Signers must execute their actions according to a predefined signing order.
Example:
Signer #1 β Signer #2 β Signer #3
Attempts to sign out of order are rejected by workflow validation rules.
The ordering logic is enforced inside the workflow service layer rather than the persistence layer.
Core services publish workflow events whenever significant state transitions occur.
[ Workflow Service ]
β
βΌ
Audit Event
β
ββββΊ Audit Listener
β ββββΊ AuditLog Entry
β
ββββΊ Notification Listener
ββββΊ Notification Entry
This design keeps workflow execution independent from supporting concerns while maintaining a complete historical record of system activity.
src/main/java/com/docusign/docusign/
βββ config/
βββ controller/
βββ domain/
βββ dto/
β βββ request/
β βββ response/
βββ event/
βββ repository/
βββ service/
POST /api/auth/register POST /api/auth/login
POST /api/documents/upload GET /api/documents/{id} GET /api/documents
POST /api/signature-requests GET /api/signature-requests/{id} GET /api/signature-requests
GET /api/signer-workflow/pending POST /api/signer-workflow/requests/{requestId}/signers/{signerId}/decline
POST /api/signing/{signerId}/sign
GET /api/audit/{signatureRequestId} GET /api/notifications
While the project demonstrates a strong architectural foundation, the following enhancements remain for production-scale readiness.
Replace local filesystem storage with cloud object storage (AWS S3 or equivalent) and serve documents through pre-signed URLs.
Move audit persistence into an isolated processing pipeline to further decouple workflow execution from historical record generation.
Signature request creation currently performs multiple persistence operations across related entities.
A future enhancement will introduce explicit transaction boundaries to guarantee atomic creation of requests and signer assignments under failure conditions.
Rate Limiting
Introduce API rate limiting using Bucket4j or gateway-level throttling.
Email Verification
Require successful email verification before JWT issuance.
Duplicate Registration Checks
Add application-level duplicate email validation before persistence.
Empty Signer Protection
Reject workflow requests that contain empty signer collections.
Token Expiration Metadata
Expose expiration information within authentication responses.
Notification Deep Linking
Include workflow identifiers inside notification payloads to simplify client-side navigation.
- Java 17+
- Maven 3.8+
- PostgreSQL 14+
git clone https://github.com/AkshayTeja3/docusign-clone.git
cd docusign-cloneCREATE DATABASE docusign;spring.datasource.url=jdbc:postgresql://localhost:5432/docusign
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.jpa.hibernate.ddl-auto=update
jwt.secret=your_secret
jwt.expiration=86400000
Run Application
./mvnw spring-boot:run
Developed as a backend engineering project focused on workflow orchestration, authorization boundaries, auditability, and clean service-layer design.