cd /news/ai-agents/experiments-in-software-factories-1-… · home › topics › ai-agents › article
[ARTICLE · art-154332] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=↑ positive

Experiments in Software Factories #1: Production app in 40 minutes

A developer built and shipped pastmonday.com, a complete SaaS app with auth, a weekly calendar, Stripe tiered billing, referral credits, file uploads, and a calendar-aware AI chat, in about 40 minutes using a "software factory" of four reusable Claude Code skills that turn a one-page PROJECT.md brief into a staged product build. The app runs on a single backend vendor, Neon, using its GA Postgres, Auth, and Data API plus private-preview Object Storage, Functions, and AI Gateway, with Stripe handling payments and the developer's own cluster serving containers. The skills are public on GitHub, and each stage stops at an approval gate and verifies current package versions rather than relying on training data.

by read9 min views2 publishedOct 21, 2026

pastmonday.com is live. It has auth, a weekly calendar, tiered billing with Stripe, referral credits, file uploads, and an AI chat that knows your calendar. A small but complete SaaS, the kind of thing that used to be a three-month project.

Two things about it are unusual, and they're the reason for this post.

First: I didn't hand-write it. A software factory did.. four reusable Claude Code skills that turn a one-page brief into a shipped product, stage by stage. I talked about this on YouTube recently, and the skills themselves are public on GitHub.

Second: look at the vendor list. Postgres is Neon. Auth is Neon. The data API is Neon. Object storage is Neon. The LLM calls go through Neon. Stripe handles money and my own cluster serves the containers, and that's the entire list. The backend is one vendor, and until a few weeks ago that sentence was impossible to say, because half of these services didn't exist.

Neon announced they're building the full backend: Postgres, Auth, and the Data API are GA, and Object Storage, Functions, and an AI Gateway just entered private preview. I got early access, pointed the factory at all of it, and this post is the build report.

Note: this post is a transcription of my video on software factories, passed through AI and edited for reading. If you'd rather watch than read, here it is:

▶ Watch: Software Factories are SCARY but possible (and easy to do)

PROJECT.md brief, shipped The core idea is one separation: the skill is the HOW, the brief is the WHAT.

Everything project-specific lives in a single PROJECT.md in the repo: name, one-liner, the plans table, the palette and fonts, the entities, which services are enabled. Everything reusable lives in the skills. When I want a different product, I write a different brief. The factory doesn't change.

There are four stages, each a separate skill, each reading that same brief:

set-project-structure) builds the skeleton: Next.js with the directory contracts, the Drizzle schema, env keys with comments on where to get each value, design tokens, and placeholder clients for every enabled service. It deliberately builds set-landing-page) is the taste stage. It studies the brief's reference sites, writes real copy before layout, and works against an explicit banned-patterns list: no gradient hero, no "Supercharge your workflow", no fake testimonials.set-app-backend) is the correctness stage. Money and limits. Every quota, credit, token budget, and dollar is enforced on the server, atomically, idempotently. More on this below, because this is where Neon's new services plug in.set-dashboard) builds the app people live in: the calendar, the modals, the streaming AI chat, consuming only the contracts stage 3 exposed. Each stage stops at an approval gate before building, verifies current package versions instead of trusting its training data, and must leave the repo shippable when it ends. No half-built sections, no "we'll polish later".

Click through the stages here.. this is the actual pipeline that built pastmonday:

▶ The software factory pipeline (interactive), an interactive widget, runs on the original post.

I've written the first three stages up in detail before, if you want the deep dives: the concept, the brief, and the landing page.

What matters for this post: a factory like this is only as good as the surfaces it builds on. Stage 3 is where the factory has to wire auth, storage, data access, and LLM calls, and that's usually where you accumulate vendors. One for identity, one for buckets, one for model routing, plus the database. Four dashboards, four bills, four sets of credentials to leak.

This time, all four seams landed on the same platform.

Here's what pastmonday actually runs on, and the state of each piece:

Service Role in pastmonday Status
Postgres entries, profiles, billing, referrals, asset metadata GA
Neon Auth signup, login, sessions, the identity table GA
Data API PostgREST-style HTTP reads GA
Object Storage user file uploads, S3-compatible private preview
AI Gateway all LLM calls, metered per request private preview

A few receipts from the codebase, because "it works" is cheap to say.

Auth ships its own schema. Identity lives in neon_auth.user, and the factory's rule is: never mirror it. App tables hold foreign keys straight into it, so there's no sync job, no webhook that copies users around, no second source of truth:

// Neon Auth's identity schema, referenced, never mirrored
export const neonAuth = pgSchema("neon_auth");
export const authUser = neonAuth.table("user", { id: text("id").primaryKey() });

// profiles FK straight into it
userId: text("user_id").notNull()
  .references(() => authUser.id, { onDelete: "cascade" }),

Storage speaks S3, so there's no proprietary SDK to learn. The client is the plain AWS SDK, and it auto-reads the endpoint from AWS_ENDPOINT_URL_S3. Uploads are presigned PUTs with keys scoped per user, and since a presigned PUT can't enforce a size limit, the confirm route does a HeadObject and deletes anything oversized. The interesting part: Neon's storage branches with your database. Every branch gets its own isolated storage state. Your files and your rows stop drifting apart across environments.

AI Gateway is one API for models from Anthropic, OpenAI, Google and others, with per-request logging and rate limits, running on the same gateway infrastructure Databricks says handles 125 trillion tokens a month. For the app it means one token in the environment instead of a drawer full of provider keys, and the model is a config value:

const provider = createOpenAICompatible({
  name: "neon-ai-gateway",
  baseURL: `${NEON_AI_GATEWAY_BASE_URL}/ai-gateway/mlflow/v1`,
  apiKey: process.env.NEON_AI_GATEWAY_TOKEN,
});
export const chatModel = provider(process.env.NEON_AI_GATEWAY_MODEL);

Poke around the real architecture here, every box is clickable:

▶ pastmonday's backend, all Neon (interactive), an interactive widget, runs on the original post.

In the last Neon post I made one argument: Neon is API-first, so an agent can reach a primitive the moment it exists, before anyone builds it a button. I proved it by building a feature Neon hadn't shipped yet.

This build pushed that idea further than I expected, twice.

First, the AI Gateway is so new that its official AI SDK provider package wasn't even installable yet when the factory ran stage 3. A human would have stopped there. The agent didn't: it probed the gateway, found the OpenAI-compatible endpoint at /ai-gateway/mlflow/v1, verified it live with a real request, and wired the app through the AI SDK's generic OpenAI-compatible provider instead. The code carries a comment saying "swap to the official provider once it installs". That's what API-first buys you: the endpoint existed, so the missing package didn't matter.

Second, the convergence I didn't see coming: a week after I published my factory skills, Neon shipped agent skills of their own.. instruction files that teach coding agents how to integrate Functions, Storage, and the AI Gateway, installable with one command:

npx skills add neondatabase/agent-skills

Read that again from where I'm standing. I write skills that teach an agent how to build products. Neon now writes skills that teach the same agent how to consume their platform. The factory and the platform are meeting in the middle, and neither side needed the other's permission. This is what it looks like when a vendor treats agents as the primary developer.

A factory that ships beautiful broken apps is a liability, so stage 3 is paranoid by design. pastmonday charges money and sells limits: Free gets 1 entry and a 5,000-token AI budget, Pro gets 10 entries and 20,000 tokens a cycle, Max is unlimited. Limits only mean something if they can't be raced.

One constraint made this sharper than usual: the factory wired Drizzle through Neon's HTTP driver, which doesn't do interactive transactions. No BEGIN, hold the lock, decide, COMMIT. So every money-critical operation had to become a single atomic statement. This is the actual entry creation, quota check and insert in one round trip:

WITH consumed AS (
  UPDATE billing
     SET used_this_cycle = CASE WHEN used_this_cycle < monthly_quota
                                THEN used_this_cycle + 1 ELSE used_this_cycle END,
         extra_credits   = CASE WHEN used_this_cycle >= monthly_quota AND extra_credits > 0
                                THEN extra_credits - 1 ELSE extra_credits END
   WHERE profile_id = ${profileId}
     AND (used_this_cycle < monthly_quota OR extra_credits > 0)
  RETURNING id
)
INSERT INTO calendar_entries (user_id, title, ...)
SELECT ${userId}, ${title}, ...
WHERE EXISTS (SELECT 1 FROM consumed)

Quota first, then credits, else nothing gets inserted and the caller gets a 402. Two concurrent requests can't both take the last unit, not because the code is careful, but because the statement can't be split.

The same paranoia runs through the rest: the AI budget is checked server-side before every gateway call and metered from real usage on finish, Stripe webhooks dedupe on event id in a processed_stripe_events ledger so a replayed event can't grant credits twice, and quota-exhausted returns a typed 402 the UI turns into an upgrade prompt instead of an error toast.

None of this is Neon-specific, but it's the standard the factory holds, and the new services slotted into it without a fight. That's the actual test of a backend platform: not the demo, the enforcement paths.

My favorite Neon primitive has always been branching. I've built preview environments where every pull request gets its own database branch, created and destroyed by the agent through the API.

The new services extend that idea past the database. Storage state branches with your data today, and Neon manages Functions through the same CLI and API as everything else. The direction is obvious and they're saying it out loud: a branch should fork the backend, not just the schema.

For a software factory, that's the missing piece. Today my factory pipeline validates each stage against the production-shaped environment it builds. The version I want is: every factory run, every agent session, every experiment gets a full isolated copy of the backend.. rows, files, functions.. for the lifetime of a task, then vanishes. Database branching already proved this workflow for schema changes. Extending it to the whole backend turns "spin up a staging environment" from an afternoon of Terraform into a flag on a CLI call.

That's the same story as the spending-caps feature from my last post, which is still marked "coming soon" by the way, and I'm still holding them to it: the primitives ship first, through the API, and the people building on top get to run ahead of the roadmap.

The pitch for this stack isn't "Neon does everything". It's narrower and more honest: a full working SaaS.. identity, data, files, AI, money.. now fits in one brief, four skills, one backend vendor, and one Stripe account. pastmonday went from empty repo to production on my cluster in about 40 minutes, and most of that time I was making taste decisions at the approval gates, not doing integration work.

If you want to go deeper: the video covers the factory concept, the skills are on GitHub to steal, the series walks each stage, and pastmonday.com is the living proof.. go create an entry, that's a race-safe atomic quota consume you're clicking.

And if you're at Neon: ship the branch-forks-everything future. I have a factory waiting for it.

── more in #ai-agents 4 stories · sorted by recency
── more on @neon 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/experiments-in-softw…] indexed:0 read:9min 2026-10-21 · —