- Project: DrawingFlow
- Type: Laravel 12 monolith with Inertia.js + Vue 3
- Backend: PHP
^8.2, Laravel^12.0 - Frontend: Vite 7, Vue 3, Inertia Vue 2, Tailwind CSS 4
- Infrastructure in repo: Docker Compose services for
app,nginx,mysql,redis,meilisearch,mailhog - Runtime model: Docker app (container-first local development)
- Primary source roots:
app/,routes/,resources/js/,database/,tests/
This repository is not empty and contains active application code.
Checked these user-requested locations:
.cursor/rules/*.md→ not found.cursorrules→ not found.github/copilot-instructions.md→ not foundclaude.md→ not foundagents.md(lowercase) → not foundAGENTS.md(this file) → found
No additional rule files were discovered in those locations.
composer setup
composer dev
composer test
composer lint
composer lint:fix
composer analysecomposer setupcomposer install- create
.envfrom.env.exampleif missing php artisan key:generatephp artisan migrate --forcenpm installnpm run build
composer dev- runs concurrently:
php artisan serve,php artisan queue:listen --tries=1 --timeout=0,php artisan pail --timeout=0,npm run dev
- runs concurrently:
composer testphp artisan config:clear --ansiphp artisan test
composer lintvendor/bin/pint --testvendor/bin/phpstan analyse --no-progress --memory-limit=1G
composer lint:fixvendor/bin/pint
composer analysevendor/bin/phpstan analyse --no-progress --memory-limit=1G
npm run dev
npm run build
npm run lint
npm run lint:check
npm run format
npm run format:check- ESLint target:
resources/js - Prettier target:
resources/js/**/*.{js,vue}
docker compose up -d
docker compose down
docker compose exec app composer install
docker compose exec app php artisan migrate
docker compose exec app php artisan testPublished endpoints/ports from compose:
- App (nginx):
http://localhost(port 80) - Mailhog UI:
http://localhost:8025 - MySQL:
localhost:3306 - Redis:
localhost:6379 - Meilisearch:
localhost:7700
start-and-test.sh- restarts containers, waits for MySQL, runs migrations, then runs
php artisan test --testsuite=Unit
- restarts containers, waits for MySQL, runs migrations, then runs
dev-utility.sh- interactive menu wrapper for common Docker/Sail, artisan, composer, npm, lint, test, and import commands
php artisan data:import-legacy-csv- Implemented by
app/Console/Commands/ImportLegacyCsvData.php - Reads these CSV files from project root:
Shop Drawing Request.csvDrawing Submittal Log.csvFabrication Drawing Log.csv
app/Http/Controllers/→ HTTP controllers (auth, dashboard, customers, projects, submittals, fab queue, admin)app/Http/Requests/→ FormRequest validation classesapp/Models/→ Eloquent models for domain entitiesapp/Services/→ business logic services (DrawingRequestService,SubmittalService,FabHandoffService, etc.)app/Console/Commands/→ custom artisan command(s), currently legacy CSV importroutes/web.php→ all web routes (guest/auth/admin)app/Providers/AppServiceProvider.php→ explicit route model bindings and admin gate
resources/js/app.jsbootstraps Inertia app with Pinia + Ziggyresources/js/Layouts/contains layout shellsresources/js/Pages/domain pages (Dashboard,DrawingRequests,Submittals,FabQueue,Projects,Customers,Admin,Profile,Auth)resources/js/Components/shared UI; includes largePdfMarkupWorkspace.vue
database/migrations/includes Laravel defaults plus workflow tables- PDF review tables and follow-up enum migrations are present:
create_pdf_markups_tableexpand_pdf_markup_typesexpand_pdf_markup_types_for_pathscreate_pdf_page_scales_table
database/seeders/DatabaseSeeder.phpseeds two users, customers, projects, and customer workflows
tests/Feature/includes domain and UI workflow coveragetests/Feature/Admin/has backup and user management teststests/Feature/SubmittalPdfMarkupTest.phpcovers PDF file access, markup CRUD/import/export, and page scalestests/Unit/exists (minimal baseline test present)phpunit.xmluses in-memory SQLite (DB_CONNECTION=sqlite,DB_DATABASE=:memory:)
- Controllers are generally thin and delegate business operations to service classes.
- Multi-step writes are wrapped in
DB::transaction()in services/commands. - Validation uses FormRequest classes and route-level validation behavior.
- Models commonly define:
- typed relationship methods
- query scopes (for status/priority/etc.)
- helper methods/accessors (e.g., status labels)
- Several models use
protected function casts(): arrayrather than$castsproperty.
- Vue SFCs use
<script setup>+ Composition API. - Inertia page resolution uses
resolvePageComponentwithimport.meta.glob('./Pages/**/*.vue'). - Shared Inertia props in
HandleInertiaRequestsinclude:auth.userwith flattened fieldsauth.user.notification_unread_countziggyflash.success/flash.error
- Named routes are used throughout.
- Admin routes use
admin.prefix andcan:admin-accessmiddleware. - Explicit route model bindings exist for
submittalandfab_queue; preserve these parameter names. - Numbering formats in domain logic/docs:
- Drawing requests:
DR-YYYY-#### - Submittals:
SUB-YYYY-#### - Fab queue:
FAB-YYYY-####
- Drawing requests:
PdfMarkupWorkspace.vuesupports tools:circle,rectangle,cloud,pen,polyline,polygon,arrow,dimension,text,highlight,stamp.- Backend routes include markup CRUD, import/export, and page-scale CRUD under
submittals/{submittal}/files/{submittalFile}/.... - Tests validate markup type restrictions and shape-specific payload requirements.
From config files:
.editorconfig- default: 4 spaces, LF, UTF-8, trim trailing whitespace, final newline
- JS/Vue: 2 spaces
- YAML: 2 spaces
.prettierrc- 2 spaces, single quotes, semicolons, trailing commas (
es5), print width 100
- 2 spaces, single quotes, semicolons, trailing commas (
eslint.config.js- flat config
- ignores:
public/build/**,vendor/**,resources/js/ziggy.js - Vue recommended flat config with multiple Vue formatting rules disabled
Preferred in this repo (Docker app runtime):
docker compose exec app php artisan test
docker compose exec app php artisan test --testsuite=Feature
docker compose exec app php artisan test --testsuite=Unit
docker compose exec app php artisan test tests/Feature/Profile/ProfileManagementTest.phpHost equivalents also exist (php artisan ...) but depend on compatible local PHP/composer platform requirements.
Observed patterns in tests:
- Feature tests often use
RefreshDatabase. - File-heavy tests use
Storage::fake(...)andUploadedFile::fake(). - Submittal PDF tests use JSON route assertions and database assertions for workflow behavior.
-
No additional rule files in requested locations
- Only
AGENTS.mdexists among the specified agent-rule paths.
- Only
-
CI workflow config exists in-repo
.github/workflows/is present; align local validation with configured CI checks when touching build/test/lint behavior.
-
Route-model binding depends on non-standard parameter names
submittalandfab_queuebindings are explicit inAppServiceProvider; changing param names can break resolution.
-
PDF markup types were extended through follow-up migrations
- Enum changes are represented by newer forward migrations; preserve this pattern when adding new types.
-
Submittal-file routes enforce ownership relationships
- Tests verify a file/markup must belong to the routed submittal/submittal file context.
-
Legacy import command expects exact CSV filenames at repo root
- Missing/renamed files will break import.
-
Host PHP can mismatch composer platform requirements
- Observed locally: host
php artisan testfails with Composer platform check whiledocker compose exec app php artisan test --testsuite=Unitpasses. - Prefer running artisan/composer via Docker container in this project.
- Observed locally: host
-
Boost MCP tooling is environment-gated
laravel/boostMCP registration depends on local/debug context inBoostServiceProvider::shouldRun().- Running Boost MCP commands may require
APP_ENV=localandAPP_DEBUG=truein container executions.
-
Container migrations may require
--force- In this environment,
docker compose exec app php artisan migratecan trigger Laravel's production safety prompt. - Use
docker compose exec app php artisan migrate --forcefor non-interactive container runs.
- In this environment,
- Prefer service-layer changes (
app/Services) for business state transitions. - Keep controllers thin and return named-route redirects / Inertia responses consistent with existing patterns.
- Reuse existing status vocabulary and route names to avoid breaking filters/UI badges/tests.
- For dashboard, notifications, and profile work, preserve shared Inertia payload shape in
HandleInertiaRequests. - For PDF features, keep frontend tool names, backend validation, database enum values, and tests aligned.
- For calibration/measurement features, use page-scale routes/data (
page_number) rather than embedding scale assumptions in individual markups. - Customers and projects enforce US state abbreviations (
app/Support/UsStates.php) via FormRequests; keep form dropdown options and validation list aligned. - Project attachments now include a delete path (
projects.attachments.destroy) and should remove both DB records and stored files. - Admin Boost log viewer merges browser logs with MCP status-check events and supports reset via admin routes.
- Rebuild the app and clear cache after changes.
- Never perform changes that risk existing production data, especially user passwords.