# School Paperless Intake Workflow Workflows: - `n8n-workflows/18-school-paperless-intake.json` - `n8n-workflows/19-paperless-school-metadata-enrichment.json` This workflow is meant for a Telegram chat-driven upload pipeline that sends schoolwork into Paperless-NGX while recording intake metadata in shared Postgres. ## What it does 1. Accepts a multipart upload at `POST /webhook/school/intake/upload` 2. Requires form fields: - `class_name` - `assignment_name` - `submission_kind` 3. Accepts optional fields: - `semester` - `course_code` - `paper_kind` - `notes` - `source` (defaults to `telegram`) - `telegram_chat_id` - `telegram_message_id` 4. Generates a deterministic `intake_id` from date + class + assignment + file checksum 5. Stores/updates the intake row in Postgres first 6. Uploads the file to Paperless using the deterministic intake ID in the filename 7. Marks the row as `uploaded` after Paperless accepts the upload ## Shared Postgres expectations - Use the shared Postgres network/credentials pattern already used by the automation stack. - The workflow expects an n8n Postgres credential named `Shared Postgres`. - Recommended target database: `school_intake` - Tracked schema: `docs/reference/SCHOOL_INTAKE_POSTGRES_SCHEMA.sql` ## Required environment variables Add to `automation/.env`: ```env PAPERLESS_BASE_URL=https://paperless.paccoco.com PAPERLESS_API_TOKEN=CHANGE_ME LITELLM_API_KEY=CHANGE_ME PAPERLESS_CORRESPONDENT_SCHOOL= PAPERLESS_DOCUMENT_TYPE_SCHOOL= PAPERLESS_TAG_SCHOOL= PAPERLESS_TAG_ASSIGNMENTS= PAPERLESS_TAG_TELEGRAM= NODE_FUNCTION_ALLOW_BUILTIN=crypto ``` Add to the `n8n` service `environment:` block in `automation/docker-compose.yaml`: ```yaml PAPERLESS_BASE_URL: ${PAPERLESS_BASE_URL} PAPERLESS_API_TOKEN: ${PAPERLESS_API_TOKEN} PAPERLESS_CORRESPONDENT_SCHOOL: ${PAPERLESS_CORRESPONDENT_SCHOOL} PAPERLESS_DOCUMENT_TYPE_SCHOOL: ${PAPERLESS_DOCUMENT_TYPE_SCHOOL} PAPERLESS_TAG_SCHOOL: ${PAPERLESS_TAG_SCHOOL} PAPERLESS_TAG_ASSIGNMENTS: ${PAPERLESS_TAG_ASSIGNMENTS} PAPERLESS_TAG_TELEGRAM: ${PAPERLESS_TAG_TELEGRAM} NODE_FUNCTION_ALLOW_BUILTIN: crypto ``` Notes: - `PAPERLESS_CORRESPONDENT_SCHOOL` and `PAPERLESS_DOCUMENT_TYPE_SCHOOL` should be numeric IDs if you want those fields auto-assigned. - Leave optional Paperless IDs blank if you prefer Paperless rules to classify later. - `NODE_FUNCTION_ALLOW_BUILTIN=crypto` is required because the Code node hashes the uploaded file. - `N8N_BLOCK_ENV_ACCESS_IN_NODE` must remain `false`. ## Paperless metadata behavior The upload uses: - filename: `.` - title: `` Workflow 18 deliberately keeps the Paperless upload minimal and safe: - multipart `document` - deterministic title The deterministic filename/title preserve the `intake_id` for later correlation. Workflow 19 handles the follow-up metadata pass after Paperless finishes processing: - fetch Paperless document by webhook document id - resolve `intake_id` from the stored filename - look up the intake record in shared Postgres - re-apply deterministic title - merge generic school tags plus optional class/submission-kind mappings - optionally set document type / correspondent from JSON env mappings ## Testing Use the example curl request in: - `n8n-workflows/fixtures/school-paperless-intake-webhook.curl.example.txt` Minimum test checklist: 1. Import the workflow into n8n. 2. Attach the `Shared Postgres` credential. 3. Confirm the target DB/table exists. 4. Send the sample multipart request. 5. Verify a row appears in `school_paperless_intake` with `status=uploaded`. 6. Verify the uploaded Paperless document title and stored filename both include the deterministic intake ID. 7. Trigger workflow 19 with the Paperless document id and verify the row moves to `status=enriched`. 8. Re-submit the same file and metadata to confirm the same `intake_id` is reused and the Postgres row is upserted. ## Known assumptions / caveats - The workflow is repo-only and was not live-tested against the running n8n/Paperless stack. - The Postgres node uses SQL expressions inline rather than parameter binding because exported n8n node JSON can differ by version. - If your n8n build blocks `require('crypto')`, add `NODE_FUNCTION_ALLOW_BUILTIN=crypto` to the container env. - If Paperless needs tags as repeated `tags[]` fields instead of a comma-separated `tags` field, adjust the HTTP Request node after import.