This is a complete full-stack real-estate application built with Laravel (REST API), React (Frontend), and MySQL/SQLite (Database).
Realstate/
├── backend/ # Laravel API server
│ ├── app/
│ │ ├── Http/
│ │ │ ├── Controllers/Api/
│ │ │ ├── Requests/
│ │ │ └── Resources/
│ │ └── Models/
│ ├── database/
│ │ └── migrations/
│ ├── routes/
│ │ └── api.php
│ ├── .env # DO NOT COMMIT - copy from .env.example
│ └── storage/
├── frontend/ # React + Vite application
│ ├── src/
│ │ ├── pages/ # Page components
│ │ ├── components/ # Reusable components
│ │ ├── services/ # API service layer
│ │ └── context/ # Auth context
│ └── package.json
├── SECURITY.md # Security requirements (READ FIRST)
└── README.md
- PHP 8.2+ (XAMPP includes this)
- Composer (install globally or use
php composer.phar) - Node.js 16+ and npm
- MySQL 5.7+ or SQLite (default for development)
cd backend
# Install dependencies (already done in scaffold)
php composer.phar install
# Configure environment
cp .env.example .env
php artisan key:generate
# Run migrations
php artisan migrate --force
# Serve API on Windows/XAMPP
serve.bat
# or manually:
php -S 127.0.0.1:8001 -t publicOn Windows,
php artisan servecan fail in some XAMPP/PHP setups. The direct PHP server command above is the reliable fallback.
To test the API, create a user via Laravel Tinker:
php artisan tinkerThen run:
use App\Models\User;
use Illuminate\Support\Facades\Hash;
$user = User::create([
'user_id' => 'TEST001',
'name' => 'Test User',
'pin' => Hash::make('1234'),
'account_level' => 'standard',
'balance' => 10000.00,
]);cd frontend
# Install dependencies (already done in scaffold)
npm install
# Start development server (runs on http://localhost:5173)
npm run dev
# Build for production
npm run build- User ID:
TEST001 - PIN:
1234
If you want to use MySQL instead of SQLite:
-
Create a database:
CREATE DATABASE realstate_beha;
-
Update
.env:DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=realstate_beha DB_USERNAME=root DB_PASSWORD= -
Run migrations:
php artisan migrate --force
This project implements security standards per SECURITY.md:
✅ Authentication: Laravel Sanctum for secure API tokens
✅ Authorization: Protected routes with middleware
✅ Input Validation: Form Requests for all endpoints
✅ Password Security: Bcrypt hashing for PINs
✅ CSRF Protection: Built into Laravel (cookies mode)
✅ Session Security: HTTP-only, Secure, SameSite cookies
✅ Error Handling: Generic user-facing messages
✅ Parameterized Queries: ORM prevents SQL injection
- Set
APP_DEBUG=falsein.envproduction - Set
APP_ENV=production - Update
SESSION_DRIVERtodatabase(already set) - Regenerate
APP_KEY - Enable HTTPS in production
- Set secure cookie flags for HTTPS
- Configure rate limiting on auth endpoints
- Audit all dependencies:
composer audit,npm audit - Review logs for security events
POST /api/login→ Login with user_id and pinPOST /api/logout→ Logout (requires auth token)
GET /api/user/profile→ Get current user profilePOST /api/user/upgrade-level→ Upgrade account levelPOST /api/user/add-member→ Register a new member under current user
GET /api/properties→ List all properties (with filters)GET /api/properties/{id}→ Get property details
POST /api/cash-out→ Submit cash-out request
GET /api/updates→ Get announcements and updates
- LoginPage → Login form with language toggle (EN/Amharic)
- DashboardPage → Home screen with updates feed
- PropertySearchPage → Property listing with advanced filters
- ProfilePage → User profile and account details
- CashOutPage → Mobile banking withdrawal form
- AddMemberPage → Register new members
- UpgradeLevelPage → Upgrade account level
- Header → User info and dropdown menu
- Sidebar → Navigation menu
Create a .env file in the backend directory (copy from .env.example):
APP_NAME=Beha
APP_ENV=local
APP_DEBUG=true
APP_KEY=base64:...
APP_URL=http://localhost:8000
DB_CONNECTION=sqlite
# For MySQL:
# DB_CONNECTION=mysql
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=realstate_beha
# DB_USERNAME=root
# DB_PASSWORD=
SANCTUM_STATEFUL_DOMAINS=localhost,127.0.0.1,localhost:5173
SANCTUM_GUARD=sanctumFor React, update API_BASE_URL in frontend/src/services/api.js if backend runs on a different port.
SQLSTATE[HY000] [1049] Unknown database 'realstate_beha'
→ Create the database: CREATE DATABASE realstate_beha;
Access to XMLHttpRequest blocked by CORS policy
→ Add your frontend URL to SANCTUM_STATEFUL_DOMAINS in .env
Failed to connect to http://localhost:8000/api/...
→ Verify backend is running (php artisan serve)
→ Check API_BASE_URL in src/services/api.js
npm install react-router-dom axios
- Secure Login with PIN-based authentication
- User Dashboard with updates feed
- Property Listings with advanced search filters
- User Profiles with balance and account level tracking
- Cash-Out Requests for mobile banking withdrawals
- Member Referral System to track network growth
- Account Level Upgrades for tier-based access
- Bilingual Support (English & Amharic)
- RESTful API following Laravel best practices
- Token-Based Auth using Laravel Sanctum
- SQLite database (file-based, no setup needed)
- Debug mode enabled
- CORS allows localhost
- MySQL database with proper credentials
- Debug mode disabled
- HTTPS enforced
- Rate limiting enabled
- Secure cookie flags set
-
Server Setup
git clone <repo> cd backend composer install --no-dev php artisan config:cache php artisan route:cache php artisan view:cache
-
Environment
cp .env.example .env # Edit .env with production values php artisan key:generate -
Database
php artisan migrate --force php artisan db:seed # Optional: seed data -
Frontend Build
cd ../frontend npm install npm run build # Deploy dist/ to web server
-
Web Server (Nginx example)
server { listen 80; server_name your-domain.com; root /var/www/realstate/public; index index.php; location ~ \.php$ { fastcgi_pass unix:/var/run/php-fpm.sock; fastcgi_index index.php; include fastcgi_params; } location / { try_files $uri $uri/ /index.php?$query_string; } }
Last Updated: 2026-07-09
Version: 1.0.0-alpha