What is Expiry?
Expiry is a modern contract management dashboard that helps teams track, manage, and automate notifications for contract renewals and expirations. It eliminates surprises by providing visibility into all contract deadlines and automatically alerting stakeholders before contracts expire.
This is a production-ready Next.js 14 application with built-in AI scanning, smart notifications, cost analytics, and a fully automated cron-based email system.
Core Problem Solved
The Problem
- Teams often miss contract renewal deadlines
- Manual tracking across spreadsheets is error-prone
- No clear visibility into upcoming costs and renewal exposure
- Renewal notifications arrive too late or get lost
The Solution
- All contracts tracked in one place
- AI automatically extracts key terms from PDFs
- Smart alerts notify teams 30 days before expiry
- Dashboard with cost breakdown and renewal calendar
- Automated emails ensure no contract is forgotten
Key Features
Highlights based on the official product page:
1. AI Contract Scanning
- Upload PDF or DOCX contracts
- AI extracts vendor, cost, renewal dates, and notice periods
- No manual data entry; batch uploads supported
2. Smart Alert System
- Automatic notifications 30 days before expiry
- Customizable alert windows per contract
- Stay proactive with timely reminders
3. Cost Dashboard
- Total monthly/annual spend and renewal exposure
- Identify cost-saving opportunities; multi-currency
4. Calendar View
- Interactive calendar for expirations; plan renewals
5. Export & Share
- One-click CSV export with up-to-date expiry calculations
- Shareable with finance, legal, and leadership
5. Contract Status Tracking
- Active, Upcoming, Expiring Soon, Expired
6. Authentication & Security
- Supabase Auth; role-based access; service role for cron
7. Automated Email Notifications
- Branded templates sent via Resend
- Includes vendor, costs, expiry date, action links
Architecture Overview
Tech Stack
Frontend: Next.js 14, React 18, TypeScript, Tailwind CSS
Backend: Next.js API Routes, Node.js
Database: Supabase (PostgreSQL)
Storage: Supabase Storage
Auth: Supabase Auth
Email: Resend API
AI: OpenAI API
Hosting: Vercel
High-Level Flow
Upload Contract → AI Scanning → Save to Supabase → Daily Cron → Send Email → Dashboard Visibility
Database Schema (Core)
contracts
- id (UUID)
- user_id (FK)
- vendor_name (text)
- cost (decimal)
- currency (text)
- start_date (date)
- end_date (date)
- notice_date (date)
- status (enum: active, expired, upcoming)
- file_url (text)
- created_at, updated_at
profiles
- id (UUID)
- email (text)
- company_name (text)
- created_at
notifications
- id (UUID)
- contract_id (FK)
- user_id (FK)
- email_id (text)
- sent_at (timestamp)
- status (enum: sent, failed)
How It Works
- User uploads a contract → stored in Supabase Storage
- AI parses vendor, costs, dates, and notice period
- Data saved; notice_date calculated from end_date - notice
- Notifications trigger before expiry; email templates available
- Dashboard shows color-coded statuses and calendar
Project Structure (High-Level)
src/app
- dashboard, profile, pricing, login
- api/cron/check-expiries (⭐)
- api/parse-contract (AI extraction)
- emails/ExpiryNotification (⭐)
lib
- supabaseClient, stripe, email utils
Getting Started
- Install dependencies (Node 18+)
- Configure .env with Supabase, OpenAI, Resend, Stripe
- Create storage bucket `contract-files`
- Run migrations and start dev server
Security Considerations
- Supabase Auth + RLS policies; server-side service role keys
- Cron protected via token; validated uploads (PDF/DOCX)
Future Enhancements
- Slack integration; approval workflows; budget management
- Vendor analytics; renewal automation; APIs; mobile apps