This is a demo of system that analyzes potential patent infringements by comparing patent claims against company products. The system utilizes AI to assess infringement risks and provides detailed analysis reports.
This project consists of three main services:
- Web service (
Next.jsfrontend running on port 8080) - API service (
Laravelbackend running on port 8000) - Database service (
PostgreSQLwith pgvector extension running on port 54321)
Before running the application, ensure you have the following installed on your system:
- Docker (20.10.x or higher)
- Docker Compose (v2.x or higher)
- Make (GNU Make 4.x or higher)
- OpenAI API credentials
- API Key
- Organization ID
Please check the commnad make -h for all the available commands you can use to manage the application.
- Frontend (Web):
http://localhost:8080 - Backend (API):
http://localhost:8000 - Database:
localhost:54321(for native database client)
.
├── api/ # Laravel backend service
├── web/ # Next.js frontend service
├── docker-compose.yaml # Docker services configuration
└── Makefile # Command shortcuts
-
Make sure update environment config for API with OpenAI key:
OPENAI_API_KEY="sk-proj-xxxxxxxxxxxxxxxx" OPENAI_ORGANIZATION="org-xxxxxxxxxxxxx"
-
Initialize the environment files and container images:
make setup make init-db
-
Verify all services are running:
make ps
-
Access the application:
- Frontend: http://localhost:8080
- API: http://localhost:8000
-
Access the search interface:
http://localhost:8080/search/ -
Example to run analysis URL:
http://localhost:8080/search/?patent_id=US-RE49889-E1&company_name=Target%20Corporation -
View analysis history:
http://localhost:8080
The application provides a REST API that serves the patent analysis functionality. All API endpoints are hosted at the base URL specified in the environment variable NEXT_PUBLIC_API_HOST.
Retrieves all patent analysis results.
GET /api/list
Response
[
{
"analysis_id": number,
"patent_id": string,
"company_name": string,
"analysis_date": string,
"overall_risk_assessment": string,
"top_infringing_products": [
{
"product_name": string,
"infringement_likelihood": "High" | "Medium" | "Low",
"relevant_claims": string[],
"explanation": string,
"specific_features": string[]
}
]
}
]Analyzes a patent for potential infringement by a specific company.
GET /api/search
Note
The result of the API with the same patent_id and company_name will be cache for 10s for preventing submitting multiple times.
Query Parameters
patent_id(required): The ID of the patent to analyzecompany_name(required): The name of the company to check against
Response
{
"analysis_id": number,
"patent_id": string,
"company_name": string,
"analysis_date": string,
"overall_risk_assessment": string,
"top_infringing_products": [
{
"product_name": string,
"infringement_likelihood": "High" | "Medium" | "Low",
"relevant_claims": string[],
"explanation": string,
"specific_features": string[]
}
]
}Both endpoints may return the following error responses:
{
"message": string
}The API is integrated with the frontend using React Query for data fetching and state management. Here's how to use the API endpoints in your frontend code:
import { useQuery } from '@tanstack/react-query'
const fetchAnalyses = async (): Promise<AnalysisResult[]> => {
const response = await fetch(`${process.env.NEXT_PUBLIC_API_HOST}/api/list`)
if (!response.ok) {
const errorData = await response.json().catch(() => ({}))
throw new Error(errorData.message || 'Failed to fetch analyses')
}
return response.json()
}
// In your component:
const { data: analyses, error, isLoading } = useQuery({
queryKey: ['analyses'],
queryFn: fetchAnalyses,
})import { useQuery } from '@tanstack/react-query'
type SearchParams = {
patentId: string
companyName: string
}
const analyzePatent = async ({ patentId, companyName }: SearchParams): Promise<AnalysisResult> => {
const params = new URLSearchParams({
patent_id: patentId,
company_name: companyName
})
const response = await fetch(`${process.env.NEXT_PUBLIC_API_HOST}/api/search?${params.toString()}`)
if (!response.ok) {
const errorData = await response.json().catch(() => ({}))
throw new Error(errorData.message || 'Failed to analyze patent')
}
return response.json()
}
// In your component:
const { data: analysisResult, error, isLoading } = useQuery({
queryKey: ['patentAnalysis', queryParams],
queryFn: () => analyzePatent(queryParams),
enabled: Boolean(patentId && companyName),
})interface AnalysisResult {
analysis_id: number
patent_id: string
company_name: string
analysis_date: string
overall_risk_assessment: string
top_infringing_products: InfringingProduct[]
}
interface InfringingProduct {
product_name: string
infringement_likelihood: 'High' | 'Medium' | 'Low'
relevant_claims: string[]
explanation: string
specific_features: string[]
}