spfn 0.2.0-beta.66 → 0.2.0-beta.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +51 -4
  2. package/dist/index.js +349 -455
  3. package/package.json +9 -8
package/README.md CHANGED
@@ -5,6 +5,11 @@ architecture. It can scaffold either a core-only backend or a production baselin
5
5
  authentication, internationalization, and an agent-facing MCP endpoint, then runs the
6
6
  dev/build/start lifecycle, database tooling, RPC codegen, and environment validation.
7
7
 
8
+ Consistent is the point rather than a nicety: what it scaffolds is one fixed shape per
9
+ feature, so a coding agent has no architecture left to invent and the codebase does not
10
+ acquire several. That problem has a name —
11
+ [architecture drift](https://superfunction.xyz/architecture-drift).
12
+
8
13
  > Beta: install with the `@beta` tag (`spfn@beta`). The binary is `spfn`.
9
14
 
10
15
  ## Install
@@ -19,8 +24,8 @@ pnpm dlx spfn@beta <command>
19
24
  Or add it as a project dependency (`spfn init`/`spfn create` do this for you), then
20
25
  call it via `pnpm spfn <command>` / `npm run spfn:<script>`.
21
26
 
22
- Requirements: Node.js 18.18+ for bare mode, Node.js 20+ for full mode's MCP server,
23
- Next.js 16.2.11+ (App Router, `src/` dir), PostgreSQL 14+ (Redis optional). Next.js 15
27
+ Requirements: Node.js 20+ in both modes, Next.js 16.2.11+ (App Router, `src/` dir),
28
+ PostgreSQL 14+ (Redis optional). Next.js 15
24
29
  is not supported — see [the root README](../../README.md#what-do-i-need-installed).
25
30
 
26
31
  ## Usage
@@ -132,9 +137,13 @@ no pre-build needed.
132
137
  | `-p, --port <port>` | Server port | from `server.config.ts` / env (`4000` in server-only fallback) |
133
138
  | `-H, --host <host>` | Server host | `localhost` |
134
139
  | `--routes <path>` | Routes directory path | server default |
140
+ | `--allow-pending-migrations` | Start even when migrations are pending (they are listed as a warning) | off |
135
141
 
136
142
  Note: hot reload is **off by default** — pass `--watch` to restart on file changes.
137
143
 
144
+ Pending migrations stop the boot — see [Database](#spfn-db) for what the refusal looks
145
+ like and how to override it.
146
+
138
147
  ### `spfn build`
139
148
 
140
149
  Runs codegen, builds Next.js (via the project's `build` script), and compiles
@@ -158,9 +167,14 @@ if `.spfn/server`, `.spfn/prod-server.mjs`, or `.next` are missing.
158
167
  | `--next-only` | Run only Next.js | off |
159
168
  | `-p, --port <port>` | SPFN server port (sets `SPFN_PORT`) | `8790` |
160
169
  | `-h, --host <host>` | SPFN server host (sets `SPFN_HOST`) | `0.0.0.0` |
170
+ | `--allow-pending-migrations` | Start even when migrations are pending (they are listed as a warning) | off |
161
171
 
162
172
  Next.js is started on `0.0.0.0:3790`. Both run together via `concurrently --kill-others`.
163
173
 
174
+ Pending migrations stop the boot unless `--allow-pending-migrations` or
175
+ `SPFN_ALLOW_PENDING_MIGRATIONS=true` is set — see [Database](#spfn-db). `--next-only`
176
+ skips the check: no SPFN server starts, so nothing can drift.
177
+
164
178
  ### `spfn codegen`
165
179
 
166
180
  Manages code generators driven by `.spfnrc.ts`. The default generator is
@@ -254,6 +268,27 @@ loaded `.env` chain.
254
268
  > `db push` is for development. For production, use `db generate` + `db migrate` to keep
255
269
  > migration history.
256
270
 
271
+ **A server refuses to start while migrations are pending.** Bumping `@spfn/auth` and
272
+ skipping `db migrate` used to boot fine, pass the health check, and then fail every
273
+ request that touched a new column as an opaque 500. `spfn dev` and `spfn start` now
274
+ compare the migrations each installed function package ships (and `src/server/drizzle`,
275
+ where present) against what the database records as applied, print the ones still
276
+ waiting, and stop:
277
+
278
+ ```
279
+ ❌ Refusing to start: 1 pending migration(s) in @spfn/auth
280
+ @spfn/auth: 1 pending migration(s) (12/13 applied)
281
+ - 20260805143152_client_identity
282
+
283
+ Run: pnpm spfn db migrate
284
+ ```
285
+
286
+ `--allow-pending-migrations` starts anyway and logs the same list as a warning.
287
+ `SPFN_ALLOW_PENDING_MIGRATIONS=true` does the same where no flag can be passed — a
288
+ container's env, a CI job. The check is skipped when the app initializes no database
289
+ or no package ships migrations, and a database it cannot reach is reported as
290
+ "could not verify", never as drift.
291
+
257
292
  `db push` and `db migrate` also replay migrations shipped by installed SPFN function
258
293
  packages (`@spfn/auth`, `@spfn/cms`, …) into per-package tracking tables
259
294
  (`drizzle.__spfn_fn_<pkg>_migrations`). The CLI applies these with a built-in runner
@@ -482,6 +517,18 @@ Run migrations against the target DB before/with deploy:
482
517
  docker exec <container> npx spfn db migrate
483
518
  ```
484
519
 
520
+ Forget, and the container will not come up: the server refuses to serve while migrations
521
+ are pending and prints which ones. That is the intended failure — a deploy that stops at
522
+ the gate is one that never served the 500s. If a rollout has to proceed anyway, set
523
+ `SPFN_ALLOW_PENDING_MIGRATIONS=true` in the container's environment; the pending list is
524
+ logged as a warning instead.
525
+
526
+ A readiness probe can catch the same drift on a cluster the local gate never sees. When
527
+ detailed health is on, `GET /health` carries a `migrations` object with per-package
528
+ applied/pending counts — assert `migrations.pending === 0` in the probe to hold a
529
+ drifted pod out of rotation. Reporting drift does not, by itself, change the overall
530
+ health `status`.
531
+
485
532
  `spfn.config.js` (committed) configures the managed `*.spfn.app` deployment: `subdomain`,
486
533
  `region` (`us` default, `kr`, …), `customDomains`, and non-secret `env`. Its `SpfnConfig`
487
534
  type ships from `spfn` (`@type {import('spfn').SpfnConfig}`).
@@ -511,8 +558,8 @@ and `docker compose up -d` is also the convenient way to get PostgreSQL and Redi
511
558
  pointing at your own PostgreSQL works too. PostgreSQL itself is not optional.
512
559
 
513
560
  **Which Node version do I need?**
514
- 18.18 or later for bare mode, 20 or later for full mode, because full mode includes the
515
- MCP server.
561
+ 20 or later, in both modes. `@spfn/core` runs on `@hono/node-server` 2, which declares
562
+ that floor, and full mode's MCP server needs the same.
516
563
 
517
564
  **When do I have to run codegen by hand?**
518
565
  Whenever routes change outside `spfn dev`, which runs a codegen watcher for you. A stale or