v2

slug: / sidebar_position: 1

Loreax Engineering Documentation

Latest: v1.0 (MVP)
Status: In Development
Last Updated: April 2026

Loreax is a creator-economy platform built on Laravel 12, designed for trust, correctness, and real money. These wikis document the implemented behaviour of each domain — what is live, what the contracts are, and how the pieces connect.

All financial operations flow through a single double-entry ledger. All API responses follow a consistent envelope. All access decisions are enforced server-side.


📚 Quick Navigation

Getting Started

Deployment & Operations

  • Deployment Guide — Laravel Cloud, self-hosted, CI/CD pipeline, scaling, rollback

Platform Architecture

Financial System

Feature Areas

Reference & Integrations


🏗️ Platform Overview

What is Loreax?

Loreax is a creator monetization platform (MPESA-first for Kenya) where:

  • Creators publish exclusive content (text, images, video, audio, livestreams, polls)
  • Fans access content through 3 models: subscriptions, one-off purchases, free engagement-based access
  • Platform handles all money through a double-entry ledger for perfect financial integrity

Tech Stack:

Frontend          Backend            Database           Cache & Jobs
─────────────     ──────────────     ────────────       ─────────────
React/Vue  ────→  Laravel 12 ───────→ PostgreSQL  ─→    Redis 7
           ←──    PHP 8.4      ├──→ MongoDB (logs)      Horizon
           (API)                └──→ AWS S3 (media)

Core Principles

  1. Single Ledger of Truth — All money moves via ILedgerService::post(), ledger must always sum to zero
  2. Type-Safe Codedeclare(strict_types=1), Larastan level 8, strict types everywhere
  3. Action Pattern — All business logic in Actions (run() methods), controllers are thin I/O adapters
  4. Immutable Financial Records — Ledger entries are write-once, audit-logged forever
  5. Server-Side Authorization — All access decisions enforced server-side, no client-side trust
  6. Consistent APIs — Response shapes derived from HTTP status, no success flags

📋 Domain References

Core Infrastructure

  • Core Domain — Request correlation, authorization scopes, response envelopes, error handling, infrastructure services

User & Identity Management

  • Identity Domain — Registration, email verification, OAuth (Google/Facebook/Apple), MFA (TOTP), admin realm, password resets

Financial System

  • Ledger Domain — Double-entry accounting, wallet projections, account hierarchies, settlement workflows
  • Payments Domain — MPESA integration (C2B top-ups, B2C withdrawals), withdrawal requests, settlement batches

Content & Access

  • Content Domain — Posts (text/image/video/audio/livestream/poll), media processing, drafts, publishing
  • Access Domain — Access rules, post purchases, subscriptions, tier management, visibility enforcement

Discovery & Social

  • Discovery Domain — Home timeline ranking, explore feeds, search, creator browse, signal refresh
  • Social Domain — Follows, likes, saves, shares, interactions, blocking, muting

Creator Features

  • Monetization Domain — Creator tiers, subscription verification, payout calculations, earnings forecasting
  • FanClub Domain — Creator community spaces, member management, exclusive engagement

Platform Operations


🔑 Key Concepts

The Ledger

Every shilling on Loreax is accounted for in a double-entry ledger:

Payment Flow:
  Fan wallet (cash)   -100 KES
      ↓
  Creator holdings    +80 KES   (creator's 3-day hold)
  Platform revenue    +20 KES   (15% fee)

Invariant: Every transaction's entries must sum to exactly zero.

Access Rules

Content visibility is controlled by:

  • Public — Anyone can see
  • Tier-Gated — Only tier subscribers
  • Purchase-Gated — Only one-off buyers
  • Exclusive — Only active fans (high engagement)

All checks happen server-side in IAccessService::canView().

Authorization Scopes

Admin operations are gated by scope + dual-approval for sensitive changes:

Scope::PostReadWrite           — Edit posts
Scope::UserManagement         — Create/edit users
Scope::PlatformSettings       — Change platform config
Scope::WithdrawalApproval     — Approve payouts

Scopes are defined in App\Core\Authorization\Scope enum.

API Response Shapes

Three shapes, derived from HTTP status:

2xx Success (Shape A):

{
  "message": "Created",
  "data": { "id": "01HQ...", ... },
  "meta": {
    "requestId": "01HQ0PZFGJEJHJV5...",
    "traceId": "0af7651916cd43dd8448eb211c80319c",
    "timestamp": "2026-04-25T10:30:00Z"
  }
}

422 Validation (Shape B):

{
  "message": "Invalid input",
  "errors": {
    "email": ["The email field is required."],
    "amount": ["Must be a positive integer."]
  },
  "meta": { ... }
}

430 Business Error (Shape C):

{
  "errorCode": "INSUFFICIENT_FUNDS",
  "message": "Wallet balance is lower than requested.",
  "meta": { ... }
}

🧪 Testing Standards

Test Organization

tests/
  ├── Unit/              # Pure logic, no DB/HTTP
  ├── Feature/           # Full HTTP flow + DB
  ├── Contract/          # Interface compliance
  └── Invariant/         # Ledger/financial checks

Naming Convention

All test methods use #[Test] attribute with PascalCase or Subject_Condition:

#[Test]
public function LoginSuccess(): void {}

#[Test]
public function LoginWithInvalidPassword_ReturnsUnauthenticated(): void {}

#[Test]
public function Login_WhenRateLimited_Returns429(): void {}

Coverage

Requirement: ≥80% line coverage for modified domains.

./vendor/bin/phpunit --coverage-text

🛠️ Development Workflow

1. Check Assignment

Reference IMPLEMENTATION_PLAN.md for your assigned chunks.

2. Create Feature Branch

git checkout -b feat/domain-feature-name

3. Implement (Follow Conventions)

  • declare(strict_types=1) on every file
  • Classes are final by default
  • Interfaces are I-prefixed
  • Business logic lives in Actions
  • Controllers are thin I/O adapters
  • Ledger operations use ILedgerService::post()

See AGENTS.md and CLAUDE.md for detailed patterns.

4. Test & Validate

./vendor/bin/phpunit              # Run all tests
./vendor/bin/pint                 # Fix style
./vendor/bin/phpstan analyse      # Level 8 compliance
php artisan l5-swagger:generate   # Update API docs

5. Commit & Push

git commit -m "feat: domain: describe change"
git push origin feat/domain-feature-name

6. Open PR

Request at least one peer review. CI must pass before merge.

7. Deploy

Auto-deploys to staging on merge to master. Production deploys manually via Ansible.


📖 Code References

Key Files to Read First

  1. AGENTS.md — Non-negotiable implementation rules for AI code generation
  2. CLAUDE.md — Guide for developers using AI assistants
  3. loreax-technical-design.md — 5000+ line canonical specification
  4. loreax-ai-agent-brief.md — Quick reference for AI agents

Example Implementations

Reference these to learn patterns:

  • Action Pattern: app/Identity/Actions/RegisterUserAction.php
  • Service Pattern: app/Core/Services/PlatformSettingsService.php
  • Exception Pattern: app/Core/Exceptions/DomainException.php + domain exceptions
  • Controller Pattern: app/Identity/Http/Controllers/RegisterUserController.php
  • Test Pattern: tests/Feature/Identity/LoginTest.php

🚀 Quick Start for New Developers

  1. Install: Follow Installation & Setup
  2. Configure: Read Configuration Guide
  3. Understand Structure: Review File Structure & DDD
  4. Understand Domains: Skim Domains Overview
  5. Onboard: Follow Developer Onboarding
  6. Pick a Chunk: Check IMPLEMENTATION_PLAN.md for unfinished work
  7. Implement: Follow patterns in AGENTS.md
  8. Test: Run ./vendor/bin/phpunit to validate
  9. Submit: Open a PR for code review

📊 Key Invariants

Rule Where enforced
Money moves only via ILedgerService::post() LedgerService
Every ledger transaction must sum to zero LedgerInvariantTest
All monetary values are integers (smallest unit) Platform-wide
Access rules are enforced server-side only IAccessService
All test methods use #[Test] with approved naming CI/Code Review

🔗 Related Documentation


❓ FAQ

Q: Where do I find the API documentation?
A: Live at http://localhost:8000/docs/api (Swagger) or in loreax-technical-design.md

Q: How do I add a new field to a model?
A: Create a migration, add the field to the model, test it, update the DTO/FormRequest, update the controller, write tests. See a domain README for examples.

Q: Can I write business logic in a controller?
A: No. All business logic goes in Actions. Controllers are thin I/O adapters only.

Q: Can I modify wallet.balance directly?
A: No. All money moves via ILedgerService::post(). Direct writes will fail ledger invariant tests.

Q: How do I add a new scope for authorization?
A: Add a case to App\Core\Authorization\Scope enum. Use Scope::YourNewScope everywhere, never raw strings.

Q: What if my test uses a test* prefix or BDD-style name?
A: It will be rejected in code review. Use #[Test] with PascalCase or Subject_Condition pattern.


📞 Support


Last Updated: April 25, 2026
Maintained By: Loreax Engineering Team