Skip to main content
Filebright provides a comprehensive document management system that allows you to upload, track, and organize your PDF and text files. All documents are processed through an intelligent pipeline that makes them searchable via AI-powered chat.

Supported file types

Filebright currently supports the following document formats:
  • PDF files (.pdf) - Parsed using the Smalot PDF Parser library
  • Text files (.txt) - Directly read as plain text
The maximum file size is 100MB per document.

Uploading documents

Users can upload documents through an intuitive drag-and-drop interface or by clicking to browse files.
1

Access the upload zone

Navigate to your dashboard where you’ll see the upload zone prominently displayed.
2

Select your files

Either drag and drop your PDF or TXT files into the upload zone, or click the zone to open a file browser. You can upload multiple files at once.The frontend validates file types client-side before upload:
// UploadZone.vue - Multiple file upload support
const uploadFiles = (files) => {
  Array.from(files).forEach((file) => {
    documentStore.uploadFile(file);
  });
};
3

Upload and processing begins

Files are uploaded to the backend API at /api/upload with validation:
// DocumentController.php:21-44
public function upload(Request $request)
{
    $request->validate([
        'file' => 'required|file|mimes:pdf,txt|max:102400',
    ]);

    $file = $request->file('file');
    $path = $file->store('documents', 'private');

    $document = DocumentMetadata::create([
        'user_id' => $request->user()->id,
        'filename' => $file->getClientOriginalName(),
        'mime_type' => $file->getMimeType(),
        'path' => $path,
        'status' => 'pending',
    ]);

    ProcessDocument::dispatch($document);

    return response()->json([
        'message' => 'File uploaded successfully',
        'document' => $document
    ], 201);
}
Documents are stored securely in a private storage disk that is not publicly accessible.

Document status tracking

Every document goes through a multi-stage processing pipeline. You can track the status in real-time through the document list interface.

Status stages

The document has been uploaded and is waiting to enter the processing queue. This is the initial state immediately after upload.
The document content is being extracted. For PDFs, this uses the Smalot PDF Parser to extract text. For TXT files, the content is read directly from the file.
// DocumentParserService.php:20-31
public function parse(string $filePath, string $mimeType): string
{
    if (!file_exists($filePath)) {
        return '';
    }

    return match ($mimeType) {
        'application/pdf' => $this->parsePdf($filePath),
        'text/plain' => file_get_contents($filePath) ?: '',
        default => '',
    };
}
The extracted text has been chunked into smaller segments (1200 characters with 300 character overlap), and embeddings are being generated for each chunk using the OpenRouter API.
// ProcessDocument.php:48-49
$this->document->update(['status' => 'vectorizing']);
$embeddings = $embeddingService->getBulkEmbeddings($chunks);
The document chunks and their vector embeddings are being stored in MongoDB with metadata for retrieval during AI queries.
// ProcessDocument.php:56-62
$this->document->update(['status' => 'indexing']);
$vectorStorage->storeChunks(
    $this->document->id,
    $this->document->user_id,
    $chunks,
    $embeddings
);
The document has been successfully processed and is now searchable via the AI chat interface. All chunks are indexed and ready for semantic search.
An error occurred during processing. This could be due to corrupted files, parsing errors, or API failures. Failed documents will not be searchable until re-uploaded.
The document list shows real-time status updates with animated loading indicators for documents in processing states (parsing, vectorizing, indexing).

Listing documents

All your uploaded documents are displayed in the “Recent Documents” list on your dashboard. Documents are sorted by creation date (newest first).
// DocumentController.php:12-19
public function index(Request $request)
{
    $documents = DocumentMetadata::where('user_id', $request->user()->id)
        ->orderBy('created_at', 'desc')
        ->get();

    return response()->json($documents);
}
The document list includes:
  • Search filtering - Type to filter documents by filename
  • Status badges - Color-coded status indicators (green for completed, red for failed, blue for processing)
  • Document count - Shows total number of documents matching your search
  • Quick actions - Rename and delete buttons appear on hover
Use the search bar at the top of the document list to quickly find documents by name. The search is case-insensitive and filters in real-time.

Renaming documents

You can rename documents to better organize your library.
1

Click the rename button

Hover over a document in the list and click the pencil icon to enter rename mode.
2

Edit the filename

The filename becomes editable inline. Type your new filename (you don’t need to include the file extension).
3

Save or cancel

Press Enter or click the checkmark to save. Press Escape or click the X to cancel.
// DocumentController.php:66-87
public function rename(Request $request, $id)
{
    $request->validate([
        'filename' => 'required|string|max:255',
    ]);

    $document = DocumentMetadata::where('id', $id)
        ->where('user_id', $request->user()->id)
        ->first();

    if (!$document) {
        return response()->json(['message' => 'Document not found'], 404);
    }

    $document->filename = $request->input('filename');
    $document->save();

    return response()->json([
        'message' => 'Document renamed successfully',
        'document' => $document
    ]);
}
Renaming a document only changes its display name in Filebright. It does not affect the actual file stored on disk.

Deleting documents

Delete documents you no longer need. This removes both the document metadata and the associated file from storage.
1

Click the delete button

Hover over a document and click the trash icon. A confirmation overlay will appear.
2

Confirm deletion

The document item will highlight in red with the message “Delete this file?” Click the checkmark to confirm or X to cancel.
3

Document removed

Upon confirmation, the document and all its associated chunks are permanently deleted:
// DocumentController.php:46-64
public function destroy(Request $request, $id)
{
    $document = DocumentMetadata::where('id', $id)
        ->where('user_id', $request->user()->id)
        ->first();

    if (!$document) {
        return response()->json(['message' => 'Document not found'], 404);
    }

    // Delete the stored file from disk
    if ($document->path && Storage::disk('private')->exists($document->path)) {
        Storage::disk('private')->delete($document->path);
    }

    $document->delete();

    return response()->json(['message' => 'Document deleted successfully']);
}
Deletion is permanent and cannot be undone. The document file and all its indexed chunks will be removed from the system.

Security and privacy

  • User isolation: Documents are scoped to individual users. You can only view, rename, or delete your own documents.
  • Private storage: Document files are stored in a private disk that is not accessible via public URLs.
  • Authentication required: All document operations require valid authentication tokens (Laravel Sanctum).
// api.php:12-23 - All routes are protected
Route::middleware('auth:sanctum')->group(function () {
    Route::get('/documents', [DocumentController::class, 'index']);
    Route::post('/upload', [DocumentController::class, 'upload']);
    Route::delete('/documents/{id}', [DocumentController::class, 'destroy']);
    Route::patch('/documents/{id}/rename', [DocumentController::class, 'rename']);
});

Build docs developers (and LLMs) love