Skip to content

ddcore 0.15 ​

0.15.1 — 2026-09-18 ​

Added ​

  • ddcore init writes a docker-compose.yml that runs PostgreSQL with the user, password, database and port in the DSN, so docker compose up -d gives a new project its database. It writes the file only for a DSN on this machine, and leaves an existing compose.yaml, compose.yml, docker-compose.yaml or docker-compose.yml alone.
  • ddcore init --name <n> --db-port <p> builds the DSN postgres://n:n@localhost:p/n?sslmode=disable, so you no longer have to type it out. --dsn still points at an existing database, and it cannot be combined with the two new flags.
  • ddcore init also writes the project's README.md (setup, commands, MCP), AGENTS.md with the conventions for coding agents (CLAUDE.md is a symlink to it), a .mcp.json that registers ddcore mcp, and a .gitignore that keeps .env, .ddcore/ and data/ out. It never overwrites an existing file. Its closing message lists every step up to ddcore user passwd Admin and the URL.
  • ddcore new-app writes version: "0.1.0" and a ddcore range for the running minor release (>=0.15.0 <0.16.0 on 0.15.x) into ddcore.app.ts. A build that is not a release leaves the range commented out.

Changed ​

  • Without --dsn or --name, ddcore init now names the database, user and password after the directory (for example my-shop becomes my_shop) instead of ddcore.
  • ddcore new-app no longer writes apps/<app>/CLAUDE.md. The guide now lives once, at the project root, as AGENTS.md. Existing apps keep their file.

Fixed ​

  • The ddcore running log line reports the configured public url instead of always http://localhost:<port>; the local address moved to a listen field.

0.15.0 — 2026-09-17 ​

Added ​

  • Release awareness: this file now ships inside the binary and is served as the MCP resource ddcore://changelog. The whats_new tool returns the part of it above the running version, together with the newest published release.

  • ddcore doctor asks GitHub for the newest published release and warns when the binary is behind it, so --strict fails on a stale one. It asks at most once an hour, stays silent when it cannot reach GitHub or when the binary is not a release, and is skipped by --no-update-check for one run or DDCORE_UPDATE_CHECK=off for every run.

  • Backup, restore and maintenance (PRD-01, PRD-02):

    • ddcore backup writes one checksummed archive of the database, stored files, configuration and versions, with optional S3 upload and retention.
    • ddcore restore verifies the archive, restores it into an isolated target, migrates, and times each phase. --smoke adds a check pass.
    • ddcore maintenance on|off pauses writes and jobs on every process and shows a Desk banner.
    • DDCORE_DATA_DIR overrides dataDir. ops.backupMaxAgeHours warns on a stale backup.
  • S3-compatible file storage (PRD-05): DDCORE_STORAGE=s3 with DDCORE_S3_* (AWS, R2, MinIO, B2) beside the default local backend under <dataDir>/files. file_url is the only name on both; a download is permission-checked by the server and then streamed, or redirected to a short-lived presigned URL; deleting a File or its document removes the bytes after commit, and a failed upload removes what it wrote. Mail, export and the CLI read through the store. See storage.

  • Document sharing (SEC-03): the Core Document Share DocType grants one user read, write or share on one document, given by someone holding the share right and capped by their own write. A share stands in for a missing role grant on reads, lists, counts, link search, saves, dbSet, attachments, versions and comments, print, SSE and notifications, while controller hooks, workflow allowEdit and docstatus still apply. Override security scope lifts the recipient's User Permission scopes for the granted rights only. Renames move shares and deletions remove them; every grant, change and revocation is an audit event. /api/shares/*, ddcore.share.* and a Desk sidebar section. See sharing.

  • Global search (OPS-08): a Mod+K palette in the desk and GET /api/search/global, matching the title and search fields of every DocType the user can list, with roles, scopes, shares and field levels applied. globalSearch on a DocType opts it in or out. Core log DocTypes are opted out.

  • Kanban and Gantt list views (OPS-08) through defineListView({ kanban, gantt }). Dragging a Kanban card saves its Select field.

  • Single sign-on through OpenID Connect (SEC-05, partial): Google, PocketID or any OIDC provider, configured with DDCORE_OIDC_* in .env. It signs in existing Users only, linked by a verified e-mail address. auth.passwordLogin: false in ddcore.json leaves single sign-on as the only way in, except for Admin. See authentication.

  • Core/app compatibility contract (PRD-07): defineApp({ ddcore: "<range>" }) declares the ddcore releases an app supports, and a binary outside the range refuses to load it. ddcore doctor and the export manifest report each app's version and range.

Breaking ​

  • A binary older than the one that last ran migrate on a database now refuses to open it, naming the core or app version that is older. Roll forward, or pass --allow-older-binary (DDCORE_ALLOW_OLDER_BINARY=1) when the migrations since were expand-only. Databases migrated before this release have no ledger row and are not checked until their next migrate.

  • storage.Store has a new List method; an embedder with its own store must implement it.

  • An app whose version is not a version — "1", "1.0" and "1.0.0" are all fine, "beta" and "1.0.0-rc.1" are not — no longer loads. Fix the value or remove it.

Fixed ​

  • ^ and ~ with an abbreviated version now bound what the author left out, as npm does: ^0 is every 0.x, ^0.0 every 0.0.x, and ~1 every 1.x. The spelt-out forms are unchanged.
  • A job whose write is refused by maintenance mode goes back to the queue without consuming an attempt and without an Error Log row, instead of failing — on its last attempt it used to die of a pause that was nobody's fault.
  • Global search applies its five-hits-per-DocType cap after ranking, so an exact match is no longer lost behind more recently modified rows, and % and _ in the search text now match themselves instead of acting as wildcards.
  • A migrate run by a build with no release version (a dev binary) no longer replaces the ledger's core version, which silently disarmed the rollback guard for every later binary.
  • ddcore.share.* refuses a right it does not know (override_scope for overrideScope) with the same 417 as the endpoint, rather than dropping it and granting a share without it.
  • Single sign-on clears the client address's failed attempts on a successful sign-in, as a password sign-in does, and a failure on the server's own side is reported as sso_error=server rather than blamed on the provider.
  • --allow-older-binary=true is accepted; only the bare flag used to be.
  • ddcore doctor reports a rollback refusal as its own critical instead of "the apps could not be loaded", and prints an S3 bucket with no prefix without a trailing slash.
  • ddcore restore warns when it stops after the database was replaced: the target keeps the restored database and stays paused.
  • A list view listed in views but never configured no longer shows a button that falls back to the table.

MIT Licensed · ddcore (Data Driven Core) · Development documentation (main)