# Nexus Backend — Claude Code Instructions

## Project
Multi-tenant B2B SaaS for Nigerian SMEs. Laravel 13, PHP 8.3,
PostgreSQL 16, Railway, Redis, Horizon, Cloudflare R2, Paystack.

## Architecture
Modular — see docs/nexus_modular_architecture.php
Every major concern is a self-contained module in app/Modules/


I wnat to build a 4 page webite. One landing page for a buiniess called NobleDev -- web design agency -- Our major clients are celebrities(not necessarily artists) and Rich People who look to control the narrative about themselves online.. So we are selling credibility, control and premium narrative for these sets of people. THe portfolios you can make example out of them like a very popular and rich person, add some mature animations and lal. Disrgard the gold and black color recommendation is from te file ignore it -- use the best colors you think will do. Use A premium web design agency for high-net-worth individuals and celebrities who need narrative control—that's a sophisticated positioning. . Like lets the texts be simple stratforward and conincing selling Pro to rich people,  premium aesthetics, sophisticated animations, and a color palette that screams exclusivity and control. Do a very good jobs that a rich man would immediate put his money beacuse of the value he would get.

## Non-negotiable rules
- Every response via ApiResponse (app/Http/Responses/ApiResponse.php)
- Every validation via FormRequest — never $request->validate() in controllers
- Every plan check via PlanLimits::enforce() — never hardcode plan logic
- Every audit event via AuditLogger::log() — never DB::table('audit_log') directly
- Every notification via NotificationRouter — never email/WhatsApp directly
- Every model that needs tracking gets TracksActivity trait
- Controllers are thin — logic in Action classes
- Never string-concatenate SQL — always parameterized queries
- Paystack amounts always in kobo (multiply Naira × 100)
- tenant() context always initialized in Jobs manually

## Module map
app/Modules/Auth/
app/Modules/Tenancy/
app/Modules/Ingestion/
app/Modules/Analytics/
app/Modules/Inventory/
app/Modules/Vendors/
app/Modules/Billing/
app/Modules/Notifications/
app/Modules/Team/
app/Modules/Activity/
app/Modules/Infrastructure/

## Migration folders
database/migrations/        → central tables only
database/tenant-migrations/ → per-tenant tables only

## Error codes the frontend expects
VALIDATION_FAILED, UNAUTHORIZED, FORBIDDEN, PLAN_LIMIT_EXCEEDED,
NOT_FOUND, RATE_LIMITED, SERVER_ERROR

## Currency
Nigerian Naira (NGN, ₦). Paystack receives kobo. Display uses formatNaira().

## Deployment
Migrations only during low-traffic windows (01:00–05:00 WAT on weekdays).
Run: php artisan tenants:migrate-parallel (never tenants:migrate)

## Docs
See docs/ folder for full architecture, security, and activity tracking specs.


1. app/Http/Responses/ApiResponse.php
What it does: Every single API response in the entire project goes through this class. Instead of every controller returning response()->json() differently, this gives us one consistent shape for every response — success, error, validation failure, plan limit exceeded etc.
Why it matters: The frontend developer knows exactly what shape to expect. No surprises. If something goes wrong, there's one place to fix the response format.


2. app/Exceptions/PlanLimitException.php
What it does: A custom exception that gets thrown whenever a tenant tries to do something their plan doesn't allow — like adding a 21st product on the Starter plan.
Why it matters: Instead of every controller having its own way of handling plan limits, this exception gets thrown once and caught automatically by Laravel's exception handler, which converts it to a clean PLAN_LIMIT_EXCEEDED response.


3. app/Services/PlanLimits.php
What it does: The single source of truth for every plan restriction. All four plans (Starter, Growth, Pro, Team) and all their limits live here. One class, one place.
Why it matters: If you want to change the Starter plan from 20 products to 30, you change it in one place — not scattered across 10 controllers.


4. app/Services/AuditLogger.php
What it does: Records important business events — login, plan upgrade, team member invited, payment received etc. These are intentional business actions, not every database change.
Why it matters: If a customer disputes a charge or a team member says "I never did that", you have a clean log of who did what and when.


5. app/Traits/TracksActivity.php
What it does: Add use TracksActivity; to any model and it automatically records every create, update, delete, and restore — with the before and after values.
Why it matters: This is different from AuditLogger. AuditLogger tracks business events. TracksActivity tracks database changes. If a staff member changes a transaction from ₦5,000 to ₦500, you see exactly what changed, when, and who did it.


6. app/Casts/EncryptedValue.php
What it does: A Laravel cast that automatically encrypts a value before saving to the database and decrypts it when reading. Used on sensitive fields like Paystack authorization codes.



Emails we need to build
1. Welcome email          → after signup/onboarding
2. Email verification     → verify your email
3. Payment receipt        → after successful payment
4. Payment failed         → first failed charge
5. Account paused         → after dunning exhausted
6. Low wallet warning     → wallet balance getting low
7. Low stock alert        → product below reorder threshold
8. Daily summary          → business metrics digest
9. Team invite            → invited to join a business
10. Password reset        → reset your password