Skip to content

feat: configurable table names#122

Open
cjmellor wants to merge 17 commits into
mainfrom
feat/configurable-table-names
Open

feat: configurable table names#122
cjmellor wants to merge 17 commits into
mainfrom
feat/configurable-table-names

Conversation

@cjmellor
Copy link
Copy Markdown
Owner

@cjmellor cjmellor commented May 13, 2026

Summary

Resolves #121.

  • Adds a LEVEL_UP_TABLE_PREFIX env var (and matching table_prefix config key) that prepends a single prefix to every default package table name.
  • Adds a tables config array for per-table renames. Any value left equal to the default receives the table_prefix; any value you change is taken verbatim and escapes the prefix.
  • Preserves backwards compatibility: the existing top-level 'table' config key keeps working as a fallback for tables.experiences.

A new "Customizing Table Names" section in the README walks through the three usage patterns (prefix only, per-table override, combining both).

cjmellor added 16 commits May 12, 2026 22:54
All 13 create-table stubs now use config('level-up.tables.<key>') for
Schema::create/dropIfExists, and every constrained() call that points at
a package table passes an explicit table: named argument.
Also disable phpdoc_type_annotations_only rule in Pint as it was removing documentation comments that aren't type annotations.
The previous commit added an explanatory comment requested in code review,
then disabled Pint's phpdoc_type_annotations_only rule (which strips it).
The project-wide config change wasn't worth keeping for one comment.
Reverts both changes; the timing rationale lives in the spec/plan docs.
belongsToMany and morphedByMany relationships were referencing pivot
tables (achievement_user, challenge_user, multiplier_scopes) by their
default names. They now read from config('level-up.tables.<key>') so
the table_prefix and per-table overrides actually apply.

Affects: HasAchievements, HasChallenges, Achievement, Challenge,
Multiplier. Adds regression coverage in TablePrefixIntegrationTest.
…vements

Folds the duplicated belongsToMany(...)->withPivot('progress') chain
shared by allAchievements(), achievements(), achievementsWithProgress(),
and secretAchievements() into a single private helper.
@cjmellor cjmellor self-assigned this May 13, 2026
@cjmellor cjmellor added the enhancement New feature or request label May 13, 2026
Seven query fragments in HasChallenges and ChallengeService still
hardcoded the default table names ('challenge_user.completed_at',
'achievements.id', DB::table('challenge_user')) and bypassed the
table-name resolver. Under a prefix or override, this silently
broke activeChallenges/completedChallenges, the achievement_ids
preload, and challenge completion (the raw DB::table UPDATE matched
zero rows, so ChallengeCompleted never fired and rewards were
never dispatched).

Resolve each fragment through config('level-up.tables.*').

Surfaced by a sandbox integration test that exercised every README
operation against five table-naming configurations across SQLite
and MySQL.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant