Skip to content

anewholm/user

Repository files navigation

User

The User plugin was initially produced by a human, including CI & Semgrep Actions, and then substantially advanced using AI-directed methodology.

AI guided development CI Security Scan

A WinterCMS plugin providing UUID-based user management as an abstraction layer over WinterCMS's built-in backend_users. Adds front-end user accounts, group membership with temporal history, roles, languages, and ethnicities.

Requirements

  • WinterCMS 1.2+ (Laravel 9+)
  • PostgreSQL 13+ (for gen_random_uuid(); DATERANGE and EXCLUDE USING GIST are available since PostgreSQL 9.2)
  • PHP 8.1+
  • Acorn module installed at modules/acorn/

Why PostgreSQL

Two features depend on PostgreSQL specifically:

  • DATERANGE columns with GiST indexes make point-in-time membership queries a single indexed join rather than a row-by-row subquery.
  • EXCLUDE USING GIST enforces the constraint that a user cannot be in the same group twice during overlapping periods while still permitting leave-and-rejoin (two sequential, non-overlapping rows).

MySQL is not supported.

Installation

  1. Copy this plugin to plugins/acorn/user/.
  2. Ensure the Acorn module is at modules/acorn/.
  3. Run migrations:
    php artisan winter:up
    
  4. Navigate to Settings → Acorn → User to configure login mode, password rules, etc.

What it provides

Concept Table Notes
Front-end users acorn_user_users UUID PK, SoftDelete, avatar, IP logging
Groups acorn_user_user_groups Nested tree, translatable name/description
Current membership acorn_user_user_group Fast pivot for admin UI
Temporal membership acorn_user_user_group_users Daterange history — who was in a group on a given date
Roles acorn_user_roles Many-to-many with primary flag
Languages acorn_user_languages User language preferences

Two membership concepts

Current membership (acorn_user_user_group) is the simple pivot used by the admin UI and fast $group->users lookups.

Temporal membership (acorn_user_user_group_users) answers the historical question "who was in group G on date D?" using a PostgreSQL DATERANGE column:

// Who is in this group right now?
$group->currentMembers();

// Who was in this group on a specific date?
$group->membersOn('2025-01-15');

period = daterange(join_date, NULL) means currently active. Leave-and-rejoin creates two sequential non-overlapping rows — both are valid.

Calendar integration pattern

The temporal membership table enables an efficient single-query calendar month view. Instead of per-event PHP loops, join once in SQL:

SELECT ep.*
FROM acorn_calendar_event_parts ep
JOIN acorn_calendar_events e     ON e.id = ep.event_id
JOIN acorn_calendar_calendars c  ON c.id = e.calendar_id
JOIN acorn_user_user_group_users m
  ON m.user_group_id = c.owner_user_group_id
 AND m.user_id       = :current_user
 AND m.period        @> ep.start::date
WHERE ep.start >= '2026-01-01'
  AND ep.start <  '2026-02-01'

The GiST index on (user_group_id, period) makes this query fast even on large datasets.

UUID primary keys

All tables use UUID primary keys generated by gen_random_uuid(). This supports distributed record creation across plugins and installations without central counters, and avoids predictable sequential IDs in URLs.

Dependency policy

The Acorn module is a hard requirement — models, controllers, and migrations all extend Acorn base classes. Install it at modules/acorn/ before running migrations.

This plugin declares no $require plugin dependencies (the $require array in WinterCMS is for plugin-to-plugin dependencies; module load order is guaranteed by WinterCMS separately). Every other plugin can optionally depend on this one via created_by_user_id columns — declaring a hard $require here would create circular dependencies. Install this plugin before any plugin that references its tables.

Known limitations

  • The acorn_user_user_group_users period is currently set via raw SQL; there is no dedicated form widget for PostgreSQL daterange editing in the WinterCMS backend.
  • MySQL is not supported by design.

License

MIT

About

Fork of the WinterCMS User plugin

Topics

Resources

Stars

Watchers

Forks

Releases

Used by

Contributors

Languages