{"slug": "hacktoberfest-2026-i-submission-for-a-friend", "title": "Hacktoberfest 2026 I - Submission for a friend", "summary": "A developer is building \"Paperwork Translator,\" a mobile-first PWA that lets non-technical Spanish speakers photograph documents such as CFE electricity bills, SAT notices, or court summonses and receive plain-language explanations, deadline and amount extraction, step-by-step guidance, fraud warnings, and downloadable .ics calendar reminders. The project, an entry in the DEV Hacktoberfest Weekend Challenge 2026, runs entirely on open-source AI components with no closed-model APIs at runtime, and is developed in a FastAPI/SQLModel monorepo under a GitFlow workflow with non-stacked pull requests.", "body_md": "now help me to accomplish this huge feature:\n\nI'm entering the DEV Hacktoberfest Weekend Challenge 2026 (\"Build for a Friend\").\n\nThe project MUST comply with these rules:\n\n- The repo was created within the challenge window, which closes Monday, October 5,\n\n  00:59 Mexico City time. I want a working MVP by Sunday at 15:00 so I have time for the\n\n  write-up and to hand it over.\n\n- Open-source AI must be the core of the product: at runtime, NO closed-model APIs are used\n\n  (no Claude, OpenAI, or Gemini). You're helping me build it, but the product runs entirely\n\n  on open components.\n\n- Any commits after the deadline must be documented in the README.\n\nAll architecture decisions below are already made. Build the whole project end to end,\n\nfollowing the build order, without waiting for confirmation between steps unless a step\n\nexplicitly says to stop. Time is the main constraint: always choose the simplest solution\n\nthat works.\n\n# Git workflow: GitFlow with non-stacked PRs (ESSENTIAL, never skip)\n\nBranches:\n\n- main: production only. Changes arrive only through release/* or hotfix/* PRs.\n\n- develop: integration branch. Changes arrive only through feature/* PRs.\n\n- feature/<short-name>: one per build step, always created from the latest develop.\n\n- release/<version>: created from develop when the MVP is ready; PR into main, then\n\n  merged back into develop.\n\n- hotfix/<short-name>: from main, only for urgent production fixes; PR into main and\n\n  merged back into develop.\n\nRules:\n\n- Never commit directly to main or develop.\n\n- One feature branch per build step, one PR per feature branch, base branch = develop.\n\n- NO stacked PRs: never create a branch from another feature branch, and never open a PR\n\n  whose base is anything other than develop (or main for release/hotfix).\n\n- Sequence for every step:\n\n  1. git checkout develop && git pull\n\n  2. git checkout -b feature/<name>\n\n  3. Work with small Conventional Commits.\n\n  4. Run lint + typecheck + tests for the parts touched; all must pass.\n\n  5. Push and open the PR with gh pr create --base develop.\n\n  6. Merge it with gh pr merge (merge commit, delete the branch).\n\n  7. Only then start the next step from the updated develop.\n\n- PR description: what changed, why, how it was tested, and whether DECISIONS.md was\n\n  updated.\n\n- PR title follows Conventional Commits.\n\n# The product: \"Paperwork Translator\"\n\nA mobile-first web app for my mom. She takes a photo of a document (an electricity bill\n\nfrom CFE, a bank letter, a notice from the SAT tax authority, a court summons, etc.) or\n\nrecords a voice question about it. The app replies in plain, simple Spanish, with no\n\njargon, covering:\n\n1. What the document is and who sent it.\n\n2. Whether there's a deadline and how much she owes (if applicable).\n\n3. What she needs to do, in short steps.\n\n4. A clear warning if it looks like fraud or phishing (requests for personal data,\n\n   suspicious urgency, strange links).\n\nIf there's a deadline, she can tap \"Agregar a mi calendario\" to download an .ics reminder\n\nset a few days before the due date.\n\nA simple history screen lists her past documents and upcoming deadlines.\n\nBehavior rules for the AI responses:\n\n- ALL user-facing text is in Spanish (Mexican Spanish, warm and simple).\n\n- If the photo is unreadable or the model isn't confident, say so and ask for another\n\n  photo. Never make up amounts or dates.\n\n- Explain only; no legal or financial advice. For serious cases (summons, lawsuits, large\n\n  debts) recommend talking to her son or a professional.\n\n- Never ask for passwords, PINs, card numbers, or ID numbers.\n\nUX for an older, non-technical user:\n\n- Two big primary buttons on the home screen: \"Tomar foto\" and \"Preguntar con voz\".\n\n- Large text, high contrast, minimal steps, no jargon, clear loading state.\n\n- Installable as a PWA (add to home screen).\n\n# Architecture\n\nMonorepo:\n\n/api    FastAPI (Python 3.12+, uv, Pydantic, SQLModel, SQLite, pytest, ruff).\n\n        - POST /documents/analyze: receives an image, calls Gemma 4 via Ollama with a strict\n\n          JSON schema, returns structured data: document type, issuer, deadline, amount,\n\n          required actions, fraud flag + reason, confidence, and a plain-Spanish explanation.\n\n          Validate model output with Pydantic; on invalid output, retry once, then return a\n\n          low-confidence result instead of guessing.\n\n        - POST /questions/voice: receives audio, answers the question (optionally about a\n\n          previously analyzed document).\n\n        - GET /documents: history. GET /documents/{id}/reminder.ics: calendar reminder.\n\n/web    Nuxt (latest stable, TypeScript strict), mobile-first PWA, UI in Spanish.\n\n        Camera capture and audio recording via standard browser APIs.\n\n        Minimal access protection: a single family access code stored in a cookie.\n\n/samples  Anonymized test documents (already provided).\n\n/docs     DECISIONS.md.\n\nRoot:     README.md, CLAUDE.md, .claude/rules/, docker-compose.yml (Ollama + api + web for\n\n          local dev), render.yaml (Render Blueprint), .env.example, .gitignore.\n\nModel: Gemma 4 (Apache 2.0) via Ollama, running locally during development.\n\nAudio: if Ollama supports Gemma 4 audio input, use it; otherwise transcribe with\n\nfaster-whisper (open source) and send the text to Gemma 4.\n\n# Privacy (this is the project's core argument)\n\n- Images and audio are processed in memory and discarded; never stored.\n- Only the extracted structured data is persisted.\n- No logging of document contents or personal data.\n- Secrets in .env, never in the repo.\n- Tests and demos use only the anonymized documents in /samples.\n\n# Build order (each step = one feature branch + one PR into develop)\n\n1. Git setup: verify the GitHub remote and that gh is authenticated (if not, STOP and\ntell me). Ensure main exists, create develop from main, and push it.\n2. feature/scaffold: /api with uv, /web with Nuxt, docker-compose.yml, .env.example,\n.gitignore, docs/DECISIONS.md.\n3. \nfeature/claude-memory: Claude Code project memory, following current Claude Code\n practices. Keep every file short: only what you can't infer from the code and what\n differs from standard conventions.\na. CLAUDE.md at the repo root (committed), under ~60 lines:\n   - One-paragraph project overview and the monorepo layout.\n  - Exact commands: install, run api, run web, run Ollama, test, lint, typecheck.\n  - The GitFlow and non-stacked PR rules above, condensed.\n  - Workflow: run lint + tests for the part you touched before each commit;\nConventional Commits; update docs/DECISIONS.md when a technical decision is made\nor changed; check official docs instead of guessing Ollama/Nuxt/Render APIs.\n  - Non-negotiables: no closed-model APIs at runtime; images and audio never written\nto disk or logs; never log document contents or personal data; all user-facing\ntext in Spanish, everything else in English.\n  - A \"Gotchas\" section, updated as we discover them.\nb. .claude/rules/api.md with paths frontmatter scoped to api/**:\n  - Config only via pydantic-settings and .env.\n  - Every model output validated with Pydantic; retry once, then low confidence.\n  - Ollama calls async with explicit timeouts; a model failure never crashes a request.\n  - Prompts live in api/prompts/, versioned, never inline.\n  - Unit tests mock the model; one integration test hits the real model using /samples.\n  - Validate upload type and size before processing.\nc. .claude/rules/web.md with paths frontmatter scoped to web/**:\n  - API base URL only via runtimeConfig; no secrets in client code.\n  - Composables handle API calls; components stay presentational.\n  - All UI strings centralized in one file, in Spanish.\n  - Designed for an older, non-technical user: large tap targets, high contrast,\nalways-visible loading and error states.\nd. CLAUDE.local.md (in .gitignore) only for machine-specific settings: local Ollama\nURL, the Gemma 4 tag pulled, and the local access code for testing.\n4. feature/model-spike: check the exact Gemma 4 tag in the Ollama docs, pull it, and write\n a script in /api that sends the images in /samples with the extraction schema and\n prints the results. If the reading quality in Spanish is poor (wrong amounts or dates,\n unreadable text), STOP before opening the PR and show me the results with options.\nOtherwise, summarize the results in DECISIONS.md and continue.\n5. feature/api-analyze: /documents/analyze with tests.\n6. feature/api-history-reminder: history endpoint and .ics reminder, with tests.\n7. feature/web-photo-flow: home with the two buttons, photo flow, result screen, connected\nto the API. Verify the photo flow works end to end locally.\n8. feature/web-history-pwa: history screen and PWA setup.\n9. feature/voice-questions: check the Ollama docs for Gemma 4 audio support first.\n10. feature/deploy-render: render.yaml for /api and /web, deploying from main. Check whether\n Render offers GPUs for inference. If not, STOP and propose the alternatives (a smaller\n Gemma 4 variant, a DigitalOcean GPU Droplet, or inference on my own machine exposed\nsecurely) with pros and cons, and wait for my choice.\n11. feature/readme: README in English: what it is, who it's for, architecture diagram, how\n to run it, the branching model, and a \"Why open source matters here\" section\n(privacy, zero cost per request, control over the model).\n12. release/1.0.0: from develop, PR into main, merge, tag v1.0.0, then merge main back\ninto develop.\n\nPriority if time runs short: photo flow end to end > history > .ics reminder > voice.\n\nEven when cutting scope, never skip the GitFlow sequence.\n\n# General rules\n\n- Code, comments, commits, PRs, and README in English. All user-facing text in Spanish.\n- Don't invent Ollama, Nuxt, or Render APIs or flags: when unsure, check the official\ndocs before writing code, and tell me if something isn't documented.\n- Ask before installing anything globally or touching anything outside the repo.\n- Keep docs/DECISIONS.md logging each technical decision and why; I'll use it for the post.\n- Whenever I correct you on something that should apply to future sessions, propose\nadding it to CLAUDE.md or the right rules file instead of only fixing the code.", "url": "https://wpnews.pro/news/hacktoberfest-2026-i-submission-for-a-friend", "canonical_source": "https://dev.to/rzerostern/hacktoberfest-2026-i-submission-for-a-friend-4aa0", "published_at": "2026-10-04 20:35:40+00:00", "updated_at": "2026-10-04 20:42:45.097582+00:00", "lang": "en", "topics": ["ai-tools", "generative-ai", "ai-products", "developer-tools"], "entities": ["Paperwork Translator", "DEV Hacktoberfest Weekend Challenge 2026", "FastAPI", "SQLModel", "CFE", "SAT"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/hacktoberfest-2026-i-submission-for-a-friend", "markdown": "https://wpnews.pro/news/hacktoberfest-2026-i-submission-for-a-friend.md", "text": "https://wpnews.pro/news/hacktoberfest-2026-i-submission-for-a-friend.txt", "jsonld": "https://wpnews.pro/news/hacktoberfest-2026-i-submission-for-a-friend.jsonld"}}