Skip to content

mdavidgm/signature-workflow

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

64 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

โœ๏ธ Signature Workflow

Live Demo Test Coverage TypeScript License

Production-ready document signature workflow system showcasing complex state management and 100% test coverage.

โœจ Features

  • โœ๏ธ 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

๐ŸŽฏ Why This Project?

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.


๐Ÿš€ Quick Start

Prerequisites

  • Node.js 16+
  • npm or yarn

Installation

# 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 start

Open http://localhost:3000 to view it in your browser.


๐Ÿ—๏ธ Architecture

High-Level Design

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                   Document Actions                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”‚
โ”‚  โ”‚   Sign   โ”‚  โ”‚  Decline โ”‚  โ”‚   Send   โ”‚         โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜         โ”‚
โ”‚       โ”‚             โ”‚              โ”‚                โ”‚
โ”‚       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ”‚
โ”‚                     โ”‚                               โ”‚
โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”                        โ”‚
โ”‚              โ”‚   Workflow  โ”‚                        โ”‚
โ”‚              โ”‚   Manager   โ”‚                        โ”‚
โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜                        โ”‚
โ”‚                     โ”‚                               โ”‚
โ”‚         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚
โ”‚         โ”‚           โ”‚           โ”‚                   โ”‚
โ”‚    โ”Œโ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”              โ”‚
โ”‚    โ”‚ Pending โ”‚ โ”‚ Signed โ”‚ โ”‚Declinedโ”‚              โ”‚
โ”‚    โ”‚  State  โ”‚ โ”‚  State โ”‚ โ”‚ State  โ”‚              โ”‚
โ”‚    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Component Structure

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__/

Key Design Decisions

1. Workflow State Machine

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

2. Signature Canvas Component

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;
}

3. Document Management

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 };
};

๐Ÿงช Testing Philosophy

This project achieves 100% test coverage through rigorous Test-Driven Development.

Test Coverage Breakdown

Coverage Report

Statements   : 100%
Branches     : 100%
Functions    : 100%
Lines        : 100%

Testing Strategy

1. Unit Tests (Components)

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));
  });
});

2. Integration Tests (Workflows)

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();
  });
});

3. State Management Tests

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');
  });
});

Test Commands

# 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.html

๐Ÿ’ก Technical Highlights

1. Signature Capture Technology

Custom 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');
  }
}

2. Workflow Validation

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

3. Responsive Design

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;
  }
}

๐Ÿ› ๏ธ Tech Stack

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

๐Ÿ“ฆ Available Scripts

Development

npm start              # Start dev server (port 3000)
npm test               # Run tests in watch mode
npm run build          # Production build

Quality Assurance

npm run test:coverage  # Generate coverage report
npm run lint           # Run ESLint

Deployment

npm run deploy         # Deploy to GitHub Pages

๐ŸŽ“ What I Learned

Building this signature workflow system taught me:

  1. Complex State Management

    • Finite state machines for workflows
    • State transition validation
    • Immutable state updates
  2. Canvas API Mastery

    • Touch and mouse event handling
    • Drawing optimization
    • Image export and data URLs
  3. 100% Coverage is Achievable

    • Every interaction tested
    • Edge cases covered
    • Confidence in refactoring
  4. Workflow Design Patterns

    • Command pattern for actions
    • Observer pattern for state changes
    • Strategy pattern for validation

๐Ÿš€ Deployment

The app is automatically deployed to GitHub Pages.

Live URL: https://mdavidgm.github.io/signature-workflow/


๐Ÿค Use Cases

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

๐Ÿ”ฎ Future Enhancements

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

๐Ÿ“„ License

This project is licensed under the AGPL-3.0 License - see the LICENSE file for details.


๐Ÿ‘ค Author

Manuel David Garcia Mateos

Full Stack Developer since 2004 | Specialist in Complex Workflows & State Management


๐Ÿ™ Acknowledgments

  • 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


๐Ÿ“Š Project Stats

  • 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

About

Prototype functional to sign, decline, send document to sign and view documents.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages