Skip to content

Fix external_id auto-generation: keep acronyms together (e.g. dns_cloudflare not d_n_s_cloudflare)#95

Merged
scottgrayson merged 5 commits into4.xfrom
course-ext-id-fix
Feb 19, 2026
Merged

Fix external_id auto-generation: keep acronyms together (e.g. dns_cloudflare not d_n_s_cloudflare)#95
scottgrayson merged 5 commits into4.xfrom
course-ext-id-fix

Conversation

@scottgrayson
Copy link
Copy Markdown
Contributor

@scottgrayson scottgrayson commented Feb 18, 2026

Summary

Auto-generated course external_id (from the name field on create/edit) was using Str::snake(), which inserts underscores before every uppercase letter. That turned names like "DNS Cloudflare Training" into d_n_s_cloudflare_training instead of dns_cloudflare_training, breaking external integrations (e.g. HubSpot property keys).

Changes

  • CourseResource: When the name field updates, set external_id with Str::slug($state, '_') instead of Str::snake($state), so acronyms stay as one token (e.g. dns_cloudflare_training).
  • CourseFactory: Use Str::slug($name, '_') for external_id in tests for consistency.

Testing

  • Create a new course with name "DNS Cloudflare Training" → External ID should show dns_cloudflare_training.
  • Existing courses with d_n_s_... in DB are unchanged; they can be edited and re-derived from the name or updated manually if needed.

Made with Cursor


Note

Medium Risk
Includes a data backfill that inserts/updates lms_course_user rows via a migration and could affect completion reporting if run on large datasets or with unexpected course/test configurations.

Overview
Fixes course external_id auto-generation to keep acronyms intact by switching from Str::snake() to underscore-based Str::slug() in both CourseResource and CourseFactory.

Adds a new backfill migration plus filament-lms:backfill-course-completed-at command to populate lms_course_user.completed_at from the latest per-step completion timestamp (respecting required_test_percentage), and registers both in the service provider.

Updates course progress reporting/export to dynamically show either a single Name column or First Name/Last Name based on config, and adjusts Course::steps() to explicitly select('lms_steps.*') to avoid column ambiguity in joins.

Written by Cursor Bugbot for commit c970c9c. This will update automatically on new commits. Configure here.

scott grayson and others added 3 commits February 18, 2026 10:59
… stay together

Str::snake() was splitting acronyms (e.g. DNS Cloudflare Training -> d_n_s_cloudflare_training).
Use Str::slug($state, '_') so we get dns_cloudflare_training for external integrations like HubSpot.

- CourseResource: afterStateUpdated on name now sets external_id via Str::slug(..., '_')
- CourseFactory: use Str::slug($name, '_') for external_id in tests

Co-authored-by: Cursor <cursoragent@cursor.com>
- reportUsesSingleNameColumn() helper in CourseProgressQueryService
- Reporting page: one 'Name' column when report_user_name_columns is ['name'], else First/Last
- CourseProgressExport: dynamic headings and map to match

Co-authored-by: Cursor <cursoragent@cursor.com>
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Comment thread src/Services/CourseProgressQueryService.php
scott grayson and others added 2 commits February 18, 2026 14:41
… to avoid duplicated logic

Co-authored-by: Cursor <cursoragent@cursor.com>
- BackfillCourseCompletedAt command: finds users who completed all steps from
  lms_step_user, inserts/updates lms_course_user with completed_at = max step date
- Migration stub runs filament-lms:backfill-course-completed-at on deploy
- Register command and migration in FilamentLmsServiceProvider
- Course model: steps() select/order fix for ambiguous id

Co-authored-by: Cursor <cursoragent@cursor.com>
@scottgrayson scottgrayson merged commit 7d92b21 into 4.x Feb 19, 2026
8 checks passed
@scottgrayson scottgrayson deleted the course-ext-id-fix branch February 19, 2026 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant