Welcome to Day 1 of building an AI-Powered Document Parser + Validator using Laravel and GPT. By the end of this series, you’ll have a smart system that parses uploaded contracts or invoices and highlights key details, risks, and missing fields.
🎯 Goal for Today
- Set up the document upload system
- Create models/tables for uploaded files
- Prepare for GPT-based parsing
🗂 Step 1: Create Document Model
php artisan make:model Document -m
In the migration:
public function up()
{
Schema::create('documents', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('filename');
$table->string('type'); // e.g. contract, invoice
$table->foreignId('user_id')->nullable()->constrained()->onDelete('cascade');
$table->timestamps();
});
}
Then:
php artisan migrate
📥 Step 2: Upload Form
In your view (resources/views/documents/upload.blade.php
):
<form action="{{ route('documents.store') }}" method="POST" enctype="multipart/form-data">
@csrf
<label>Title</label>
<input type="text" name="title" required>
<label>Document Type</label>
<select name="type">
<option value="contract">Contract</option>
<option value="invoice">Invoice</option>
</select>
<label>Upload File (PDF)</label>
<input type="file" name="document" accept="application/pdf" required>
<button type="submit">Upload</button>
</form>
📦 Step 3: Controller Logic
php artisan make:controller DocumentController
In DocumentController.php
:
public function store(Request $request)
{
$request->validate([
'title' => 'required|string',
'type' => 'required|in:contract,invoice',
'document' => 'required|file|mimes:pdf|max:20480',
]);
$file = $request->file('document');
$filename = time() . '-' . $file->getClientOriginalName();
$file->storeAs('documents', $filename, 'public');
Document::create([
'title' => $request->title,
'type' => $request->type,
'filename' => $filename,
'user_id' => auth()->id(),
]);
return redirect()->back()->with('success', 'Document uploaded successfully.');
}
🛣 Step 4: Add Routes
In web.php
:
use App\Http\Controllers\DocumentController;
Route::get('/documents/upload', fn() => view('documents.upload'))->name('documents.upload');
Route::post('/documents', [DocumentController::class, 'store'])->name('documents.store');
✅ Summary
✅ Today you:
- Created a
Document
model with type tracking - Built a form to upload contracts/invoices
- Stored uploaded files securely
- Set up the foundation for parsing and validating
✅ Up next (Day 2): We’ll extract text content from PDF and prepare it for GPT processing.