API Integration and Data Flow¶
API Architecture Overview¶
graph TB
subgraph "Frontend (Next.js)"
UI[User Interface]
APIClient[API Client Layer]
StateMan[State Management]
Cache[Client Cache]
end
subgraph "API Layer"
NextAuth[NextAuth Endpoints]
APIRoutes[API Routes]
Middleware[Auth Middleware]
end
subgraph "Backend (NestJS)"
Controllers[Controllers]
Services[Services]
Guards[Auth Guards]
DTOs[Data Transfer Objects]
end
subgraph "Data Layer"
Database[(PostgreSQL)]
Redis[Redis Cache]
External[External APIs]
end
UI --> APIClient
APIClient --> StateMan
StateMan --> Cache
APIClient --> NextAuth
APIClient --> APIRoutes
APIRoutes --> Middleware
Middleware --> Controllers
Controllers --> Guards
Guards --> Services
Services --> DTOs
Services --> Database
Services --> Redis
Services --> External
API Request Flow¶
sequenceDiagram
participant User
participant Frontend as Next.js App
participant Auth as NextAuth
participant API as API Routes
participant Backend as NestJS API
participant DB as PostgreSQL
participant Cache as Redis
User->>Frontend: User Action
Frontend->>Auth: Check Authentication
Auth-->>Frontend: Return Auth Status
alt Authenticated
Frontend->>API: API Request + Token
API->>Backend: Forward Request
Backend->>Cache: Check Cache
alt Cache Hit
Cache-->>Backend: Return Cached Data
else Cache Miss
Backend->>DB: Query Database
DB-->>Backend: Return Data
Backend->>Cache: Store in Cache
end
Backend-->>API: Response Data
API-->>Frontend: Return Response
Frontend-->>User: Update UI
else Not Authenticated
Frontend->>Auth: Redirect to Login
Auth-->>User: Show Login Form
end
API Endpoints¶
Authentication¶
Login
- Endpoint:
/api/auth/[...nextauth] - Method:
POST - Purpose: User authentication and session creation
- Response: Authentication token and user data
Refresh Token
- Endpoint:
/api/auth/[...nextauth] - Method:
POST - Purpose: Refresh expired authentication tokens
- Response: New authentication token
Document Management¶
Upload Document
- Endpoint:
/api/documents - Method:
POST - Purpose: Upload new documents for processing
- Response: Document ID and processing status
Get Unassigned Documents
- Endpoint:
/api/documents - Method:
GET - Purpose: Retrieve documents not assigned to projects
- Response: Array of unassigned document objects
Create Project
- Endpoint:
/api/documents/createNewProject - Method:
POST - Purpose: Create new project for document organisation
- Response: Project ID and creation status
Get User Projects
- Endpoint:
/api/documents/getUserProject - Method:
POST - Purpose: Retrieve all projects for a user
- Response: Array of project objects
Profile Management¶
Profile Statistics
- Endpoint:
/api/profileStats - Method:
GET - Purpose: Retrieve user activity statistics
- Response: Usage metrics and document counts
Data Models¶
Document Object¶
interface Document {
DocumentID: string;
DocumentName: string;
Status: string;
DateCreated: Date;
LastModified: Date;
ClientName: string | null;
}
Project Object¶
User Statistics¶
interface ProfileStats {
documentsInLast7Days: number;
documentsInLast30Days: number;
documentsInLastDay: number;
totalRequestsInLast7Days: number;
totalRequestsInLast30Days: number;
totalRequestsInLastDay: number;
}
Data Flow¶
Document Processing Flow¶
- Upload Phase
// Upload initiation
const handleUpload = async (file: File) => {
setIsProcessing(true);
const response = await uploadDocument(file);
setPayload(response);
};
- Processing Phase
// Document processing
const processDocument = async (payload: any) => {
const stages = ["Parsing", "Processing", "Populating Editor"];
for (const stage of stages) {
setCurrentStage(stage);
await processStage(stage, payload);
}
setIsComplete(true);
};
- Editor Population
Project Management Flow¶
- Project Creation
const handleNewProject = async (clientName: string, name: string) => {
await fetch("/app/api/documents/createNewProject", {
method: "POST",
body: JSON.stringify({ userID, clientName, name }),
});
fetchProjects();
};
- Document Assignment
Error Handling¶
API Error Structure¶
Error Handling Implementation¶
const handleAPIRequest = async (endpoint: string, options: RequestInit) => {
try {
const response = await fetch(endpoint, options);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error("API Error:", error);
handleError(error);
}
};
State Management¶
Session Management¶
Document State¶
const [documents, setDocuments] = useState<Document[]>([]);
const [selectedDocument, setSelectedDocument] = useState<string | null>(null);
Processing State¶
const [isProcessing, setIsProcessing] = useState<boolean>(false);
const [currentStage, setCurrentStage] = useState<number>(0);
const [isComplete, setIsComplete] = useState<boolean>(false);
WebSocket Integration¶
Real-time Updates¶
const socket = new WebSocket(WS_URL);
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
handleRealtimeUpdate(data);
};
Connection Management¶
useEffect(() => {
const connectWebSocket = () => {
socket.onopen = () => console.log("WebSocket Connected");
socket.onclose = () => {
console.log("WebSocket Disconnected");
setTimeout(connectWebSocket, 3000);
};
};
connectWebSocket();
return () => socket.close();
}, []);
Security¶
Token Management¶
const fetchWithAuth = async (url: string, options: RequestInit) => {
const session = await getSession();
return fetch(url, {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${session?.accessToken}`,
},
});
};