Skip to content

Changelog

All notable changes to SchemaStack are documented here.

2026-04-24

Improved

  • Faster production error detection — uncaught exceptions on both the frontend and backend are now forwarded to an error-tracking service in production, so regressions surface without waiting for users to report them. No change to behaviour; dev builds are unaffected.
  • Gzip compression on API responses — Traefik now compresses application responses on the edge (SSE streams are excluded so real-time events still flow immediately), reducing payload sizes on large view reads and metadata endpoints.

Added

  • One-command rollback for deployments — the deploy runner supports run.sh rollback, which brings the previously-active blue/green color back up from existing images and swaps traffic over without rebuilding.

2026-04-20

Added

  • View search in the toolbar — a new search box (right of the Help menu, under the hamburger menu on mobile) finds columns and cell values in the current view. Results open in a split dialog with two sections: Metadata for matching tables/columns (click to jump to the header and open its properties panel) and Row Data for matching cell values anywhere in the view (click to open the matched column's properties panel; if the row is already on screen, it's scrolled to and the cell pulses). Row cards offer Copy value and Filter by value quick actions — the filter is added as a temporary chip that only becomes permanent if you save the current preset. Keyboard: ↑/↓ to move between results, Enter to activate, Esc to close, and Cmd/Ctrl+K anywhere to focus the search input. Row-data search is server-side (case-insensitive substring across all columns), capped at 50 matches with a "refine your search" hint when more exist.

Improved

  • Stronger regression coverage on MCP and relationship-picker code paths — internal test additions guard against bugs that previously slipped through: the MCP HTTP endpoint is now exercised end-to-end with real API keys (closing the gap where every test authenticated via JWT and missed MCP-key-specific failures), and the relationship picker's widget-type inference plus the OWNED inline editor's date input rendering are now covered by Playwright tests.

Removed

  • Dead MCP JAX-RS auth filter — an unused McpApiKeyAuthFilter (which never fired because MCP endpoints are Vert.x routes, not JAX-RS) has been deleted. Auth still runs as before via McpAccessGuard.requireAuth() invoked from each tool — no behavior change.

2026-04-19

Added

  • Computed/Formula widget surfaces in the Add Column dropdown — the Formula widget type was previously hidden because it was misclassified as a relationship type. It now appears under a new "Computed" category alongside other widgets.
  • Stable per-view column data key — every ViewColumn now carries a persisted dataKey that's the single source of truth for the row-JSON key, SQL alias, filter rules, presets, and frontend state. Two columns over the same path (e.g. a "Roles" chips column and a "Role Count" column) now get distinct keys (rolesName, rolesName_2) instead of overwriting each other in row data.

Improved

  • Owned-mode inline editor pre-fills with the related row's data — opening a relationship cell in OWNED mode now fetches the linked entity's current values (e.g. the author's name/email/bio when editing a book's author inline) before the form renders, so saving sends a complete payload instead of empty NOT NULL fields.
  • Owned-mode save updates every field in the nested form — the backend used to update only one column from the OWNED payload (and could pick the wrong one, e.g. setting the PK). It now matches each form field to the terminal entity's columns and updates them all in order, skipping the PK.
  • Numeric widget consolidation — the redundant "Number" widget (functionally a duplicate of "Decimal" — both stored as NUMERIC) is removed. Existing scalar columns map cleanly: integer types → Integer, decimal/float types → Decimal.

Fixed

  • Wrong PK in cell-edit URLs — opening a popover for a row with a non-trivial primary key sometimes called the API with /0 instead of the actual PK. The backend's primaryKeyColumns response now derives PK aliases from the schema directly instead of looking them up in a column map that an M:N relationship column with displayField="id" could overwrite.
  • "Hidden FK column not found for relationship: …" 500 on relationship saves — when the relationship's internal name didn't match the FK column's camelCase alias (e.g. constraint-named relationships like users_company_id_foreign), saving the relationship cell failed with a 500. The backend now matches the rel column to its hidden FK by the underlying snake_case column name.
  • Schema-sync OWNED mode crash on relationship-property resolution — the property resolver iterated a lazy collection on canonical view columns without fetching it, causing LazyInitializationException during cell saves. Now uses the isRelationshipColumn flag, which doesn't trigger the lazy load.

2026-04-19 (earlier)

Added

  • Relationship picker — drill into nested entities — you can now expand a nested relationship (e.g. Enrolment ▸ personalPhysicalAddress) and pick a column from the leaf entity (Address.street) as the display field. Nested levels lazy-load on expand, so the picker stays fast on dense schemas and handles cyclic relationships safely.
  • Relationship picker — drill through association entities (rich junctions) — when a 1:N target is junction-shaped (a table that bridges two other entities, with or without extra columns), the picker now lets you keep walking through it to reach the other side. Example: from an Enrolment view, drill invoiceEnrolments ▸ invoice ▸ invoice_number to display invoice numbers per enrolment. Aggregate functions (Count, Chips, Sum, Avg, Min, Max, Concat) apply at any depth where a collection hop appears in the path.
  • Relationship picker — Concat aggregate — added a "Concatenated (joined string)" option to the display-mode dropdown for collection-valued relationships. Same SQL underpinnings as Chips (string_agg / GROUP_CONCAT), but rendered as a single delimited string rather than chip widgets.
  • Relationship picker — Edit Mode in Add Column dialog — restores the dropdown that was previously available, letting you pick the cell's edit behavior (Not Editable / Reference / Owned / Association) at column-creation time instead of going to the properties panel afterwards.

Improved

  • Picker — full-path collection detection — the aggregate-mode dropdown now appears whenever a 1:N or N:N hop sits anywhere in the relationship path (top-level OR nested), not just at the top level.
  • Picker — Widget Type filtered by column type — the Widget Type dropdown now only shows widgets compatible with the selected column's database type (e.g. a YEAR column won't offer Email or Image). The list also accepts an "Inherit" option so the backend infers the default — matching whatever the source view uses.
  • Picker — junction detection covers rich junctions — previously only pure junctions (PK = composite of FKs) were detected. Now also matches association entities (surrogate PK + composite UNIQUE on the FK pair, with extras), so the through-target M:1 surfaces under their 1:N back-pointer.
  • Picker — alphabetical ordering — top-level rels in Existing Relationships and the entire Other Entities list are sorted alphabetically. Within each entity expansion: PK pinned at top, scalar columns alphabetized, then nested relationships alphabetized.
  • Picker — cycle guard catches all path lineage — drilling like Administration ▸ Enrolment ▸ Category ▸ Enrolment is suppressed because the second Enrolment lands on the same row as the first. Previously only direct back-pointers to the view's source entity were filtered.
  • Picker — N:1 chip — added the missing N:1 chip alongside 1:1 / 1:N / N:N for visual consistency.
  • Picker — clearer relationship labels — auto-generated relationship names (e.g. fkC04d5114a1c904b3 from hashed FK constraints) now derive a readable label from the underlying FK column name (personal_physical_address_id → "Personal Physical Address"). Collection rels (1:N / N:N) use the relationship's own name rather than the back-pointer FK column.

Fixed

  • Inline-edit popover prefills correctly for nested relationship columns — when toggling Owned mode on a relationship column that targets a nested field (e.g. Enrolment ▸ Address ▸ address1), the form now uses the column's actual JSON key (fk…Address1) for prefill instead of the bare leaf name. Existing columns with the wrong saved value can be fixed by clearing inlineEditFields in the column properties.
  • API rejects FK-to-FK target columns — the backend now refuses to create a new relationship pointing at a column that is itself a foreign key. Previously the picker filtered these out client-side, but MCP/API callers could bypass the guard.
  • Schema sync correctly classifies composite-PK FK columns as MANY_TO_ONE — previously, every column in a composite primary key was marked individually unique, so a foreign key whose column happened to be part of a composite PK (e.g. book_authors_link.book_id in PRIMARY KEY (book_id, author_id)) got classified as ONE_TO_ONE. That suppressed the reverse 1:N back-pointer on the parent (e.g. books → bookAuthorsLinks), making rich-junction tables unreachable from the parent view's relationship picker. Re-syncing the workspace now creates the back-pointers correctly and the multi-hop drill-through works.

Improved

  • Relationship picker — clearer existing-relationship tree — multiple foreign keys to the same table (e.g. personalPhysicalAddress and companyPhysicalAddress, both → Address) are now distinguishable: each row shows the relationship name with the target entity as a chip. Foreign-key id columns are no longer offered as display values — drill into the relationship and pick a real field instead.
  • Relationship picker — Display Field dropdown removed for existing relationships — clicking a leaf column in the tree is the display field, so the redundant follow-up dropdown is gone. The dropdown still appears for new "Other Entities" relationships, where it controls the optional display column alongside the new FK.
  • Relationship picker — cleaner "Other Entities" expansions — non-junction entities now show only their PK/unique columns (the valid FK targets). Nested-relationship drill-down is reserved for actual junction entities, where it backs the M2M through-path flow.

2026-04-17

Improved

  • Relationship columns are editable by default — newly-added relationship columns now default to editable (dropdown picker that changes the foreign key) instead of read-only. The three edit modes — Reference (change FK), Owned (edit the related row inline), and Association (pick or create) — are exposed on the add-column flow. Read-only is still available as an explicit opt-in.
  • Widget type is inferred for relationship columns — when you add a relationship column without specifying a widget, SchemaStack now picks a sensible default from the underlying database column's type (same inference used by schema sync). You can still override in the Properties Panel.
  • AI/MCP add_relationship_column tool — now accepts readonly and relationshipEditMode parameters, with documentation describing each mode. widgetType is optional — omitted, it's inferred.

Fixed

  • MCP-originated relationship column delete — removing a relationship column through the MCP interface no longer throws a threading error mid-transaction; the delete completes cleanly.
  • Widget Type selector is editable for relationship columns — the properties panel no longer blocks changing a relationship column's widget (previously disabled with "Foreign key columns cannot change type," which incorrectly applied to display widget changes).
  • "Relationship data not loaded" message replaced with live loading state — the properties panel now shows a spinner while relationship metadata is loading, and only displays an error banner if the load actually fails.

Changed

  • Add Column dialog split into two tabs — the dialog now has a Normal column tab and a Relationship column tab, cleanly separating scalar columns from relationship-backed columns. The Relationship widget option was removed from the Normal tab's widget dropdown. Existing relationship columns with widgetType: RELATIONSHIP keep working as before.

2026-04-16

Added

  • Hide/unhide views — views can now be hidden from the tab bar and restored from the properties panel
  • Hide/unhide columns — columns can now be hidden from the spreadsheet and restored from the properties panel
  • MCP filter preset tools — AI assistants can now create, update, and delete filter presets via the MCP interface

Improved

  • E2E test runner--grep flag now correctly filters to specific tests; fully isolated PostgreSQL container per run
  • E2E test helpers — API helper methods now use correct backend endpoints for column listing and updates
  • View visibility SSE events — hiding/unhiding views broadcasts real-time updates to all connected users
  • Auth resource cleanup — streamlined login endpoint code

Fixed

  • View hidden state persistence — hidden views are now correctly saved and restored across sessions

2026-04-14

Added

  • Login button on website — the brand website navbar now has a "Log In" button alongside the "Get Started Free" CTA
  • Image column support in E2E seeds — books view now has sample cover images for testing

Improved

  • Dashboard layout — organization description no longer overlaps the Settings button
  • E2E test coverage — expanded from 212 to 1160+ tests across 24 spec files, covering all spread and admin app features
  • E2E test stability — added cleanup hooks to mutation specs, fixed flaky filter/sort/M2M tests, improved login timeouts
  • E2E infrastructure — isolated messaging and metadata database for tests (no longer shared with dev)

Fixed

  • SERIAL column type handlingSERIAL, SMALLSERIAL, and BIGSERIAL PostgreSQL types are now correctly parsed as integers in the data layer

2026-04-12

Improved

  • Formula column filters — formula columns that produce numeric results (e.g., price * quantity) now show the correct filter operators (greater than, less than, etc.) instead of text-only operators
  • Notification snackbars — redesigned with a neutral gray card, white inner content area tinted by type (green for success, red for error, amber for warning), with dark mode support
  • Schema drift dialog — clean centered layout when schema is in sync, replacing the old message box
  • CSV import column matching — improved column mapping dialog with better auto-detection
  • Login dialog accessibility — fixed Angular content projection warning for button icons

Fixed

  • Dark mode consistency — forced dark mode now matches browser-detected dark mode exactly across all components, chips, row colors, and Material styles
  • Filter evaluator type detection — numeric formula results are now correctly compared as numbers in client-side filter evaluation

2026-04-11

Added

  • Conditional Row Styles — color and format rows based on filter conditions. Create rules like "status = active → green background" with support for background colors, bold, italic, and strikethrough. Rules are priority-ordered (first match wins) and saved as part of filter presets, so shared presets include their visual formatting
  • Live preview in row styles dialog — conditional formatting rules now apply to the data table in real-time while editing, so you can see the effect before saving

Improved

  • Dark mode for conditional row colors — the 8 preset row background colors now properly adapt to dark mode in both "Match Browser" and forced dark theme
  • Readonly cell tinting — readonly cells on conditional-colored rows now darken the row color instead of always showing a blue tint

Fixed

  • Column width stability on infinite scroll — column widths no longer jump when loading additional rows via infinite scroll
  • Drift detection false positives for unique indexes — columns marked as unique no longer trigger spurious "index added" drift warnings
  • Drift detection false positives for timestamp defaults — auto-generated now() defaults on timestamp columns no longer reported as drift

2026-04-10

Added

  • CSV Import — import CSV files into any view with a Sequel Ace-inspired field mapping dialog. Supports auto-mapping by column name, record browsing to verify mappings, and saved mapping presets for repeated imports
  • Bulk insert endpoint — new POST /api/data/bulk/{viewUuid}/insert for inserting up to 1000 rows per request, with per-row error reporting
  • Import mapping presets — save and load CSV-to-view column mapping configurations. Supports PRIVATE and SHARED visibility, same pattern as filter presets

Improved

  • Tab bar scroll — active tab now scrolls into view on page load when there are many tabs
  • Tab chevron sizing — dropdown chevron properly contributes to tab width instead of overlapping
  • Properties panel elevation — panel now has a subtle box-shadow for better visual separation
  • Properties panel drag handle — thicker green bar on hover, only opens panel on drag (not click), drag-to-close supported
  • Relationship picker — circular references (current entity) hidden in both existing and available entity trees; empty junction table children no longer shown
  • Widget type for relationships — FK columns now show "Relationship" in the widget type dropdown instead of empty
  • Insert column dialog — title split into "Insert Column" heading with position as subtitle
  • Preset dialog spacing — reduced vertical gap between search input and filter/sort chips

Fixed

  • Hardcoded PK column assumptions eliminated — all relationship query builders now use actual PK column names from metadata instead of assuming "id". Missing metadata throws clear errors instead of silently producing wrong SQL
  • Target entity metadata cached on relationshipstargetTableName and targetPkColumn stored during sync/creation, eliminating runtime DB lookups in query builder
  • Display mode switching — changing between Count/Values/Aggregate now sends a single API call instead of two, fixing stale displayField being sent
  • Guest token access recording — fixed session lifecycle error in GuestTokenAuthFilter by chaining recordAccess into the reactive pipeline
  • Dashboard broadcast stability — set read-only flush mode to prevent StaleObjectStateException during concurrent entity deletions

2026-04-09

Added

  • OneToMany relationship columns — display child record counts or aggregated values (chips) from related tables. Supports rollup functions: Count, Sum, Average, Min, Max
  • Relationship type labels — discovery tree shows cardinality badges (1:1, 1:N, N:N) for each relationship
  • Relationship search filter — filter entities by name in the relationship picker for large schemas
  • Clear FK value — new "Clear selection" option in the relationship cell editor to set a foreign key to NULL
  • Display mode switching — toggle between Count and Values (chips) for M2M and OneToMany columns after creation
  • Rollup aggregate functions — Sum, Average, Min, Max aggregations for OneToMany columns

Improved

  • M2M column properties — simplified panel hides irrelevant schema settings and referential actions
  • M2M real-time sync — association toggles now broadcast to other users via SSE
  • UUID support in M2M editor — multi-select editor handles both numeric and UUID primary keys
  • Junction entity detection — relationship picker auto-detects junction tables and hides PK columns
  • Column position management — all column creation paths (regular, formula, relationship, M2M) now use the position manager for correct insertion ordering

Fixed

  • Schema sync cascade failure — sync now uses isolated sessions per view, preventing one view's failure from cascading to all others (25P02 fix)
  • Schema drift false positives — synthetic M2M columns excluded from drift detection
  • M2M column deletion — proper Hibernate cascade cleanup prevents OptimisticLockException
  • Stale column backfill — sync no longer tries to create ViewColumns for columns deleted in the same transaction
  • Primary key detection — relationship display columns no longer collide with PK columns in query metadata, fixing incorrect rowId resolution for all cell editors
  • Relationship options on MySQL — FK value lookup now uses vendor-aware SQL, fixing the "selected" indicator in relationship dropdowns
  • M2M toggle returns full row — association changes now return the complete updated row, ensuring computed columns refresh correctly

2026-04-08

Added

  • Many-to-many relationships — link records across entities with a new "Multiple links" option in the relationship picker. Creates a join table automatically — no manual schema setup needed
  • M2M chips display — many-to-many columns show linked records as compact colored chips in the spreadsheet grid
  • M2M association endpoints — new API endpoints for managing many-to-many associations (add/remove links, fetch options with search and pagination)
  • AI usage counter — daily AI message usage shown in the chat title bar (e.g. 2/3), resets daily per member
  • Chat history — conversation persists in the browser per workspace, survives page reloads. Use /clear to reset
  • Chat help button? icon in chat input shows available commands (/clear, /help)

Improved

  • Column position SSE — moving a column now broadcasts all affected positions to other users, fixing visual ordering glitches in real-time

  • Schema Advisor rate limits — daily AI message limits per member by plan: Free (3/day), Pro (20/day), Enterprise (unlimited). When limits are reached, users are guided to connect their own AI client via MCP for unlimited access

  • Workspace status banners — consistent purple Design mode color across admin and spread apps, with dark mode support. Status changes from admin now update the spread app banner in real-time

  • Mobile banner layout — status and connection banners now have proper padding and icon sizing on narrow screens

  • Floating panels — shared drag handle and close button styles between Activity and Chat panels, uppercase titles matching table headers

Fixed

  • Workspace status SSE — changing workspace status in admin now immediately updates the banner in the spread app (was filtered as own-event)
  • Column update persistence — relationship edit mode and other display properties now correctly saved via schema detection path

2026-04-07

Added

  • Schema Advisor — AI-powered schema assistant built into the spreadsheet interface. Inspects your schema, suggests improvements, creates tables/columns/indexes/constraints, and manages relationship columns through natural conversation. Only schema metadata is sent to the AI — your actual data stays private. Learn more
  • Column search API — fuzzy search for columns by name or display name across all views in a workspace, with trigram similarity matching for typo tolerance
  • "Start with sample data" workspace option — new template-based workspace creation that provisions a managed database pre-loaded with the Acme Store demo dataset (categories, products, customers, orders). Available from the create workspace wizard
  • Database indexes documentation — new public docs page covering index creation, listing, deletion, schema import, and best practices
  • Relationship lookup columns via MCP — add columns from related entities (including multi-hop relationships) directly through AI assistants

Improved

  • Workspace detail header — "Open Workspace" replaced with a clean "Open in SchemaStack" link; Settings button uses gradient styling aligned with card padding
  • Roadmap updates — moved database indexes, computed columns, migration impact prediction, MCP server, and Zapier integration from roadmap to "Available Now"
  • Floating panels — activity and chat panels share a consistent draggable window design with title bars
  • Properties panel — dragging the resize border now opens the panel if it was collapsed
  • Email verification — first input auto-focuses for immediate paste support

Fixed

  • MCP column creation — fixed BlockingOperationNotAllowedException when adding relationship columns via MCP (JWT identity resolution blocked on IO thread)
  • Column update SSE — UI-only column changes (readonly, edit mode, position, display name) now broadcast real-time to other users
  • Column update persistence — relationship edit mode, sortable, apiVisible, and other display properties now correctly saved via the schema detection update path
  • Relationship column positions — new relationship/lookup columns now get a valid position instead of null
  • Workspace slug reuse — deleted workspaces and organisations free up their slug for reuse

2026-04-06

Improved

  • Zapier integration — new row and updated row triggers now automatically detect common timestamp column names so triggers work regardless of your column naming convention. Supported names:
    • New Row: created_at, createdAt, created, inserted_at, insertedAt, inserted, insert_at, insertAt, date_created, dateCreated, creation_date, creationDate, created_date, createdDate, added_at, addedAt, added
    • Updated Row: updated_at, updatedAt, updated, modified_at, modifiedAt, modified, update_at, updateAt, date_modified, dateModified, date_updated, dateUpdated, modified_date, modifiedDate, updated_date, updatedDate, last_modified, lastModified, last_updated, lastUpdated, changed_at, changedAt
  • Zapier "Find Row" search — search field is now a dropdown populated from your table's columns instead of freeform text
  • Zapier deduplication — updated row trigger no longer fires on newly inserted rows, and correctly re-triggers on each update
  • Bulk export downloads — export files are now stored in S3, fixing download failures when the processor and API run on separate containers
  • Export download reliability — download links no longer disappear on transient errors; only expired exports are removed from the toolbar
  • Timestamp behavior — columns with "On update" auto-set now get an initial timestamp on insert (previously NULL via both the Data Platform and the Workspace API)

Fixed

  • Migration tracking — fixed stale migration locks between services causing "migration already in progress" errors
  • Timestamp behavior migrations — dry-run no longer corrupts auto-generation state, preventing subsequent migrations from being silently skipped
  • Add row form — columns with auto-set timestamp behavior are now hidden from the form (they're auto-generated)
  • Workspace API filters — invalid filter values (e.g., text in a UUID field) now return empty results instead of a 500 error
  • Workspace API stability — fixed crash when tables have foreign key columns that share a primary key (e.g., shared-PK inheritance patterns), and tables without a primary key (e.g., Liquibase changelog tables) no longer break the API for the entire workspace
  • Status page reliability — health checks no longer report false "down" status when services are deployed individually on different blue/green colors

2026-04-05

Added

  • Column rename — rename database columns directly from the column properties panel in Schema Settings

2026-04-04

Added

  • Outbound webhooks — configure webhook endpoints on any view and send selected rows to external services with a single click. Includes HMAC-SHA256 payload signing, automatic retries with exponential backoff, and a delivery log for tracking each request
  • "Send to webhook" bulk action — select rows in the Data Platform, choose "Send to webhook" from the bulk action menu, and pick which configured endpoint to send to
  • Zapier integration — new native Zapier app lets you automate workflows: trigger on new/updated rows, create or update rows from other apps, and search for rows by field value
  • Webhook delivery log — view the status, response code, duration, and retry count for each webhook delivery attempt directly in the view properties panel
  • Row-level security (RLS) — per-view policies that filter data based on JWT claims, so external users only see and modify their own rows (e.g., customer_id = {jwt.sub})
  • External identity provider support — workspace owners can now configure an external OIDC provider (Auth0, Clerk, Firebase) so end-users can authenticate with their own accounts and call the workspace API directly without a SchemaStack account
  • Passwordless database authentication — workspaces can now connect to databases using IAM, peer, or certificate-based auth without requiring a password
  • Processor test suite — comprehensive integration tests for column creation types, column drop/default, foreign key operations, index operations, table creation, and error handling

Improved

  • Schema sync — improved composite foreign key extraction, drift detection, and schema hashing for more reliable sync
  • Schema repair — diagnose now detects partially missing view columns (not just fully empty views) and repair backfills them
  • Repair display — repair report now shows the exact missing column names instead of just a count
  • Column properties panel — improved relationship picker and column schema options UI
  • Migration warning — clearer migration impact warnings in the column properties panel

Fixed

  • Missing view columns after failed task completion — when an internal message was lost during column creation, the view column was never created. Schema sync and repair now detect and fix these orphaned column metadata rows
  • Member limit — settings page now shows the correct member limit from your subscription tier instead of a hardcoded value
  • Query performance — fixed Hibernate in-memory pagination (HHH90003004) on organisation queries; memberships are no longer loaded entirely into memory

Removed

  • SQL Server vendor option — removed from workspace creation (PostgreSQL and MySQL only)
  • Push notifications — removed non-functional push notification settings (email preferences remain)

2026-04-03

Added

  • OAuth2 Authorization Code + PKCE — workspace API now supports OAuth2 token-based access for SPAs and mobile apps, alongside existing API keys
  • OAuth2 client management — new "OAuth2" tab in workspace settings to register and manage OAuth2 clients with redirect URIs and scopes
  • OAuth2 consent page — when a third-party app requests access, users see a consent screen showing the app name, workspace, and requested permissions before approving
  • API key expiration — API keys can now be created with an optional expiry date

Improved

  • CORS handling — workspace API now allows all origins for token-authenticated requests, following industry standard (Stripe, Supabase); CORS configuration removed from settings since Bearer tokens provide the security, not origin restrictions
  • Multiple foreign keys to same table — workspace API now correctly handles tables with multiple FKs pointing to the same target table

2026-04-02

Added

  • Composite foreign key support — full stack support for multi-column foreign keys: sync extracts them, DDL generates FOREIGN KEY (a,b) REFERENCES target(x,y), ByteBuddy generates @JoinColumns annotations
  • Composite PK relationship picker — when a target table has a composite primary key, the picker shows checkboxes with a "Select all PK columns" shortcut for multi-column FK creation
  • Composite PK bulk operations — bulk delete, update, and export now support tables with composite primary keys using (col1,col2) IN ((?,?),(?,?)) syntax

Improved

  • Input validation — all REST endpoints now validate request bodies; invalid input returns clear 400 errors instead of server errors
  • Security headers — added X-Content-Type-Options, X-Frame-Options, X-XSS-Protection, and Referrer-Policy headers on all responses
  • Password reset security — response is now identical whether the email exists or not, preventing account enumeration
  • CORS security — workspace API CORS headers are now set via a dedicated servlet filter
  • Error messages — internal error details no longer leak in API responses; 500 errors return generic messages
  • JDBC timeouts — all database connections and queries now have timeouts to prevent indefinite hangs
  • File upload protection — oversized uploads are rejected before reading into memory

Fixed

  • Bulk operations with composite PKs — scalar IDs on composite PK tables correctly use the first PK column instead of failing with a cast error
  • Column creation positioning — inserting a column at a specific position now correctly shifts existing columns using the position manager

Removed

  • Deprecated relationship endpoint — removed POST /api/views/{uuid}/relationship-columns and MCP add_related_column tool; use POST /api/columns with relationshipPath instead
  • Unused dependencies — removed Apache Camel (unused), dead code, deprecated consumer class, unused repository methods

2026-04-01

Added

  • Database view support — database views (CREATE VIEW) are now imported during schema sync as read-only views; all columns are marked non-editable
  • Generated column support — columns defined as GENERATED ALWAYS AS (...) are automatically detected and marked as read-only, preventing insert/update errors
  • Column comments as display names — if your database columns have comments (COMMENT ON COLUMN ...), they're used as the default display name instead of converting from snake_case
  • PostgreSQL ENUM support — enum types are detected with their allowed values extracted from the database
  • PostgreSQL array type support — array columns (TEXT[], INTEGER[]) are imported and displayed as text
  • Database compatibility guide — new documentation page listing all supported and unsupported database features for PostgreSQL and MySQL

Improved

  • Schema sync reliability — new per-view transaction architecture ensures one table failing doesn't break the entire sync; each table's success or failure is independent
  • FK cascade rule syncing — foreign key cascade actions (ON DELETE CASCADE, SET NULL, etc.) are now properly synced and kept up to date when changed in the database
  • Widget type detection — expanded to cover 30+ database types including JSONB, UUID, INTERVAL, MONEY, TIMESTAMPTZ, DATETIME, MEDIUMTEXT, and more
  • Column positioning — creating a column at a specific position now correctly shifts existing columns using the position manager
  • Auto-generation type syncing — changes to auto-generation (e.g., switching from SERIAL to IDENTITY) are now detected and synced
  • Native image build speed — removed unused Apache Camel dependency and excluded large SDK JARs from resource scanning
  • Native image compatibility — comprehensive reflection config for all DTOs ensures correct serialization in native builds

Fixed

  • ViewColumn generation on sync — views imported by the old sync that were missing ViewColumns now get them automatically on re-sync
  • Relationship columns on fresh import — FK columns now correctly create both a hidden FK ViewColumn and a visible relationship ViewColumn with the RELATIONSHIP widget
  • Column ordering — ViewColumn positions now follow database column order (JDBC ordinal position) instead of arbitrary ID order
  • Password reset security — response is now identical whether or not the email exists, preventing user enumeration

Removed

  • Old sync engine — removed the monolithic SchemaImportService (~2,600 lines) and SchemaSyncService wrapper, replaced by the new per-view sync architecture
  • Deprecated consumer — removed unused TaskCompletionConsumer (functionality merged into TaskCompletionBusinessLogicConsumer)
  • Dead code cleanup — removed unused repository methods, debug print statements, and unused messaging DTOs

2026-03-31

Added

  • Per-view sync architecture — schema sync now uses independent transactions per table; if one table fails, others still sync successfully
  • Relationship widget type — unified column creation with inline relationship configuration in the properties panel
  • Formula/computed columns — virtual columns evaluated at query time using SQL expressions, created via POST /api/columns with a formula field
  • Unified column creation API — relationship columns and regular columns now use the same POST /api/columns endpoint

Improved

  • Relationship picker — embedded inline in the column properties panel with source column auto-hidden when active
  • Column creation dialog — enhanced with widget type selector, reference picker, and formula editor components
  • Migration warning component — new UI component showing impact warnings before schema changes

Fixed

  • FK cascade action syncing — foreign key ON DELETE/ON UPDATE rules are now properly extracted from the database and synced to column metadata
  • ViewColumn generation — fresh imports now correctly generate ViewColumns for all columns
  • Relationship ViewColumns — fresh import creates both hidden FK and visible relationship ViewColumns with correct widget type

2026-03-28

Fixed

  • Schema sync column changes — syncing a workspace after columns are added or removed in the database now works correctly; previously this could cause internal errors due to Hibernate cascade conflicts
  • Schema drift false positives — composite unique constraints (e.g. multi-column unique indexes) no longer incorrectly report individual columns as having unique constraint changes
  • Feedback screenshot upload — fixed threading error that prevented screenshot uploads; upload now runs on a worker thread pool
  • Feedback dialog reset on error — when a screenshot upload fails, the drag area now resets instead of showing a broken preview

Improved

  • Feedback screenshot storage — screenshot metadata is now stored as a single JSON field (matching the image widget format) instead of two separate columns
  • Feedback screenshot preview — the dialog now shows a server-confirmed preview image instead of a local base64 preview, ensuring the upload actually succeeded
  • Avatar upload buttons — "Upload Avatar" and "Use This Image" buttons now use flat green style consistent with the rest of the app

2026-03-27

Fixed

  • Warning notifications — warning snackbar no longer appears transparent over the toolbar
  • Schema drift detection — composite unique indexes no longer cause false-positive drift; FK cascade actions are now synced correctly
  • Feedback screenshots — large screenshots are now compressed client-side before upload, preventing timeouts

Added

  • Foreign key cascade rules — configure ON DELETE and ON UPDATE actions (Cascade, Set Null, Restrict, Set Default) per foreign key column in the column properties panel under "Referential Actions"
  • Default preset per view — set a personal default preset that auto-loads when opening a view (pin icon in preset dialog), each user has their own independent default
  • Schema import preserves cascade rules — importing an existing database now detects and stores both ON DELETE and ON UPDATE rules from FK constraints

2026-03-26

Added

  • Schema repair tool — new Repair tab in workspace settings diagnoses and fixes metadata inconsistencies (orphaned entities, missing view columns)
  • Add Column from empty view — views with no columns now show an "Add Column" button, and the view tab menu includes an "Add Column" option
  • API Docs & Sandbox in Help menu — the spread app Help menu now links to API documentation and Swagger sandbox
  • Feedback screenshot drag & drop — the feedback form now supports dragging and dropping images in addition to clicking to upload
  • Composite primary keys — the workspace API now supports entities with composite primary keys (comma-separated in URL path)

Improved

  • Timestamp behavior changes — changing a column's auto-set timestamp behavior now shows the unified orange migration warning box instead of a separate inline banner
  • Real-time connection stability — switching between view tabs no longer shows a false "Connection was interrupted" warning
  • Migration conflict handling — when a column update conflicts with an in-progress migration, a "Force Cancel Migration" action lets you cancel and retry
  • Workspace API validation — auto-generated columns (timestamps, UUIDs) and columns with default values are no longer required in POST requests
  • Workspace API type support — added support for 25+ SQL types (SMALLINT, SERIAL, JSONB, TIMESTAMPTZ, BYTEA, etc.) across entity generation, validation, filtering, and OpenAPI docs
  • OpenAPI documentation — Swagger docs now show nullable indicators, readOnly markers, default values, and correct types for UUID/composite primary keys

Fixed

  • UUID primary key CRUD — creating, reading, updating, and deleting records in tables with UUID primary keys now works correctly
  • Auto-generated timestamp columns — columns with DEFAULT CURRENT_TIMESTAMP are no longer included in INSERT statements (lets the database default apply)
  • Null value updates — setting a nullable field to null via PUT request now works instead of being silently ignored
  • Bulk operations with UUID PKs — bulk update and delete now correctly handle UUID and composite primary keys
  • Filtering on UUID/date columns — filtering by UUID, DATE, and TIMESTAMP columns no longer causes type mismatch errors
  • Dark mode badge colors — validation rules, filter badges, and other mint/blue badges now display with subdued colors in dark mode instead of bright green
  • Dark mode consistency — fixed sidebar going dark while main content stayed light when OS dark mode is active
  • Add Row with UUID primary key — creating records in views with UUID primary keys no longer fails with "Field 'uuid' is required"
  • Schema drift on UUID PK views — creating a view with a UUID primary key no longer triggers false "Column type changed" drift detection
  • Schema sync data loss — syncing a workspace no longer deletes view columns from other workspaces (critical fix)
  • Double data load on column add — adding a column no longer triggers two redundant data queries causing a table flicker
  • Workspace Overview link — the avatar menu in the spread app now correctly links to the current workspace instead of the organization slug
  • Database settings form validation — credential fields now properly update validation state when pre-filled from saved settings
  • Test cleanup — added missing workspace_activity_log table to test cleanup, fixing cascade failures in metadata tests

Security

  • Authorization audit — added view-level permission checks to relationship endpoints, bulk action endpoints, and removed unused unscoped query methods

2026-03-25

Improved

  • View deletion UX — deleting a view now instantly removes the tab and navigates away, with a confirmation dialog instead of a browser prompt
  • View creation UX — creating a view shows a pulsing tab with spinner while the backend processes, and a loading indicator in the main content area
  • MCP key badges — changing the workspace MCP access level now immediately updates the effective access badges on all keys
  • SSL certificate validation — the "Test Connection" button now includes uploaded SSL certificates in the test, and the CA certificate field is required when using VERIFY_CA or VERIFY_FULL mode
  • SSE reconnect awareness — a subtle banner appears after a real-time connection interruption, offering a one-click refresh to sync any missed changes

Fixed

  • UUID primary key on view creation — creating a view with a UUID primary key type now correctly generates the primary key column without needing an extra flag
  • Read-only table after view creation — views created with a primary key are no longer incorrectly marked as read-only
  • Constraint SSE events — constraint changes (add, update, toggle, delete) now broadcast on the view stream and include column name and constraint type for richer activity messages
  • Richer real-time events — column created events now include widget type and database name; view member/guest events include the view name; preset events include the preset name; API key revoked events include the key name
  • Dark mode — the "Your Canvas Awaits" empty state and delete confirmation dialog warning text now display correctly in dark mode
  • Real-time event data — SSE events now use flat data access consistently, fixing "undefined" values in activity messages and key creation notifications

2026-03-24

Added

  • Database indexes — create, list, and delete single or multi-column indexes (including unique indexes) on views via the new Indexes API
  • FK cascade rules — foreign key columns now support ON DELETE actions (CASCADE, SET NULL, RESTRICT, SET DEFAULT) that are stored in metadata and applied during schema generation
  • Index import — importing an existing database schema now detects and preserves database indexes (composite and non-unique) as metadata

Improved

  • Unique index DDL generation — unique indexes are now generated as CREATE UNIQUE INDEX instead of regular indexes in the schema processor
  • Schema import accuracy — composite unique indexes are no longer incorrectly flagged as single-column unique constraints during import

2026-03-23

Added

  • Views usage card on dashboard — the organisation dashboard now shows a Views stat card with usage bar, matching the existing Workspaces, Members, and Storage cards

Improved

  • Dashboard handles unlimited plan limits — stat cards now hide the usage bar when a plan limit is unlimited (null) instead of showing "0 of 0"

Fixed

  • "undefined B" storage display — the Storage stat card on the Plan & Billing page no longer shows "undefined B" when storage is zero or not reported
  • Properties panel dark mode on "match browser" theme — the column properties panel in the spread app now correctly uses dark background when the browser is set to dark mode (previously only worked with explicit dark theme toggle)
  • Plan & Billing page crash for new orgs — fixed "can't access property 'length' of undefined" error when the workspace list is not returned by the API

2026-03-22

Added

  • Demo video scripts — automated Playwright-based screen recordings for admin and spread app demos, with narration text files and reset scripts for reproducible recordings
  • YouTube demo video embedded on website — the landing page hero section now shows the product demo video instead of a placeholder, and "Watch Demo" buttons scroll to it

Improved

  • Create workspace now includes Connection Security settings — SSL/TLS mode, connection timeout, and certificate upload options are now available when configuring a database during workspace creation, matching the existing workspace settings form
  • Workspace links fixed in production — "Open Workspace" and "Open in SchemaStack" links on the workspace overview page now correctly route to the spread app
  • Pro plan pricing reduced — Pro plan price lowered from $29/month to $19/month
  • Dark mode input borders — cell edit popover and dialog form fields now use subtle border styling instead of bright primary-color outlines in dark mode
  • Loading bar no longer shifts login form — the progress bar on the login page now overlays the page (matching the authenticated layout) instead of pushing content down
  • Bulk action bar styling — column select dropdown is now compact with proper font weight
  • Cell edit autofocus — opening the cell edit popover now automatically focuses the first input field
  • Boolean bulk edit default — boolean fields now default to "false" in bulk edit mode instead of null, preventing validation errors

Fixed

  • Validation error messages now show details — API validation errors (e.g. "Description cannot contain < or > characters") now display the specific field error instead of just "Validation failed"
  • Registration no longer briefly flashes a red error box on success before navigating to the verification page
  • DECIMAL widget icon now renders correctly (was using non-existent Material icon name)
  • Schema drift dialog expansion panels no longer show dark borders in light mode
  • Organisation description with newlines — saving a description containing line breaks no longer triggers a false "cannot contain < or >" validation error. Newlines are now automatically converted to spaces
  • Relationship columns positioned correctly on sync — when a new workspace is synced, relationship display columns (e.g., "Category") now appear in the same position as the foreign key column in the database schema, instead of being appended at the end
  • Database cascade cleanup — fixed missing ON DELETE CASCADE constraints across the schema, preventing orphaned rows after workspace or view deletion. Reset scripts are now simpler and more reliable

2026-03-20

Improved

  • Filter preset visibility simplified — the three visibility options (Private, Team, Public) have been reduced to two: Private (only you) and Shared (anyone with access to the view). The "Public" option was redundant since view access already requires workspace membership. Existing Team and Public presets are automatically migrated to Shared

2026-03-18

Added

  • Composite primary key support — tables with multi-column primary keys now support full CRUD operations (view, edit, insert, delete). Composite key values are passed as JSON objects in both the REST API and SSE events
  • Read-only mode for tables without primary keys — tables that have no primary key can now be viewed and exported, but write operations (edit, insert, delete) return a clear error explaining that a primary key is required
  • Export file retention — bulk exports now include an expiration timestamp (default 24 hours). The download link and SSE event show when the file expires so you know how long it remains available
  • Scroll-to-warning button — when a pending schema migration warning is scrolled out of view in the properties panel, a floating orange pill button appears to quickly jump back to it

Improved

  • Admin dark mode background — the admin app now uses a subtle dark blue gradient (matching Tailwind's gray-950/gray-900) across all pages in dark mode, replacing the flat background
  • Shared login dark mode styles — both spread and admin login pages now share the same dark mode card styling (emerald gradient tint, green border, green-tinted shadow, dark input backgrounds) via a shared SCSS mixin
  • SSE reconnection banner no longer flashes on page load — the "Reconnecting to real-time updates" banner is now suppressed during the initial SSE connection and only appears on actual reconnection attempts

Fixed

  • Filtering on date and timestamp columns now works correctly — previously returned a type coercion error when using date filters like shipped_at > 2025-11-01
  • Bulk operations (delete, update, export) now work correctly on tables with UUID primary keys — previously failed with a type conversion error
  • Bulk delete/update that completely fails (e.g. due to a foreign key constraint) now correctly reports as failed instead of succeeded. The error response includes per-row details explaining why each row could not be processed
  • Spread login card width now matches admin at 448px
  • "Forgot password?" link in spread login now renders at 14px as intended

2026-03-17

Added

  • Migration impact preview with SQL highlighting — when a schema change requires a database migration, the properties panel now shows the exact SQL operations that will be executed, with syntax-highlighted queries, impact level classification, and a list of affected foreign key references with read/write impact badges
  • Real-time migration progress — during long-running schema migrations, the system now reports real-time progress via SSE (view.column.schema.progress events). For PostgreSQL 12+, progress is derived from pg_stat_progress_alter_table with actual rows-processed counts. For MySQL and older PostgreSQL, time-based progress estimation is used instead. Progress includes phase info (e.g. "Rewriting table", "Building index"), percentage complete, and elapsed time
  • API protection during migrations — the REST API and MCP tools now return 503 Service Unavailable with a Retry-After header when a blocking schema migration is in progress, instead of hanging on database locks. The error response includes blocksReads, blocksWrites, and retryAfterSeconds so clients know exactly what's blocked and when to retry
  • Data-driven duration estimates — migration duration predictions are now refined over time using historical data from your workspace. After enough migrations, the system replaces static assumptions with actual measured ms/row rates specific to your database hardware
  • Row count estimation for migrations — migration impact predictions now use real approximate row counts from the workspace database (pg_stat_user_tables for PostgreSQL, information_schema.TABLES for MySQL), making duration estimates far more accurate for large tables
  • Migration duration tracking — the system now records actual migration durations and compares them to estimates. Over time, this historical data refines future predictions — your workspace's actual hardware performance replaces static assumptions
  • MySQL storage engine detection — impact analysis now detects whether a MySQL table uses InnoDB, MyISAM, or another engine, and adjusts the impact classification accordingly. Non-InnoDB tables are classified as fully blocking since they lack Online DDL

2026-03-16

Added

  • Migration impact prediction — when a schema change requires a database migration (column type change, adding NOT NULL, etc.), the system now predicts the impact: whether it will be instant, brief, or blocking, whether reads and/or writes are affected, and the estimated duration. This is vendor-aware — the same operation can have different impacts on PostgreSQL vs MySQL (InnoDB vs MyISAM). Impact data is included in the 202 API response and in the view.column.schema.changing SSE event

Improved

  • SSE event type naming has been reorganised — the event prefix now directly determines which stream carries it: view.* events go to the view stream only, workspace.* events go to the workspace stream, and organization.*/dashboard.* events go to the org stream. Data events are now prefixed view.data.* and view lifecycle events are now workspace.view.*
  • Migration prediction now correctly detects all database type changes (e.g. VARCHAR → TEXT) — previously, types in the same family were incorrectly skipped. Only true aliases (e.g. VARCHAR ↔ CHARACTER VARYING) now bypass migration
  • Faster initial load — non-core UI components (properties panel, activity feed, filter panel, bulk action bar) are now lazy-loaded, reducing the initial bundle size
  • Migration info popover is now readable in both light and dark mode — text colors are hardcoded to a dark theme for consistent contrast
  • Migration rule descriptions are now more informative — each rule shows context-aware detail text (e.g. "Not applicable for VARCHAR type" instead of generic "No change")
  • Widget type changes now correctly trigger migration detection — changing a widget from STRING to NUMBER (or any change that implies a different DB type) is properly routed through schema change detection instead of being silently applied as a metadata-only update
  • Column migration prediction is now fully accurate for all PostgreSQL and MySQL type variants — the backend correctly distinguishes between true type aliases (no migration) and different types (migration required)
  • All 16 widget types (STRING, TEXT, EMAIL, URL, PHONE, NUMBER, INTEGER, DECIMAL, BOOLEAN, DATE, DATETIME, SELECT, MULTI_SELECT, FILE, IMAGE, UUID) now have complete widget configurations — creating columns with any widget type works without errors
  • Schema processor now handles cross-vendor type mapping for all common types — MySQL-specific types (MEDIUMTEXT, TINYINT, ENUM, SET, YEAR) are correctly translated when targeting PostgreSQL, and PostgreSQL-specific types (INTERVAL, INET, BYTEA, JSONB, SERIAL) are translated when targeting MySQL

Fixed

  • Fixed currentDbType returning widget type names (URL, EMAIL, PHONE) instead of actual database types (VARCHAR) in the column properties response
  • Fixed widget-type-only changes (without advanced options) bypassing schema change detection entirely — VARCHAR→INTEGER type changes were applied without generating the required database migration
  • Fixed NUMBER widget mapping to INTEGER instead of NUMERIC — now correctly maps to NUMERIC to match the widget's default precision/scale settings
  • Fixed FILE and IMAGE widget DB type mapping — now correctly maps to TEXT (matching their widget configuration) instead of VARCHAR

2026-03-15

Added

  • Image columns now support a URL mode (imageMode: "url" in widget options) — set this when your column contains plain image URLs instead of uploaded files. Thumbnails are generated on first view and cached weekly. Failed URLs are remembered to avoid repeated fetch attempts
  • Signed thumbnail URLs for secure access without requiring authentication headers on image tags
  • Organisation description is now included in the selected organisation response, so dashboard and settings pages can display it without an extra API call

Improved

  • SSE events now include originClientId and userId across all event types — enables reliable echo prevention so your own changes don't trigger duplicate UI updates
  • Organisation settings SSE events now send only the changed fields instead of the full organisation object, and use the organisation slug as entity identifier

2026-03-14

Improved

  • Organisation member role changes and removals now broadcast real-time SSE events — other admin users see member updates instantly without refreshing
  • All SSE streams now enforce membership checks at connection time — workspace stream requires workspace membership (or org admin), organisation stream requires org membership, and task completions require authentication
  • SSE event type naming is now consistent — all column events use the metadata.view.column.* prefix for a uniform hierarchy
  • SSE event payloads now follow a uniform structure — create events include the new entity under data.entity, update events include only changed fields under data.changes, and delete events include identifiers only
  • Workspace slug can now be updated via the workspace settings endpoint
  • Workspace status change responses now include the previousStatus field
  • View permissions dialog now updates in real time — member and guest changes by other users appear instantly via SSE
  • When an admin syncs the database schema, other users viewing the spreadsheet see a warning banner prompting them to refresh for the latest columns and data
  • Other admin clients now silently update schema status metadata (view count, last checked, last synced) without showing disruptive alerts

Added

  • View-level SSE stream (/sse/view/{orgSlug}/{workspaceSlug}/{viewUuid}/stream) — only users with a view open receive view-scoped events like cell edits, column changes, and bulk operations, with permission checked at connection time
  • Real-time notification when view access flags (addable, editable, exportable) change — other users see updates instantly
  • Real-time notification when a schema sync or drift check completes — other users on the workspace page see updated sync status, drift results, and last-checked timestamps without refreshing
  • Real-time notification when organisation subscription plan or status changes (e.g. upgrade, cancellation)

Fixed

  • Row insertion now correctly checks the view's "addable" flag — previously it checked "editable" instead, allowing row inserts on views that had editing enabled but adding disabled
  • Workspace database config updates now persist correctly — previously the update response showed the right values but stale data could appear in subsequent reads
  • Login and signup pages now respect your saved dark mode preference
  • New workspaces now appear at the top of the dashboard list instead of the bottom

2026-03-13

Added

  • Real-time dashboard updates — usage stats and recent activity now push automatically via SSE when workspaces, views, or members change, so the dashboard always shows current data without refreshing
  • Dedicated database config endpoints (GET/PUT/DELETE /api/workspaces/{uuid}/database-config) — manage database connection settings independently from the workspace, consistent with storage, API, and MCP config endpoints
  • Standalone database connection test (POST /api/database-config/test) — validate database credentials before creating a workspace
  • Workspace list and detail responses now include a databaseName field for quick reference without loading full config

Fixed

  • Filter presets now apply their saved filters and sort order when loading a view — previously only column layout was applied, so reloading a page with a preset would show unfiltered data

Improved

  • Token refresh endpoint is more resilient — no longer returns intermittent 500 errors when organisation role is missing from the token

2026-03-12

Added

  • About, Careers, and Status pages on the public website
  • System health endpoint (GET /api/status) — check the status of all backend services with latency measurements
  • "Manage Account" and "Workspace Overview" links in the spread app user menu for quick navigation to the admin app
  • Recent organisation/workspace autocomplete on the spread login form, powered by localStorage history
  • API documentation now links to the MCP integration guide and mentions per-workspace Swagger UI and OpenAPI spec endpoints

Improved

  • Spread login form redesigned to match the admin login (Material card, OAuth buttons, form field icons)
  • Admin and website footers unified with the same four columns: Product, Resources, Company, Legal
  • Footer links now point to real pages instead of placeholders
  • "Contact Us" footer link now uses the correct support email address
  • API documentation landing page (/api/) no longer returns a 404

Removed

  • "Remember me" checkbox removed from both login forms (was not functional)

2026-03-11

Added

  • Billing email address — set an optional billing email on your organisation that's used for invoices and payment communications, separate from your primary organisation email
  • Country selector — organisation country is now selected from a searchable dropdown of standardized ISO countries instead of free-text input
  • Public countries endpoint (GET /api/countries) — returns all available countries with ISO codes for use in dropdowns
  • GDPR consent tracking — registration, invitation acceptance, and OAuth first login now require explicit acceptance of terms of service and privacy policy, with optional marketing consent
  • Billing history — view past invoices with order numbers, amounts, and download links on the Plan & Billing page
  • Cancel subscription confirmation — cancelling a subscription now requires explicit confirmation via a dialog

Improved

  • Checkout now pre-fills your billing address (country, postal code) and tax number when starting a subscription
  • Customer records at the payment provider now include your organisation's city and country
  • Existing free-text country values have been automatically migrated to standardized country codes
  • Billing integration — real API endpoints for subscription, checkout, cancel, invoices, and billing portal replace mock data
  • Invoice styling — order numbers, teal avatars, hover states, and consistent box-shadow across billing history
  • Eliminated M3 default tertiary green — all success/active states now use the app's proper teal/green palette in both light and dark mode
  • Organisation email is now required and cannot be left blank

2026-03-10

Added

  • Billing and subscription management — subscribe to a plan, view your current subscription, cancel or resume, and access the billing portal directly from the app
  • Provider-agnostic payment architecture — payment processing works through LemonSqueezy today with built-in support for switching to Stripe or other providers in the future
  • Webhook-based subscription sync — plan changes, cancellations, and payment events are automatically reflected in your account via secure webhook processing

Improved

  • Dark mode styling across the admin app — plan cards, alert banners, empty states, input fields, and member tables now render correctly in dark mode
  • Workspace settings button shows a label on desktop and an icon-only cogwheel on mobile
  • Pages now scroll to the top when navigating between routes
  • Brand logo in the toolbar now links to the dashboard
  • Fixed duplicate workspaces appearing briefly after creating a new workspace
  • Fixed workspace delete failing with "Method Not Allowed" when the workspace was loaded from the list endpoint
  • Data platform app is now mobile responsive — hamburger menu with sidebar navigation, compact toolbar with filter and preset controls, and the properties panel overlays content instead of squeezing it on small screens
  • Tapping outside the properties panel on mobile now closes it
  • View permissions dialog hides the source column on mobile for a cleaner layout, and shortens the "Add Member" button to "Add"
  • Real-time workspace events (create, update, delete, status change) now include echo prevention so the originating browser tab won't show redundant notifications

2026-03-08

Added

  • Sign in with Google or GitHub — use your existing account to log in or register with one click, no password needed
  • Security alert emails — you now receive email notifications when sensitive account actions occur: password changes, email changes, two-factor authentication toggles, and API/MCP key operations
  • New device login detection — when you log in from a device you haven't used before, you'll receive a security alert email with device and IP details
  • Known devices tracking — SchemaStack remembers your devices and only alerts on truly new ones
  • Send Feedback link in the admin footer — quickly share feedback without leaving the app

Improved

  • New organisations now land on the workspaces page instead of an empty dashboard, making it easier to create your first workspace
  • Error messages on login and registration pages now clear automatically when you navigate between pages
  • Organisation settings button on the dashboard is now only visible to admins and owners
  • More consistent and reliable error responses across all API endpoints — errors now always return a JSON {"error": "..."} format with correct HTTP status codes
  • MCP add_column tool now accepts widget types (STRING, EMAIL, NUMBER, DATE, etc.) instead of raw database types — matches the same experience as the UI
  • Feedback screenshots are now stored in S3 with auto-generated thumbnails instead of inline base64 in the database
  • Auto-login after email verification — you're signed in immediately after confirming your code, no extra login step needed
  • Auto-login after accepting an invitation — new and existing users are signed in and taken straight to the organisation
  • Email verification now uses a 6-digit code instead of a clickable link — enter the code directly in the app without leaving the page
  • Verification codes expire after 10 minutes with a maximum of 5 attempts for added security
  • Resend verification is rate-limited to one request per 60 seconds to prevent spam

2026-03-07

Added

  • API key rotation — regenerate the secret for a workspace API key or MCP API key while keeping its name, permissions, access mode, view scopes, and expiration intact. The old key stops working immediately
  • Organisation-level SSE stream — a single real-time connection per organisation delivers workspace lifecycle events, member changes, config updates, and API/MCP key events to the admin app
  • Real-time notifications when workspaces are created or deleted within your organisation
  • Real-time notifications when organisation members are added, updated, or removed
  • Real-time notifications for workspace configuration changes (API keys, MCP keys, MCP config, API config, storage config)
  • Rich onboarding empty state when you have no workspaces yet — includes feature highlights, benefits overview, and a quick-start button
  • Welcome screen when a workspace has no views, with a one-click "Create View" button
  • MCP (Model Context Protocol) support — AI clients like Claude Desktop can now interact with your workspaces through the standard MCP protocol
  • Per-workspace MCP access control with four levels: Disabled, Read-Only, Data-Only, and Full
  • 18 MCP tools covering workspace browsing, view/column management, data querying, record creation/editing, and constraint management
  • New MCP config endpoints to manage per-workspace access settings
  • MCP API keys — dedicated API keys for AI agents to connect via MCP without a browser session. Create, list, and revoke keys per workspace
  • Per-key MCP access control — each MCP API key can have its own access level (Read-Only, Data-Only, Full) independent of the workspace default, and can be scoped to specific views with per-view roles (Viewer, Editor, Admin)

Improved

  • Slug fields now show a live URL preview (e.g. schemastack.io/my-org/my-workspace) instead of generic hint text when creating organisations, workspaces, and views
  • Platform upgraded to Quarkus 3.30 for improved performance and compatibility with the MCP server extension

2026-03-06

Added

  • Create your own organisation after registration — no invitation required
  • Check organisation slug availability before creating an organisation
  • Check workspace slug availability within an organisation
  • Check view slug availability within a workspace
  • Schema options (nullable, unique, length, precision, scale, default value) can now be set directly when creating a new column
  • Timestamp auto-set behavior (created_at, updated_at) configurable in both the add-column dialog and column properties panel

Improved

  • New SVG logo replaces the text lettermark across the entire app for a sharper, scalable brand identity
  • SVG favicons added for both admin and app
  • Dialog widths standardized across all dialogs for a more consistent experience
  • Column type selector now shows icons alongside type names for easier scanning
  • Workspace overview shows a prominent call-to-action when no workspaces exist yet
  • All documentation and help links now point to docs.schemastack.io

2026-03-05

Improved

  • File uploads and thumbnail generation moved to dedicated JVM worker for better performance with large files and improved reliability
  • Replacing a file or image in a cell now automatically deletes the old file from storage — no orphaned files left behind

2026-03-04

Added

  • Column constraints (e.g., NOT_BLANK, MAX_LENGTH, EMAIL, PATTERN) can now be sent inline when creating a column, removing the need for separate API calls
  • Default value support in advanced column options
  • Visibility and access controls (API visible, sortable) can now be set when creating a column

Improved

  • Default values are now validated against the column type before saving — invalid combinations (e.g., now() on a boolean) are rejected with a clear error message
  • Default value input now shows type-aware placeholders, contextual hints, and quick-insert chips for common defaults (e.g., true/false for checkboxes, now() for timestamps)

2026-03-03

Added

  • Owner crown badge on member tables across organization, workspace, and view permissions
  • Inline "Pending" badge for invited members in the organization members list
  • Joined date shown on all member rows (e.g., "Joined Mar 2026")
  • Summary stat cards below member tables: Active Members, Pending Invites, and Admin Users
  • Reusable alert banner component with warning, error, info, and success variants
  • "Current Usage" overview section and "Usage by Workspace" breakdown on the Plan & Billing page
  • View column properties panel with description editing

Improved

  • Access mode dialog redesigned with colored icon avatars, capability chips, "Selected" badge, and blue info box
  • Dialog headers updated with larger icons, bolder titles, and subtle gradient in dark mode
  • Consistent green/red capability chips across the app with proper dark mode colors
  • Blue info boxes now have explicit light and dark mode styling
  • Form field backgrounds now properly adapt to dark mode
  • Gray borders unified across the app for a cleaner look
  • Plan & Billing page redesigned: active plan card is visually elevated with teal-green border and badges, Enterprise card has a dark premium look with golden crown
  • Consistent elevation styling across header cards, member tables, and plan cards
  • Standardized lighter gray for secondary/metadata text across all admin pages
  • Typography utility classes (.mat-display-large through .mat-label-small) now correctly generated in compiled CSS
  • Member avatars updated to 40px rounded squares for a modern look
  • Workspace overview tabs no longer stretch to full width

2026-03-01

Added

  • Widget options framework: per-widget-type configurable settings stored as JSONB on view columns
  • DATETIME auto-set timestamps: configure columns to auto-fill CURRENT_TIMESTAMP on insert, update, or both — applied at the database level via DEFAULT and triggers
  • S3 storage backend: configure per-workspace S3 credentials (AWS S3, MinIO, DigitalOcean Spaces, Backblaze B2) for file and image storage instead of local filesystem
  • S3 connection testing: verify bucket access before saving configuration
  • Smart file mapping: map existing S3 files to FILE/IMAGE columns using path templates with row-level expressions (${value}, ${row.column_name}, ${workspace.uuid})
  • Entity-level default file path template: set a fallback S3 template for all FILE/IMAGE columns in an entity
  • Column-level S3 path template: override the entity default for individual columns
  • Presigned URLs enabled by default: file downloads redirect directly to S3, reducing API bandwidth
  • Thumbnail presigned URLs served from platform S3 for faster image previews
  • hasStorageConfig field on workspace membership endpoint so the frontend knows when S3 is configured
  • Proxied mapped file downloads: seamless download of template-resolved S3 files through the existing file download endpoint
  • File path templates configurable at 3 levels: workspace (admin), view, and column (IMAGE/FILE columns only), with collapsible variable reference and live preview
  • Shared widget components for file upload and simple inputs, reused across cell-edit popover and add-row dialog
  • IMAGE/FILE upload support in the add-row dialog

Fixed

  • Column schema migrations (widget options, type changes, constraints) now correctly use the actual database column name instead of the display name
  • SQL identifiers in schema migrations are now properly quoted, preventing errors with column names containing spaces or special characters

Improved

  • New columns created through the UI now use sanitized database column names (e.g., "Created at" → created_at) instead of storing the display name
  • Renamed column-level s3PathTemplate to filePathTemplate for consistency across all levels (column, entity, workspace)
  • Managed files (uploaded through SchemaStack) now always resolve correctly even when a file path template is configured on the column
  • File path template changes require explicit "Apply" instead of auto-saving, preventing interference with in-progress uploads
  • Warning shown when changing path templates that existing files will not be moved
  • Storage configuration check now uses the workspace member endpoint instead of a separate API call

Security

  • S3 credentials encrypted at rest using AES-256/GCM (same encryption as database credentials)
  • S3 secrets are write-only in the API — never returned in responses
  • Path traversal protection in S3 template resolution

2026-02-28

Added

  • Real-time SSE updates for workspace events: status changes, settings updates, member changes, and database configuration now sync instantly across all open tabs and users
  • Real-time view access updates: changes to view permissions (addable, editable, exportable) are reflected immediately for all collaborators
  • Real-time view member and guest link changes are broadcast to all connected users
  • Plan limit enforcement: workspace, view, and member creation is now blocked when your subscription tier limit is reached, with clear error messages showing the current count and maximum allowed
  • Subscription tiers (Free, Pro, Enterprise) with configurable plan limits for workspaces, views, members, API calls, and storage
  • Usage tracking: monthly request counts, row reads/writes, and storage are recorded per workspace
  • Usage & Subscription API: view current plan, usage summary, and per-workspace breakdown via /api/subscription
  • Rate limiting for the workspace API: per-minute burst limits and monthly request quotas, with standard X-RateLimit-* response headers
  • Per-workspace and per-entity rate limit overrides configurable from the admin app
  • SSL/TLS support for external database connections: configure SSL mode (Disable, Prefer, Require, Verify CA, Verify Full), upload CA and client certificates for secure connections to cloud-managed databases (AWS RDS, Azure, DigitalOcean, Google Cloud SQL)
  • Connection timeout setting for external database connections
  • Categorized connection test errors (Network, Auth, SSL, Timeout) for clearer troubleshooting
  • Workspace-level API settings: configure max expand depth and CORS allowed origins per workspace
  • Per-entity API settings: manage default expand, field selection, expandable relationship whitelists, and filterable field whitelists from the admin app
  • Column API visibility: hide sensitive columns from REST API responses while keeping them visible in the admin UI
  • Public access for entities: configure unauthenticated access (None, Read Only, or Read & Write) per entity
  • Dynamic CORS: per-workspace origin restrictions replace the previous allow-all default
  • Workspace-level max expand depth acts as fallback when entity-level is not configured

Security

  • Upgraded encryption from AES/ECB to AES/GCM for database credential and 2FA secret storage (existing encrypted values are automatically decrypted via backward-compatible fallback)
  • SSL certificate temp files are now cleaned up when workspace metadata is evicted from cache instead of accumulating until shutdown

Improved

  • Workspace API URLs now use dashed slugs (e.g. /column-metadata) matching org and workspace URL conventions
  • Swagger/OpenAPI sandbox lists entities with dashed slug URLs
  • SSE connection status banners now show when real-time connection is lost or reconnecting
  • Offline detection banners in both Admin and Data Platform apps
  • Confirmation dialogs for all destructive actions (replaces browser confirm prompts)
  • SSE reconnection uses jitter to prevent thundering herd on server restarts

Fixed

  • Production environment detection now uses Angular's built-in isDevMode()
  • CI/CD pipeline build paths and linting
  • Console logging stripped from production builds

Fixed

  • SSE disconnect banner now matches the height of other status banners
  • View permissions toggles (addable, editable, exportable) no longer break after the first change
  • Workspace status changes now update the status banner in real time
  • Retry logic for newly created views no longer silently drops the final error

SchemaStack Documentation