# Development Guidelines

**Author:** Vikash Kumar  
**Company:** TAS Technologies  
**Document Version:** 1.0  
**Last Updated:** 2026-05-20

These guidelines must be followed for all development work in this Laravel-based custom framework.

## Core Laravel Approach

- Follow standard Laravel development practices and the existing project structure.
- Keep code modular, readable, and consistent with the current framework patterns.
- Do not modify Laravel core files, vendor files, or third-party package files unless there is a clear approved reason.
- Keep business logic out of Blade files. Use controllers, models, services, helpers, or request classes as appropriate.
- Use Laravel validation, route names, middleware, policies/permissions, language files, and breadcrumbs consistently.
- Avoid hard-coded URLs, paths, credentials, email addresses, and environment-specific values. Use `.env`, config files, route helpers, and storage helpers.

## Database Development Rules

- Before developing any new module that requires database tables, first create the required database migration files.
- New tables must be created through Laravel migration files.
- If an existing table requires changes, make the alteration directly in phpMyAdmin first when required by the project workflow, then update the respective existing migration file so the database structure remains documented in code.
- Keep every existing-table alter query or required data change in:

```text
tests/non-git-files/db/alter-db-query-data.txt
```

- Add database alter queries and required data under a date-wise heading with the developer name.

Example:

```text
## 2026-05-20 - Ubesh

ALTER TABLE banner_ad_categories ADD status TINYINT(1) NOT NULL DEFAULT 1;

INSERT INTO permissions (name, guard_name, created_at, updated_at)
VALUES ('admin.banner-ad-categories.index', 'web', NOW(), NOW());
```

- Keep a daily local project database SQL backup whenever database-related work is done.
- Save the backup before leaving work, going outside, restarting, or shutting down the local machine.
- Store Ubesh local database backups under:

```text
tests/non-git-files/db/ubesh-local/
```

- Use a clear backup filename format:

```text
project-name_YYYY-MM-DD_HH-mm.sql
```

## CRUD Module Naming Convention

Use the following naming convention for Laravel CRUD modules.

| Item | Convention | Example |
| --- | --- | --- |
| Table | Snake case, plural | `banner_ad_categories` |
| Model | StudlyCase, singular | `BannerAdCategory` |
| Controller | StudlyCase with `Controller` suffix | `BannerAdCategoryController` |
| Routes | Admin route names, kebab case | `admin.banner-ad-categories.*` |
| Views | Admin folder, kebab case | `admin/banner-ad-categories/*.blade.php` |
| Language file | Snake case | `lang/en/banner_ad_categories.php` |
| Breadcrumbs | Match route names | `admin.banner-ad-categories.*` |
| Requests | Admin request folder per module | `app/Http/Requests/Admin/BannerAdCategory/*` |
| Storage | Snake case folder | `banner_ad_categories/` |

## CRUD Module Seeder Entries

When starting any new CRUD module, or when altering an existing module that affects admin menu, permissions, methods, or access rights, update all related seeder files.

Update the seeder files in this sequence:

1. `database/seeders/ModuleClassSeeder.php`
2. `database/seeders/ModulesSeeder.php`
3. `database/seeders/ModuleMethodsSeeder.php`
4. `database/seeders/RoleModuleMethodRightsSeeder.php`

Keep the `module_id`, `class_id`, method IDs, route names, controller name, model name, slug, menu status, and permission rights consistent across all four files.

### 1. Module Class Seeder

File:

```text
database/seeders/ModuleClassSeeder.php
```

Use this file to register the controller, model, and slug mapping for the module.

- Add one entry per module class.
- Use a unique `class_id`.
- Keep `class_id` aligned with `ModulesSeeder.php`.
- Use the controller class name in `class_name`.
- Use the model name in `model_name`.
- Use the route slug in `slug`.
- Keep `status` aligned with the module status.

Example:

```php
array('class_id' => '60', 'class_name' => 'BannerAdCategoryController', 'model_name' => 'BannerAdCategory', 'slug' => 'banner-ad-categories', 'info' => NULL, 'status' => 'enabled'),
```

### 2. Modules Seeder

File:

```text
database/seeders/ModulesSeeder.php
```

Use this file to register the module in the admin system and menu.

- Add one entry per module.
- Use a unique `module_id`.
- Keep `class_id` the same as the related `ModuleClassSeeder.php` entry unless there is a specific reason to separate them.
- Use the actual controller class name in `class_name`.
- Set `is_menu => yes` if the module should appear in the admin menu.
- Set `parent_module_id => 0` for a top-level menu item.
- Set `parent_module_id` to another module ID for a child menu item.
- Use `status => enabled` only when the module should be active.

Example:

```php
array('module_id' => '60', 'class_id' => '60', 'has_templates' => 'no', 'title' => 'Banner Ad Categories', 'label' => 'Banner Ad Categories', 'info' => NULL, 'class_name' => 'BannerAdCategoryController', 'is_menu' => 'yes', 'icon_class' => 'ri-image-line', 'hot_text' => '', 'c_order' => '5', 'parent_module_id' => '0', 'status' => 'enabled'),
```

### 3. Module Methods Seeder

File:

```text
database/seeders/ModuleMethodsSeeder.php
```

Use this file to register all route-level methods/actions for the module.

- Add method entries for every required CRUD action.
- Use the same `module_id` as the module entry.
- Use a unique `method_id` from the reserved range.
- Keep `route_link` exactly the same as the Laravel route name.
- Use `affected_route_link` when an action belongs under another page, such as store under create or update under edit.
- Set `is_left_nav => 1` only for methods that should appear in the left navigation.
- Set `is_left_nav => 0` for background actions such as store, update, delete, export, and file delete.

Recommended CRUD method pattern:

```php
array('method_id' => '601', 'module_id' => '60', 'title' => 'All Banner Ad Categories', 'method_name' => 'index', 'default_present' => '0', 'access_role_id' => '0', 'route_link' => 'admin.banner-ad-categories.index', 'affected_route_link' => NULL, 'is_left_nav' => '1', 'is_external_link' => '0', 'c_order' => '1', 'updated_id' => '1', 'created_at' => now(), 'updated_at' => NULL),
array('method_id' => '602', 'module_id' => '60', 'title' => 'Add Banner Ad Category', 'method_name' => 'create', 'default_present' => '0', 'access_role_id' => '0', 'route_link' => 'admin.banner-ad-categories.create', 'affected_route_link' => NULL, 'is_left_nav' => '1', 'is_external_link' => '0', 'c_order' => '2', 'updated_id' => '1', 'created_at' => now(), 'updated_at' => NULL),
array('method_id' => '603', 'module_id' => '60', 'title' => 'Store Banner Ad Category', 'method_name' => 'store', 'default_present' => '0', 'access_role_id' => '0', 'route_link' => 'admin.banner-ad-categories.store', 'affected_route_link' => 'admin.banner-ad-categories.create', 'is_left_nav' => '0', 'is_external_link' => '0', 'c_order' => '0', 'updated_id' => '1', 'created_at' => now(), 'updated_at' => NULL),
array('method_id' => '604', 'module_id' => '60', 'title' => 'Edit Banner Ad Category', 'method_name' => 'edit', 'default_present' => '0', 'access_role_id' => '0', 'route_link' => 'admin.banner-ad-categories.edit', 'affected_route_link' => NULL, 'is_left_nav' => '0', 'is_external_link' => '0', 'c_order' => '0', 'updated_id' => '1', 'created_at' => now(), 'updated_at' => NULL),
array('method_id' => '605', 'module_id' => '60', 'title' => 'Update Banner Ad Category', 'method_name' => 'update', 'default_present' => '0', 'access_role_id' => '0', 'route_link' => 'admin.banner-ad-categories.update', 'affected_route_link' => 'admin.banner-ad-categories.edit', 'is_left_nav' => '0', 'is_external_link' => '0', 'c_order' => '0', 'updated_id' => '1', 'created_at' => now(), 'updated_at' => NULL),
array('method_id' => '606', 'module_id' => '60', 'title' => 'Delete Banner Ad Category', 'method_name' => 'deleteData', 'default_present' => '0', 'access_role_id' => '0', 'route_link' => 'admin.banner-ad-categories.delete', 'affected_route_link' => NULL, 'is_left_nav' => '0', 'is_external_link' => '0', 'c_order' => '0', 'updated_id' => '1', 'created_at' => now(), 'updated_at' => NULL),
array('method_id' => '607', 'module_id' => '60', 'title' => 'Delete Banner Ad Category Image', 'method_name' => 'deleteFile', 'default_present' => '0', 'access_role_id' => '0', 'route_link' => 'admin.banner-ad-categories.deletefile', 'affected_route_link' => 'admin.banner-ad-categories.edit', 'is_left_nav' => '0', 'is_external_link' => '0', 'c_order' => '0', 'updated_id' => '1', 'created_at' => now(), 'updated_at' => NULL),
```

### 4. Role Module Method Rights Seeder

File:

```text
database/seeders/RoleModuleMethodRightsSeeder.php
```

Use this file to assign module method rights to roles.

- Add one entry for each method that the role should access.
- For admin access, use `role_id => 1` unless the requirement is different.
- Use the same `module_id` that is added in `ModulesSeeder.php`.
- Use the same `method_id` values that are added in `ModuleMethodsSeeder.php`.
- Place the entries under the correct reserved ID range comment.

Example:

```php
array('role_id' => '1', 'module_id' => '60', 'method_id' => '601', 'created_at' => now(), 'updated_at' => now(), 'deleted_at' => NULL),
array('role_id' => '1', 'module_id' => '60', 'method_id' => '602', 'created_at' => now(), 'updated_at' => now(), 'deleted_at' => NULL),
array('role_id' => '1', 'module_id' => '60', 'method_id' => '603', 'created_at' => now(), 'updated_at' => now(), 'deleted_at' => NULL),
array('role_id' => '1', 'module_id' => '60', 'method_id' => '604', 'created_at' => now(), 'updated_at' => now(), 'deleted_at' => NULL),
array('role_id' => '1', 'module_id' => '60', 'method_id' => '605', 'created_at' => now(), 'updated_at' => now(), 'deleted_at' => NULL),
array('role_id' => '1', 'module_id' => '60', 'method_id' => '606', 'created_at' => now(), 'updated_at' => now(), 'deleted_at' => NULL),
array('role_id' => '1', 'module_id' => '60', 'method_id' => '607', 'created_at' => now(), 'updated_at' => now(), 'deleted_at' => NULL),
```

### Seeder Update Checklist

- Confirm the new `module_id` is not already used.
- Confirm the new `class_id` is not already used.
- Confirm every `method_id` is unique.
- Confirm the method ID range matches the reserved range comment.
- Confirm all route names exist in `routes/web.php`.
- Confirm `method_name` values match the controller methods.
- Confirm left navigation entries are intentional.
- Confirm parent and child menu relationships are correct.
- Confirm status is correct: `enabled` or `disabled`.
- After changing these seeders, document any required staging/live data changes in `tests/non-git-files/db/alter-db-query-data.txt`.

## Recommended CRUD File Structure

For a module such as `BannerAdCategory`, use this structure where applicable:

```text
app/Models/BannerAdCategory.php
app/Http/Controllers/Admin/BannerAdCategoryController.php
app/Http/Requests/Admin/BannerAdCategory/StoreBannerAdCategoryRequest.php
app/Http/Requests/Admin/BannerAdCategory/UpdateBannerAdCategoryRequest.php
resources/views/themes/backend/admin/banner-ad-categories/index.blade.php
resources/views/themes/backend/admin/banner-ad-categories/create.blade.php
resources/views/themes/backend/admin/banner-ad-categories/edit.blade.php
resources/views/themes/backend/admin/banner-ad-categories/show.blade.php
lang/en/banner_ad_categories.php
database/migrations/YYYY_MM_DD_HHMMSS_create_banner_ad_categories_table.php
```

## Controller and Route Guidelines

- Use resource-style controller methods where possible: `index`, `create`, `store`, `show`, `edit`, `update`, and `destroy`.
- Keep route names consistent with the module route prefix.
- Use named routes instead of hard-coded URLs.
- Apply admin middleware, authentication, permission checks, and breadcrumb names consistently.
- Keep controller methods small. Move reusable business logic into services, model methods, or helpers when needed.

## Model Guidelines

- Define table name only when Laravel cannot infer it correctly.
- Define `$fillable` or `$guarded` clearly.
- Add relationships in the model using Laravel relationship methods.
- Use accessors, mutators, casts, scopes, and constants where they make the code cleaner.
- Avoid writing raw queries when Laravel query builder or Eloquent can handle the requirement clearly.

## Request and Validation Guidelines

- Use Form Request classes for create and update validation.
- Keep validation messages readable and, where possible, reusable through language files.
- Do not duplicate validation rules in controllers.
- Validate uploaded files for type, size, and dimensions where relevant.

## Blade and Language Guidelines

- Keep Blade files focused on presentation.
- Reuse existing backend theme components, layout files, form partials, and table patterns.
- The system admin panel is built using a paid admin theme template. If the required UI or component is not available in the existing module Blade files, ask for the admin theme template files before creating the UI. All admin panel components must exist within the approved theme.
- Follow the admin theme's HTML structure, CSS classes, JavaScript plugins, icons, form controls, tables, modals, alerts, tabs, cards, and layout patterns.
- Do not introduce a new UI library, custom component style, or unrelated CSS framework unless it is approved.
- Keep admin pages visually consistent with the existing backend theme.
- Use the theme's existing responsive grid, spacing, buttons, badges, status labels, loaders, and validation error styles.
- Before adding custom CSS or JavaScript, check whether the paid admin theme already provides the required component or plugin.
- Do not hard-code repeated labels or messages. Add them to the module language file.
- Escape output by default using Blade syntax unless trusted HTML output is intentionally required.

## File Upload and Storage Guidelines

- Store module files in a module-specific folder, for example:

```text
banner_ad_categories/
```

- Use Laravel storage helpers instead of hard-coded public paths.
- Delete or replace old uploaded files when records are updated or deleted, if the file is no longer required.
- Keep file names predictable and safe. Avoid spaces and unsafe special characters in stored file names.

## Deployment and Staging Checklist

Before moving work to staging or live:

- Confirm all required migration changes are documented.
- Confirm all manual alter queries and data changes are added to `tests/non-git-files/db/alter-db-query-data.txt`.
- Confirm the latest local SQL backup is saved under the correct developer backup folder.
- Confirm routes, breadcrumbs, permissions, language files, views, and storage paths are included.
- Clear and rebuild caches where required:

```text
php artisan optimize:clear
php artisan config:cache
php artisan route:cache
php artisan view:cache
```

- Test the module manually in the admin panel for list, create, edit, update, delete, validation errors, permissions, and file upload behavior.

## General Code Quality

- Keep naming consistent across database, model, controller, routes, views, language files, breadcrumbs, request classes, and storage folders.
- Follow existing indentation, formatting, and project conventions.
- Keep commits or task changes focused on one feature or fix.
- Check logs after testing any new module or database change.
- Do not leave debug code such as `dd()`, `dump()`, `console.log()`, or temporary test routes in completed work.
- Document any special staging/live step clearly in the alter query text file.
