Step 5: Determine Services

Phase: plan

Context

You have the confirmed app_spec. Now determine which run402 services the app needs.

What to do

Based on the app spec, determine which run402 services are required. Every app uses at least database + static hosting.

run402 services checklist

ServiceWhen neededrun402 feature
Database Always — every app stores data Postgres via PostgREST API. Tables created via SQL migration endpoint.
REST API Always — how the frontend reads/writes data Auto-generated from database schema. CRUD + filters at /rest/v1/{table}.
Authentication When app_spec.features.auth is true Email/password signup + login at /auth/v1/signup and /auth/v1/token.
Row-Level Security When users should only see their own data, or when some data is public and some private Expose manifest with policies: user_owns_rows, public_read_authenticated_write, public_read_write_UNRESTRICTED, custom. Tables are dark by default — they need an expose: true entry to appear in the REST API.
File Storage When app_spec.features.file_uploads is true Content-addressed CDN. Browser uploads go through a deployed function that calls assets.put; server-side uploads use (await r.project(id)).assets.put(). Reads use GET /storage/v1/blob/:key, or the returned paste-and-go cdnUrl.
Serverless Functions When server-side logic is needed that can't run in the browser (e.g., password hashing, matching algorithms, secret operations) Node 22 Fetch functions: export default async (req) => Response. Deployed via unified deploy (functions.replace in the ReleaseSpec). Called from frontend at /functions/v1/{name} (API-key protected) or via same-origin web routes (routes.replace).
AI Image Generation When the app creates images from text prompts (e.g., sticker makers, art generators) Generate images via POST /generate-image/v1 ($0.03/image, x402-gated). SDK: r.ai.generateImage({ prompt, aspect }). Returns image bytes to upload to File Storage.
Static Hosting Always — how the app is deployed Unified deploy: (await r.project(id)).apply({ site: { replace }, subdomains: { set } }) (SDK 2.0+). HTTP wire is POST /apply/v1/plans + /commit. Returns a shareable URL.

Database table planning

For each data type in app_spec.features.data_types, plan a database table. Consider:

  • What columns does each table need?
  • Which tables reference each other (foreign keys)?
  • Which RLS template applies to each table?
  • Does any table need seed data (e.g., default categories, sample content)?

Do NOT tell the user about tables, columns, or SQL. Just note this internally for the build.

Expected output

  • required_services — List of run402 services needed with details:
    {
      "database": true,
      "tables": [
        {"name": "todos", "columns": ["id", "task", "done", "user_id", "created_at"], "rls": "user_owns_rows"}
      ],
      "auth": true,
      "file_storage": false,
      "static_hosting": true,
      "seed_data": false
    }

Memory directive