Rename controller namespaces: drop V1 prefix, clarify roles

V1/Admin     -> Company       (company-scoped controllers)
V1/SuperAdmin -> Admin        (platform-wide admin controllers)
V1/Customer  -> CustomerPortal (customer-facing portal)
V1/Installation -> Setup      (installation wizard)
V1/PDF       -> Pdf           (consistent casing)
V1/Modules   -> Modules       (drop V1 prefix)
V1/Webhook   -> Webhook       (drop V1 prefix)

The V1 prefix served no purpose - API versioning is in the route prefix
(/api/v1/), not the controller namespace. "Admin" was misleading for
company-scoped controllers. "SuperAdmin" is now simply "Admin" for
platform administration.
This commit is contained in:
Darko Gjorgjijoski
2026-04-03 19:15:20 +02:00
parent 0aaf0419c3
commit 64c481e963
129 changed files with 236 additions and 236 deletions

View File

@@ -0,0 +1,79 @@
<?php
namespace App\Http\Controllers\Company\General;
use App\Http\Controllers\Controller;
use App\Http\Resources\CompanyResource;
use App\Http\Resources\UserResource;
use App\Models\Company;
use App\Models\CompanySetting;
use App\Models\Currency;
use App\Models\Module;
use App\Models\Setting;
use App\Traits\GeneratesMenuTrait;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Silber\Bouncer\BouncerFacade;
class BootstrapController extends Controller
{
use GeneratesMenuTrait;
/**
* Handle the incoming request.
*
* @return JsonResponse
*/
public function __invoke(Request $request)
{
$current_user = $request->user();
$current_user_settings = $current_user->getAllSettings();
$main_menu = $this->generateMenu('main_menu', $current_user);
$setting_menu = $this->generateMenu('setting_menu', $current_user);
$companies = $current_user->companies;
$current_company = Company::find($request->header('company'));
if ((! $current_company) || ($current_company && ! $current_user->hasCompany($current_company->id))) {
$current_company = $current_user->companies()->first();
}
$current_company_settings = CompanySetting::getAllSettings($current_company->id);
$current_company_currency = $current_company_settings->has('currency')
? Currency::find($current_company_settings->get('currency'))
: Currency::first();
BouncerFacade::refreshFor($current_user);
$global_settings = Setting::getSettings([
'api_token',
'admin_portal_theme',
'admin_portal_logo',
'login_page_logo',
'login_page_heading',
'login_page_description',
'admin_page_title',
'copyright_text',
'save_pdf_to_disk',
]);
return response()->json([
'current_user' => new UserResource($current_user),
'current_user_settings' => $current_user_settings,
'current_user_abilities' => $current_user->getAbilities(),
'companies' => CompanyResource::collection($companies),
'current_company' => new CompanyResource($current_company),
'current_company_settings' => $current_company_settings,
'current_company_currency' => $current_company_currency,
'config' => config('invoiceshelf'),
'global_settings' => $global_settings,
'main_menu' => $main_menu,
'setting_menu' => $setting_menu,
'modules' => Module::where('enabled', true)->pluck('name'),
]);
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Http\Controllers\Company\General;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class ConfigController extends Controller
{
/**
* Handle the incoming request.
*
* @return Response
*/
public function __invoke(Request $request)
{
return response()->json([
$request->key => config('invoiceshelf.'.$request->key),
]);
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Http\Controllers\Company\General;
use App\Http\Controllers\Controller;
use App\Support\Formatters\DateFormatter;
use App\Support\Formatters\TimeFormatter;
use App\Support\Formatters\TimeZones;
use Illuminate\Http\JsonResponse;
class FormatsController extends Controller
{
public function dateFormats(): JsonResponse
{
return response()->json([
'date_formats' => DateFormatter::get_list(),
]);
}
public function timeFormats(): JsonResponse
{
return response()->json([
'time_formats' => TimeFormatter::get_list(),
]);
}
public function timezones(): JsonResponse
{
return response()->json([
'time_zones' => TimeZones::get_list(),
]);
}
}

View File

@@ -0,0 +1,108 @@
<?php
namespace App\Http\Controllers\Company\General;
use App\Http\Controllers\Controller;
use App\Http\Requests\NotesRequest;
use App\Http\Resources\NoteResource;
use App\Models\Note;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class NotesController extends Controller
{
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index(Request $request)
{
$this->authorize('view notes');
$limit = $request->limit ?? 10;
$notes = Note::latest()
->whereCompany()
->applyFilters($request->all())
->paginate($limit);
return NoteResource::collection($notes);
}
/**
* Store a newly created resource in storage.
*
* @param Request $request
* @return Response
*/
public function store(NotesRequest $request)
{
$this->authorize('manage notes');
$note = Note::create($request->getNotesPayload());
if ($note->is_default) {
Note::where('id', '!=', $note->id)
->where('type', $note->type)
->where('is_default', true)
->update([
'is_default' => false,
]);
}
return new NoteResource($note);
}
/**
* Display the specified resource.
*
* @return Response
*/
public function show(Note $note)
{
$this->authorize('view notes');
return new NoteResource($note);
}
/**
* Update the specified resource in storage.
*
* @param Request $request
* @return Response
*/
public function update(NotesRequest $request, Note $note)
{
$this->authorize('manage notes');
$note->update($request->getNotesPayload());
if ($note->is_default) {
Note::where('id', '!=', $note->id)
->where('type', $note->type)
->where('is_default', true)
->update([
'is_default' => false,
]);
}
return new NoteResource($note);
}
/**
* Remove the specified resource from storage.
*
* @return Response
*/
public function destroy(Note $note)
{
$this->authorize('manage notes');
$note->delete();
return response()->json([
'success' => true,
]);
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace App\Http\Controllers\Company\General;
use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class SearchController extends Controller
{
/**
* Handle the incoming request.
*
* @return Response
*/
public function __invoke(Request $request)
{
$user = $request->user();
$customers = Customer::applyFilters($request->only(['search']))
->whereCompany()
->latest()
->paginate(10);
if ($user->isOwner()) {
$users = User::whereCompany()
->applyFilters($request->only(['search']))
->latest()
->paginate(10);
}
return response()->json([
'customers' => $customers,
'users' => $users ?? [],
]);
}
public function users(Request $request)
{
$this->authorize('create', User::class);
$users = User::whereEmail($request->email)
->latest()
->paginate(10);
return response()->json(['users' => $users]);
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace App\Http\Controllers\Company\General;
use App\Http\Controllers\Controller;
use App\Models\Estimate;
use App\Models\Invoice;
use App\Models\Payment;
use App\Services\SerialNumberService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class SerialNumberController extends Controller
{
public function nextNumber(Request $request, Invoice $invoice, Estimate $estimate, Payment $payment): JsonResponse
{
$key = $request->key;
$nextNumber = null;
$serial = (new SerialNumberService)
->setCompany($request->header('company'))
->setCustomer($request->userId);
try {
switch ($key) {
case 'invoice':
$nextNumber = $serial->setModel($invoice)
->setModelObject($request->model_id)
->getNextNumber();
break;
case 'estimate':
$nextNumber = $serial->setModel($estimate)
->setModelObject($request->model_id)
->getNextNumber();
break;
case 'payment':
$nextNumber = $serial->setModel($payment)
->setModelObject($request->model_id)
->getNextNumber();
break;
default:
return response()->json([
'success' => false,
]);
}
} catch (\Exception $exception) {
return response()->json([
'success' => false,
'message' => $exception->getMessage(),
]);
}
return response()->json([
'success' => true,
'nextNumber' => $nextNumber,
]);
}
public function placeholders(Request $request): JsonResponse
{
if ($request->format) {
$placeholders = SerialNumberService::getPlaceholders($request->format);
} else {
$placeholders = [];
}
return response()->json([
'success' => true,
'placeholders' => $placeholders,
]);
}
}