# Project pack: Papra @ d0638d1

Facts about **Papra** for an AI following the [BespokeAI handover guide](https://handoff.bespokeai.software/guide/v2.md). This pack is pinned to one version and never changes after publication.

> Papra is a simple, self-hosted document archive. Drop in scans and PDFs, tag them, search their text, and let it read new files from an email or a watched folder. It is a lighter alternative to bigger document systems and is designed to be easy to run.

## Version and source
- Repository: https://github.com/papra-hq/papra
- Pinned commit: `d0638d11e1ca3795600b7baa68afed1d5b1daabb`. Use exactly this version.
- Fresh checkout: use the setup below in an empty folder. If you already have this exact source checked out, keep your branch and use the development command instead; do not clone again or reset local changes.
- Or download a zip: https://github.com/papra-hq/papra/archive/d0638d11e1ca3795600b7baa68afed1d5b1daabb.zip
- Official docs: https://docs.papra.app
- Live demo: https://demo.papra.app/. The official demo. Don't upload real documents.
- Licence: **AGPL-3.0-only**. Free to use and change. If other people use your changed version, including over a network (for example a website you host for them), you must offer them your source code under the same licence. Using it privately for yourself or your household has no extra obligations.

## Running the pinned source
- Fresh pinned-source setup (skip clone and checkout in an existing worktree):

  ```sh
  git clone https://github.com/papra-hq/papra bespoke-papra
  cd bespoke-papra
  git checkout --detach d0638d11e1ca3795600b7baa68afed1d5b1daabb
  # Prepare development requirements and local configuration first.
  corepack enable
  pnpm install
  pnpm dev
  ```

The commands below are a starting point from the reviewed source. Prepare the listed tools, local configuration and companion services before starting the app. These instructions have not yet been validated in participant sessions.

### Separate trial of the current release
This tries an upstream release, which may differ from the pinned source above. It does not run your source changes. Use only sample data and a separate data directory or volume. Check the upstream documentation before running it.

  ```sh
  docker run -d --name papra -p 1221:1221 -e AUTH_SECRET=replace-with-a-long-random-string -v papra-data:/app/app-data ghcr.io/papra-hq/papra:latest
  # then open http://localhost:1221
  ```

- Needs: Docker for a trial, Node 22 and pnpm for development
- Develop: `pnpm dev`
- Test: `pnpm test`
- Check/lint: `pnpm lint`
- Stack: typescript (SolidJS, Hono, Drizzle ORM, pnpm). Difficulty for a non-developer with an AI: **moderate**. A modern TypeScript monorepo with a Solid front end, a Hono server and a SQLite database. Tags, rules and ingestion are configuration; new features touch both sides.

## Customisation points (settings → extend → code)
- **tags-and-rules** [settings]: Automatically tag by text such as 'invoice' or a company name. → `Organization → Tags and tagging rules`
- **ingestion-folder** [settings]: Drop files into a folder or send them by email. → `Ingestion folder and email ingestion settings`
- **api-and-webhooks** [extend]: Upload documents and receive events from scripts. → `Settings → API keys, apps/docs, packages/api-sdk`
- **client-ui** [code]: Screens and views. → `apps/papra-client/src`
- **server-modules** [code]: New server features and rules. → `apps/papra-server/src/modules`

## Must keep working
- Document storage and the database migrations. Add new migrations; never edit old ones.
- Authentication and organisation permissions.
- Full-text search indexing.

## Staying updatable
Use tags, rules and webhooks first. Add new server features as separate modules.

## Data, costs and safety
- Personal data: **yes**. Stored in: A SQLite database and your documents in /app/app-data (a Docker volume). Contains copies of your private paperwork. Back up the whole data folder.
- Service: Email ingestion (optional) (optional, free): Send receipts to Papra by email.
- Setting `AUTH_SECRET` (**secret**: the person enters it themselves, never in chat): Long random secret used to sign logins. Never paste it into an AI chat.
- Setting `APP_BASE_URL`: The address people use to reach Papra if it is not localhost.
- Your documents may include IDs and financial records. Use a strong AUTH_SECRET and HTTPS.
- Don't expose it publicly without a reverse proxy and login.

---

# Customising Papra

Papra is a pnpm monorepo. The server uses a module-per-feature layout that is easy to follow.

## How the code is laid out

| You want to change… | Look in |
|---|---|
| Web app | apps/papra-client/src/ |
| Server modules (documents, tags, ingestion) | apps/papra-server/src/modules/ |
| API SDK and CLI | packages/api-sdk/ and packages/cli/ |
| Documentation | apps/docs/ |
| Marketing site | apps/website/ |

## Use the gentlest change first

1. **Settings (no code):** tags, tagging rules, ingestion and API keys.
2. **Extend:** webhooks and the API SDK.
3. **Code:** server modules and screens.

## Recipes

- **New tagging rule type:** look in the tagging rules module and add the condition beside the existing ones, with a test.
- **New field on documents:** add a Drizzle migration, update the schema and repository, expose it in the route, then show it in the document page.

## Running and checking your changes

- `pnpm dev` and upload a PDF, tag it and search for text inside it.
- `pnpm test` and `pnpm lint`.

## Pitfalls

- Don't commit `app-data` or `.env`.
- Add migrations for schema changes.

---
Machine-readable: [bespoke.yaml](https://handoff.bespokeai.software/p/papra/d0638d1/r2/bespoke.yaml) · Hosting options: [hosting.md](https://handoff.bespokeai.software/p/papra/d0638d1/r2/hosting.md) · Agent skill: [SKILL.md](https://handoff.bespokeai.software/p/papra/d0638d1/r2/SKILL.md)
