Getting Started with OATERS Development
Prerequisites
System Requirements
- PHP 8.1 or higher
- Node.js 16+ and npm
- Composer 2.0 or higher
- Git
- A local development environment (Laravel Valet, Docker, or similar)
Backend Setup
1. Clone and Install the Project
OATERS is available as a public repository on GitHub. Clone the repository and install dependencies:
# Clone the OATERS repository
git clone https://github.com/grey-dev-0/oaters.git my-oaters-project
# Navigate to the project directory
cd my-oaters-project
# Install PHP dependencies
composer installThis process will:
- Clone the OATERS repository from GitHub
- Install all PHP dependencies from
composer.json - Set up the Laravel module system
- Install required packages for multi-tenancy, permissions, localization, and more
2. Configure Environment
# Copy the example environment file
cp .env.example .env
# Generate application key
php artisan key:generateEdit .env and configure:
APP_NAME,APP_URL- Database credentials (
DB_HOST,DB_DATABASE,DB_USERNAME,DB_PASSWORD) - Mail settings (optional)
3. Set Up Database
OATERS uses a sophisticated multi-tenancy architecture with separate databases:
- Central Database: Houses the super admin tenant and Sapphire module
- Tenant Databases: Each tenant has an isolated database with their own data
3.1 Migrate Central Database
First, migrate the default Laravel migrations for the central database:
# Migrate the central database schema
php artisan migrateThis creates tables for the super admin tenant and system-wide entities.
3.2 Migrate and Seed Sapphire Module
The Sapphire module (authentication, tenants, users) must be migrated into the central database:
# Migrate the Sapphire module
php artisan module:migrate Sapphire3.3 Seed the Central Database
Seed the central application data, which automatically includes all Sapphire module data:
# Run the central app seeder (includes Sapphire module seeding)
php artisan db:seed --class=Database\Seeders\CentralAppSeeder3.4 Migrate Module into Tenant Database
All other modules (Ruby, Onyx, Amethyst, etc.) need to be migrated into each tenant's database.
For the second tenant (example tenant), use the multi-tenancy artisan command:
# Migrate all modules for the second tenant
php artisan tenants:artisan "module:migrate" --tenant=23.5 Seed Tenant Database
Seed all tenant-specific data using the TenantAppSeeder, which automatically handles seeding all necessary module data:
# Run the tenant app seeder for the second tenant (seeds all module data)
php artisan tenants:artisan "db:seed --class=Database\Seeders\TenantAppSeeder" --tenant=2Complete Database Setup Command Sequence
Here's the complete sequence to set up everything from scratch:
# 1. Migrate central database
php artisan migrate
# 2. Migrate Sapphire module (central)
php artisan module:migrate Sapphire
# 3. Seed central database (includes Sapphire module data)
php artisan db:seed --class=Database\Seeders\CentralAppSeeder
# 4. Migrate all modules for tenant #2
php artisan tenants:artisan "module:migrate" --tenant=2
# 5. Seed tenant #2 database (includes all module data)
php artisan tenants:artisan "db:seed --class=Database\Seeders\TenantAppSeeder" --tenant=2Understanding the Architecture
Central Database Structure:
- System configuration and super admin data
- Sapphire module tables (tenants, users, roles, permissions)
Tenant Database Structure:
- All module data specific to that tenant
- Shared entities (countries, colors, etc.)
- Other module tables as they're developed
Note: If you add additional tenants later, repeat steps 4-6 for each new tenant.
4. Start Laravel Development Server
# Start the PHP development server
php artisan serveThe application will be available at http://127.0.0.1:8000
Frontend Setup
Prerequisites
- Node.js 16+ and npm installed
- Backend server running (see Backend Setup above)
Installation
# Install frontend dependencies
npm install
# Start the development server with hot module replacement
npm run devKeep both servers running:
- Backend:
php artisan serve(port 8000) - Frontend:
npm run dev(port 5173 by default)
Development Workflow
1. Start Development Server
npm run devThis starts Vite with hot module replacement enabled.
2. Create a New Vue Component
File: resources/components/MyNewComponent.vue
<template>
<div class="my-component">
<h2>{{ title }}</h2>
<button @click="count++">Count: {{ count }}</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
defineProps({
title: String
})
const count = ref(0)
</script>
<style scoped>
.my-component {
padding: 1rem;
border: 1px solid #ccc;
}
</style>3. Register Component in Entry Point
File: resources/js/{moduleName}/{pageName}.js
Example: resources/js/ruby/employees.js
import { createApp } from 'vue'
import MyNewComponent from '@/components/MyNewComponent.vue'
const app = createApp({})
app.component('MyNewComponent', MyNewComponent)
app.mount('#app')
> **Note**: No changes to `vite.config.js` are needed. The glob pattern automatically discovers all files in `resources/js/*.js` and `resources/js/*/*.js` directories.4. Use in Blade Template
File: Modules/{ModuleName}/resources/views/{page}.blade.php
Example: Modules/Ruby/resources/views/employees/index.blade.php
@extends('layouts.app')
@section('content')
<div id="app">
<my-new-component title="Hello World" />
</div>
@endsection
@vite(['resources/js/ruby/employees.js'])Common Tasks
Add Props to Component
<script setup>
const props = defineProps({
title: {
type: String,
required: true
},
count: {
type: Number,
default: 0
},
items: Array
})
</script>Emit Events
<script setup>
const emit = defineEmits(['save', 'cancel'])
function handleSave() {
emit('save', formData)
}
</script>Use Slots
<template>
<div class="card">
<div class="card-header">
<slot name="header">Default Header</slot>
</div>
<div class="card-body">
<slot />
</div>
</div>
</template>API Calls in Composable
export function useData() {
const data = ref(null)
const loading = ref(false)
const error = ref(null)
const fetchData = async () => {
loading.value = true
try {
const response = await fetch('/api/data')
data.value = await response.json()
} catch (err) {
error.value = err.message
} finally {
loading.value = false
}
}
return { data, loading, error, fetchData }
}Form Handling
<script setup>
import { ref } from 'vue'
const formData = ref({
name: '',
email: ''
})
async function handleSubmit() {
const response = await fetch('/api/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
},
body: JSON.stringify(formData.value)
})
// Handle response
}
</script>
<template>
<form @submit.prevent="handleSubmit">
<input v-model="formData.name" placeholder="Name" />
<input v-model="formData.email" type="email" placeholder="Email" />
<button type="submit">Submit</button>
</form>
</template>Debugging
Vue DevTools
Install Vue DevTools browser extension to inspect components and state.
Browser Console
// Access app instance from console
const app = document.querySelector('#app').__vue__
// Inspect component data
app.$dataNetwork Tab
Monitor API calls and network performance in browser DevTools.
Production Build
npm run productionThis creates optimized, minified assets ready for deployment.
Troubleshooting
Components Not Rendering
- Check if component is registered in JavaScript entry point
- Verify
@vite()directive is in Blade template - Check browser console for errors
Hot Module Replacement Not Working
- Ensure
npm run devis running - Check Vite configuration
- Try restarting the dev server
Build Errors
- Run
npm run lintto check for syntax errors - Verify all imports are correct
- Check component props and events