Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Core Laravel Package

badaso/core

Badaso is an open-source headless CMS and admin dashboard for Laravel built with Vue.js. This core package provides CRUD generators, media management, API-first content delivery, roles and permissions, and customizable modules for rapid backend and app development.

View on GitHub
Deep Wiki
Context7

Getting Started

Badaso is a Laravel package that bolts an admin panel, a JWT-authenticated REST API, a CRUD/schema generator, a media manager, a menu builder, and a role/permission system onto a fresh Laravel app. Mentally model it as "Nova's admin + a low-code entity builder + an API layer you can extend," not as a library you call into from your own code.

Minimal path:

  1. Start from a fresh Laravel app that matches the package's supported version (check composer.json of the release you pin — 2025 releases track current Laravel majors).
  2. composer require badaso/core
  3. Run the installer: php artisan badaso:setup. This publishes config/badaso.php, runs the package migrations, seeds roles/permissions/menus/configurations, and creates the first admin user. If the command isn't present in your version, the manual equivalent is: publish config + migrations, php artisan migrate, then seed the Badaso seeders.
  4. php artisan storage:link, and set the JWT secret in .env (Badaso uses tymon/jwt-auth, not Sanctum).
  5. Log into the dashboard at /badaso (prefix lives in config/badaso.php) with the seeded admin, and change the credentials and JWT secret before anything else.
  6. Check the registration mode setting (2.9.13+) in config/badaso.php — it controls whether the public registration endpoint is open, closed, or restricted. Decide this before exposing the API.
  7. First real use case: Dashboard → CRUD Generator → define a table and its fields → Badaso writes a migration + model and exposes REST endpoints under /api/v1/.... Hit one with the JWT from the login endpoint to confirm the loop end to end.

Where to look first, in order:

  • config/badaso.php — dashboard prefix, API prefix, guards/providers, media disk, module registration, and (from 2.9.13) the registration mode.
  • The seeded badaso_* tables (badaso_users, badaso_roles, badaso_permissions, badaso_configurations, badaso_menus, badaso_media, badaso_activity_logs) — this is the actual data model of the platform.
  • vendor/uasoft-indonesia/badaso/core/src — Routes/, Helpers/ApiResponse.php, and the module directory structure. Read the routes file once; it tells you what you'd otherwise guess.
  • php artisan route:list --path=api/v1 to see exactly what surface you got — including the auth/registration endpoints, which change behavior with the registration mode setting.

Implementation Patterns

Use it as the control plane, not the app. Keep your business logic in App\ controllers/models and let Badaso own auth, RBAC, media, settings, and admin UI. The moment you write domain logic inside the dashboard's CRUD entities, you've coupled your product to a UI generator.

Generated CRUD is scaffolding, not the contract. Generate the entity, then treat the produced migration/model as a starting point you own. Add indexes, casts, relationships, and validation in code — the generator gives you columns and endpoints, not domain rules.

Reuse the response envelope. Badaso controllers return a wrapped payload via its ApiResponse helper (success/failed). If you add your own endpoints and return raw response()->json(), any client or dashboard page built against the Badaso shape breaks. Match the envelope in every custom controller.

One module per bounded context. Badaso's module system is a mini-package: routes, migrations, controllers, config, registered in config/badaso.php. Put each business domain in its own module, never edit vendor/. That's also the only sane way to ship dashboard pages — a module with its own routes and menu entry, registered through the menu manager.

Auth flow. Login → JWT access token → store it client-side → refresh on a schedule shorter than the TTL. Badaso authenticates against badaso_users with its own guard/provider, so treat it as a separate identity store from Laravel's default users table unless you deliberately unify them.

Registration is a policy decision, not a default. Since 2.9.13 the registration mode is configurable. Set it explicitly per environment: closed for internal admin panels, open only where you actually want self-service signup, and restricted where new accounts need approval or role assignment. Anyone who lands in badaso_users inherits whatever your default role grants, so pair the mode with a deliberately minimal default role. If you need invite-only or domain-restricted signup, override the registration handler in your own module rather than forking the vendor route.

Permissions as the single source of truth. Seed permissions per entity/action, attach to roles in the dashboard, and guard both your API routes and your own controllers with the same permission names. This keeps the admin UI and the API in agreement about who can do what.

Settings table as feature flags. Read configurable values from badaso_configurations instead of hardcoding, so ops can change limits, keys, and toggles from the UI without a deploy. Wrap reads in a small cached accessor — the table is not meant to be hit on every request.

Media through the manager. Upload via Badaso's media endpoints and store the returned path/id, not a raw file. You get dashboard-browsable assets, thumbnails, and a consistent disk config for free; hand-rolled uploads end up invisible to the admin UI.

Deploy script reality. Every environment needs the publish + migrate + storage:link steps, plus a cache clear. Add php artisan migrate --force and the publish step to your pipeline, and re-check published files after each version bump.

Gotchas and Tips

  • Never edit vendor/. Published config, migrations, and custom modules are the extension points. Vendor edits vanish on composer update and are the most common way people get stuck on an old version.
  • New config keys don't appear in your already-published config. The registration mode added in 2.9.13 lands in the vendor copy of config/badaso.php; an app that published its config on 2.9.12 won't have the key, and the package falls back to the vendor default. Diff your published config against the new vendor copy and merge the new key explicitly — otherwise you're on an implicit default you never chose.
  • Config cache freezes config/badaso.php. Changing BADASO_* env values, the dashboard prefix, or the registration mode does nothing until php artisan config:clear. Symptom: "I changed the setting and it's still behaving the old way."
  • Open registration on a public host is an attack surface. If registration defaults to enabled and the dashboard host is internet-facing, bots will create accounts and consume your default role's permissions. Verify the mode right after install and right after every upgrade, and check badaso_users for unexpected rows.
  • Route collisions on /api/v1. Badaso owns a large slice of that namespace. Run route:list before adding routes, and put your own endpoints under a distinct segment rather than fighting for the same prefix.
  • Two auth systems is a trap. Adding Sanctum or Passport alongside Badaso's JWT means two guards, two middleware stacks, and two failure modes in one app. Pick one per surface (dashboard/API vs. mobile) and document it.
  • Auth::user() may not be what you expect. On the default web guard it's a plain Laravel user; Badaso users live behind its own provider. Permission checks written against the wrong guard silently return false — a classic "403 that looks like a bug."
  • Broken images = storage symlink or APP_URL. Media paths are stored relative to the configured disk; a mismatched APP_URL, a missing storage:link, or a different FILESYSTEM_DISK per environment produces 404s that look like upload failures.
  • Upload limits are php.ini, not the package. Large files fail before Laravel validation runs. Check upload_max_filesize/post_max_size alongside the package's own validation rules.
  • Generated tables have no indexes. The CRUD generator produces correct columns and nothing else. Add indexes on anything you filter or join on before it hits production traffic.
  • Renaming entities leaves orphans. Change a generated entity's slug and the old table and permissions linger. Clean up migrations and badaso_permissions rows manually.
  • The dashboard hides errors. Failures surface as generic toasts. Debug in the browser Network tab plus storage/logs/laravel.log, and check badaso_activity_logs to see what the admin actually did.
  • Pin and diff on upgrade. Patch releases like 2.9.13 still add config surface. Lock the version, upgrade deliberately, and diff your published config/migrations against the new vendor copies — that diff is your migration checklist.
  • Keep the dashboard bundle out of your public app. It ships a lot of JS/CSS. Serve /badaso on a separate host or behind auth/IP rules so it never loads in customer sessions.
  • Useful extension points, in order of leverage: config/badaso.php (prefix, guards, modules, media disk, registration mode) → module service providers and route files → the ApiResponse helper for payload consistency → the menu manager for dashboard navigation → custom middleware registered in a module's config.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin