Production-ready document signature workflow system showcasing complex state management and 100% test coverage.
- โ๏ธ Digital Signature - Sign documents with interactive signature pad
- ๐ค Document Workflow - Send, approve, or decline documents
- ๐ Document Management - View and track all documents
- ๐ State Management - Complex workflow states handled gracefully
- ๐งช 100% Test Coverage - Every interaction fully tested
- โฟ Accessible - WCAG AA compliant interface
- ๐ฑ Responsive - Works seamlessly on all devices
- ๐ Type-Safe - Built with TypeScript in strict mode
Initially created as a technical assessment, this project demonstrates production-grade implementation of a complex document signature workflow:
- โ Complex State Management - Multi-step workflow with validation
- โ Test-Driven Development - 100% coverage achieved through TDD
- โ Clean Architecture - Separation of concerns, maintainable code
- โ Real-world Use Case - Actual DocuSign-like functionality
- โ Professional UI/UX - Polished interface with excellent user experience
This is not just a prototypeโit's a showcase of professional development practices applied to a real business problem.
- Node.js 16+
- npm or yarn
# Clone the repository
git clone https://github.com/mdavidgm/signature-workflow.git
# Navigate to project directory
cd signature-workflow
# Install dependencies
npm install
# Start development server
npm startOpen http://localhost:3000 to view it in your browser.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Document Actions โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ Sign โ โ Decline โ โ Send โ โ
โ โโโโโโฌโโโโโโ โโโโโโฌโโโโโโ โโโโโโฌโโโโโโ โ
โ โ โ โ โ
โ โโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโผโโโโโโโ โ
โ โ Workflow โ โ
โ โ Manager โ โ
โ โโโโโโโโฌโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโผโโโโโโโโโโโโ โ
โ โ โ โ โ
โ โโโโโโผโโโโโ โโโโโผโโโโโ โโโโโผโโโโโ โ
โ โ Pending โ โ Signed โ โDeclinedโ โ
โ โ State โ โ State โ โ State โ โ
โ โโโโโโโโโโโ โโโโโโโโโโ โโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
src/
โโโ components/
โ โโโ DocumentList/ # View all documents
โ โ โโโ DocumentList.tsx
โ โ โโโ DocumentItem.tsx
โ โ โโโ __tests__/
โ โโโ SignatureCanvas/ # Interactive signature pad
โ โ โโโ SignatureCanvas.tsx
โ โ โโโ __tests__/
โ โโโ DocumentActions/ # Sign, Decline, Send
โ โ โโโ SignButton.tsx
โ โ โโโ DeclineButton.tsx
โ โ โโโ __tests__/
โ โโโ shared/ # Reusable components
โ โโโ Button/
โ โโโ Modal/
โ โโโ StatusBadge/
โโโ services/
โ โโโ documentService.ts # Business logic
โ โโโ __tests__/
โโโ hooks/
โ โโโ useDocuments.ts # Document state management
โ โโโ __tests__/
โโโ types/
โ โโโ document.ts # TypeScript definitions
โโโ utils/
โโโ validators.ts # Input validation
โโโ __tests__/
The signature workflow implements a finite state machine:
type DocumentState = 'pending' | 'signed' | 'declined' | 'sent';
interface StateTransition {
from: DocumentState;
to: DocumentState;
action: 'sign' | 'decline' | 'send' | 'reset';
validate: () => boolean;
}Benefits:
- Predictable state transitions
- Easy to test
- Prevents invalid states
- Clear business logic
Interactive signature pad with:
- Touch and mouse support
- Clear/undo functionality
- Signature validation (not empty)
- Export to image data
Implementation:
interface SignatureCanvasProps {
onSave: (signatureData: string) => void;
onClear: () => void;
width?: number;
height?: number;
}Centralized document state using custom hook:
const useDocuments = () => {
const [documents, setDocuments] = useState<Document[]>([]);
const signDocument = (id: string, signature: string) => { /* ... */ };
const declineDocument = (id: string, reason: string) => { /* ... */ };
const sendDocument = (id: string, recipient: string) => { /* ... */ };
return { documents, signDocument, declineDocument, sendDocument };
};This project achieves 100% test coverage through rigorous Test-Driven Development.
Statements : 100%
Branches : 100%
Functions : 100%
Lines : 100%
describe('SignButton', () => {
it('should be disabled when no signature exists', () => {
render(<SignButton hasSignature={false} />);
expect(screen.getByRole('button')).toBeDisabled();
});
it('should call onSign with signature data', () => {
const onSign = jest.fn();
render(<SignButton hasSignature={true} onSign={onSign} />);
fireEvent.click(screen.getByRole('button'));
expect(onSign).toHaveBeenCalledWith(expect.any(String));
});
});describe('Document Signature Workflow', () => {
it('should complete full signing process', async () => {
render(<SignatureWorkflow />);
// 1. Select document
fireEvent.click(screen.getByText('Document 1'));
// 2. Draw signature
const canvas = screen.getByTestId('signature-canvas');
fireEvent.mouseDown(canvas, { clientX: 10, clientY: 10 });
fireEvent.mouseMove(canvas, { clientX: 50, clientY: 50 });
fireEvent.mouseUp(canvas);
// 3. Sign document
fireEvent.click(screen.getByText('Sign Document'));
// 4. Verify success
expect(await screen.findByText('Document signed successfully')).toBeInTheDocument();
});
});describe('useDocuments hook', () => {
it('should update document status when signed', () => {
const { result } = renderHook(() => useDocuments());
act(() => {
result.current.signDocument('doc-1', 'signature-data');
});
const signedDoc = result.current.documents.find(d => d.id === 'doc-1');
expect(signedDoc?.status).toBe('signed');
expect(signedDoc?.signature).toBe('signature-data');
});
});# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Generate coverage report
npm run test:coverage
# View coverage in browser
open coverage/lcov-report/index.htmlCustom implementation using HTML5 Canvas API:
class SignatureCapture {
private ctx: CanvasRenderingContext2D;
private isDrawing: boolean = false;
startDrawing(x: number, y: number): void {
this.isDrawing = true;
this.ctx.beginPath();
this.ctx.moveTo(x, y);
}
draw(x: number, y: number): void {
if (!this.isDrawing) return;
this.ctx.lineTo(x, y);
this.ctx.stroke();
}
stopDrawing(): void {
this.isDrawing = false;
}
export(): string {
return this.canvas.toDataURL('image/png');
}
}Comprehensive validation at each step:
- โ Document exists and is in valid state
- โ Signature is not empty
- โ User has permission to perform action
- โ State transitions are allowed
- โ Required fields are filled
Mobile-first approach with touch support:
/* Desktop */
.signature-canvas {
width: 600px;
height: 300px;
}
/* Tablet */
@media (max-width: 768px) {
.signature-canvas {
width: 100%;
height: 250px;
}
}
/* Mobile */
@media (max-width: 480px) {
.signature-canvas {
height: 200px;
}
}| Category | Technology |
|---|---|
| Framework | React 18 |
| Language | TypeScript 5.0+ (97.2%) |
| Build Tool | Create React App |
| Testing | Jest + React Testing Library |
| State Management | React Hooks (useState, useReducer) |
| Canvas API | HTML5 Canvas for signatures |
| Styling | CSS Modules |
| Linting | ESLint 9 |
| Deployment | GitHub Pages |
npm start # Start dev server (port 3000)
npm test # Run tests in watch mode
npm run build # Production buildnpm run test:coverage # Generate coverage report
npm run lint # Run ESLintnpm run deploy # Deploy to GitHub PagesBuilding this signature workflow system taught me:
-
Complex State Management
- Finite state machines for workflows
- State transition validation
- Immutable state updates
-
Canvas API Mastery
- Touch and mouse event handling
- Drawing optimization
- Image export and data URLs
-
100% Coverage is Achievable
- Every interaction tested
- Edge cases covered
- Confidence in refactoring
-
Workflow Design Patterns
- Command pattern for actions
- Observer pattern for state changes
- Strategy pattern for validation
The app is automatically deployed to GitHub Pages.
Live URL: https://mdavidgm.github.io/signature-workflow/
This signature workflow can be adapted for:
- ๐ Document Management Systems - Internal approval workflows
- ๐ข HR Systems - Employee document signing
- ๐ผ Contract Management - Legal document signing
- ๐ฅ Healthcare - Patient consent forms
- ๐ฆ Financial Services - Account opening documents
Potential features for v2.0:
- Multi-page document support
- Email notifications
- Audit trail logging
- PDF generation
- Biometric signature
- Bulk signing
- Document templates
- Role-based permissions
This project is licensed under the AGPL-3.0 License - see the LICENSE file for details.
Manuel David Garcia Mateos
Full Stack Developer since 2004 | Specialist in Complex Workflows & State Management
- ๐ Website: mdavidgm.com
- ๐ผ LinkedIn: manuel-david-garcia-mateos
- ๐ง Email: mdavid29021984@gmail.com
- ๐ GitHub: @mdavidgm
- Built to demonstrate real-world application architecture
- Showcases professional development practices
- Proves that 100% coverage is practical with good design
- Example of complex state management done right
โก Built with TDD, TypeScript, and 20 years of experience
Transforming complex workflows into elegant solutions
- Lines of Code: 5,000+
- Test Cases: 150+
- Components: 25+
- Coverage: 100%
- TypeScript: 97.2%
- Build Time: <30s
- Bundle Size: Optimized
If this project demonstrates valuable patterns for document workflows, consider:
- โญ Starring the repository
- ๐ Forking for your own use
- ๐ฌ Sharing feedback via issues
