- How do I install assada/laravel-achievements in a Laravel app?
- Run composer require assada/laravel-achievements, publish the package config and migrations with vendor:publish, then run php artisan migrate. Add the Achiever trait to your User model, or to any model that should earn achievements, to expose the achievements API. Check the README on your pinned tag for the exact provider and publish tags, since this is a fork and the docs may not match your Laravel release.
- Which Laravel and PHP versions does this package support?
- The package targets Laravel 6 and newer, but the tested Laravel and PHP matrix is not reliably documented because of the fork lineage. Confirm it installs cleanly on your current Laravel major before committing, and avoid using --ignore-platform-reqs as a workaround. Expect to need a composer constraint bump or a small signature patch for each new Laravel major.
- How do I define a new achievement?
- Insert an achievement row through a seeder, an admin panel, or plain Eloquent, and optionally add one achievement detail row per locale for name, description, and image. Achievement references in your code are typically by ID or slug, so a typo silently becomes a no-op rather than an error. Consider wrapping lookups in your own helper or enum so misconfiguration fails loudly instead of passing unnoticed.
- How does progress tracking work in laravel-achievements?
- Progress is stored as a single integer per achiever and achievement, updated through addProgress(), setProgress(), and resetProgress() on the Achiever trait. That maps cleanly to counter-style goals such as posting 10 comments or inviting 3 teammates. Set-based, time-windowed, or compound conditions are not modeled, so you would need to derive and store those yourself.
- Can I use this package for team or organization achievements instead of users?
- Yes. The achiever relation is polymorphic, so the same tables can serve users, teams, or organizations without a schema change. You only need to add the Achiever trait to each model that should earn achievements. This is useful if multi-tenant or team-level rewards are on your roadmap.
- How do I know when a user unlocks an achievement?
- Unlocking happens through the trait's unlockAchievement() method, which marks the stored progress as achieved. The package advertises unlock events, but there is no assumed first-class queue or notification integration, so verify the exact event class and payload on your pinned tag. Wire email, push, or ledger side effects yourself, and make any listener idempotent in case of retries or duplicate dispatch.
- Is addProgress() safe under concurrent requests?
- Not guaranteed. A read-modify-write on the same achiever and achievement row is a classic lost-update race, so confirm the implementation uses an atomic increment or a lockForUpdate transaction. If it does not, wrap call sites yourself or avoid concurrent updates per user. This is the most likely production incident with the package.
- Can I customize the Achievement and AchievementProgress models?
- The models are plain Eloquent classes, so you can extend them or swap them out through configuration if your tag supports it. Because data lives in ordinary tables with no opaque serialization, you can read and export it, and reimplement the feature on the same schema later with near-zero migration cost. That portability is the main reason to adopt it.
- Is assada/laravel-achievements still maintained?
- The repository is flagged abandoned, effectively single-maintainer, and around 78 stars, with a 2025 release that looks like a compatibility bump rather than active development. The code surface is small enough to fork if you need to. Budget roughly one fork-and-patch cycle per Laravel major, or accept being pinned out of upgrades.
- What is missing from this package, and do I still need my own achievements engine?
- Yes, for anything beyond simple counters. Rule authoring, evaluation, idempotent award dispatch, retroactive backfill, notification fan-out, anti-cheat and rate limits, and moderation tooling all stay with you. Treat the package as a thin, replaceable persistence layer behind an internal abstraction rather than a strategy dependency, and plan for account deletion since polymorphic relations do not cascade by default.