Migration rules

The one rule that reads a package's migrations — every table created carries the connector's prefix and no core table is touched — and exactly how the sources are scanned.

migrations.own_tables_only

Runs when a package path is passed. Checks every *.php file under <package>/database/migrations with MigrationRules::violations($key, $path).

Fails with a connector creates only tables prefixed with its key and never alters a core table: 2026_10_01_000000_create_rooms_table.php: creates "rooms" without the example_ prefix, 2026_10_02_000000_add_column.php: alters "project_resources", which is not the connector's table.

Why the data rules: a connector owns only what the platform makes it keep, in tables named after it, so it can be removed from the codebase without breaking the core and uninstalled from a project without cascading into anything a member paid for.

How the sources are scanned

The rule reads the migration files as text, not the database, so it fails on the developer's machine before anything runs. Two patterns:

PatternMust name
Schema::create('<table>'A table starting with <key>_.
Schema::table('<table>', Schema::drop(…), Schema::dropIfExists(…), Schema::rename(…)A table starting with <key>_.

Both accept single or double quotes and whitespace after the parenthesis. A missing database/migrations directory is not a violation: a connector with no tables of its own passes.

What it does not catch

  • Raw statements. DB::statement('ALTER TABLE project_resources …') is not matched. Review reads for it, and Subscriby's own suite forbids raw schema changes in application migrations; hold your package to the same standard.
  • Foreign keys the wrong way. A foreignId('project_id')->constrained() inside your own table is allowed and encouraged (rule 3 of the data rules); the scanner does not check the direction, because a connector table pointing into the core is exactly the intended shape.
  • Column-level rules inside your own tables. Anything inside Schema::create('example_…') is yours to design.

Running it alone

use Subscriby\Connector\Testing\Conformance\MigrationRules;

$offences = MigrationRules::violations('example', __DIR__.'/../database/migrations');
expect($offences)->toBe([]);

The static method needs no application and no registry, so it belongs in every connector's own test suite, whether or not you can run the rest of the kit locally.

Additive after first publish

The scanner enforces ownership, not history. Once a version of your package is installed anywhere, later migrations add rather than change; a data move is expand → verify → contract, with proof that the data moved before any drop. That rule is review's, and yours.

How is this guide?

On this page

Subscriby is a product designed by you — for you.

No boardroom full of executives deciding what we ships next. Our roadmap always shaped by you with your feedback.

Share feedback or a request