Just Upload:讓申請文件整理不再是最後一道難關
I Built Just Upload Because the Upload Box Shouldn't Be the Final Boss
Just Upload 將申請文件的頁面挑選、排序、旋轉、PDF 製作及檔案大小檢查整合到同一個審閲流程,讓用戶按要求整理文件並下載 PDF。應用程式在用戶電腦上運作,無需帳戶或上傳至雲端;可選用本機 Ollama 視覺模型提出文件分類建議,並由用戶審閲後才建立 PDF。
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady
What I Built
You finished the application.
You found the certificates. You checked the dates. You are one click away from being done.
Then the upload box speaks:
One PDF. Under 1 MB. Application first. Certificates oldest to newest. No instruction pages.
Apparently, the final stage of applying for anything is becoming a part-time PDF technician.
Just Upload is my attempt to make that stage smaller: drop in the paperwork, paste the requirements, review a proposed plan, and take away one PDF.
The local MVP. All documents shown below are fictional samples.
The idea grew out of the Slow and Steady theme: make a tool that handles a chore so someone can get on with their day.
This is for the person assembling an application, a workshop registration, or a bundle of supporting documents. They already have the information. The annoying part is packaging it.
Just Upload brings page selection, ordering, rotation, PDF creation, and file-size checks into one review flow. It accepts static PDFs and JPG, PNG, or WebP images. The output is a PDF.
The current app runs on the user's computer. No account is needed in the app, and there is no cloud AI upload step.
Demo
A paced slideshow of actual browser captures, not a real-time performance recording. This demo uses Basic mode, not Gemma inference.
The sample starts in an inconvenient order:
| Original position | Page | What should happen |
|---|---|---|
| 1 | Instructions | Leave out |
| 2 | Certificate dated 2025-06-18 | Put last |
| 3 | Application | Put first |
| 4 | Certificate dated 2024-03-12 | Put second |
Paste this requirement:
One PDF under 1 MB. Application first, then certificates
oldest to newest. Exclude instruction pages.
The app proposes application → 2024 certificate → 2025 certificate. The instruction page stays visible in an excluded section, where it can be restored.
That review step matters. A label is a suggestion. You can open the page, move it, rotate it, or change whether it belongs in the output.
Click Create my PDF, and the sample becomes a three-page file displayed as 5.6 KB, below its 1 MB cap. In this run, the original page content was preserved; stronger scan compression was unnecessary.
I haven't measured time saved across users. The concrete payoff demonstrated here is narrower: one interface handles the ordering, exclusion, assembly, and size check that would otherwise require several manual steps.
What happens when the limit is impossible?
I gave the same package a deliberately unrealistic cap: 0.001 MB, or 1 KB.
The output was still 5.6 KB. The app reported it as oversized and changed the download label accordingly.
The check is ordinary code:
passed = body.max_bytes is None or len(data) <= body.max_bytes
A plausible-looking PDF is not evidence that it fits. Measuring the actual output is.
Stronger compression is opt-in because it turns pages into images and can sacrifice selectable text and small-print readability. The user should make that tradeoff knowingly.
Code
The project currently lives in a local Python application; the repository has not been published yet. The stack is FastAPI, PyMuPDF, Pillow, and a plain HTML/CSS/JavaScript interface, with Ollama for the optional local vision path.
The model gets a limited vocabulary. Here is the actual page-finding schema from the app:
class Finding(BaseModel):
title: str = Field(max_length=120)
category: Literal["application", "certificate", "instructions", "other"]
date: str | None = Field(default=None, description="ISO YYYY-MM-DD only if explicitly visible; otherwise null")
suggested_include: bool = True
reason: str = Field(max_length=500)
needs_review: bool = True
The response is validated before it becomes a proposal. That catches malformed output; it cannot prove that a model read a date correctly. Human review remains part of the product.
How I Built It
During planning, a fair objection came up:
Doesn't most of this just need ordinary algorithms?
Yes. Merging PDFs does. Rotating a page does. Counting bytes definitely does.
The useful place for AI is the interpretation before those operations: reading a portal's wording, examining a scanned page, and suggesting what the document is and where it belongs.
So the app has two explicit modes:
| Mode | What it does | What it doesn't establish |
|---|---|---|
| Basic | Reads selectable PDF text and explicit phrases; uses keyword and date rules to suggest a plan | Understanding of photographed text or arbitrary instructions |
| Local AI | Calls an installed Ollama vision model to interpret requirements and propose page labels, dates, inclusion decisions, and reasons | Correctness of those suggestions or acceptance by a portal |
Both lead to the same human review and deterministic PDF builder.
Files + portal instructions
|
Basic rules OR local vision model
|
Structured proposal
|
Your page-by-page review
|
Merge / rotate / compress in code
|
Check actual output -> Download
The small details that earned their place
Two early mistakes were surprisingly instructive. An “oldest to newest” instruction could be mishandled by looking for the word “newest” alone. An application mentioning supporting certificates could be mislabeled as a certificate.
Those became reasons to make ordering explicit and prioritize document headings in the Basic classifier. They also reinforced why the review screen should stay.
The current verification run passes 25 tests, covering the sample flow and cases such as ambiguous dates, invalid files, page order, rotations, impossible size limits, session restoration, and the local-model API contract.
There are intentional limits: 12 files, 30 pages, 40 MB per package, and 12 pages per local AI request. Form/signature-widget PDFs and encrypted PDFs are rejected. Photo-dimension rules, form filling, and guaranteed portal acceptance are outside this MVP.
Files stay in the local server's memory. Start over clears the package; inactive sessions expire after an hour; restarting the server clears all sessions. The original files are unchanged.
Why Does Open Innovation Matter?
Documents can contain information you would rather keep on your own machine. That makes the location of inference a product decision.
The local AI path targets Gemma 3 4B through Ollama. A downloaded, compatible vision model can run on the user's machine; the app's AI endpoint is fixed to the local Ollama service. It checks vision capability and rejects cloud model configurations.
That approach gives this project three useful properties:
- Control over the data path. Page images go to a local model process rather than a hosted AI API.
- Control over the model and behavior. A compatible installed vision model can be selected, and the prompts and validation rules can be changed.
- No hosted inference fee per document. Local hardware, electricity, setup, and model downloads still have costs.
Once the app dependencies and model are installed, the design does not require a cloud inference service. That is an architectural advantage here, not a claim that local inference is faster or more accurate than a hosted model.
Current status: the Ollama integration is implemented and tested with simulated model responses. A real Gemma model was not running during these demos. I have not measured its document accuracy or inference latency yet. The working demo above proves the Basic-mode workflow, not the AI path.
The next useful milestone is running the vision path on real, consented document examples: phone photos, rotated scans, faint dates, and confusing headings. I want to record which suggestions people correct, along with latency on actual hardware.
The Lazy Payoff
The fictional sample was exercised in the running app: four input pages became three selected pages in the requested order, with the instruction page excluded and the finished PDF measured at 5.6 KB.
That puts page review, reordering, exclusion, merging, and size checks into one place. The intended payoff is fewer tools to juggle when preparing an application or registration packet. I have not measured time saved with real users, and this is not yet a field-tested AI workflow.
Two DEV reads helped frame the engineering choices: The Hidden Failure Modes of PDF Processing and Building Reliable File Processing Pipelines without Glue Code, both by @iterationlayer. They emphasize early validation, explicit outputs, and visible uncertainty. These are vendor-authored perspectives, not independent validation of this app.
What is the most ridiculous upload requirement you've had to satisfy? A tiny file-size limit? A photo with exact dimensions? Five documents that somehow have to become one?
That last mile is the part I want to make easier.
來源:DEV Community · dev.to






