Tech Stack
| Layer |
Technology |
| Language |
Java 21 |
| Framework |
Spring Boot 3.4+ |
| AI Framework |
Spring AI 1.0.0 |
| Database |
PostgreSQL + pgvector |
| ORM |
Spring Data JPA |
| Build Tool |
Maven |
| Authentication |
JWT + Spring Security |
| Storage |
AWS S3 / MinIO |
| PDF Parsing |
Apache PDFBox + Tika |
| Queue |
RabbitMQ / Kafka (Optional) |
| Cache |
Redis |
| API Docs |
Swagger OpenAPI |
| Deployment |
Docker + Kubernetes |
| Monitoring |
Prometheus + Grafana |
| Logging |
ELK Stack |
High Level Architecture
┌────────────────────┐
│ Frontend App │
│ React / Next.js │
└─────────┬──────────┘
│
▼
┌────────────────────┐
│ API Gateway │
└─────────┬──────────┘
│
┌──────────────┴──────────────┐
▼ ▼
┌────────────────────┐ ┌────────────────────┐
│ Authentication │ │ PDF Chat Service │
│ Service │ │ Spring AI │
└────────────────────┘ └─────────┬──────────┘
│
┌─────────────────────┼────────────────────┐
▼ ▼ ▼
┌────────────────┐ ┌──────────────────┐ ┌────────────────┐
│ PostgreSQL │ │ OpenAI/Gemini │ │ AWS S3/MinIO │
│ + pgvector │ │ Embedding Model │ │ PDF Storage │
└────────────────┘ └──────────────────┘ └────────────────┘
Project Structure
pdf-chat-ai/
│
├── src/main/java/com/ayshriv/pdfchat
│
├── config/
│ ├── OpenAiConfig.java
│ ├── PgVectorConfig.java
│ ├── SecurityConfig.java
│ ├── SwaggerConfig.java
│ ├── RedisConfig.java
│ └── AsyncConfig.java
│
├── controller/
│ ├── AuthController.java
│ ├── PdfController.java
│ ├── ChatController.java
│ └── AdminController.java
│
├── service/
│ ├── auth/
│ ├── pdf/
│ │ ├── PdfUploadService.java
│ │ ├── PdfParserService.java
│ │ ├── PdfChunkingService.java
│ │ ├── PdfEmbeddingService.java
│ │ ├── PdfVectorStoreService.java
│ │ └── PdfProcessingService.java
│ │
│ ├── chat/
│ │ ├── ChatService.java
│ │ ├── ContextBuilderService.java
│ │ ├── SimilaritySearchService.java
│ │ └── AiResponseService.java
│ │
│ └── storage/
│ ├── S3StorageService.java
│ └── MinioStorageService.java
│
├── repository/
│ ├── UserRepository.java
│ ├── PdfDocumentRepository.java
│ ├── DocumentChunkRepository.java
│ └── ChatHistoryRepository.java
│
├── entity/
│ ├── BaseEntity.java
│ ├── User.java
│ ├── PdfDocument.java
│ ├── DocumentChunk.java
│ ├── ChatHistory.java
│ └── EmbeddingMetadata.java
│
├── dto/
│ ├── request/
│ ├── response/
│ └── common/
│
├── security/
│ ├── JwtService.java
│ ├── JwtFilter.java
│ ├── CustomUserDetailsService.java
│ └── SecurityUtils.java
│
├── exception/
│ ├── GlobalExceptionHandler.java
│ ├── BadRequestException.java
│ ├── UnauthorizedException.java
│ └── ResourceNotFoundException.java
│
├── util/
│ ├── FileUtils.java
│ ├── PromptUtils.java
│ ├── TokenUtils.java
│ └── ValidationUtils.java
│
├── scheduler/
│ ├── CleanupScheduler.java
│ └── RetryScheduler.java
│
├── listener/
│ ├── PdfUploadListener.java
│ └── EmbeddingGenerationListener.java
│
├── constant/
│ ├── AppConstants.java
│ └── PromptConstants.java
│
└── PdfChatApplication.java
Database Design
users
CREATE TABLE users (
id UUID PRIMARY KEY,
name VARCHAR(255),
email VARCHAR(255) UNIQUE,
password VARCHAR(255),
role VARCHAR(50),
created_at TIMESTAMP,
updated_at TIMESTAMP
);
pdf_documents
CREATE TABLE pdf_documents (
id UUID PRIMARY KEY,
user_id UUID,
file_name VARCHAR(500),
original_file_name VARCHAR(500),
file_url TEXT,
file_size BIGINT,
total_pages INTEGER,
processing_status VARCHAR(50),
uploaded_at TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
document_chunks
CREATE TABLE document_chunks (
id UUID PRIMARY KEY,
document_id UUID,
chunk_text TEXT,
page_number INTEGER,
chunk_index INTEGER,
embedding VECTOR(1536),
created_at TIMESTAMP,
FOREIGN KEY (document_id) REFERENCES pdf_documents(id)
);
chat_history