lthn.io/app/Core
Claude 41a90cbff8
feat: lthn.io API serving live chain data
Fixed: basePath self→static binding, namespace detection, event wiring,
SQLite cache, file cache driver. All Mod Boot classes converted to
$listens pattern for lifecycle event discovery.

Working endpoints:
- /v1/explorer/info — live chain height, difficulty, aliases
- /v1/explorer/stats — formatted chain statistics
- /v1/names/directory — alias directory grouped by type
- /v1/names/available/{name} — name availability check
- /v1/names/lookup/{name} — name details

Co-Authored-By: Charon <charon@lethean.io>
2026-04-03 17:17:42 +01:00
..
Actions feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Activity feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Bouncer feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Cdn feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Config feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Console feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Crypt feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Database/Seeders feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Events feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Front feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Headers feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Helpers feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Input feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Lang feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Mail feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Media feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Rules feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Search feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Seo feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Storage feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Tests feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Webhook feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Boot.php feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
CLAUDE.md feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
config.php feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Init.php feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
LazyModuleListener.php feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
LifecycleEventProvider.php feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
ModuleRegistry.php feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
ModuleScanner.php feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
Pro.php feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
README.md feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
RELEASE-BLOCKERS.md feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
TODO.md feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00
views.md feat: lthn.io API serving live chain data 2026-04-03 17:17:42 +01:00

Core Architecture: The Core Module Protocol

================================================

  • A highly opinionated, encapsulated module structure for Laravel.
  • Designed to prevent monolithic spaghetti by enforcing strict boundaries.

Philosophy

  1. Everything is a Module: If it's a feature, it belongs in app/Mod/.
  2. One Boot File: No complex Provider naming. Every module has a Boot.php at its root.
  3. Strict Encapsulation: Modules should be self-contained.

Directory Structure (Per Module)

app/Mod/{ModuleName}/
├── Boot.php                   # The single ServiceProvider entry point
├── Console/                   # Artisan Commands
├── Controllers/               # HTTP Controllers (Web & API)
├── Database/                  # Migrations, Factories, Seeders
├── Events/                    # Events & Listeners
├── Jobs/                      # Queueable Jobs
├── Mail/                      # Mailables
├── Mcp/                       # MCP Tools & Servers
├── Models/                    # Eloquent Models (Namespace: Mod\{Mod}\Models)
├── Services/                  # Business Logic (The "Brain")
├── Tests/                     # Pest Tests (Feature & Unit)
└── View/                      # The UI Layer (See views.md)
    ├── Modal/                 # Livewire Components (ViewModels)
    │   ├── Admin/             # Admin-facing ViewModels
    │   └── Web/               # Public-facing ViewModels
    ├── Blade/                 # Dumb Blade Templates
    │   ├── admin/             # Admin templates
    │   └── web/               # Public templates
    ├── Components/            # Reusable Blade Components
    └── routes/                # Route definitions

Component Details

Boot.php

The entry point. Must extend Illuminate\Support\ServiceProvider. It registers routes, views, migrations, and binds services. Namespace: Mod\{Name} Class: Boot

Models

All Eloquent models live here. Namespace: Mod\{Name}\Models Table Name: [module_snake_case]_[table_name] (e.g., agentic_plans).

View (Modern Flexy)

See views.md for the strict separation of Logic (Modal) and Layout (Blade).

Tests

Tests must exist within the module. Run via: php artisan test app/Mod/{Name}/Tests

Best Practices

  1. Skinny Controllers: Controllers only delegate to Services or return View Modals.
  2. Explicit Boundaries: Do not query another module's database tables directly using raw SQL. Use Service contracts or Events if modules need to talk.
  3. Self-Contained: A module should be able to be extracted into a composer package with minimal effort.

Core Architecture: The Core View Protocol (Modern Flexy)

=========================================================

  • A strict architectural guideline for implementing Server-Side MVVM in Laravel.
  • Part of the Core PHP Framework.

Philosophy

  1. The Controller is a Traffic Cop: It accepts input, delegates to the Domain, and selects a View Modal. It never touches HTML or data formatting.
  2. The View Modal is the Interface: All presentation logic, formatting, state management, and data preparation happen here. This is the "ViewModel" (implemented as Livewire Components).
  3. The Template is Dumb: The template file (.blade.php) contains ONLY HTML and simple variable interpolation. No complex logic, no database calls, no calculations.

Directory Structure

Inside a Core Module (app/Mod/{Name}/):

View/
├── Modal/                 # The View Modals (Livewire Components)
│   ├── Admin/             # (Namespace: Mod\{Mod}\View\Modal\Admin)
│   │   └── {Resource}Manager.php
│   ├── Web/               # (Namespace: Mod\{Mod}\View\Modal\Web)
│   │   └── {Resource}Page.php
│   └── {Resource}Page.php
└── Blade/                 # The Dumb HTML Templates
    ├── admin/             # (View Namespace: {mod}::admin)
    │   └── {resource}-manager.blade.php
    └── web/               # (View Namespace: {mod}::web)
        └── {resource}-page.blade.php

Implementation Guide

1. The Controller (Optional with Livewire)

Role: Accept request, fetch raw Domain Entity (if needed), return View Modal. Constraint: Must return an instance of a View Modal or render it via Livewire route binding.

// Example: InvoiceController.php
namespace Mod\Billing\Controllers\Web;

use Mod\Billing\View\Modal\InvoicePage;

class InvoiceController
{
    public function show(int $id)
    {
        // Delegate directly to the View Modal
        // Livewire handles the hydration
        return new InvoicePage($id);
    }
}

2. The View Modal (The "Flexy" Layer)

Role: Prepare data for display. Format currencies, dates, handle conditional UI logic, and manage state. Constraint: Public properties/methods correspond 1:1 with what the template needs.

// Example: InvoicePage.php
namespace Mod\Billing\View\Modal;

use Livewire\Component;
use Mod\Billing\Models\Invoice;

class InvoicePage extends Component
{
    public Invoice $invoice;

    public function mount(Invoice $invoice)
    {
        $this->invoice = $invoice;
    }

    // Logic lives HERE, not in the HTML.
    public function getInvoiceIdProperty(): string
    {
        return '#' . str_pad($this->invoice->id, 6, '0', STR_PAD_LEFT);
    }

    public function getFormattedTotalProperty(): string
    {
        return number_format($this->invoice->total / 100, 2);
    }

    public function getIsOverdueProperty(): bool
    {
        return $this->invoice->due_date->isPast() && !$this->invoice->paid;
    }

    public function render()
    {
        // Points to the dumb template in the module
        // Structure: app/Mod/Billing/View/Blade/invoice-page.blade.php
        return view('billing::invoice-page');
    }
}

3. The Template (The Dumb Layer)

Role: Layout and structure only. Constraint: No method calls with arguments. No @php blocks. No complex @if conditions (use boolean getters from the View Modal instead).

<!-- invoice-page.blade.php -->
<div class="invoice-container">
    <h1>Invoice {{ $this->invoiceId }}</h1>

    <div class="status">
        <!-- Logic is hidden behind the boolean getter -->
        @if($this->isOverdue)
            <span class="badge-danger">Overdue</span>
        @else
            <span class="badge-success">Active</span>
        @endif
    </div>

    <div class="amount">
        Total: ${{ $this->formattedTotal }}
    </div>
</div>

Enforcement Rules

  1. No Logic in Blade: Regex check for logic operators (&&, ||, >) inside {{ }} tags in .blade.php files.
  2. No Eloquent in Blade: The template should interact with the View Modal's getters/properties, not the raw Eloquent model relationships.
  3. Strict Typing: View Modals must strictly type their dependencies.