Skip to content

Releases: signals-rental/framework

v0.5.0 — Opportunities, Availability, Shortage Resolution & Quote Versioning

Choose a tag to compare

@benjaminbowles benjaminbowles released this 27 Jun 15:42

Phase 3 — Core Operational Workflow. The make-or-break release: rental jobs now flow end-to-end from quote through order to dispatch and return.

Highlights

  • Event-sourced Opportunities — a two-axis state (Draft → Quotation → Order) + per-state status model on a Verbs event stream with a fast projected read model. 14 lifecycle actions, FX/tax locks, auto-numbering, soft-delete + archive/restore.
  • Local-first line-item editor — a drag-sortable nested tree of product lines, group sub-sections, and free-text notes (one unified event-sourced model, no separate sections table). Two-tier product search, per-line pricing/discount/dates/notes, accessory sub-rows, deal price, and price lock.
  • Demand-based Availability Engineavailable = stock − demands per product/store/slot, backed by PostgreSQL range types, a GiST index, and an exclusion constraint. By-Product-Group grid, Calendar, and per-product Timeline (Gantt), with live Reverb updates.
  • Shortage detection & resolution — computed on every read; a Block/Warn/Allow confirmation gate per store policy; six resolvers (Reallocate, Substitute, Transfer, Date Shift, Partial, Waitlist) with a persisted resolution lifecycle.
  • Quote Versioning — revision + alternative trees, version diff, accepted-version → order on conversion.
  • Asset allocation, dispatch & return — serialised per-asset and bulk-by-quantity, with automatic order-status promotion.
  • Job Planner, dashboard pipeline/shortage widget, and real-time wiring (Laravel Echo / Reverb).
  • APIs — Opportunities, Availability, Shortages, and Containers under /api/v1 with Sanctum abilities, Ransack filtering, includes, and auto-generated OpenAPI (Scramble).

Deferred to Phase 4 (Billing)

Serialised Containers (seal/dissolve lifecycle) and the Discount & Surcharge Engine — both ship alongside invoice generation so they have the right context.

Testing & Quality

  • 6,654 passing tests / 19,529 assertions across three lanes (SQLite parallel 6,470 · env-writing 97 · PostgreSQL 87)
  • Coverage: 96.64% lines · 95.31% methods · 91.24% classes
  • PHPStan level 6 — zero errors across ~1,700 files; Laravel Pint clean
  • Shipped after a full pre-release review (correctness / simplification / maintainability) with all high- and medium-severity findings remediated

Full feature changelog: docs/changelog/0.5.0.md.

v0.4.2 — Activities Calendar, iCal Feeds, SSO & Magic-Link Login

Choose a tag to compare

@benjaminbowles benjaminbowles released this 16 Jun 12:21

Added

Calendar

  • Full-page Calendar at /calendar that visualises scheduled activities, gated on the existing activities.access permission — no new entity, table, or permission
  • Three views — Day (staff columns against a vertical hour-axis), Week (seven day-columns against an hour-axis, coloured by owner; the default view), and Month (a seven-column grid of day-cells with event chips)
  • Pixel-precise hour-axis placement in Day and Week views; the visible hour window auto-expands to include any event outside working hours so nothing is clipped
  • All-day handling computed from the activity's times (starts at 00:00 with no end or ending at 23:59/next midnight), rendered in a band above the grid and as month chips
  • Pickable start date defaulting to today and looking forwards, with Today / Previous / Next navigation that steps by the active view
  • Owner filter restricting the calendar to selected staff users, with deterministic per-user colours shared across columns, blocks, chips, and avatars
  • Owner and participant avatars on each event (owner first, then participants), showing each user's photo where available and coloured initials otherwise
  • Unscheduled tray listing activities with no start time, each opening its detail modal so it can be scheduled
  • View, date, and filter state persisted in the URL so a calendar link reopens exactly as shared

Modals & Realtime

  • Add modal opened from an empty slot (pre-filled owner and start time) or a month day-cell (pre-filled date), reusing the existing activity form
  • Detail modal showing an activity's subject, type, status, owner, time, and location, with Complete, Edit, and Delete actions and a link to the full /activities/{id} page
  • Edit modal using the same form as create, reached from the detail modal
  • All writes flow through the existing CreateActivity / UpdateActivity / CompleteActivity / DeleteActivity actions — same validation, authorisation, audit logging, and activity.* webhooks — and the calendar refreshes instantly and locally after every change

iCal Feeds

  • Secure global iCal feed at /calendar/feed.ics (every scheduled activity) and per-user feeds at /calendar/feed/{user}.ics (a single owner's activities)
  • Feeds secured with Laravel signed URLs (no expiry); a missing or tampered signature returns 403, and the feeds serve without an authenticated session
  • Feed window covers activities from one year ago with no forward bound; activities without a start time are excluded
  • Hand-rolled RFC 5545 output (no new Composer dependency) — one VEVENT per activity with UID, DTSTAMP, DTSTART/DTEND in UTC, SUMMARY, LOCATION, DESCRIPTION, STATUS, TRANSP, and ORGANIZER, with proper text escaping and 75-octet line folding; all-day events emit ;VALUE=DATE
  • Copyable subscribe URLs surfaced in a feed modal on the calendar page (global and own feed for every user; full per-user list for administrators)

Settings

  • New Settings → Calendar page at /settings/calendar showing the current user's personal feed: a subscribe URL with a copy button, a Download .ics button, and Google/Apple/Outlook subscription help; administrators also see the global feed URL

Navigation

  • Calendar opened from the top navigation bar's calendar icon (gated on activities.access), with Activities relocated into the CRM menu; a "Go to Calendar" command-palette navigation entry is also available

Documentation

  • Platform documentation page for the Calendar (views, navigation, owner filter, modals, unscheduled tray, the settings page, and the week-start / working-hours / weekend settings that affect it)
  • API documentation page for the calendar feed endpoints, covering the signed-URL security model and its global-only revocation tradeoff

Single Sign-On (SSO)

  • SSO login via Google and Microsoft 365 (Azure common tenant) powered by Laravel Socialite — staff can sign in with their Google or Microsoft account without a Signals password
  • Auto-link by verified email: on first SSO login the provider's verified email is matched to an existing, active Signals user and the identity is linked automatically; unknown or unverified emails are denied and the user must be invited before using SSO
  • Subsequent logins match by stored provider identity (robust to later email changes in Signals)
  • Self-hosted credential configuration in Settings → Integrations → Single Sign-On: per-provider enable toggle, Client ID, and Client Secret (stored encrypted at rest; write-only — not re-displayed after save), with the correct callback URL shown for copy-paste into the Google Cloud Console or Azure portal
  • Signals Cloud mode: credential fields are hidden in the Integrations UI; only enable/disable toggles are shown (credentials are managed centrally by Signals Cloud)
  • Per-role SSO enforcement in Settings → Security → SSO Enforcement: admins can require specific roles to use SSO; password login for enforced roles is blocked with an inline guidance message and SSO buttons; the Owner role is always exempt (break-glass — cannot be selected)
  • 2FA still applies: SSO replaces only the password step; users with 2FA enabled are redirected to the existing one-time-code challenge after a successful OAuth callback
  • Allowed email domains allow-list (Settings → Integrations → Single Sign-On): when set, only users whose IdP email domain is on the list may sign in or auto-link — enforced on both the auto-link and existing-link paths — strongly recommended with Microsoft's multitenant common setting to prevent cross-tenant account takeover; an empty list permits any domain
  • Client secrets are now write-only end-to-end: they are never loaded back into the Integrations form, never rendered to the browser, and a blank secret field on save keeps the existing stored secret (enter a new value to rotate)
  • Routes: GET /auth/google/redirect, GET /auth/google/callback, GET /auth/microsoft/redirect, GET /auth/microsoft/callback; unknown providers return 404
  • oauth_identities table and OAuthIdentity model recording the (provider, provider_id, user_id, email) link

Authentication — Password Manager & Accessibility

  • One-time-code 2FA input now auto-submits when six digits are entered, removing the need to press Enter or click a button
  • /.well-known/change-password well-known URL pointing to the profile password-change page, so browsers and password managers can locate the change-password flow automatically
  • Invitation acceptance page includes a username field pre-filled with the invited email, giving password managers the anchor they need to save the credential against the right account on first use
  • Login and password forms now carry canonical autocomplete="username" / autocomplete="current-password" / autocomplete="new-password" attributes throughout the auth flow for consistent password-manager integration

Documentation

  • Platform documentation page for Single Sign-On — covers enabling Google and Microsoft (self-hosted and Signals Cloud), callback URL registration, auto-link matching, per-role enforcement, and 2FA interaction

Magic-Link Login

  • Passwordless login for existing users via a single-use link emailed to their address — an opt-in alternative to password login, enabled in Settings → Security → Magic-Link Login (off by default)
  • Links are valid for 15 minutes and can only be consumed once; requesting a new link invalidates any prior unconsumed link for that account
  • 2FA is not bypassed — users with 2FA enabled (or enforced) are redirected to the existing one-time-code challenge after the link is consumed
  • Anti-enumeration: Signals always returns the same neutral response ("if an account exists, we've emailed a link") regardless of whether the email is registered, so no information about account existence is leaked; the email is dispatched asynchronously so response timing cannot be used to infer an account's existence
  • Blocked for SSO-enforced roles at both the request step and the consume step, so a policy change after issue invalidates the outstanding link; the Owner role is always exempt
  • Tokens are stored as a SHA-256 hash only — the plaintext travels only in the email and is compared with hash_equals; request and consume endpoints are rate-limited per email and per IP
  • Platform documentation page for Magic-Link Login — covers the login flow, enabling the feature, anti-enumeration behaviour, SSO interaction, and the security model

Changed

Activities

  • Activity type is now a user-editable list of values — the seeded "Activity Type" list (Task, Call, Fax, Email, Meeting, Note, Letter), manageable in Settings → List Names — replacing the previous fixed enum. The change applies across the Activities pages, the Calendar create/edit/detail modals, and the API, where type_id now references a list_values id and responses include activity_type_name
  • Activity participants now resolve to the linked user's name and avatar (with photo where available) on the activity page, in the calendar, and in the owner/participant pickers; the activity page lists the owner first followed by participants
  • Activities API operations now publish full OpenAPI request/response schemas — the paginated list envelope, the single-resource envelope, and the create/update request bodies

Notes

  • The calendar reuses the existing Activities write path and activities.* permissions; no new permissions, webhook events, or database tables were introduced
  • Feed URLs are not individually revocable — rotating the application's APP_KEY invalidates all existing feed URLs at once

_Also in this release: the 12-module scaffolding audit & remediation, UAT ...

Read more

v0.4.1 — Product Catalogue, Stock Levels & Members

Choose a tag to compare

@benjaminbowles benjaminbowles released this 12 Jun 23:36

Patch release building on v0.4.0 (rate engine). Focuses on the product catalogue, stock-level, and members domain slices, plus an oss-maintainer + PR review pass.

Product Catalogue & Stock

  • Product show-page redesign; products/groups/stock UX polish
  • Auto stock level for bulk products; bulk serialised stock entry
  • Stock-level show page: badges, ledger, transaction modals, skeletons
  • Serialised/bulk rules, opening balances, and a "bulk product must keep ≥1 stock level" guard
  • Entity-specific custom views (per-entity ViewBuilder)

Members

  • User-type member restrictions (name / active state / location type managed from the user profile)
  • Related-member avatars; merge/anonymise webhooks + API; module-audit gap closure
  • Searchable, bounded merge picker

API

  • Expanded token ability picker (Phase-2 / rate scopes, edit scopes, grouped UI)
  • Ransack / include / custom_fields consistency fixes
  • ViewResolver now honours cf.* custom-field filters alongside saved views
  • stock_transaction.deleted registered as a subscribable webhook event
  • Scramble @apiresponse annotations on member/schema endpoints

UI, Navigation & Auth

  • Top-navigation restructure; search palette images; combobox styling; data-list link/badge/mono
  • Split auth layout with component montage
  • Component-library compliance pass (design tokens, stat-card, stock-method-badge, x-signals.field)

Quality

  • Custom-field schema cache invalidation (UAT D6); security & API test coverage
  • oss-maintainer + PR review follow-ups: simplicity refactors, docs (new product-groups platform page, bulk-entry docs), and added test coverage
  • Gates: PHPStan level 6 clean, Pint clean, full suite + env-writing group green

🤖 Generated with Claude Code

v0.4.0 — Rate Engine

Choose a tag to compare

@benjaminbowles benjaminbowles released this 27 May 13:09

Rate Engine

The fourth release of Signals Framework adds the rate engine — a composable pricing system of calculation strategies, base periods, and modifiers, with CRMS-parity presets, a reusable config-schema system, REST API, and admin UI.

Added

Rate Engine

  • Composable rate engine — a rate definition combines a calculation strategy, a base period, and optional modifiers to describe how a charge is calculated over a rental window
  • Three calculation strategies — Period-based (charge per chargeable unit), Fixed (flat charge), and Hybrid (fixed initial charge plus per-unit charge thereafter)
  • Five base periods — half-hourly, hourly, daily, weekly, and monthly, each converting elapsed time into chargeable units
  • Multiplier modifier — tiered duration multipliers that scale the unit price as a rental lengthens, with the final tier inheriting forward
  • Factor modifier — quantity ranges that scale the per-unit subtotal, with an open-ended final range
  • Rate breakdown value objects — lossless integer-minor-unit arithmetic via Brick Money, rounded once at assembly, with structured line items and applied-modifier records
  • Time options for period and hybrid strategies — clock vs business-hours day type, business hours, rental days per week, leeway minutes, and first/last day cutoffs
  • 11 rate definition presets replicating the Current RMS engine types (Daily Rate, Daily Multiplier and Factor, Hourly Rate, Hourly Multiplier and Factor, Half Hourly Rate, Weekly Rate, Monthly Rate, Monthly Multiplier and Factor, Fixed Rate, Fixed Rate and Factor, Fixed Rate and Subs Days)
  • Presets seeded on install and re-runnable from the Database Seeders admin panel
  • Rate resolver — resolves the highest-priority product rate by store, transaction type, date validity, and priority, with per-product tagged caching invalidated on write
  • RateTransactionType enum (rental, sale, service) for product rates, distinct from the int-backed stock transaction type

Config Schema System

  • Reusable App\Support\ConfigSchema subsystem for dynamic, schema-driven configuration forms — Field hierarchy (Text, Number, Decimal, Toggle, Select, Time), GroupField, RepeaterField, Schema, and Section
  • Conditional field visibility evaluated server-side, validation rule generation for visible fields, and sanitisation that strips hidden and disabled-modifier values

Persistence

  • rate_definitions table — strategy, base period, JSONB enabled modifiers and config, preset slug, and self-referential clone tracking
  • product_rates table — integer minor-unit price, transaction type, currency, optional store scope, validity dates, and priority
  • RateDefinition and ProductRate models with factories, schema definitions, and a Product.rates() relationship

Actions & DTOs

  • Seven rate actions — Create/Update/Delete/Duplicate RateDefinition and Create/Update/Delete ProductRate — each authorising via gate, wrapping writes in a transaction, firing audit events, and dispatching webhooks
  • Rate DTOs for input validation and API serialisation, including RateBreakdownData (decimal-string money, structured line items)
  • Config validation on create/update against the composed schema; disabled-modifier configs stripped on update
  • Non-blocking product rate overlap detection surfaced as a warning

API

  • Rate definition endpoints — full CRUD plus duplicate, with Ransack filtering by strategy, base period, and preset
  • Nested product rate endpoints under products/{product}/rates, with an overlapping_rate_ids warning in the response meta
  • POST products/{product}/calculate_rate — returns a rate breakdown, or a zero-priced breakdown with meta.resolved: false when no rate is configured
  • Rate engine metadata endpoints — rate_engine/strategies, /modifiers, /presets, and /schema for external form builders
  • rates:read / rates:write Sanctum abilities and the rates.* permission group

Admin & Catalogue UI

  • Rate Definitions admin panel under Admin → Pricing — list of presets and custom definitions with in-use counts, schema-driven create/edit form with preset picker and From Scratch option, and duplicate support
  • Server-driven config form — choosing a strategy constrains base periods, enabling a modifier reveals its tier/range table, and fields show/hide based on other values
  • Config-schema Blade field partials styled to Signals conventions, including bordered repeater row cards with add/remove/reorder controls
  • Product Rates tab on the product detail page with a dedicated rate assignment form, modal-confirmed removal, and an overlap warning banner
  • New Pricing group in the admin sidebar, landing grid, and group switcher

Documentation

  • Platform documentation page for Rate Definitions
  • API documentation page for rate definitions, product rates, calculation, and metadata, including the Current RMS rate engine mapping table

Changed

  • AppServiceProvider registers the rate engine registry as a singleton with the three strategies and two modifiers
  • PermissionSeeder adds the rates.* permission group, assigned to the Admin and Operations Manager roles
  • CompleteSetup and DatabaseSeeder seed the rate definition presets on install

v0.3.0 — Products, Activities & Inventory

Choose a tag to compare

@benjaminbowles benjaminbowles released this 27 May 13:09

Products, Activities & Inventory

The third release of Signals Framework adds the Products catalogue, inventory (stock levels and stock transactions), and a CRM Activities module — with product groups, accessories, full REST API coverage, and CRMS-compatible response shapes.

Added

Products Module

  • Product model with ProductType enum (Rental, Sale, Service, Loss & Damage), StockMethod enum (Bulk, Serialised), and HasSchema integration
  • Products list page with type filter chips (Rental/Sale/Service), archive filter (Active/Archived/All), per-type counts, and data table with column sorting, filtering, and bulk selection
  • Product detail page — 3-column layout with description, quick stats, product group, tax & revenue (left), product details, pricing, activity timeline placeholder (center), product image, key attributes, tags (right)
  • Product create and edit forms — 2-column layout with basic info, identification, stock, pricing, tax & revenue, options, and custom fields panel
  • Product merge — select two products, side-by-side comparison modal, migrates stock levels, accessories, attachments, and custom fields to primary; archives secondary
  • Product icon upload on show and edit pages
  • Product tabs — Overview, Stock, Accessories, Custom Fields, Activities, Files
  • Product API endpoints — full CRUD with Ransack filtering, custom view support, and CRMS-compatible response shape
  • Product policies for view, create, edit, and delete permissions
  • Product column registry for custom views with 11 columns and 6 defaults
  • Custom views for products — All Products, Rental Products, Sale Products, Active Products, Inactive Products

Product Groups

  • Product group model with hierarchical structure and product count
  • Product groups list page with data table, search, and product count column
  • Product group detail page — sidebar with group details, main area with products-in-group data table
  • Product group create and edit forms
  • Product group API endpoints — full CRUD with Ransack filtering
  • Product group policy for view, create, edit, and delete permissions
  • Delete product group action with audit trail and webhook dispatch
  • Navigation — mega menu link, command palette commands

Stock Levels

  • Stock level model with StockCategory enum (Bulk, Serialised) and HasSchema integration
  • Stock levels list page with data table and search
  • Stock level detail page — 2-column layout with details, quantities (with available calculation), dates, and transactions panel
  • Stock level tab on product pages — scoped data table showing stock for the product
  • Stock level API endpoints — full CRUD with Ransack filtering and custom view support
  • Stock level policies and column registry
  • Custom views — All Stock Levels, Serialised Stock, Bulk Stock

Stock Transactions

  • Stock transaction model with TransactionType enum — 11 types: Opening Balance, Increase, Decrease, Buy, Find, Write Off, Sell, Return, Make, Transfer Out, Transfer In
  • Signed quantity calculation via quantitySign() — negative for reductions (Decrease, WriteOff, Sell, TransferOut), positive for additions
  • quantity_move accessor on model — signed quantity for display
  • Manual transaction creation restricted to Buy, Find, Write Off, Sell, Make (system types like Opening, Transfer are API-only)
  • Inline transaction form on stock level show page — type selector, quantity, date, description
  • Automatic quantity_held update on stock level when transactions are created
  • Stock transaction API endpoints — CRMS-compatible nested routes (products/{product}/stock_levels/{stock_level}/stock_transactions) with index, show, and store
  • CRMS-compatible response shape with transaction_type, transaction_type_name, quantity, quantity_move, manual flags

Activities (CRM)

  • Activity model with polymorphic regarding relationship (Member, Product, StockLevel), owned_by user, and participants many-to-many with members
  • ActivityType enum — Task (1001), Call (1002), Fax (1003), Email (1004), Meeting (1005), Note (1006), Letter (1007) — mapped to CRMS type_id integer codes
  • ActivityStatus enum — Scheduled (2001), Completed (2002), Cancelled (2003), Held (2004)
  • ActivityPriority enum — Low (0), Normal (1), High (2)
  • TimeStatus enum — Free (0), Busy (1) for calendar blocking
  • Activities list page with type filter chips (Task/Call/Meeting/Email/Note), status filter chips (Scheduled/Completed/Cancelled/Held), per-type and per-status counts
  • Activity detail page with badges (type, status, priority), details panel, regarding link, participants list, quick actions (Complete, Edit, Delete)
  • Activity create and edit forms — 2-column layout with basic info, classification, schedule (left), assignment and entity picker (right)
  • Member activities tab — scoped data table with "New Activity" button pre-filling regarding_type=Member
  • Product activities tab — scoped data table with "New Activity" button pre-filling regarding_type=Product
  • Stock level activities tab — scoped data table with "New Activity" button pre-filling regarding_type=StockLevel
  • Complete activity action — sets status to Completed, completed=true, fires audit event
  • Activity API endpoints — full CRUD plus POST /activities/{id}/complete, Ransack filtering, custom view support
  • CRMS-compatible API responses — type_id, status_id, activity_type_name, activity_status_name, time_status_name, participants array, nested regarding and owner objects
  • Activity permissions — access, view, create, edit, delete, complete — assigned to Admin, Operations Manager, Sales, and Read Only roles
  • Activity column registry for custom views with 11 columns and 7 defaults
  • Custom views — All Activities, Scheduled Activities, Completed Activities
  • CRMS type mapping via Activity::resolveRegardingType() and Activity::shortRegardingType() — stores full class names in DB, exposes short names (Member, Product, StockLevel) in API responses

Accessories

  • Accessory model linking products to other products with quantity
  • Accessories tab on product pages
  • Accessories API endpoints — index, store, destroy nested under products

Navigation & Search

  • Activities mega menu link under CRM > Engagement with active state
  • Product Groups mega menu link under Resources with active state
  • Command palette — Activities, Product Groups, Stock Levels navigation commands; New Activity, New Product, New Product Group create commands
  • Global search — activities searchable by subject (permission-gated), results displayed in command palette with calendar icon
  • Search results for products, stock levels, and product groups in command palette

Schema & Services

  • Schema definitions registered on 14 Phase 1 models (Address, Country, Currency, ExchangeRate, Email, Phone, Link, Attachment, User, ActionLog, Webhook, CustomView, TaxRate, TaxRule)
  • Two-tier caching on SchemaRegistry — L1 in-memory + L2 Redis with tag-based invalidation
  • Schema Discovery API — GET /api/v1/schema and GET /api/v1/schema/{model} for introspecting field metadata
  • VisibilityRuleEvaluator — 11 operators (equals, not_equals, contains, in, gt, lt, etc.) with AND logic
  • AutoNumberService — atomic increment, preview, and reset for custom field auto-numbering
  • Formatter::money() and moneyDecimal() — brick/money string-based formatting without float conversion
  • EnforceSessionTimeout middleware — settings-driven idle session expiry

Security

  • SecuritySettings enforcement for login rate limiting (max_login_attempts, lockout_duration)
  • FileService hardened — S3 path changed to entity-organised structure, scan_status default changed to pending, Storage::put() failure checks added
  • Icon thumbnail size corrected from 400px to 150px

Changed

  • Member activities tab replaced placeholder with scoped data table and action buttons
  • Custom view description column added to custom_views table
  • Attachment scan_status default changed from clean to pending
  • AppServiceProvider cleanup — removed unused Relation import after morph map evaluation
  • Search controller expanded to cover products, stock levels, product groups, and activities alongside members
  • Command palette expanded from 22 to 30+ static commands with product, activity, and product group entries

Quality

  • 227 new/modified files, 17,200+ lines of code added
  • 130+ new tests across enums, models, policies, actions, API controllers, column registries, Livewire components, and search
  • PHPStan level 6 — zero errors across all new code
  • Pint formatting enforced on all changes
  • Documentation pages for Activities (platform + API)

v0.2.0 — People & Places

Choose a tag to compare

@benjaminbowles benjaminbowles released this 12 Mar 20:32

People & Places

The second release of Signals Framework adds the Members module — a universal entity system for contacts, organisations, venues, and users — along with custom fields, reference data management, and full API coverage.

Added

  • Members module — universal entity for contacts, organisations, venues, and users
  • Members list page with search, type filter chips, column sorting, column filtering, bulk selection, and bulk delete
  • Member detail page with overview, contact details tabs, custom fields, and relationships
  • Member create and edit forms with membership type, status, description, locale, currency, and tax class
  • Contact detail management — addresses, emails, phones, and links with primary flags and type classification
  • Member relationships — link contacts to organisations with relationship type labels
  • Reusable DataTable Livewire component with configurable columns, sorting, filtering, pagination, row selection with shift-click range support, bulk actions, and event-driven refresh
  • Custom field groups — create, edit, reorder, and delete groups that organise custom fields
  • Custom fields admin — create and manage 16 field types (Text, TextArea, Integer, Decimal, Boolean, Date, DateTime, Time, Select, MultiSelect, URL, Email, Phone, Colour, Currency, Percentage, RichText) with validation rules, default values, and list-backed dropdowns
  • Custom field values on member detail pages, grouped by field group
  • Lists (reference data) — create and manage named lists with hierarchical values, system/non-system flags, and active/inactive status
  • Built-in system lists seeded on install: AddressType, EmailType, PhoneType, LinkType
  • Countries admin page — browse, search, and toggle active status on pre-seeded country reference data
  • Tax classes — product and organisation tax classifications with default designation
  • Member API endpoints — full CRUD for members, addresses, emails, phones, links, and relationships
  • Custom field API endpoints — CRUD for custom field groups and custom field definitions
  • List API endpoints — CRUD for list names and list values
  • Tax class API endpoints — CRUD for product and organisation tax classes
  • Countries API endpoints — read-only index and show
  • Documentation pages for Members, Custom Fields, Lists, Tax Classes, and Countries

Changed

  • Admin sidebar expanded with Data section (Custom Field Groups, Custom Fields, Lists, Countries) and Tax section (Product Tax Classes, Organisation Tax Classes)
  • Demo data seeder updated with sample members, contact details, custom fields, lists, and tax classes