04 β Phase 1 Implementation Plan (MVP)
Back to README | Prev: Database Design | Next: Roadmap
Goal
A user can open SchemaCraft, design tables visually on a canvas, define relationships, preview and export working Laravel migration files.
Build Order β 8 Steps
Each step builds on the previous one. The project should be runnable and testable after each step.
Step 1: Project Scaffolding
What: Create the Laravel app and package skeleton.
Tasks:
- Create a Laravel 12 app (with Pest) in a temp folder, then move into
SchemaCraft/ - Install Livewire 4:
composer require livewire/livewire - Verify Tailwind CSS 4 + Vite setup (Laravel 12 ships with it)
- Add
@source "../../packages/schemacraft/resources/views";toresources/css/app.cssso Tailwind scans package views - Create the package directory structure under
packages/schemacraft/ - Create
packages/schemacraft/composer.jsonwith:- PSR-4 autoload (
SchemaCraft\\maps tosrc/) - Laravel auto-discovery for the service provider
- Dependencies:
illuminate/support,livewire/livewire
- PSR-4 autoload (
- Add path repository to root
composer.jsonand requireschemacraft/schemacraft:@dev - Run
composer updateto symlink the package
Files created/modified:
packages/schemacraft/composer.json(new)- Root
composer.json(modified β path repo + require) resources/css/app.css(modified β Tailwind source path)
Verify: composer update completes without errors. Package is symlinked in vendor/schemacraft/.
Step 2: Package Foundation
What: Service provider, config, routes, migrations, models, enums, and layout.
Service Provider β src/SchemaCraftServiceProvider.php
- Merges config from
config/schemacraft.php - Loads routes from
routes/web.php(with configurable prefix + middleware) - Loads views namespaced as
schemacraft:: - Publishes migrations to host app
- Registers Livewire components via
Livewire::addNamespace('schemacraft', ...)
Config β config/schemacraft.php
route_prefix(default:schemacraft)middleware(default:['web'])default_canvassettings (zoom, pan, grid_size, snap_to_grid)default_tablesettings (width, color)
Routes β routes/web.php
| Method | URI | Action |
|---|---|---|
| GET | /schemacraft |
ProjectManager Livewire component |
| GET | /schemacraft/project/{project} |
Canvas designer view |
| GET | /schemacraft/project/{project}/export |
ZIP download |
Migrations (5 files)
All prefixed schemacraft_ β see Database Design for full schemas.
| Migration | Table |
|---|---|
2026_01_01_000001_create_schemacraft_projects_table.php |
schemacraft_projects |
2026_01_01_000002_create_schemacraft_tables_table.php |
schemacraft_tables |
2026_01_01_000003_create_schemacraft_columns_table.php |
schemacraft_columns |
2026_01_01_000004_create_schemacraft_relationships_table.php |
schemacraft_relationships |
2026_01_01_000005_create_schemacraft_indexes_table.php |
schemacraft_indexes |
Models (5 files in src/Models/)
| Model | Key Relationships | Casts |
|---|---|---|
Project |
hasMany tables, hasMany relationships | canvas_settings β array, SoftDeletes |
Table |
belongsTo project, hasMany columns, hasMany indexes | booleans, decimals |
Column |
belongsTo table | enum_values β array, booleans |
Relationship |
belongsTo project, belongsTo sourceTable/targetTable | line_points β array |
Index |
belongsTo table | column_ids β array |
Enums (2 files in src/Enums/)
| Enum | Values | Helper Methods |
|---|---|---|
ColumnType |
All 30+ Laravel column types | requiresLength(), requiresPrecision(), requiresValues() |
RelationshipType |
hasOne, hasMany, belongsTo, belongsToMany, morphOne, morphMany, etc. | β |
Layout β resources/views/layouts/app.blade.php
- Uses
@vite()from host app - Includes
@livewireStyles/@livewireScripts - Simple nav bar with "SchemaCraft" branding
- Renders Livewire component dynamically
Files created:
packages/schemacraft/src/SchemaCraftServiceProvider.php
packages/schemacraft/config/schemacraft.php
packages/schemacraft/routes/web.php
packages/schemacraft/database/migrations/ (5 files)
packages/schemacraft/src/Models/ (5 files β Project, Table, Column, Relationship, Index)
packages/schemacraft/src/Enums/ (2 files β ColumnType, RelationshipType)
packages/schemacraft/resources/views/layouts/app.blade.php
Verify: php artisan migrate creates all 5 tables. Visit /schemacraft renders the layout.
Step 3: Project Management (CRUD)
What: List, create, rename, and delete projects.
Livewire Component β ProjectManager.php
- Lists all projects in a card grid with pagination
- Create new project (name + description) via modal
- Rename project inline
- Delete project with confirmation
- Navigate to canvas designer on click
View β project-manager.blade.php
- Card grid showing: project name, description, table count, created date
- "Create New Project" button opens Alpine.js modal
- Action buttons per card: Open Designer, Rename, Delete
Files created:
packages/schemacraft/src/Http/Livewire/ProjectManager.php
packages/schemacraft/resources/views/livewire/project-manager.blade.php
Verify: Create, rename, delete projects via the UI. Database records update correctly.
Steps 4 & 5: Canvas + Table Nodes
What: The visual canvas with pan, zoom, drag, and table node rendering. This is the most technically complex step.
Canvas Livewire Component β Canvas.php
| Method | Purpose |
|---|---|
mount($project) |
Loads project with tables, columns, relationships |
addTable() |
Creates new table with offset position |
updateTablePosition($tableId, $x, $y) |
Persists drag result (called from Alpine) |
updateCanvasSettings($settings) |
Persists zoom/pan state |
selectTable($tableId) |
Opens side panel for editing |
deselectTable() |
Closes side panel |
deleteTable($tableId) |
Removes table with cascading deletes |
Canvas View β canvas.blade.php
Structure:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Toolbar: [Add Table] [Reset View] [Zoom: 100%] β
βββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββββ€
β β Table β
β SVG Canvas (full viewport) βEditor β
β ββββββββββββββββ β Panel β
β β users β ββββββββββββββββ β(when β
β β id ββββββ posts β βselect β
β β name β β id β βed) β
β β email β β user_id (FK) β β β
β ββββββββββββββββ β title β β β
β ββββββββββββββββ β β
β β β
βββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββ
- Full-viewport
<div x-data="schemaCanvas(...)">wrapping an SVG - SVG grid background using
<pattern>(minor + major grid lines) <g :transform="viewTransform">applies pan/zoom to all content- Table nodes via
<template x-for>: white card with colored header, column rows wire:ignoreon SVG container prevents Livewire DOM-diffing during drags
Alpine.js schemaCanvas Component (inline in canvas view)
| Feature | Implementation |
|---|---|
| Pan | mousedown on background starts pan, mousemove updates panX/panY, mouseup persists |
| Zoom | wheel event adjusts zoom (0.2β3.0), zooms toward mouse via getScreenCTM() |
| Drag tables | mousedown on table captures offset, mousemove updates position (snap-to-grid optional), mouseup calls $wire.updateTablePosition() |
| Dynamic height | Computed from column count + built-in fields (id, timestamps, softDeletes) |
| Livewire sync | $wire.$on('table-added', ...) pushes updates into Alpine state |
Files created:
packages/schemacraft/src/Http/Livewire/Canvas.php
packages/schemacraft/resources/views/livewire/canvas.blade.php
Verify: Add tables, drag to reposition, refresh page β positions persist. Zoom/pan works smoothly at 60fps.
Step 6: Table Editor Panel
What: Side panel for editing table settings and columns.
Livewire Component β TableEditor.php
| Feature | Details |
|---|---|
| Table name | Edit with snake_case validation |
| Toggle switches | use_id, use_timestamps, use_soft_deletes |
| Color picker | Table header color |
| Add column | Name, type (dropdown from ColumnType enum), nullable, default, unique, index |
| Edit columns | Inline editing with wire:model.blur for performance |
| Remove columns | With confirmation |
| Reorder columns | Via sort_order |
| Delete table | With confirmation |
| Event dispatch | table-updated after every change |
View β table-editor.blade.php
ββββββββββββββββ Table Editor βββββββββββββββ
β Table: [users ] β
β Color: [β #3B82F6] β
β β
β β id() β timestamps() β softDeletes() β
β β
β ββ Columns ββββββββββββββββββββββββββ β
β name β string β βN βU βI β [Γ] β
β email β string β βN βU βI β [Γ] β
β bio β text β βN βU βI β [Γ] β
β β
β ββ Add Column βββββββββββββββββββββββ β
β Name: [____________] β
β Type: [string βΌ] β
β [β Nullable] [β Unique] [β Index] β
β [+ Add Column] β
β β
β [π Delete Table] β
ββββββββββββββββββββββββββββββββββββββββββββββ
- Right-side sliding panel (w-96, full height)
- Table settings section at top
- Scrollable column list in middle
- "Add Column" form at bottom
Files created:
packages/schemacraft/src/Http/Livewire/TableEditor.php
packages/schemacraft/resources/views/livewire/table-editor.blade.php
Verify: Click table to open editor. Add/edit/remove columns. Canvas table node updates to show changes.
Step 7: Relationships
What: Draw relationships between tables with auto FK creation and SVG lines.
User Flow
- Click "Draw Relationship" button in toolbar (enters relationship mode)
- Click source table β highlight appears
- Click target table β modal opens for type selection
- Select type (hasOne, hasMany, belongsTo, belongsToMany) + on_delete action
- System auto-creates FK column on the correct table
- SVG line appears between the two tables with cardinality indicators
RelationshipManager Component β RelationshipManager.php
| Method | Purpose |
|---|---|
createRelationship($sourceId, $targetId, $type) |
Creates relationship + auto-creates FK column |
deleteRelationship($id) |
Removes relationship and optionally the FK column |
| List/edit | Manage existing relationships |
FK Column Placement Logic:
| Relationship Type | FK Goes On | Example |
|---|---|---|
belongsTo |
Source table | posts.user_id |
hasOne / hasMany |
Target table | phones.user_id |
belongsToMany |
Pivot table | No FK on either table directly |
SVG Relationship Lines (in canvas view)
- Lines rendered as
<line>or<path>between table nodes - Coordinates computed from table positions (midpoints of nearest edges)
- SVG
<marker>definitions for cardinality:- "1" side β vertical line (
|) - "Many" side β crow's foot (three fanning lines)
- "1" side β vertical line (
Files created:
packages/schemacraft/src/Http/Livewire/RelationshipManager.php
packages/schemacraft/resources/views/livewire/relationship-manager.blade.php
Verify: Draw relationships. Lines appear on canvas. FK columns auto-created. Cardinality indicators visible.
Step 8: Code Generation + Export
What: Generate valid Laravel migrations and export as ZIP.
MigrationGenerator β src/Generators/MigrationGenerator.php
Pure PHP class with no HTTP/Livewire dependency.
| Method | Purpose |
|---|---|
generateForProject(Project $project): array |
Returns ['filename.php' => 'content'] |
Generates:
- All 30+ column types with correct parameters (length, precision, enum values)
- All modifiers: nullable, default, unique, index, unsigned, comment
- Foreign key constraints with cascadeOnDelete
id(),timestamps(),softDeletes()shortcuts- Pivot table migrations for belongsToMany relationships
- Proper
down()methods withSchema::dropIfExists()
CodePreview Component β src/Http/Livewire/CodePreview.php
- Shows generated migration code in a tabbed viewer
- File tabs on left, syntax-highlighted code on right
- Uses MigrationGenerator to produce output
SchemaExportService β src/Services/SchemaExportService.php
- Creates a ZIP file containing
database/migrations/folder - Uses PHP's
ZipArchiveextension
ExportController β src/Http/Controllers/ExportController.php
download($project)β generates ZIP, returns download response, deletes temp file
Files created:
packages/schemacraft/src/Generators/MigrationGenerator.php
packages/schemacraft/src/Services/SchemaExportService.php
packages/schemacraft/src/Http/Controllers/ExportController.php
packages/schemacraft/src/Http/Livewire/CodePreview.php
packages/schemacraft/resources/views/livewire/code-preview.blade.php
Verify: Click "Preview Code" β see generated migrations. Click "Export" β download ZIP. Unzip contains valid Laravel migration syntax.
Complete File Manifest (30 files)
packages/schemacraft/
βββ composer.json
βββ config/
β βββ schemacraft.php
βββ database/migrations/
β βββ 2026_01_01_000001_create_schemacraft_projects_table.php
β βββ 2026_01_01_000002_create_schemacraft_tables_table.php
β βββ 2026_01_01_000003_create_schemacraft_columns_table.php
β βββ 2026_01_01_000004_create_schemacraft_relationships_table.php
β βββ 2026_01_01_000005_create_schemacraft_indexes_table.php
βββ resources/views/
β βββ layouts/
β β βββ app.blade.php
β βββ livewire/
β βββ canvas.blade.php
β βββ code-preview.blade.php
β βββ project-manager.blade.php
β βββ relationship-manager.blade.php
β βββ table-editor.blade.php
βββ routes/
β βββ web.php
βββ src/
βββ SchemaCraftServiceProvider.php
βββ Enums/
β βββ ColumnType.php
β βββ RelationshipType.php
βββ Generators/
β βββ MigrationGenerator.php
βββ Http/
β βββ Controllers/
β β βββ ExportController.php
β βββ Livewire/
β βββ Canvas.php
β βββ CodePreview.php
β βββ ProjectManager.php
β βββ RelationshipManager.php
β βββ TableEditor.php
βββ Models/
β βββ Column.php
β βββ Index.php
β βββ Project.php
β βββ Relationship.php
β βββ Table.php
βββ Services/
βββ SchemaExportService.php
Verification Checklist
Run these checks after completing each step:
| After Step | Test |
|---|---|
| 1 | composer update β package symlinks without errors |
| 2 | php artisan migrate β 5 tables created. /schemacraft renders layout |
| 3 | Create, rename, delete projects via UI. Database records correct |
| 4-5 | Add tables, drag to reposition, refresh β positions persist. Zoom/pan smooth |
| 6 | Click table β editor opens. Add/edit/remove columns. Canvas updates |
| 7 | Draw relationships. Lines appear. FK columns auto-created. Cardinality visible |
| 8 | Preview code β valid migrations. Export ZIP β contains migration files |
End-to-End Test
Design a small schema: users, posts, comments, tags (with pivot). Export migrations, paste into a fresh Laravel app, run php artisan migrate β all tables created correctly with foreign keys.
Next: Roadmap