# Architecture

## Overview

Three Goats Club is a Laravel 13 modular monolith: one deployable application and database, with business capabilities separated inside the codebase. It currently follows Laravel's conventional directories; `app/Domain` does not yet exist and should appear only with implemented domain behavior.

## Current layers

- `routes/` and `app/Http/`: web entry points and request concerns.
- `app/Livewire/` and `resources/views/`: interactive UI and Blade presentation.
- `app/Filament/`: administration resources; the panel is served at `/admin`.
- `app/Actions/`: current application actions, including authentication/profile operations.
- `app/Models/`: current shared Eloquent models.
- `app/Providers/`: framework and package integration.
- `database/`: migrations, factories, and seeders.
- `resources/js` and `resources/css`: Vite/Tailwind browser assets.

Fortify supplies authentication, password reset, email verification, two-factor authentication, and passkeys. Spatie Permission supplies role/permission storage. `.env.example` defaults to file-backed sessions and cache and the synchronous queue. Database-backed or Redis-backed state and queues are optional deployment choices.

## Future domain modules

Add a module at `app/Domain/<Domain>` when a product capability has real code. Likely capabilities may include Membership, Events, Content, or Commerce, but names must follow approved product language rather than this illustrative list.

A module may contain only the folders it needs, for example `Actions`, `Contracts`, `Data`, `Events`, `Jobs`, `Models`, `Policies`, `Queries`, or `Services`. Namespace code as `App\Domain\<Domain>\...`. Keep migrations in `database/migrations` and mirror behavior in the existing test suites.

Do not create empty folders/classes, marker interfaces, placeholder services, or complete directory trees in advance.

## Dependency rules

1. Routes/controllers, Livewire components, and Filament resources are adapters. They validate/map input, authorize, invoke application/domain behavior, and format output.
2. Domain behavior must not depend on HTTP requests, Blade, Livewire, or Filament classes.
3. A domain exposes deliberate entry points—actions, contracts, immutable data/value objects, or events. Other domains must not query or mutate its internals directly.
4. Prefer synchronous calls for immediate invariants and domain events/queued listeners for side effects that can be eventually consistent.
5. Keep shared code limited to stable cross-cutting primitives. Do not create a generic dumping ground.
6. Access data through owned models/query objects and explicit relationships. Avoid circular dependencies and unbounded cross-domain joins.
7. Authorization remains server-side through policies, gates, and permissions; UI visibility is not authorization.
8. Jobs and event handlers should be idempotent and safe to retry.

## Change rule

Start with the smallest implementation in the owning domain. Extract abstractions only after a second concrete use or a clear boundary requires one. Architecture tests may enforce established boundaries once modules exist; do not add tests for nonexistent structures.