> ## Documentation Index
> Fetch the complete documentation index at: https://docs.alforse.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Documents

> A shared file library with favorites, labels, search, and AI extraction that reads PDFs and fills a form for you.

The **document explorer** is a flat, searchable library for uploaded files. A file can be standalone or **attached to a record**, such as a job, purchase order, or RFQ. Attached files appear on both the record and in the explorer. The library supports personal pins and labels, name and description search, and AI extraction that reads supported PDFs and prefills forms.

Open the explorer from **Documents** in the sidebar. It defaults to the **All Documents** view.

## The explorer

The table lists accessible files with pinned files first. Each row shows the **name**, linked **source document**, personal **labels**, **size**, **type**, **extension**, and created and updated metadata.

Five views scope the list, switched by the tab rail down the left:

FieldType

<details>
  <summary>**All Documents**</summary>

  Every active file in the company you have read access to.
</details>

<details>
  <summary>**My Documents**</summary>

  Files you uploaded (`createdBy` = you).
</details>

<details>
  <summary>**Recent**</summary>

  Sorted by last activity — the newest view, download, label, or edit first.
</details>

<details>
  <summary>**Pinned**</summary>

  Only files you have pinned.
</details>

<details>
  <summary>**Trash**</summary>

  Soft-deleted files, waiting to be restored or purged.
</details>

**Type** is derived, not chosen. When a file is uploaded, Alforse reads its extension and classifies it into one of eleven types: `Archive`, `Document`, `Presentation`, `PDF`, `Spreadsheet`, `Text`, `Image`, `Video`, `Audio`, `Model` (supported 3D formats), or `Other`. The **File Extension** column comes from the filename itself (the text after the last dot), so it always matches the real file.

NOTE

**Trash is a soft delete, not a purge**

"Move to Trash" only flips the file's `active` flag to `false` — the row and the stored file both stay put, and "Restore from Trash" flips it back. To actually remove a file, use **Permanently Delete** from the row menu; that one cannot be undone.

### Uploading

**Upload** accepts any file. The browser uploads it to private storage at `{companyId}/{random}.{ext}`, then creates a document row with its path, name, and size. Uploads, downloads, edits, favorites, and label changes create activity transactions that drive the **Recent** view.

## Who can see a file

Visibility depends on group membership and permissions. A user can view a document only when they belong to one of its `readGroups` and have `documents` view permission. Editing or deleting also requires membership in a `writeGroups` entry and the corresponding permission. Private storage applies the same read-group rule, so unauthorized links do not resolve.

NOTE

**Groups are Alforse's company groups**

Read and write groups are drawn from your company group membership, the same groups used elsewhere for scoping. Set them when you edit a document's properties; a file with no matching read group for a user is simply invisible to that user.

## Pins and labels

Two personal organizers sit on top of the shared library, and both are **per-user** — what you pin or label is yours alone, not the whole company's.

* **Pins** (shown as a pushpin, called "Favorite" in the row menu) float a file to the top of your list and power the **Pinned** view. Toggling one writes or removes a `documentFavorite` row keyed to you.
* **Labels** are free-text tags you attach to a file. Type into the label popover on a row to reuse an existing label or create a new one on the fly; click a label to filter the list down to it. Labels are stored per user, so your "Q3-audit" label doesn't clutter a colleague's view.

## Search

Search performs a case-insensitive substring match on **name** and **description**, not file contents. Combine search with filters for source document, label, type, extension, or creator and with the view tabs. **Download CSV** exports the current result set with a signed download link for each row.

## How documents attach to records

A document can point back at the record it belongs to. The row's **Source Document** column shows that link and jumps straight to the parent record. The set of record types a document can attach to is fixed:

FieldType

<details>
  <summary>**Sales side**</summary>

  Quote, Request for Quote, Sales Order, Sales Invoice, Sales Return Order, Shipment.
</details>

<details>
  <summary>**Purchasing side**</summary>

  Purchase Order, Purchase Invoice, Purchase Return Order, Purchasing Request for Quote, Supplier Quote.
</details>

<details>
  <summary>**Production & quality**</summary>

  Job, Gauge Calibration Record, Issue.
</details>

<details>
  <summary>**Service & warranty**</summary>

  Repair Order, Warranty Registration.
</details>

<details>
  <summary>**Items**</summary>

  Part, Material, Tool, Consumable, Service.
</details>

<details>
  <summary>**Trading parties**</summary>

  Supplier, Customer. These are the master records rather than transactions, for files that belong to the party itself.
</details>

The attachment is stored as a `sourceDocument` (the type) plus a `sourceDocumentId` (the record's id) on the file. Because the file also lives in the shared explorer, you can find it either by opening the record or by searching the library. See the [sales orders](/docs/reference/sales-orders.md), [purchase orders](/docs/reference/purchase-orders.md), and [jobs](/docs/reference/jobs.md) references for where each record surfaces its files, and [suppliers & customers](/docs/reference/suppliers-and-customers.md) for the party-level Documents tab.

## AI extraction

In supported workflows, Alforse can extract fields from a PDF and prefill a form. Two document types are supported:

* a **Request for Quote** PDF, on the sales side, and
* a **Purchase Invoice** PDF, on the purchasing side.

### What it does, step by step

When you drop a PDF into one of those flows, Alforse creates a `documentExtraction` row (starting at status `pending`) and enqueues a background job. The job then:

1. flips the row to `processing`;
2. downloads the PDF from private storage and extracts its **text** with a PDF parser (this is text extraction, not image OCR — a scanned image-only PDF yields no text);
3. loads the company's candidate records so the model can resolve names to real ids itself — suppliers and payment terms for an invoice, customers for an RFQ;
4. sends the text plus those candidate lists to the AI model, which returns every field as a `{ value, confidence }` pair;
5. **filters by confidence**: any field scoring below the threshold (default `0.85`) is dropped to `null`, so a low-confidence guess never lands in your form; and
6. normalizes dates to `YYYY-MM-DD` and saves both the raw output and the filtered result on the row, status `completed`.

The form then reads the filtered values and pre-fills itself, matching extracted contacts and addresses against the customer's or supplier's existing records where it can.

NOTE

**It resolves ids for you, it doesn't invent them**

The model is handed the actual list of your suppliers, payment terms, or customers and told to return the id of the single best match or `null` — never to make one up. So `supplierId` / `customerId` / `paymentTermId` come back either as a real record you already have or as blank, and the form's own matching fills the rest.

### What it pulls out

For a **Purchase Invoice**, extraction targets the supplier (name, contact, address, and a resolved `supplierId`), the invoice header (number, invoice and due dates, payment terms and a resolved `paymentTermId`, referenced PO number, currency), the money (subtotal, tax, shipping, total), and the **line items** (part number, description, quantity, unit price, line total).

For a **Request for Quote**, it targets the customer (name, a resolved `customerId`, plus separate purchasing and engineering contacts and the customer address), the RFQ header (number, RFQ date, due date, requested delivery date), and the **line items** (part number, description, quantity).

HEADS UP

**Extraction is a draft, not a commit**

A `documentExtraction` row is only a staging area — it never creates an invoice or an RFQ by itself. The extracted values pre-fill the normal form, and the real record is created through the usual permission-gated route action when you save. If the background job can't be enqueued or the parse fails, the row is marked `failed` with the error, and you just fill the form manually.

Extraction quality depends on the PDF being text-based. If extraction is unavailable or fails, the flows still work and you type the fields yourself.

NOTE

**Not the document template customizer**

This page is about the file library. The separate **document template** feature — the drag-and-drop customizer for the PDFs Alforse *generates* (quotes, order confirmations, invoices) — is a different subsystem and isn't covered here.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.