# ScopeNote: Turning Client Conversations into a Clear Freelance Scope

> Source: <https://dev.to/dkfadhila/scopenote-turning-client-conversations-into-a-clear-freelance-scope-4abe>
> Published: 2026-10-16 09:03:47+00:00

*This is a submission for the [Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle](https://dev.to/challenges/hacktoberfest-week2-2026-10-12)*

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:

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.

**Live application:** [scopenote.dktirta.tech](https://scopenote.dktirta.tech/)

You can [browse public drafts without an account](https://scopenote.dktirta.tech/#gallery). To try the editor, create an account and verify your email before generating an AI scope or importing audio.

A useful walkthrough is:

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.

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.

Node.js 22.13+ is required. From this directory:

```
npm install
npm run dev
```

This starts Vite on [http://127.0.0.1:5178](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](https://github.com/dkfadhila/scopenote) · [MIT license](https://github.com/dkfadhila/scopenote/blob/main/LICENSE) · [Render deployment configuration](https://github.com/dkfadhila/scopenote/blob/main/render.yaml)

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.

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](https://github.com/dkfadhila/scopenote/blob/main/server/agent.js) has two steps:

`extract-scope` invokes the Gemma agent.`validate-scope` parses 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”](https://dev.to/michael_maurice/schema-valid-correct-4-checks-before-you-trust-llm-extraction-4n6f). ScopeNote keeps the freelancer’s review between generation and export.

The model suggests hours, but ordinary application code calculates the estimate:

``` js
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](https://github.com/dkfadhila/scopenote/blob/main/server/telemetry.js) 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.

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.

I am entering the categories corresponding to ScopeNote’s implemented integrations:
