This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle
What I Built
A client says, “We need a small website. Maybe add bookings too.”
That sounds like a brief, but it leaves a freelancer with several decisions: does “bookings” mean linking to an existing service or building a reservation system? Who supplies the content? What belongs in the price?
ScopeNote turns that early conversation into a working scope the freelancer can review before making a commitment.
It is built for independent designers, developers, and small studios preparing client proposals. Start with a written brief or upload a recording of a client briefing, with their permission. ScopeNote helps organize the information into:
- A project overview.
- Concrete deliverables with editable estimated hours.
- Questions about missing requirements.
- Exclusions that make the boundaries of the work explicit.
- An estimate based on the freelancer’s rate and contingency.
- A proposal that can be exported as Markdown or a branded A4 PDF.
The important word is working. The generated document is a starting point for discussion, not a promise that the AI knows the right price or understands every requirement.
The paid feature is a private workspace for client work. Premium costs US$1 once for 30 days, with no subscription or automatic renewal. It includes private drafts by default, optional public sharing, and 10 voice imports per access period, up to 12 MB each. Both plans include PDF and Markdown exports, three AI scopes per quota period, and five saved projects; Free uses a calendar month and Premium uses its 30-day access period.
The Free plan makes newly saved drafts, scopes, and client names public. Public pages show a masked author label such as A***r, rather than the account email or full display name. It is intended for material the author has permission to share. Premium owners choose Public or Private before saving, and saved private projects remain private after access expires.
That is the side-hustle hypothesis: someone who regularly prepares client proposals might pay a small amount for private, reusable project work and a shorter path from conversation to proposal. The price is live; sustainable unit economics and demand still need validation.
Demo
Live application: scopenote.dktirta.tech
You can browse public drafts without an account. To try the editor, create an account and verify your email before generating an AI scope or importing audio.
A useful walkthrough is:
- Create a project with a client and project name.
- Paste a brief, or upload an existing audio recording.
- Review the transcript, then generate a scope.
- Edit the deliverables, hours, questions, and exclusions.
- Set your hourly rate and contingency.
- Export the proposal as PDF or Markdown.
For Free testing, use a fictional or non-confidential brief: saving publishes the client name, brief, scope, and estimate. There is no shared judge password or preloaded demo mode.
The voice feature imports recordings; it does not record a meeting directly inside the app.
Code
ScopeNote
A scope-of-work app for independent designers and developers. Bring a client brief or voice note, generate a draft with Gemma through Mastra, edit the document and hours, save the project, and export a PDF or Markdown proposal.
Status: account migration: email/password accounts, public Free drafts/scopes, server-side usage limits, password reset and email verification. There is no demo or simulated entry point. Premium is prepaid: US$1 once for 30 days through AllScale, with no subscription or automatic renewal. Checkout requires server configuration. Resend sender domain is verified; verification and reset email delivery plus old-session revocation passed against the production API. See CONFIGURATION.md.
Run locally
Node.js 22.13+ is required. From this directory:
npm install
npm run dev
This starts Vite on http://127.0.0.1:5178 and the Express backend on port 3001. Vite forwards /api to the backend. Copy .env.example to .env when ready to configure credentials. Real accounts require MongoDB. Public drafts and…
Source code and setup instructions · MIT license · Render deployment configuration
The repository includes the application, backend, environment-variable template, deployment configuration, and automated tests. API credentials remain on the server and are not part of the public source.
How I Built It
The frontend uses React and Vite, with Motion for transitions and Phosphor icons. A Node.js/Express backend handles accounts, project access, quotas, AI requests, and payments. Render runs the Express service and serves the built frontend; Cloudflare provides DNS for the custom domain.
The core AI flow is deliberately small:
Written brief ──────────────────────────────┐
Recording → ElevenLabs Scribe → transcript ┤
↓
Express API
↓
Mastra workflow
↓
Gemma drafts a scope
↓
Zod validates JSON
↓
Freelancer reviews it
↓
MongoDB Atlas / PDF / Markdown
Gemma and Mastra
Gemma does the transformation from unstructured brief to structured scope. The configured model is gemma-4-26b-a4b-it, accessed through the Google Generative AI adapter. Inference is hosted by the model provider; Render runs the application, not Gemma’s weights.
The Mastra workflow has two steps:
-
extract-scopeinvokes the Gemma agent. -
validate-scopeparses the response and checks it against the application’s Zod schema.
The prompt asks for concrete deliverables, estimated hours, questions, and exclusions. Missing information should become a question instead of an invented commitment. It treats the client brief as untrusted input and requests JSON matching a defined structure.
Validation checks the shape and bounds of the output. Invalid responses become an explicit error; the application does not silently replace them with a sample scope.
A valid schema still cannot establish whether the proposed work is appropriate. That distinction is also explored by Michael Maurice in “Schema-Valid Isn’t Correct: 4 Checks Before You Trust LLM Extraction”. ScopeNote keeps the freelancer’s review between generation and export.
The model suggests hours, but ordinary application code calculates the estimate:
export function estimate(items, rate, buffer) {
const hours = items.reduce((sum, item) => sum + Number(item.hours), 0);
return {
hours,
total: Math.round(hours * rate * (1 + buffer / 100) * 100) / 100
};
}
ElevenLabs
ElevenLabs Scribe transcribes uploaded recordings into text. This makes a client interview or voice briefing usable without first rewriting the entire conversation manually. The user can review the transcript before asking Gemma to generate a scope.
ScopeNote accepts audio files up to 12 MB. Audio is held in backend request memory and is not stored by ScopeNote; the transcription provider’s data policies still apply.
MongoDB Atlas and accounts
Atlas stores accounts, sessions, saved projects, usage counters, payment records, and receipt-delivery state. Projects belong to the authenticated account, and public endpoints return an explicit set of shareable fields.
Saved projects retain up to ten previous revision snapshots. Revision checks reject stale saves from another tab instead of silently overwriting newer work. Public/Private visibility is enforced on the backend, rather than relying on a frontend toggle alone.
Email verification and password reset use Resend. Reset links expire, are single-use, and revoke existing sessions after a successful password change.
Sentry Agent Tracing
Sentry instrumentation traces the agent run, Gemma request, validation step, and transcription operation. Model identity and token usage are attached when available, helping distinguish model work from the rest of the request.
The telemetry filter removes content-bearing attributes such as prompts and response text. Account identifiers and request bodies are not intentionally attached. I am not claiming measured latency or inference-cost improvements from this instrumentation.
AllScale payments
AllScale provides the one-time checkout for 30 days of Premium. The checkout accepts supported USDT/USDC crypto payments, rather than Indonesian QRIS.
A return from the checkout page does not grant Premium. The backend verifies the payment status with AllScale before extending access, and repeated processing of the same order must not grant access twice.
After confirmed payment, Resend sends a branded receipt. A MongoDB outbox stores the receipt and tracks delivery attempts; order-specific idempotency keys protect retries against duplicate sends.
Exports and verification
PDF export runs in the browser using pdf-lib, fontkit, embedded Lato fonts, and ScopeNote’s A4 stationery. It includes the project and client details, scope, estimate, questions, exclusions, and “Made with ScopeNote” credit. Document content is not sent to a separate PDF-generation service.
The latest local test run passed 60 automated tests, covering account isolation, reset flows, quota enforcement, payment reconciliation, receipt retries, public/private access, masked author labels, scope validation, estimate arithmetic, and PDF pagination. The production build also passes. These checks cover application behavior; they are not a benchmark of model accuracy.
Codex assisted with implementation and this write-up under my direction.
Why Does Open Innovation Matter?
The part of ScopeNote that interprets a brief is built around Gemma, an open-weight model, and Mastra, an open-source agent framework. The application itself is MIT licensed.
For this project, openness matters most at the boundary between the product and its inference provider. The workflow, prompt, output contract, validation, and estimate calculation are visible in the repository. Someone can inspect how a scope is produced, change the planning instructions for their own niche, or adapt the application to a different serving arrangement.
Gemma’s available weights make a future self-hosted deployment possible, subject to its license and infrastructure requirements. A model offered only through a closed API would not provide that same option to run its weights. Mastra also makes the orchestration inspectable instead of hiding the planning flow inside a proprietary application.
That flexibility is relevant to a small paid tool: hosting costs, provider availability, and client-data requirements may change as it grows. I have not yet demonstrated lower inference costs, fine-tuned the model, or implemented local inference.
The current hosted version still sends briefs to Google for inference, audio to ElevenLabs, and saved projects to Atlas. Open source does not make those requests local or automatically private. What it gives this project is an inspectable foundation and the option to change how the AI is served as the product develops.
Prize Categories
I am entering the categories corresponding to ScopeNote’s implemented integrations:
- Best Use of Render: the deployed web service runs the frontend and Express backend.
- Best Use of Gemma: Gemma converts the client brief into a structured working scope.
- Best Use of Mastra: a two-step workflow coordinates scope generation and validation.
- Best Use of MongoDB Atlas: Atlas stores account-owned projects, revisions, usage, and payment records.
- Best Use of Sentry Agent Tracing: custom spans trace the agent, model, validation, and transcription operations.
- Best Use of ElevenLabs: Scribe turns uploaded client recordings into editable brief text.
Top comments (0)