# Development Standard: Modular, Structured Applications

## Development Goal

Build practical, full-stack web applications that are easy to understand,
deploy, debug, extend, and operate. The preferred approach is pragmatic rather
than academic: use a lightweight, PHP-native application foundation with
framework-quality conventions.

**Core principle:** Organize code by responsibility, make dependencies explicit,
and keep each feature understandable in one place.

The objective is to standardize projects so every application begins with
familiar conventions for:

- Directory layout and bootstrap process
- Environment configuration and secret management
- Authentication, authorization, alerts, and shared UI patterns
- Database migrations, logging, testing, and deployment
- Naming, modular boundaries, and reusable components

## Development Profile

The working style is that of a practical full-stack engineer and systems
administrator:

- Build usable tools and keep the environment efficient.
- Debug methodically across database, application, authentication, and frontend
  layers.
- Improve both the interface and the underlying implementation.
- Favor repeatable operational patterns and automation over one-off fixes.

### Primary Stack

- PHP
- HTML
- JavaScript
- MySQL with PDO
- Bootstrap 5
- DataTables
- FontAwesome
- Datatables
- adminLTE
- macOS Terminal, SSH, SCP, mounted remote filesystems
- FileZilla for server workflows
- Git-based deployment and packaging
- NOTE NOT USING: node.js, composer, warp

### Typical Work

- PHP, JavaScript, SQL/PDO, Bootstrap 5, DataTables, and FontAwesome web
  adminLTE, html, applications.
- Remote-server administration through macOS Terminal, SSH, SCP, mounts,
  FileZilla
- Database-query, application-behavior, authentication-flow, and
  frontend-interaction debugging.
- Bootstrap/Gentelella-style admin dashboards with clean UI/UX, responsive
  layouts, and flexible themes.
- Reusable templates, installers, documented paths, and predictable deployment
  processes.

## Architecture Approach

The ideal architecture is modular and convention-driven without unnecessary
abstraction. It should allow a developer to locate all parts of a business
capability without hunting through unrelated global folders.

### Layer Responsibilities

| Layer | Responsibility | Should contain | Should not contain |
|---|---|---|---| | HTTP / Controller | Receive requests, validate intent,
choose response | Request parsing, authorization calls, service calls, redirects
or rendering | Raw SQL, complex business rules, HTML page construction | |
Application / Service | Coordinate use cases | Workflows such as create user,
approve invoice, export report | Direct `$_POST` use, markup | | Domain /
Business Logic | Define rules for correct behavior | Calculations, state
transitions, important validation rules | PDO calls, session access, Bootstrap
classes | | Repository / Data Access | Read and write persistent data | PDO
prepared statements, query mapping, transactions | UI concerns, authorization
decisions | | View / Presentation | Render responses | Templates, partials,
display formatting, components | SQL, side-effecting business logic | |
Infrastructure | Handle external concerns | Database connection, mail client,
file storage, logger, cache | Feature-specific controller logic |

This does **not** mean every small page needs six classes. It means that as the
project grows, every concern has a clear home.

### Dependency Direction

Dependencies should point inward:

- Views may depend on view models.
- Controllers may depend on services.
- Services may depend on repository interfaces.
- Domain logic should not depend on Bootstrap, `$_SESSION`, PDO, or a specific
  web request.

## Suggested Project Layout

```text project/ ├── app/ │   ├── Http/ │   │   ├── Controllers/ │   │   ├──
Middleware/ │   │   ├── Requests/ │   │   └── Responses/ │   ├── Modules/ │   │
├── Users/ │   │   │   ├── Controllers/ │   │   │   ├── Services/ │   │   │
├── Repositories/ │   │   │   ├── Policies/ │   │   │   ├── Views/ │   │   │
└── routes.php │   │   ├── Reports/ │   │   └── Billing/ │   ├── Shared/ │   │
├── Database/ │   │   ├── Auth/ │   │   ├── Validation/ │   │   ├── Logging/ │
│   └── Support/ │   ├── Views/ │   │   ├── layouts/ │   │   ├── components/ │
│   └── errors/ │   └── Bootstrap/ │       └── Application.php ├── config/ │
├── app.php │   ├── database.php │   ├── auth.php │   └── services.php ├──
database/ │   ├── migrations/ │   ├── seeds/ │   └── schema/ ├── public/ │   ├──
index.php │   └── assets/ ├── routes/ │   ├── web.php │   └── api.php ├──
storage/ │   ├── logs/ │   ├── cache/ │   └── uploads/ ├── tests/ │   ├── Unit/
│   ├── Feature/ │   └── Integration/ ├── .env ├── .env.example ├──
composer.json └── README.md ```

### Module-First Organization

For larger systems, feature modules are more maintainable than a single global
`Controllers`, `Models`, and `Views` structure.

For example, everything relating to customer management belongs under
`app/Modules/Customers/`, including:

- Routes
- Controllers
- Services
- Repositories
- Policies
- Views
- Feature-specific JavaScript
- Tests

Shared infrastructure must be genuinely cross-cutting: database access,
authentication, logging, validation, and UI components. It should never become
an accidental dumping ground.

## Golden Rules

1. **One source of truth.** Store each rule, setting, permission definition, and
configuration value in one authoritative location. Do not duplicate business
rules across JavaScript, controllers, SQL, and templates without a deliberate
reason.

2. **Keep controllers thin.** A controller should read like a short outline:
validate input, confirm authorization, call a service, and return a response.
Move underlying work into a service when it becomes more than orchestration.

3. **Never put raw SQL in views or controllers.** Centralize persistence in
repositories or query classes. Always use PDO prepared statements and meaningful
repository methods.

4. **Name by intent.** `ApproveInvoiceService` is better than `InvoiceHelper`.
`findActiveUsersForOrganization()` is better than `getData()`. Names should
communicate what and why, not merely how.

5. **Avoid god files.** Be suspicious of catch-all files such as
`functions.php`, `helpers.php`, `utilities.php`, `common.js`, `App.php`, or a
bloated `UserModel.php`. Split files when unrelated concerns accumulate.

6. **Keep dependencies inward.** Domain rules should not depend on web requests,
sessions, PDO, Bootstrap, or infrastructure details.

7. **Make invalid states hard to create.** Validate on the server. Apply
database constraints: `NOT NULL`, foreign keys, unique keys, and check
constraints where supported. Use named operations such as `approve()`,
`cancel()`, and `archive()` rather than open-ended field mutation.

8. **Prefer composition over copy/paste.** Reuse layouts, form controls, table
configurations, policy checks, query scopes, service methods, and view
components. Reuse should make behavior consistent without hiding the
application’s purpose.

9. **Use configuration instead of environment conditionals.** Do not branch on a
hostname in app logic. Put environment-specific values in `.env` and
configuration files.

10. **Make every module independently understandable.** A developer should be
able to answer what it does, what routes expose it, who can access it, what
tables it uses, and what tests cover it.

## Naming Conventions

Consistency is more important than any specific style. These conventions fit
PHP, JavaScript, SQL, and Bootstrap-oriented applications.

### PHP Classes and Files

Use PSR-style naming:

```php final class UserController {} final class UserService {} final class
UserRepository {} final class CreateUserRequest {} final class UserPolicy {}
final class UserCreatedEvent {} ```

- Classes: `PascalCase`
- Methods and variables: `camelCase`
- Constants: `UPPER_SNAKE_CASE`
- Files: Match class names, for example `UserService.php`
- Namespaces: Reflect directory and module structure

```php namespace App\Modules\Users\Services;

final class CreateUserService { public function execute(CreateUserData $data):
User { // ...  } } ```

### PHP Method Intent

Use verbs for actions and explicit nouns for retrieval:

```php $user = $userRepository->findById($userId); $users =
$userRepository->findActiveByOrganization($organizationId);
$invoiceService->approve($invoiceId, $actorId);
$reportService->generateMonthlyRevenue($year, $month);
$authService->authenticate($credentials); ```

Avoid vague method names:

```php doUserThing(); process(); handleData(); updateStuff(); getInfo(); ```

Reserve `get...()` for simple accessors. A potentially expensive database query
should usually be named `find...()`, `search...()`, `list...()`, or
`paginate...()`.

### Database Conventions

Use a consistent relational naming strategy:

```text users organizations organization_users invoices invoice_items audit_logs
```

- Tables: plural `snake_case`
- Primary key: `id`
- Foreign key: singular related table plus `_id`, such as `user_id` and
  `organization_id`
- Timestamps: `created_at`, `updated_at`, and optionally `deleted_at`
- Boolean fields: `is_active`, `has_access`, `can_export`
- Status fields: `status`, with documented allowed values
- Pivot/join tables: alphabetical or relationship-oriented names, such as
  `organization_users`
- Index names: explicit and predictable, such as
  `idx_invoices_organization_id_status`

Use a real status vocabulary instead of boolean sprawl. For example, an invoice
can be `draft`, `issued`, `paid`, `void`, or `overdue`; it should not require
overlapping flags such as `is_paid`, `is_void`, `is_draft`, and `is_overdue`.

### JavaScript Conventions

```text assets/js/ ├── app.js ├── modules/ │   ├── users/ │   │   ├──
user-form.js │   │   └── user-table.js │   └── reports/ │       └──
revenue-chart.js └── shared/ ├── api-client.js ├── notifications.js └── modal.js
```

- Variables and functions: `camelCase`
- Classes: `PascalCase`
- Files: `kebab-case`
- DOM hooks: use `data-*` attributes to separate behavior from styling

```html <button class="btn btn-primary" data-action="open-user-editor"
data-user-id="42"> Edit </button> ```

Bind JavaScript behavior to `data-action`, not to a styling class:

```js document.addEventListener("click", (event) => { const button =
event.target.closest('[data-action="open-user-editor"]'); if (!button) return;

    openUserEditor(button.dataset.userId); }); ```

## Routes and URLs

Use resource-oriented, predictable endpoints:

```text GET    /users GET    /users/create POST   /users GET    /users/{id} GET
/users/{id}/edit PUT    /users/{id} DELETE /users/{id} ```

Use action-style endpoints sparingly and only for meaningful domain commands:

```text POST /invoices/{id}/approve POST /invoices/{id}/void POST
/reports/monthly-revenue/export ```

The action should represent a real domain operation, not a generic
implementation shortcut.

## Feature Blueprint

Use this repeatable checklist for every new feature.

1. **Define the user-facing outcome.** Example: “An authorized manager can
create, edit, deactivate, and search employees.”
2. **Define data and rules.** Identify required data, uniqueness rules, allowed
values, permissions, and required audit trails.
3. **Add the migration and indexes.** Treat schema changes as versioned code;
never depend on undocumented manual production changes.
4. **Create the module boundary.** For example: `Employees/Controllers`,
`Employees/Services`, `Employees/Repositories`, `Employees/Policies`,
`Employees/Views`, and `Employees/routes.php`.
5. **Build services around use cases.** Examples: `CreateEmployeeService`,
`UpdateEmployeeService`, `DeactivateEmployeeService`, and
`SearchEmployeesService`.
6. **Build thin controller actions.** Validate input, confirm authorization,
call the service, then return a redirect, JSON response, or rendered view.
7. **Reuse standard UI components.** Standardize page headers, breadcrumbs,
alerts, empty states, table shells, pagination, form fields, validation output,
and confirmation modals.
8. **Test rule boundaries.** Use unit tests for business behavior, integration
tests for repositories and queries, and feature tests for routes, authorization,
validation, and expected responses.

## Environment and Operations

Treat local setup, hosting, deployment, logging, and recovery as part of the
application architecture.

### Environment Model

| Item | Purpose | |---|---| | `.env.example` | Safe template committed to Git |
| `.env` | Local secrets; never committed | | `.env.production` | Production
values managed securely on the server or in deployment tooling | |
`config/*.php` | Application configuration that reads environment variables |

Typical variables:

```dotenv APP_ENV=local APP_DEBUG=true APP_URL=http://localhost:8080
DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=my_app DB_USERNAME=my_app_user
DB_PASSWORD= MAIL_HOST= MAIL_PORT= MAIL_USERNAME= MAIL_PASSWORD=
SESSION_SECURE=false LOG_LEVEL=debug ```

### Operational Rules

- Never hard-code credentials, API keys, hostnames, email addresses, paths, or
  production flags in application logic.
- Commit `.env.example`, never `.env`.
- Keep development, staging, and production as similar as practical.
- Use a dedicated database user for each application and grant only required
  permissions.
- Disable detailed error display in production.
- Log errors with sufficient request context to diagnose problems safely.
- Use migrations and a documented release process for all database changes.
- Maintain predictable paths for logs, cache, uploads, backups, generated
  assets, and runtime data.

### Tooling Baseline

| Area | Practical baseline | |---|---| | PHP dependencies | Composer with
committed `composer.lock` | | PHP quality | PHPStan or Psalm; PHP-CS-Fixer or
PHP_CodeSniffer | | Tests | PHPUnit or Pest | | JavaScript dependencies | npm
with a lockfile | | JavaScript quality | ESLint and Prettier | | Database
changes | Versioned migrations and seeders | | Local environment | Docker
Compose, Laravel Valet/Herd-style setup, or a documented native stack | |
Version control | Git with a protected `main` branch and meaningful commits | |
CI | Linting, static analysis, tests, and build steps on every pull request | |
Deployment | Repeatable script or CI deployment rather than manual copying as
the primary method | | Observability | Structured logs, error monitoring, access
logs, and basic uptime checks |

FileZilla and SCP remain useful for emergency access, inspections, and narrowly
scoped changes. For normal releases, prefer Git-based deployment or a scripted
release process to reduce drift between local and production environments.

## Standard Program Baseline

Every project should include:

- A bootstrap entry point
- Environment configuration
- Routing
- Authentication and authorization boundaries
- Modular features
- Repositories for persistence
- Services for use cases
- Templates and components for UI
- Migrations for schema changes
- Logs
- Tests
- A documented deployment path

A new repository should make these answers immediately obvious:

1. How do I run it locally?
2. Where do configuration and secrets live?
3. What is the application entry point?
4. Where do routes live?
5. Where is this feature’s business logic?
6. Where are its database queries?
7. How is access controlled?
8. How are database changes applied?
9. Where are errors logged?
10. How do I test and deploy it?
11. Which files are safe to edit, and which are generated, vendor, cache, or
runtime data?

If those answers are apparent from the repository structure and `README.md`, the
project has achieved the desired modular, structured standard.

## Personal Golden Rule

> Build features vertically, organize them by business capability, and keep each
> layer responsible for one kind of work.

A user-management feature should not require changes across a dozen unrelated
global files. Its route, controller, service, repository, policy, views,
JavaScript, migration, and tests should form one coherent unit.

This approach preserves the speed of pragmatic PHP development while providing
enough structure for applications to survive new features, server changes, UI
redesigns, deployment evolution, and long-term maintenance.

