Enterprise contract lifecycle management, from authoring to audit
Role
Frontend Developer
Timeline
May 2025 – Present
Team
Frontend developer, collaborating with backend engineers and designers

11
Modules Delivered
Frontend Developer
Role
In Production
Status
An enterprise contract lifecycle management (CLM) platform that lets organizations create, collaborate on, review, approve, store, and manage contracts securely from a single system — covering everything from first-draft authoring to long-term repository and audit trail.
Legal and business teams needed a single platform to move a contract from first draft through negotiation, approval, and storage without bouncing between email threads, shared drives, and disconnected tools. The platform needed to support real-time collaboration, a structured clause library, AI-assisted drafting, and strict role-based access — all inside one enterprise-grade product.
Contract Authoring, Clause Library, Repository, and Document Collaboration all needed to reflect the same underlying contract state in real time, without each module reinventing its own local copy of that data.
Multiple users editing or commenting on the same contract needed live updates delivered over SignalR without the interface stuttering or losing the user's place mid-edit.
As Version Management, Blockchain Integration, and Audit Logs were added on top of the original authoring and approval flows, the frontend needed a component and state architecture that could absorb new modules without becoming unmanageable.
The frontend is structured around one contract entity that every module reads from and writes to through a shared Redux Toolkit slice, so the Authoring, Clause Library, Repository, and Collaboration views are always looking at the same state rather than four separate copies of it. Real-time changes — a teammate editing a clause, a status change in the approval workflow — arrive over a SignalR connection and are dispatched into that same Redux state, so every open module updates consistently instead of each screen polling independently.
Each module (Authoring, Clause Library, Repository, Collaboration, Approval Workflow, and so on) is organized as its own feature folder with its own components, Redux slice, and API calls, following the same internal pattern so a new module could be added without re-learning a different structure. Shared primitives — data tables, form controls, modals — were built once as a reusable component layer using Shadcn UI and Radix UI primitives, and consumed by every module rather than being recreated per feature.
src/
├─ app/
│ ├─ contracts/
│ │ ├─ [contractId]/
│ │ │ ├─ authoring/page.tsx
│ │ │ ├─ collaboration/page.tsx
│ │ │ └─ approval/page.tsx
│ │ └─ repository/page.tsx
├─ features/
│ ├─ authoring/
│ │ ├─ authoringSlice.ts
│ │ ├─ components/
│ │ └─ api/
│ ├─ clause-library/
│ ├─ repository/
│ ├─ collaboration/
│ │ ├─ collaborationSlice.ts
│ │ └─ use-signalr-connection.ts
│ ├─ approval-workflow/
│ ├─ version-management/
│ └─ notifications/
├─ components/ui/ # shared Shadcn/Radix-based components
├─ lib/
│ ├─ api-client.ts
│ └─ auth/Each module owns a Redux Toolkit slice scoped to its own concern (authoring draft state, clause library filters, approval workflow stage), while contract-level data that multiple modules need — status, participants, current version — lives in a shared contract slice referenced by all of them. This kept module-specific state changes from leaking into unrelated screens, while still giving every module a single, consistent view of the contract itself.
The frontend consumes a REST API backed by a .NET service for standard CRUD operations (drafts, clauses, approvals, audit entries), while live collaboration and notification events are delivered over a persistent SignalR connection rather than polling. A shared API client layer handled request/response typing, auth headers, and error normalization, so individual modules didn't each reimplement their own fetch logic.
Authentication is handled via JWT — the token is issued by the backend on login, attached to REST requests through the shared API client, and also used to authenticate the SignalR connection so real-time events are scoped to the authorized user. Role-based access control is enforced on the frontend by conditionally rendering and routing based on the user's role claims, complementing the authorization checks enforced server-side.
Moved from duplicated per-module contract data to one normalized Redux slice referenced everywhere.
Eliminated stale, out-of-sync UI between modules editing the same contract
Applied memoization to contract list tables and document comparison views to avoid re-rendering rows unaffected by a given state change.
Noticeably smoother scrolling and interaction on large contract repositories
Extracted shared form, table, and modal components used across every module.
New modules reused existing, already-optimized components instead of rebuilding from scratch
Interactive components were built on Radix UI primitives, which provide correct keyboard navigation and ARIA semantics by default for the complex patterns this platform relies on — multi-step approval forms, data tables, and modals — rather than needing to hand-roll accessibility behavior for each one.
Gallery coming soon.