Skip to content

fix(autonumber): single owner = persistent driver sequence (#1603)#1608

Merged
xuyushun441-sys merged 1 commit into
mainfrom
feat/autonumber-driver-consolidation
Jun 6, 2026
Merged

fix(autonumber): single owner = persistent driver sequence (#1603)#1608
xuyushun441-sys merged 1 commit into
mainfrom
feat/autonumber-driver-consolidation

Conversation

@xuyushun441-sys
Copy link
Copy Markdown
Contributor

Summary

Closes the #1603 "persistent autonumber sequence" gap by making autonumber generation single-owner.

Today autonumber values are generated in two places:

  • the SQL driver's persistent, atomic _objectstack_sequences table (getNextSequenceValue / fillAutoNumberFields), and
  • a non-persistent in-memory counter in the ObjectQL engine (applyAutonumbers).

Because the engine pre-fills the field before calling the driver, the driver always sees a value already set and skips (fillAutoNumberFields line ~618). So the persistent sequence is effectively dead code, and a multi-instance / post-restart deployment can mint duplicate numbers from the in-memory counter.

Changes

@objectstack/spec

  • DriverCapabilities gains an optional autonumber flag — "driver natively generates persistent autonumber/sequence values".

@objectstack/driver-sql

  • Advertises supports.autonumber = true.
  • bulkCreate() now fills autonumber fields too — previously only create() / upsert() did, so bulk inserts skipped the sequence.
  • Field parsing honors either the spec-canonical autonumberFormat key or the format shorthand (both appear in metadata). This prevents a format-loss regression now that the driver path is the live one.

@objectstack/objectql

  • When the driver advertises native autonumber support, the engine no longer pre-fills — it defers entirely to the persistent driver sequence (single source of truth). For drivers without native support (memory, mongodb) the in-memory fallback is unchanged.
  • The fallback also reads either autonumberFormat or format.
  • Record-validation exempts autonumber from the required check — the value is runtime-owned and assigned after validation, so a required record number is never rejected as "missing".

No metadata changes required. Existing data is respected — the driver bootstraps each sequence from the current max numeric tail on first use (scanMaxNumericTail).

Testing

  • driver-sql (140 pass): new tests for bulkCreate autonumber fill, the autonumberFormat key, and the supports.autonumber capability — plus the existing per-tenant / bootstrap / concurrency / global-sequence suite.
  • objectql (526 pass): new engine-autonumber-defer.test.ts (native driver → engine does NOT pre-fill and never scans; non-native driver → engine fallback fills) and record-validator.test.ts (required autonumber missing → no error; required non-autonumber missing → error).
  • Both packages build type-clean.

Risk

This activates a previously-dormant-but-fully-tested driver path. The driver's autoNumberFields map is already populated in production via syncSchema → initObjects, so generation does not silently stop. The format-key harmonization removes the one regression vector (metadata declaring autonumberFormat).

🤖 Generated with Claude Code

Autonumber values were generated twice: the SQL driver's persistent,
atomic _objectstack_sequences table AND a non-persistent in-memory
counter in the engine. The engine pre-filled before calling the driver,
so the driver always saw a value and skipped — leaving the persistent
sequence as dead code and risking duplicate numbers across instances /
after a restart.

- spec: DriverCapabilities.autonumber (optional) capability flag.
- driver-sql: advertise supports.autonumber=true; bulkCreate now fills
  autonumber too (was create/upsert only); parse honors autonumberFormat
  OR format.
- objectql: engine defers to the driver when it advertises native
  autonumber support (no more pre-fill / in-memory shadow); keeps the
  in-memory fallback for memory/mongodb; fallback also reads either
  format key; record-validation exempts autonumber from the required
  check (runtime-owned, assigned post-validation).

Tests: driver bulkCreate + autonumberFormat + capability (driver-sql
140 pass); engine defer-vs-fallback + validator exemption (objectql
526 pass). Existing data respected via scanMaxNumericTail bootstrap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 6, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Building Building Preview, Comment Jun 6, 2026 7:59am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation protocol:data tests tooling size/m labels Jun 6, 2026
@xuyushun441-sys xuyushun441-sys merged commit b990b89 into main Jun 6, 2026
10 of 11 checks passed
@xuyushun441-sys xuyushun441-sys deleted the feat/autonumber-driver-consolidation branch June 6, 2026 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation protocol:data size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants