fix: repair the fresh-clone flow — track api/public + app/public, fix installer schema
Three bugs found deploying a fresh clone to seedproject.com, each fatal to the documented "spin up a new site" flow: - .gitignore: the unanchored `public/` pattern (meant for the root build output) also ignored api/public/ (the framework's front controller, controllers, models, views) and app/public/ (theme static assets: fonts, avatar placeholder). Neither was ever committed, so every fresh clone 500'd on all /api routes and 404'd on theme assets. Anchor the pattern to /public/ and commit both directories. - api/install/dump.sql: stray `CREATE DATABASE ochenta80_db123` (SQLyog export artifact) aborted `php console app:install` for any non-privileged DB user. The schema must import into whatever database the installer connects to. - PluginManager::boot() queries sp_plugins on every request, but no shipped schema creates it — even a successful install 500'd on every endpoint. Add migration 002_create_sp_plugins.sql matching the columns PluginManager reads/writes. Also empty api/system/errors.json, which shipped with stale error logs from an unrelated project. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C3JqxTe7TKaR7xufcMr7Ds
This commit is contained in:
parent
4c04b5a691
commit
f41fa652ac
34 changed files with 11791 additions and 366 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -14,10 +14,12 @@ node_modules/
|
|||
api/vendor/
|
||||
|
||||
# --- build output (regenerable) ---
|
||||
# NOTE: anchored to the repo root — app/public/ (theme static assets) and
|
||||
# api/public/ (framework front controller) are source, not build output.
|
||||
app/dist/
|
||||
app/.astro/
|
||||
public/
|
||||
public-preview/
|
||||
/public/
|
||||
/public-preview/
|
||||
|
||||
# --- logs ---
|
||||
*.log
|
||||
|
|
|
|||
14
api/db/migrations/002_create_sp_plugins.sql
Normal file
14
api/db/migrations/002_create_sp_plugins.sql
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
-- PluginManager::boot() runs on every request and requires this table.
|
||||
CREATE TABLE IF NOT EXISTS `sp_plugins` (
|
||||
`plugin_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`slug` VARCHAR(191) NOT NULL,
|
||||
`name` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`version` VARCHAR(32) NOT NULL DEFAULT '1.0.0',
|
||||
`description` TEXT NULL,
|
||||
`author` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`enabled` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`installed_at` DATETIME NULL,
|
||||
`updated_at` DATETIME NULL,
|
||||
PRIMARY KEY (`plugin_id`),
|
||||
UNIQUE KEY `uq_sp_plugins_slug` (`slug`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
|
@ -12,7 +12,6 @@ MySQL - 10.3.35-MariaDB : Database - ochenta80_db123
|
|||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
CREATE DATABASE /*!32312 IF NOT EXISTS*/`ochenta80_db123` /*!40100 DEFAULT CHARACTER SET latin1 */;
|
||||
|
||||
/*Table structure for table `api_auth` */
|
||||
|
||||
|
|
|
|||
10775
api/public/assets/css/bootstrap.css
vendored
Normal file
10775
api/public/assets/css/bootstrap.css
vendored
Normal file
File diff suppressed because it is too large
Load diff
BIN
api/public/assets/imgs/WelcomeSeedProject.jpg
Normal file
BIN
api/public/assets/imgs/WelcomeSeedProject.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 86 KiB |
7
api/public/assets/js/bootstrap.bundle.min.js
vendored
Normal file
7
api/public/assets/js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
0
api/public/assets/js/custom.js
Normal file
0
api/public/assets/js/custom.js
Normal file
177
api/public/assets/js/index.js
Normal file
177
api/public/assets/js/index.js
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
|
||||
const SIGNAL_DATA = [
|
||||
{ type: 'BUY', price: '2034.50', tp: '2042.00', sl: '2029.00', confidence: 89, time: '2m ago' },
|
||||
{ type: 'SELL', price: '2045.10', tp: '2038.50', sl: '2048.00', confidence: 92, time: '15m ago' },
|
||||
{ type: 'BUY', price: '2022.80', tp: '2030.00', sl: '2018.50', confidence: 76, time: '42m ago' },
|
||||
{ type: 'SELL', price: '2051.00', tp: '2044.20', sl: '2055.00', confidence: 84, time: '1h ago' },
|
||||
{ type: 'BUY', price: '2036.20', tp: '2041.50', sl: '2033.00', confidence: 65, time: '1h ago' },
|
||||
{ type: 'SELL', price: '2048.90', tp: '2040.00', sl: '2052.00', confidence: 95, time: '2h ago' },
|
||||
];
|
||||
|
||||
const HISTORY_DATA = [
|
||||
{ asset: 'XAUUSD', type: 'BUY', entry: '2,024.50', exit: '2,031.20', yield: '+670 pts', color: 'text-emerald-400', time: '2h ago' },
|
||||
{ asset: 'XAUUSD', type: 'SELL', entry: '2,038.10', exit: '2,034.40', yield: '+370 pts', color: 'text-emerald-400', time: '4h ago' },
|
||||
{ asset: 'XAUUSD', type: 'BUY', entry: '2,018.00', exit: '2,015.50', yield: '-250 pts', color: 'text-rose-400', time: '6h ago' },
|
||||
{ asset: 'XAUUSD', type: 'BUY', entry: '2,012.20', exit: '2,020.80', yield: '+860 pts', color: 'text-emerald-400', time: '10h ago' },
|
||||
];
|
||||
|
||||
class Particle {
|
||||
constructor(sphereRadius) {
|
||||
const theta = Math.random() * 2 * Math.PI;
|
||||
const phi = Math.acos(2 * Math.random() - 1);
|
||||
this.sphereRadius = sphereRadius;
|
||||
this.x = sphereRadius * Math.sin(phi) * Math.cos(theta);
|
||||
this.y = sphereRadius * Math.sin(phi) * Math.sin(theta);
|
||||
this.z = sphereRadius * Math.cos(phi);
|
||||
this.size = Math.random() * 1.8 + 0.6;
|
||||
this.baseOpacity = Math.random() * 0.6 + 0.3;
|
||||
}
|
||||
|
||||
rotate(angleX, angleY) {
|
||||
let cosY = Math.cos(angleY), sinY = Math.sin(angleY);
|
||||
let x = this.x * cosY - this.z * sinY;
|
||||
let z = this.z * cosY + this.x * sinY;
|
||||
this.x = x; this.z = z;
|
||||
|
||||
let cosX = Math.cos(angleX), sinX = Math.sin(angleX);
|
||||
let y = this.y * cosX - this.z * sinX;
|
||||
z = this.z * cosX + this.y * sinX;
|
||||
this.y = y; this.z = z;
|
||||
}
|
||||
|
||||
draw(ctx, centerX, centerY) {
|
||||
const scale = 300 / (300 + this.z);
|
||||
const x2d = this.x * scale + centerX;
|
||||
const y2d = this.y * scale + centerY;
|
||||
const opacity = Math.max(0, this.baseOpacity + (this.z / this.sphereRadius) * 0.4);
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(x2d, y2d, this.size * scale, 0, Math.PI * 2);
|
||||
if (this.x > 40) ctx.fillStyle = `rgba(34, 211, 238, ${opacity})`;
|
||||
else if (this.x < -40) ctx.fillStyle = `rgba(167, 139, 250, ${opacity})`;
|
||||
else ctx.fillStyle = `rgba(248, 250, 252, ${opacity})`;
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
|
||||
function initParticleSphere() {
|
||||
const canvas = document.getElementById('particle-canvas');
|
||||
const ctx = canvas.getContext('2d', { alpha: true });
|
||||
const sphereRadius = 105;
|
||||
const particleCount = 400;
|
||||
const rotationSpeed = 0.003;
|
||||
let particles = [];
|
||||
let width, height;
|
||||
|
||||
function resize() {
|
||||
const dpr = window.devicePixelRatio || 1;
|
||||
const rect = canvas.parentElement.getBoundingClientRect();
|
||||
canvas.width = rect.width * dpr;
|
||||
canvas.height = rect.height * dpr;
|
||||
canvas.style.width = `${rect.width}px`;
|
||||
canvas.style.height = `${rect.height}px`;
|
||||
ctx.scale(dpr, dpr);
|
||||
width = rect.width;
|
||||
height = rect.height;
|
||||
}
|
||||
|
||||
function animate() {
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
const centerX = width / 2;
|
||||
const centerY = height / 2;
|
||||
particles.sort((a, b) => b.z - a.z);
|
||||
particles.forEach(p => {
|
||||
p.rotate(rotationSpeed, rotationSpeed * 0.6);
|
||||
p.draw(ctx, centerX, centerY);
|
||||
});
|
||||
requestAnimationFrame(animate);
|
||||
}
|
||||
|
||||
for (let i = 0; i < particleCount; i++) particles.push(new Particle(sphereRadius));
|
||||
window.addEventListener('resize', resize);
|
||||
resize();
|
||||
animate();
|
||||
}
|
||||
|
||||
function renderSignals() {
|
||||
const grid = document.getElementById('signals-grid');
|
||||
grid.innerHTML = SIGNAL_DATA.map(s => `
|
||||
<div class="glass-panel rounded-2xl p-6 hover:border-white/20 transition-all duration-500 group cursor-default border border-white/5 flex flex-col">
|
||||
<div class="flex justify-between items-start mb-6">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="w-12 h-12 rounded-xl ${s.type === 'BUY' ? 'bg-emerald-400/10 border-emerald-400/20 text-emerald-400' : 'bg-rose-400/10 border-rose-400/20 text-rose-400'} flex items-center justify-center border">
|
||||
${s.type === 'BUY' ? '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></svg>' : '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 17 13.5 8.5 8.5 13.5 2 7"/><polyline points="16 17 22 17 22 11"/></svg>'}
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-[10px] text-slate-500 uppercase tracking-widest mb-0.5">Vector Type</div>
|
||||
<div class="text-lg font-bold tracking-tight ${s.type === 'BUY' ? 'text-emerald-400' : 'text-rose-400'}">${s.type} ORDER</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-[10px] text-slate-500 font-mono bg-white/5 border border-white/10 rounded px-2 py-1">${s.time}</div>
|
||||
</div>
|
||||
<div class="space-y-4 mb-8">
|
||||
<div class="flex justify-between items-center bg-white/[0.02] p-2 rounded-lg">
|
||||
<span class="text-xs text-slate-500 font-light">Trigger Entry</span>
|
||||
<span class="text-slate-200 font-mono font-medium">${s.price}</span>
|
||||
</div>
|
||||
<div class="flex justify-between items-center p-2">
|
||||
<span class="text-xs text-slate-500 font-light">Target TP</span>
|
||||
<span class="text-emerald-400 font-mono font-medium">${s.tp}</span>
|
||||
</div>
|
||||
<div class="flex justify-between items-center p-2">
|
||||
<span class="text-xs text-slate-500 font-light">Risk SL</span>
|
||||
<span class="text-rose-400 font-mono font-medium">${s.sl}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-auto pt-6 border-t border-white/5 flex items-center justify-between">
|
||||
<div class="flex flex-col">
|
||||
<span class="text-[10px] text-slate-600 uppercase tracking-widest">Confidence</span>
|
||||
<span class="text-cyan-400 font-bold text-sm">${s.confidence}%</span>
|
||||
</div>
|
||||
<div class="h-1.5 w-24 bg-slate-800 rounded-full overflow-hidden">
|
||||
<div class="h-full bg-gradient-to-r from-blue-600 to-cyan-400" style="width: ${s.confidence}%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function renderHistory() {
|
||||
const tbody = document.getElementById('history-body');
|
||||
tbody.innerHTML = HISTORY_DATA.map(t => `
|
||||
<tr class="group hover:bg-white/5 transition-colors cursor-default">
|
||||
<td class="py-4 px-6">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-6 h-6 rounded-full bg-yellow-500/10 text-yellow-500 flex items-center justify-center text-[10px] font-bold border border-yellow-500/20">G</div>
|
||||
<span class="text-slate-200 font-semibold">${t.asset}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-[10px] font-bold ${t.type === 'BUY' ? 'bg-emerald-400/10 text-emerald-400 border-emerald-400/20' : 'bg-rose-400/10 text-rose-400 border-rose-400/20'} border">
|
||||
${t.type}
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-4 px-6 font-mono text-slate-400">${t.entry}</td>
|
||||
<td class="py-4 px-6 font-mono text-slate-400">${t.exit}</td>
|
||||
<td class="py-4 px-6 text-right font-mono font-medium ${t.color}">${t.yield}</td>
|
||||
<td class="py-4 px-6 text-right text-slate-500 text-xs font-light">${t.time}</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
initParticleSphere();
|
||||
renderSignals();
|
||||
renderHistory();
|
||||
|
||||
const initBtn = document.getElementById('init-btn');
|
||||
const signalsSection = document.getElementById('signals-section');
|
||||
|
||||
initBtn.addEventListener('click', () => {
|
||||
signalsSection.classList.remove('hidden-section');
|
||||
signalsSection.classList.add('visible-section');
|
||||
setTimeout(() => {
|
||||
signalsSection.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
2
api/public/assets/js/jquery.min.js
vendored
Normal file
2
api/public/assets/js/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
api/public/assets/js/sw.js
Normal file
5
api/public/assets/js/sw.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
/** An empty service worker! */
|
||||
self.addEventListener ('fetch', function(event)
|
||||
{
|
||||
/** An empty fetch handler! */
|
||||
});
|
||||
16
api/public/controllers/admin.php
Normal file
16
api/public/controllers/admin.php
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
use App\Controllers\ApiController;
|
||||
|
||||
/** GET /api/admin/ping — privileged round-trip. */
|
||||
class Admin extends ApiController
|
||||
{
|
||||
public function ping()
|
||||
{
|
||||
$this->requireAuth();
|
||||
$this->json([
|
||||
'pong' => true,
|
||||
'auth' => $this->apiUser ? 'apikey' : 'admin_token',
|
||||
'time' => date('c'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
168
api/public/controllers/controllers.md
Normal file
168
api/public/controllers/controllers.md
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
# Controllers — `public/controllers/`
|
||||
|
||||
UI page controllers. Each file maps to a URL segment via auto-routing.
|
||||
|
||||
## File Naming
|
||||
|
||||
- `PascalCase.php` → e.g. `ClientReports.php`
|
||||
- URL `/client-reports` auto-routes to `ClientReports::index()`
|
||||
|
||||
## Base Class
|
||||
|
||||
All UI controllers extend `AppController` (not `Controller` directly):
|
||||
|
||||
```
|
||||
core/Controller.php ← framework core, never modify
|
||||
↑
|
||||
app/Controllers/AppController.php ← app-wide concerns (injects $UserProfile)
|
||||
↑
|
||||
public/controllers/YourController.php
|
||||
```
|
||||
|
||||
## Standard Controller Structure
|
||||
|
||||
```php
|
||||
<?php
|
||||
class Clients extends AppController
|
||||
{
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
Auth::handleLogin(); // redirect to /login if not authenticated
|
||||
|
||||
$this->view->Footer = $this->view->PartialView('admin_footer');
|
||||
$this->view->SideBar = $this->view->PartialView('admin_sidebar');
|
||||
$this->view->Header = $this->view->PartialView('admin_header');
|
||||
$this->view->ToolBar = $this->view->PartialView('admin_toolbar');
|
||||
}
|
||||
|
||||
function index() {
|
||||
$clients = Db::select("SELECT * FROM sp_clients WHERE active = 1");
|
||||
$this->view->Clients = $clients;
|
||||
|
||||
$this->view->render(__CLASS__ . '/' . __FUNCTION__);
|
||||
}
|
||||
|
||||
function show($id) {
|
||||
$client = Db::getRow("SELECT * FROM sp_clients WHERE id = :id", [':id' => $id]);
|
||||
if (!$client) { http_response_code(404); die('Not found'); }
|
||||
|
||||
$this->view->Client = $client;
|
||||
$this->view->render(__CLASS__ . '/' . __FUNCTION__);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Render Conventions
|
||||
|
||||
```php
|
||||
// Standard admin page (default wrapper)
|
||||
$this->view->render(__CLASS__ . '/' . __FUNCTION__);
|
||||
|
||||
// Login / minimal wrapper
|
||||
$this->view->render(__CLASS__ . '/' . __FUNCTION__, 'login');
|
||||
|
||||
// Welcome screen (config flag)
|
||||
if (WELCOME) { $this->view->render(__CLASS__ . '/welcome', '', false); }
|
||||
```
|
||||
|
||||
## Injecting Page-Specific Assets
|
||||
|
||||
```php
|
||||
function index() {
|
||||
// CSS
|
||||
$this->Styles[] = '/public/assets/plugins/datatables/datatables.bundle.css';
|
||||
$this->view->Styles = $this->Styles;
|
||||
|
||||
// JS
|
||||
$this->JavaScript[] = '/public/assets/plugins/datatables/datatables.bundle.js';
|
||||
$this->JavaScript[] = '/public/assets/js/page-script.js';
|
||||
$this->view->JavaScript = $this->JavaScript;
|
||||
|
||||
$this->view->render(__CLASS__ . '/' . __FUNCTION__);
|
||||
}
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
```php
|
||||
Auth::handleLogin(); // redirects to /login if not authenticated
|
||||
Auth::can('users.create') // returns bool
|
||||
Auth::requirePermission('users.delete'); // halts with 403 JSON if denied
|
||||
```
|
||||
|
||||
## Passing Data to Views
|
||||
|
||||
```php
|
||||
$this->view->Users = Db::select("SELECT * FROM sp_users");
|
||||
$this->view->PageTitle = 'User List';
|
||||
// accessed in view as $Users, $PageTitle
|
||||
```
|
||||
|
||||
## CRUD Pattern
|
||||
|
||||
```php
|
||||
function store() {
|
||||
try {
|
||||
if (!Validator::required($_POST['name'])) {
|
||||
throw new Exception('Name is required');
|
||||
}
|
||||
|
||||
$id = Db::insert('sp_clients', [
|
||||
'name' => $_POST['name'],
|
||||
'created_at' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
redirect('/clients/show/' . $id);
|
||||
|
||||
} catch (Exception $e) {
|
||||
if (DEBUG) { echo $e->getMessage(); }
|
||||
else {
|
||||
$this->view->Error = 'Could not save. Please try again.';
|
||||
$this->view->FormData = $_POST;
|
||||
$this->view->render(__CLASS__ . '/create');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function update($id) {
|
||||
Db::update('sp_clients',
|
||||
['name' => $_POST['name'], 'updated_at' => date('Y-m-d H:i:s')],
|
||||
'id = :id',
|
||||
[':id' => $id]
|
||||
);
|
||||
redirect('/clients/show/' . $id);
|
||||
}
|
||||
|
||||
function delete($id) {
|
||||
Db::delete('sp_clients', 'id = :id', [':id' => $id]);
|
||||
redirect('/clients');
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
```php
|
||||
function create() {
|
||||
try {
|
||||
Db::beginTransaction();
|
||||
// ... operations ...
|
||||
Db::commit();
|
||||
redirect('/clients');
|
||||
|
||||
} catch (Exception $e) {
|
||||
Db::rollback();
|
||||
if (DEBUG) {
|
||||
echo "<pre>Error: {$e->getMessage()}\nFile: {$e->getFile()}:{$e->getLine()}</pre>";
|
||||
} else {
|
||||
error_log("Client creation failed: " . $e->getMessage());
|
||||
$this->view->Error = 'An error occurred. Please try again.';
|
||||
$this->view->render(__CLASS__ . '/create');
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Helper / Utility Code Rule
|
||||
|
||||
Reusable, stateless functions → `public static` method in `app/Helpers/`, never as a private controller method.
|
||||
Call via `HelperClass::methodName(...)`.
|
||||
29
api/public/controllers/docs.php
Normal file
29
api/public/controllers/docs.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
class Docs extends Controller {
|
||||
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
// echo $ this->view->PartialView('menu');
|
||||
|
||||
|
||||
$this->Styles['commenta'] = '<!-- Css files -->';
|
||||
$this->view->Styles = $this->Styles;
|
||||
|
||||
$this->JavaScript[] = ASSETS . "js/bootstrap.bundle.min.js";
|
||||
$this->JavaScript[] = ASSETS . "js/jquery.min.js";
|
||||
$this->JavaScript[] = ASSETS . "js/custom.js";
|
||||
$this->view->JavaScript = $this->JavaScript;
|
||||
}
|
||||
|
||||
|
||||
function index() {
|
||||
$this->Styles['commenta'] = '<!-- Bots Page -->';
|
||||
$this->view->Styles = $this->Styles;
|
||||
|
||||
$this->view->render('docs/index');
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
24
api/public/controllers/error.php
Normal file
24
api/public/controllers/error.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
|
||||
class _Error extends Controller {
|
||||
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
function index(){
|
||||
$this->Styles['commenta'] = '<!-- Css files -->';
|
||||
$this->view->Styles = $this->Styles;
|
||||
|
||||
$this->JavaScript[] = ASSETS . "/js/pages/crypto-dashboard.init.js";
|
||||
$this->view->JavaScript = $this->JavaScript;
|
||||
|
||||
$this->view->title = COMPANY;
|
||||
$this->view->render(__CLASS__ .'/'. __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
} // end class
|
||||
23
api/public/controllers/health.php
Normal file
23
api/public/controllers/health.php
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
use App\Controllers\PublicController;
|
||||
|
||||
/** GET /api/health — public health round-trip (proves DB connectivity). */
|
||||
class Health extends PublicController
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$this->guardPublic('health', 120, 60);
|
||||
try {
|
||||
$up = (int) \Db::getValue("SELECT 1");
|
||||
$rows = (int) \Db::getValue("SELECT COUNT(*) FROM `config`");
|
||||
} catch (\Throwable $e) {
|
||||
$this->json(null, 500, ['code' => 'db_error', 'message' => DEBUG ? $e->getMessage() : 'Database unavailable']);
|
||||
}
|
||||
$this->json([
|
||||
'db' => $up === 1 ? 'connected' : 'unknown',
|
||||
'app' => defined('PROJECT_NAME') ? PROJECT_NAME : '',
|
||||
'config_rows' => $rows,
|
||||
'time' => date('c'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
28
api/public/controllers/index.php
Normal file
28
api/public/controllers/index.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
class Index extends Controller {
|
||||
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
// echo $ this->view->PartialView('menu');
|
||||
|
||||
$this->Styles['commenta'] = '<!-- Css files -->';
|
||||
$this->view->Styles = $this->Styles;
|
||||
|
||||
$this->JavaScript[] = ASSETS . "js/bootstrap.bundle.min.js";
|
||||
$this->JavaScript[] = ASSETS . "js/jquery.min.js";
|
||||
$this->JavaScript[] = ASSETS . "js/custom.js";
|
||||
$this->view->JavaScript = $this->JavaScript;
|
||||
}
|
||||
|
||||
|
||||
function index() {
|
||||
$this->Styles['commenta'] = '<!-- Bots Page -->';
|
||||
$this->view->Styles = $this->Styles;
|
||||
|
||||
$this->view->render('index/index');
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
11
api/public/index.php
Normal file
11
api/public/index.php
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
@session_start();
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
require dirname(__DIR__) . '/config.php';
|
||||
|
||||
define('VIEWS_PATH', __DIR__);
|
||||
|
||||
|
||||
$bootstrap = new Bootstrap();
|
||||
$bootstrap->init();
|
||||
|
||||
17
api/public/models/games_model.php
Normal file
17
api/public/models/games_model.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
class Games_Model extends Model
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
|
||||
public function getGames()
|
||||
{
|
||||
//$Return = $this->db->select("select * from creditorinfo");
|
||||
//return json_encode($Return);
|
||||
}
|
||||
|
||||
|
||||
} // End Class
|
||||
11
api/public/models/index_model.php
Normal file
11
api/public/models/index_model.php
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
class Index_Model extends Model
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // End Class
|
||||
74
api/public/models/login_model.php
Normal file
74
api/public/models/login_model.php
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
class Login_Model extends Model
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This is basic authentication level for log in. However we need to enhance this a bit.
|
||||
If User Logged then redirect to User screen
|
||||
if Admin Logged then redirect to Admin Screen
|
||||
If Agency Logged then redirect to Agency screen.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$sth = $this->db->prepare("SELECT user_id, username, role_id FROM users WHERE
|
||||
username = :username AND password = :password");
|
||||
$sth->execute(array(
|
||||
':username' => $_POST['username'],
|
||||
':password' => Hash::create('sha256', $_POST['password'], HASH_PASSWORD_KEY)
|
||||
));
|
||||
|
||||
$data = $sth->fetch();
|
||||
|
||||
|
||||
$count = $sth->rowCount();
|
||||
if ($count > 0) {
|
||||
// login
|
||||
Session::init();
|
||||
Session::pSet('UserProfile', 'roleId', $data['role_id']);
|
||||
Session::pSet('UserProfile', 'loggedIn', true);
|
||||
Session::pSet('UserProfile', 'userId', $data['user_id']);
|
||||
|
||||
$sql = "SELECT t2.perm_controller,t2.perm_action FROM role_perm as t1
|
||||
JOIN permissions as t2 ON t1.perm_id = t2.perm_id
|
||||
WHERE t1.role_id = :role_id";
|
||||
|
||||
$permission = array();
|
||||
$permission = $this->db->select($sql, array(':role_id' => $data['role_id']));
|
||||
|
||||
Session::set('permission', $permission);
|
||||
|
||||
|
||||
|
||||
// This is a bit annoying to have it hard coded but its good enough for now.
|
||||
// This will set the specific redirects for the access levels Business, Client & User there's only 3 screens with sub levels of permissions.
|
||||
switch($data['role_id']) {
|
||||
# Business
|
||||
case '1' : // Administrator
|
||||
case '2' : // Marketing
|
||||
header('location: /admin');
|
||||
break;
|
||||
|
||||
# Client
|
||||
case '4' : // Agency
|
||||
header('location: /dashboard');
|
||||
break;
|
||||
|
||||
#End User
|
||||
case '6' : // Users
|
||||
header('location: /dashboard');
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
header('location: ../login');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
15
api/public/views/_error/index.php
Normal file
15
api/public/views/_error/index.php
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
<div class="middle-box text-center animated fadeInDown">
|
||||
<h1>404</h1>
|
||||
<h3 class="font-bold">Page Not Found</h3>
|
||||
|
||||
<div class="error-desc">
|
||||
Sorry, but the page you are looking for has note been found. Try checking the URL for error, then hit the refresh button on your browser or try found something else in our app.
|
||||
<form class="form-inline m-t justify-content-center" role="form">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" placeholder="Search for page">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Search</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
55
api/public/views/aitest/index.php
Normal file
55
api/public/views/aitest/index.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?
|
||||
$Response = $this->OpenAiResponse;
|
||||
?>
|
||||
|
||||
|
||||
|
||||
<main>
|
||||
|
||||
<div class="container mt-5">
|
||||
<h2>Testing OpenAI / ChatGPT API</h2>
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label for="exampleFormControlInput1">Ask Your Question: </label>
|
||||
<input type="text" class="form-control" name="question" id="exampleFormControlInput1" placeholder="How is a Rainbow Made?">
|
||||
</div>
|
||||
<!-- <div class="form-group">-->
|
||||
<!-- <label for="exampleFormControlSelect1">Example select</label>-->
|
||||
<!-- <select class="form-control" id="exampleFormControlSelect1">-->
|
||||
<!-- <option>1</option>-->
|
||||
<!-- <option>2</option>-->
|
||||
<!-- <option>3</option>-->
|
||||
<!-- <option>4</option>-->
|
||||
<!-- <option>5</option>-->
|
||||
<!-- </select>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="form-group">-->
|
||||
<!-- <label for="exampleFormControlTextarea1">Example textarea</label>-->
|
||||
<!-- <textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<div class="d-grid gap-2 mt-3">
|
||||
|
||||
<input type="submit" value="Submit Question" class="btn btn-primary">
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<hr class="mt-5">
|
||||
<h4 class="mb-3"><strong>Your Question: </strong> <?= $_POST['question']; ?></h4>
|
||||
|
||||
<h4 class="mb-4"><strong>Your Answer:</strong> </h4>
|
||||
<pre class="alert alert-light" style="white-space: pre-wrap;">
|
||||
<?= $Response; ?>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
<footer class="text-muted py-5">
|
||||
<div class="container">
|
||||
<p class="float-end mb-1">
|
||||
<a href="#">Powered by SeedProject</a>
|
||||
</p>
|
||||
<p class="mb-1">My Application © 2022 </p>
|
||||
</div>
|
||||
</footer>
|
||||
40
api/public/views/aitest/translate.php
Normal file
40
api/public/views/aitest/translate.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
A Viva Air le quedarían muy pocas horas de vuelo
|
||||
Por la crisis económica, la Junta Directiva habría tomado la decisión de cerrar la operación. Se verían afectadas un millón de personas que compraron tiquetes.
|
||||
En cuestión de horas la aerolínea Viva pondría punto final a toda su operación. La Junta Directiva de la compañía aérea de bajo costo habría dado luz verde para dejar en tierra la totalidad de sus aeronaves, así como la de liquidar la actividad de la compañía.
|
||||
|
||||
EL COLOMBIANO pudo establecer que el órgano directivo de la empresa, en un reciente cónclave extraordinario, habría tomado la decisión de no darle más largas al asunto, y tiene lista la orden para la clausura total de la compañía aérea ante su crisis financiera, que a la fecha ya le ha representado dejar aviones sin volar.
|
||||
|
||||
Trascendió que para los miembros de la Junta Directiva las finanzas de la aerolínea no le permitirían continuar con la operación, incluso señalaron que aún amparada la compañía en el Decreto 560 (norma de Recuperación Económica) y pagado el 100% de los compromisos, la operación les daría para máximo dos semanas.
|
||||
La situación es tan crítica que en una carta reciente que el anterior presidente de la compañía, Félix Antelo, envió al ministro de Transporte, Guillermo Reyes, advirtió que al 31 de enero de 2023, los pasivos de la empresa aérea de bajo costo llegaban a los $4,06 billones. “Como bien sabe la compañía no tiene la capacidad por sí misma para responder con sus obligaciones”, resaltó quien hasta el jueves pasado fuera el presidente de Viva Air.
|
||||
|
||||
Integración con Avianca
|
||||
|
||||
Se conoció además que, para los miembros de la Junta Directiva de la aerolínea será un error grande, que le causará una tragedia al turismo y a la economía de Colombia, la decisión de la Aeronáutica Civil (Aerocivil) de no hacer nada, ni decir nada, sobre la integración de Viva y Avianca.
|
||||
|
||||
Así mismo, la aerolínea de bajo costo espera que en las próximas horas, bien sea el director de la Aerocivil, Sergio París, o en su efecto el ministro Reyes, entren en contacto con los directivos de la compañía, y con el nuevo presidente de la misma, Francisco Lalinde, para lograr la tan anhelada integración con Avianca.
|
||||
|
||||
De no lograrse el aval por parte de la Aerocivil a más tardar el martes, como lo habría dictado la Junta Directiva, la aerolínea cerraría la operación con lo que resultarán damnificadas más de un millón de personas que a la fecha ya tiene comprados tiquetes y a las que no se les reembolsaría el dinero en el corto plazo.
|
||||
|
||||
No hay una decisión}
|
||||
|
||||
EL COLOMBIANO se comunicó con voceros de la compañía aérea para confirmar las versiones de su posible cierre de operaciones mañana martes. Al respecto, de manera oficial la aerolínea de bajo costo señaló: “Hasta la fecha no hay una definición de cierre de la compañía y Viva sigue operando y a la espera de una urgente definición por parte de la Aeronáutica Civil”.
|
||||
|
||||
Sin embargo, este diario pudo establecer que a la cascada de renuncias del personal del servicio en aire y en tierra, se viene ajustando la operación con los recursos y aeronaves que quedan.
|
||||
|
||||
Cabe recordar que Viva anunció hace una semana y en un comunicado interno que temporalmente tendrá que prescindir del uso de cinco aviones. “Se han presentado importantes negociaciones con los dueños de los aviones buscando llegar a acuerdos de cómo continuar nuestra operación. A pesar de esto, hemos sido notificados por uno de ellos que debemos dejar en tierra, por el momento, cinco de sus aviones hasta nueva orden en los Estados Unidos”, aseguró la compañía en el documento.
|
||||
|
||||
En menos de un mes la administración de la aerolínea no solo ha cancelado varias frecuencias entre la costa Caribe y Cali, además los 14 vuelos que operaban hacia San Andrés, lo que representa el 90% de la economía de la isla.
|
||||
|
||||
“A días de perder Viva”
|
||||
|
||||
En una inquietante carta, los trabajadores de la aerolínea se pronunciaron frente a la crítica situación financiera que vive.
|
||||
|
||||
En la misiva advierten que cerca de 5.000 personas que dependen económicamente de esta empresa se encuentran en incertidumbre ante la falta de claridad de las autoridades sobre si habrá o no rescate (integración con Avianca).
|
||||
|
||||
“Necesitamos una respuesta con urgencia”, dicen los trabajadores, quienes advierten que aunque han enviado cartas y han sido prudentes en su comunicación, no han recibido atención de la Aerocivil o del gobierno. El jueves de la semana pasada muchos de ellos protestaron en el aeropuerto José María Córdova.
|
||||
|
||||
Con la clausura de la operación de Viva en el negocio aéreo del país, quedaría un vacío del 21%, que es la participación de la aerolínea de bajo en el mercado, y teniendo en cuenta que Avianca posee el 40%.
|
||||
|
||||
|
||||
|
||||
|
||||
1
api/public/views/docs/index.php
Normal file
1
api/public/views/docs/index.php
Normal file
|
|
@ -0,0 +1 @@
|
|||
No Documentation Here
|
||||
52
api/public/views/index/index.php
Normal file
52
api/public/views/index/index.php
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<body class="text-slate-300 antialiased selection:bg-cyan-500/30 selection:text-cyan-200">
|
||||
<div class="min-h-screen flex flex-col relative overflow-hidden">
|
||||
<!-- Background Ambient Glows -->
|
||||
<div class="absolute top-0 left-1/4 -translate-x-1/2 w-[500px] h-[500px] bg-cyan-600/20 blur-[120px] rounded-full -z-10"></div>
|
||||
<div class="absolute bottom-0 right-0 translate-y-1/4 w-[600px] h-[600px] bg-violet-600/20 blur-[120px] rounded-full -z-10"></div>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="flex-grow pt-32 pb-12 flex flex-col items-center relative z-10 px-4">
|
||||
<div class="text-center max-w-3xl mx-auto mb-12">
|
||||
<div class="inline-flex items-center gap-2 px-3 py-1 rounded-full border border-cyan-500/20 bg-cyan-500/10 text-cyan-400 text-xs font-medium tracking-wide mb-8">
|
||||
<span class="relative flex h-2 w-2">
|
||||
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-cyan-400 opacity-75"></span>
|
||||
<span class="relative inline-flex rounded-full h-2 w-2 bg-cyan-500"></span>
|
||||
</span>
|
||||
Light-Weight LLM Friendly PHP Framework
|
||||
</div>
|
||||
<h1 class="text-5xl md:text-7xl font-semibold text-white tracking-tighter mb-6 leading-[1.1]">
|
||||
SeedProject <span class="bg-clip-text text-transparent bg-gradient-to-r from-cyan-400 to-blue-500"> </br>Framework</span>
|
||||
</h1>
|
||||
<p class="text-slate-400 font-light text-base md:text-lg max-w-xl mx-auto leading-relaxed">
|
||||
SeedProject Framework is revamped to work with LLM likes Claude Code, Gemini CLI to help you build more structured projects, harness the power of AI without messy confusing back-end code.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Particle Sphere Container -->
|
||||
<div class="relative w-full max-w-[21rem] aspect-square flex items-center justify-center mb-16" id="canvas-container">
|
||||
<canvas id="particle-canvas" class="absolute inset-0 z-10 w-full h-full"></canvas>
|
||||
<div class="absolute inset-0 flex items-center justify-center z-0">
|
||||
<div class="w-24 h-24 rounded-full border border-cyan-500/20 bg-cyan-900/5 backdrop-blur-sm pulse-ring"></div>
|
||||
<div class="absolute w-36 h-36 rounded-full border border-white/5 opacity-30"></div>
|
||||
</div>
|
||||
<div class="absolute top-1/4 left-0 glass px-4 py-2.5 rounded-xl border border-white/10 transform -translate-x-6 animate-bounce" style="animation-duration: 4s;">
|
||||
<div class="text-[10px] text-slate-500 uppercase tracking-widest mb-1">Light-Weight</div>
|
||||
<div class="text-sm text-white font-mono font-medium">4.9MB</div>
|
||||
</div>
|
||||
<div class="absolute bottom-1/4 right-0 glass px-4 py-2.5 rounded-xl border border-white/10 transform translate-x-6 animate-bounce" style="animation-duration: 5s;">
|
||||
<div class="text-[10px] text-slate-500 uppercase tracking-widest mb-1">Lines of Code</div>
|
||||
<div class="text-sm text-emerald-400 font-mono font-medium">1k</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CTA Button -->
|
||||
<div class="relative z-20 mb-32 group">
|
||||
<div class="absolute -inset-1 bg-gradient-to-r from-cyan-600 to-blue-600 rounded-xl blur opacity-30 group-hover:opacity-60 transition duration-500"></div>
|
||||
<button id="init-btn" class="relative px-10 py-5 bg-slate-900 rounded-xl leading-none flex items-center gap-4 border border-slate-800 hover:border-slate-700 transition-all duration-300">
|
||||
<span class="text-slate-200 font-semibold tracking-tight text-lg">Review Documentation</span>
|
||||
<svg class="text-cyan-400" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"/><path d="M5 3v4"/><path d="M19 17v4"/><path d="M3 5h4"/><path d="M17 19h4"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
0
api/public/views/partial/menu.php
Normal file
0
api/public/views/partial/menu.php
Normal file
170
api/public/views/views.md
Normal file
170
api/public/views/views.md
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
# Views — `public/views/`
|
||||
|
||||
PHP view templates, organized by controller name.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
public/views/
|
||||
├── <controller_name>/ # snake_case folder per controller
|
||||
│ ├── index.php
|
||||
│ ├── show.php
|
||||
│ └── edit.php
|
||||
├── modals/ # Modal fragment views (AJAX loaded)
|
||||
│ └── <modal_name>.php
|
||||
├── partial/ # Reusable partial views
|
||||
│ ├── admin_header.php
|
||||
│ ├── admin_sidebar.php
|
||||
│ ├── admin_toolbar.php
|
||||
│ └── admin_footer.php
|
||||
└── wrapper/ # Layout wrappers
|
||||
├── admin/
|
||||
│ ├── header.php
|
||||
│ └── footer.php
|
||||
└── site/
|
||||
├── header.php
|
||||
└── footer.php
|
||||
```
|
||||
|
||||
## File Naming
|
||||
|
||||
- Folder: `snake_case` matching the controller name (lowercased)
|
||||
- Files: `snake_case.php` matching the method name
|
||||
|
||||
## Rendering
|
||||
|
||||
Called from the controller:
|
||||
|
||||
```php
|
||||
// Standard — uses __CLASS__/__FUNCTION__ convention
|
||||
$this->view->render(__CLASS__ . '/' . __FUNCTION__);
|
||||
|
||||
// With explicit wrapper
|
||||
$this->view->render('clients/index', true, 'site');
|
||||
$this->view->render('admin/dashboard', true, 'admin');
|
||||
|
||||
// Login / minimal wrapper
|
||||
$this->view->render('auth/login', 'login');
|
||||
|
||||
// No wrapper
|
||||
$this->view->render('auth/login', false);
|
||||
```
|
||||
|
||||
## Accessing View Data
|
||||
|
||||
Variables set on the controller via `$this->view->VarName = $value` are accessed in the view as **`$this->VarName`**.
|
||||
|
||||
`View::render()` calls `extract((array) $this)` before including the template, so all properties set on the view object are available as bare `$VarName` locals.
|
||||
|
||||
```php
|
||||
// Controller
|
||||
$this->view->Users = Db::select("SELECT * FROM sp_users");
|
||||
$this->view->PageTitle = 'Users';
|
||||
|
||||
// View — use bare $VarName
|
||||
<h1><?= $PageTitle ?></h1>
|
||||
<?php foreach ($Users as $user): ?>
|
||||
<p><?= htmlspecialchars($user['name']) ?></p>
|
||||
<?php endforeach; ?>
|
||||
```
|
||||
|
||||
## Wrappers
|
||||
|
||||
Wrappers live in `public/views/wrapper/`. The wrapper auto-loads:
|
||||
- `public/assets/css/<controllername>.css` if it exists
|
||||
- `public/assets/js/<controllername>.js` if it exists
|
||||
|
||||
## Partial Views
|
||||
|
||||
Partials are reusable snippets loaded from the controller constructor:
|
||||
|
||||
```php
|
||||
// In controller __construct()
|
||||
$this->view->Header = $this->view->PartialView('admin_header');
|
||||
$this->view->SideBar = $this->view->PartialView('admin_sidebar');
|
||||
$this->view->ToolBar = $this->view->PartialView('admin_toolbar');
|
||||
$this->view->Footer = $this->view->PartialView('admin_footer');
|
||||
```
|
||||
|
||||
Then echoed in the view:
|
||||
```php
|
||||
<?= $Header ?>
|
||||
<?= $SideBar ?>
|
||||
```
|
||||
|
||||
## Modal System
|
||||
|
||||
Modals are loaded dynamically via AJAX. Trigger a modal with:
|
||||
|
||||
```html
|
||||
<button class="RegularModal btn btn-primary"
|
||||
data-url="/modals/load/<modal_name>"
|
||||
data-size="mw-650px">
|
||||
Open Modal
|
||||
</button>
|
||||
```
|
||||
|
||||
`data-size` accepts any Bootstrap modal width class or a custom `mw-*` value:
|
||||
|
||||
| Value | Width |
|
||||
|-------|-------|
|
||||
| *(omit)* | Default (~500px) |
|
||||
| `mw-500px` | 500px max-width |
|
||||
| `mw-650px` | 650px max-width |
|
||||
| `mw-750px` | 750px max-width |
|
||||
| `modal-lg` | ~800px (Bootstrap) |
|
||||
| `modal-xl` | ~1140px (Bootstrap) — use for wizards / multi-step forms |
|
||||
|
||||
Modal views live at `public/views/modals/<modal_name>.php` and render **only** the `.modal-content` fragment (no full page wrapper):
|
||||
|
||||
```html
|
||||
<!--begin::Modal content-->
|
||||
<div class="modal-content">
|
||||
<!--begin::Modal header-->
|
||||
<div class="modal-header" id="kt_modal_add_client_header">
|
||||
<h2>Add Client</h2>
|
||||
<div class="btn btn-sm btn-icon btn-active-color-primary" data-bs-dismiss="modal">
|
||||
<i class="ki-duotone ki-cross fs-1">
|
||||
<span class="path1"></span>
|
||||
<span class="path2"></span>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
<!--end::Modal header-->
|
||||
|
||||
<!--begin::Modal body-->
|
||||
<div class="modal-body">
|
||||
<!-- form or content here -->
|
||||
</div>
|
||||
<!--end::Modal body-->
|
||||
</div>
|
||||
<!--end::Modal content-->
|
||||
```
|
||||
|
||||
## Assets Structure
|
||||
|
||||
```
|
||||
public/assets/
|
||||
├── css/
|
||||
│ ├── custom.css # Global overrides
|
||||
│ └── <controller>.css # Page-specific (auto-loaded by wrapper)
|
||||
├── js/
|
||||
│ └── <controller>.js # Page-specific (auto-loaded by wrapper)
|
||||
├── plugins/
|
||||
│ └── datatables/
|
||||
│ ├── datatables.bundle.css
|
||||
│ └── datatables.bundle.js
|
||||
└── media/
|
||||
└── svg/
|
||||
└── brand-logos/ # Integration / vendor logos
|
||||
```
|
||||
|
||||
Inject additional assets from the controller method:
|
||||
|
||||
```php
|
||||
$this->Styles[] = '/public/assets/plugins/datatables/datatables.bundle.css';
|
||||
$this->view->Styles = $this->Styles;
|
||||
|
||||
$this->JavaScript[] = '/public/assets/plugins/datatables/datatables.bundle.js';
|
||||
$this->view->JavaScript = $this->JavaScript;
|
||||
```
|
||||
19
api/public/views/wrapper/site/footer.php
Normal file
19
api/public/views/wrapper/site/footer.php
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
<?php
|
||||
if($this->JavaScript) {
|
||||
foreach ($this->JavaScript as $kj => $JavaScript) :
|
||||
if(!is_numeric($kj)) {
|
||||
echo PHP_EOL;
|
||||
echo $JavaScript . PHP_EOL;
|
||||
continue;
|
||||
}
|
||||
echo '<script src="'. $JavaScript .'"></script>' . PHP_EOL;
|
||||
endforeach;
|
||||
}
|
||||
?>
|
||||
|
||||
<script type="module" src="/public/assets/js/index.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
52
api/public/views/wrapper/site/header.php
Normal file
52
api/public/views/wrapper/site/header.php
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CreditPullEngine</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Inter', sans-serif;
|
||||
background-color: #030712; /* Slate 950 */
|
||||
overflow-x: hidden;
|
||||
margin: 0;
|
||||
}
|
||||
::-webkit-scrollbar { width: 6px; height: 6px; }
|
||||
::-webkit-scrollbar-track { background: #0f172a; }
|
||||
::-webkit-scrollbar-thumb { background: #334155; border-radius: 3px; }
|
||||
.glass {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
backdrop-filter: blur(16px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
.glass-panel {
|
||||
background: linear-gradient(180deg, rgba(30, 41, 59, 0.4) 0%, rgba(15, 23, 42, 0.6) 100%);
|
||||
backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
@keyframes pulse-ring {
|
||||
0% { transform: scale(0.8); opacity: 0.5; }
|
||||
100% { transform: scale(1.2); opacity: 0; }
|
||||
}
|
||||
.pulse-ring { animation: pulse-ring 3s cubic-bezier(0.215, 0.61, 0.355, 1) infinite; }
|
||||
#signals-section { transition: opacity 1s ease, transform 1s ease; }
|
||||
.hidden-section { opacity: 0; transform: translateY(50px); pointer-events: none; height: 0; overflow: hidden; }
|
||||
.visible-section { opacity: 1; transform: translateY(0); pointer-events: auto; height: auto; }
|
||||
</style>
|
||||
|
||||
<?php
|
||||
if($this->Styles) {
|
||||
foreach ($this->Styles as $ks => $Styles) :
|
||||
if(!is_numeric($ks)) {
|
||||
echo PHP_EOL;
|
||||
echo $Styles . PHP_EOL;
|
||||
continue;
|
||||
}
|
||||
echo '<link type="text/css" rel="stylesheet" href="'. $Styles .'">' .PHP_EOL;
|
||||
|
||||
endforeach;
|
||||
}
|
||||
?>
|
||||
</head>
|
||||
|
|
@ -1,362 +1 @@
|
|||
[
|
||||
{
|
||||
"id": "err_69ee699b38a214.70118470",
|
||||
"userid": 2565,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "https:\/\/secure.creditpullengine.com\/appi\/pulls\/pullReport",
|
||||
"file": "\/www\/wwwroot\/cpeSecure\/app\/Services\/Credit\/EquifaxCodeMap.php",
|
||||
"line": 317,
|
||||
"fullerror": "Call to undefined method App\\Services\\Credit\\EquifaxCodeMap::getScoreFactors()",
|
||||
"trace": "#0 \/www\/wwwroot\/cpeSecure\/app\/Services\/Credit\/EquifaxAdapter.php(159): App\\Services\\Credit\\EquifaxCodeMap::getScoreFactor()\n#1 \/www\/wwwroot\/cpeSecure\/app\/Services\/Credit\/EquifaxAdapter.php(43): App\\Services\\Credit\\EquifaxAdapter->mapScoreFactors()\n#2 \/www\/wwwroot\/cpeSecure\/appi\/controllers\/pulls.php(134): App\\Services\\Credit\\EquifaxAdapter->transform()\n#3 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(227): pulls->pullReport()\n#4 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(64): Bootstrap->_callControllerMethod()\n#5 \/www\/wwwroot\/cpeSecure\/appi\/index.php(11): Bootstrap->init()\n#6 {main}",
|
||||
"method": "POST",
|
||||
"ip_address": "193.36.238.59",
|
||||
"user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/147.0.0.0 Safari\/537.36",
|
||||
"referer": "https:\/\/secure.creditpullengine.com\/pulls",
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-26 15:38:03"
|
||||
},
|
||||
{
|
||||
"id": "err_69ee698c669d29.22210069",
|
||||
"userid": 2565,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "https:\/\/secure.creditpullengine.com\/appi\/pulls\/pullReport",
|
||||
"file": "\/www\/wwwroot\/cpeSecure\/app\/Services\/Credit\/EquifaxCodeMap.php",
|
||||
"line": 317,
|
||||
"fullerror": "Call to undefined method App\\Services\\Credit\\EquifaxCodeMap::getScoreFactors()",
|
||||
"trace": "#0 \/www\/wwwroot\/cpeSecure\/app\/Services\/Credit\/EquifaxAdapter.php(159): App\\Services\\Credit\\EquifaxCodeMap::getScoreFactor()\n#1 \/www\/wwwroot\/cpeSecure\/app\/Services\/Credit\/EquifaxAdapter.php(43): App\\Services\\Credit\\EquifaxAdapter->mapScoreFactors()\n#2 \/www\/wwwroot\/cpeSecure\/appi\/controllers\/pulls.php(134): App\\Services\\Credit\\EquifaxAdapter->transform()\n#3 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(227): pulls->pullReport()\n#4 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(64): Bootstrap->_callControllerMethod()\n#5 \/www\/wwwroot\/cpeSecure\/appi\/index.php(11): Bootstrap->init()\n#6 {main}",
|
||||
"method": "POST",
|
||||
"ip_address": "193.36.238.59",
|
||||
"user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/147.0.0.0 Safari\/537.36",
|
||||
"referer": "https:\/\/secure.creditpullengine.com\/pulls",
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-26 15:37:48"
|
||||
},
|
||||
{
|
||||
"id": "err_69ee6950756db9.31923142",
|
||||
"userid": 2565,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "https:\/\/secure.creditpullengine.com\/appi\/pulls\/pullReport",
|
||||
"file": "\/www\/wwwroot\/cpeSecure\/app\/Services\/Credit\/EquifaxCodeMap.php",
|
||||
"line": 317,
|
||||
"fullerror": "Call to undefined method App\\Services\\Credit\\EquifaxCodeMap::getScoreFactors()",
|
||||
"trace": "#0 \/www\/wwwroot\/cpeSecure\/app\/Services\/Credit\/EquifaxAdapter.php(159): App\\Services\\Credit\\EquifaxCodeMap::getScoreFactor()\n#1 \/www\/wwwroot\/cpeSecure\/app\/Services\/Credit\/EquifaxAdapter.php(43): App\\Services\\Credit\\EquifaxAdapter->mapScoreFactors()\n#2 \/www\/wwwroot\/cpeSecure\/appi\/controllers\/pulls.php(134): App\\Services\\Credit\\EquifaxAdapter->transform()\n#3 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(227): pulls->pullReport()\n#4 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(64): Bootstrap->_callControllerMethod()\n#5 \/www\/wwwroot\/cpeSecure\/appi\/index.php(11): Bootstrap->init()\n#6 {main}",
|
||||
"method": "POST",
|
||||
"ip_address": "193.36.238.59",
|
||||
"user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/147.0.0.0 Safari\/537.36",
|
||||
"referer": "https:\/\/secure.creditpullengine.com\/pulls",
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-26 15:36:48"
|
||||
},
|
||||
{
|
||||
"id": "err_69ee6934c9c873.23488128",
|
||||
"userid": 2565,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "https:\/\/secure.creditpullengine.com\/appi\/pulls\/pullReport",
|
||||
"file": "\/www\/wwwroot\/cpeSecure\/app\/Services\/Credit\/EquifaxCodeMap.php",
|
||||
"line": 317,
|
||||
"fullerror": "Call to undefined method App\\Services\\Credit\\EquifaxCodeMap::getScoreFactors()",
|
||||
"trace": "#0 \/www\/wwwroot\/cpeSecure\/app\/Services\/Credit\/EquifaxAdapter.php(159): App\\Services\\Credit\\EquifaxCodeMap::getScoreFactor()\n#1 \/www\/wwwroot\/cpeSecure\/app\/Services\/Credit\/EquifaxAdapter.php(43): App\\Services\\Credit\\EquifaxAdapter->mapScoreFactors()\n#2 \/www\/wwwroot\/cpeSecure\/appi\/controllers\/pulls.php(134): App\\Services\\Credit\\EquifaxAdapter->transform()\n#3 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(227): pulls->pullReport()\n#4 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(64): Bootstrap->_callControllerMethod()\n#5 \/www\/wwwroot\/cpeSecure\/appi\/index.php(11): Bootstrap->init()\n#6 {main}",
|
||||
"method": "POST",
|
||||
"ip_address": "193.36.238.59",
|
||||
"user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/147.0.0.0 Safari\/537.36",
|
||||
"referer": "https:\/\/secure.creditpullengine.com\/pulls",
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-26 15:36:20"
|
||||
},
|
||||
{
|
||||
"id": "err_69ee69273633b8.88201084",
|
||||
"userid": 2565,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "https:\/\/secure.creditpullengine.com\/appi\/pulls\/pullReport",
|
||||
"file": "\/www\/wwwroot\/cpeSecure\/app\/Services\/Credit\/EquifaxCodeMap.php",
|
||||
"line": 317,
|
||||
"fullerror": "Call to undefined method App\\Services\\Credit\\EquifaxCodeMap::getScoreFactors()",
|
||||
"trace": "#0 \/www\/wwwroot\/cpeSecure\/app\/Services\/Credit\/EquifaxAdapter.php(159): App\\Services\\Credit\\EquifaxCodeMap::getScoreFactor()\n#1 \/www\/wwwroot\/cpeSecure\/app\/Services\/Credit\/EquifaxAdapter.php(43): App\\Services\\Credit\\EquifaxAdapter->mapScoreFactors()\n#2 \/www\/wwwroot\/cpeSecure\/appi\/controllers\/pulls.php(134): App\\Services\\Credit\\EquifaxAdapter->transform()\n#3 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(227): pulls->pullReport()\n#4 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(64): Bootstrap->_callControllerMethod()\n#5 \/www\/wwwroot\/cpeSecure\/appi\/index.php(11): Bootstrap->init()\n#6 {main}",
|
||||
"method": "POST",
|
||||
"ip_address": "193.36.238.59",
|
||||
"user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/147.0.0.0 Safari\/537.36",
|
||||
"referer": "https:\/\/secure.creditpullengine.com\/pulls",
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-26 15:36:07"
|
||||
},
|
||||
{
|
||||
"id": "err_69ed670a033b66.19048308",
|
||||
"userid": null,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "https:\/\/secure.creditpullengine.com\/public\/",
|
||||
"file": "\/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php",
|
||||
"line": 131,
|
||||
"fullerror": "Failed opening required 'public\/controllers\/index.php' (include_path='.:')",
|
||||
"trace": "#0 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(40): Bootstrap->_loadDefaultController()\n#1 \/www\/wwwroot\/cpeSecure\/public\/index.php(11): Bootstrap->init()\n#2 {main}",
|
||||
"method": "GET",
|
||||
"ip_address": "89.244.95.100",
|
||||
"user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/143.0.0.0 Safari\/537.36",
|
||||
"referer": "https:\/\/secure.creditpullengine.com\/login",
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-25 21:14:50"
|
||||
},
|
||||
{
|
||||
"id": "err_69ed5d01f08370.23851037",
|
||||
"userid": null,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "https:\/\/secure.creditpullengine.com\/cron\/jsonReports",
|
||||
"file": "\/www\/wwwroot\/cpeSecure\/public\/controllers\/cron.php",
|
||||
"line": 14,
|
||||
"fullerror": "Class \"Carbon\\Carbon\" not found",
|
||||
"trace": "#0 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(148): Cron->__construct()\n#1 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(63): Bootstrap->_loadExistingController()\n#2 \/www\/wwwroot\/cpeSecure\/public\/index.php(11): Bootstrap->init()\n#3 \/www\/wwwroot\/cpeSecure\/index.php(2): require_once('...')\n#4 {main}",
|
||||
"method": "GET",
|
||||
"ip_address": "140.82.26.192",
|
||||
"user_agent": "curl\/7.76.1",
|
||||
"referer": null,
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-25 20:32:01"
|
||||
},
|
||||
{
|
||||
"id": "err_69ed5d01e8bb28.09924309",
|
||||
"userid": null,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "https:\/\/secure.creditpullengine.com\/cron\/jsonReports",
|
||||
"file": "\/www\/wwwroot\/cpeSecure\/public\/controllers\/cron.php",
|
||||
"line": 14,
|
||||
"fullerror": "Class \"Carbon\\Carbon\" not found",
|
||||
"trace": "#0 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(148): Cron->__construct()\n#1 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(63): Bootstrap->_loadExistingController()\n#2 \/www\/wwwroot\/cpeSecure\/public\/index.php(11): Bootstrap->init()\n#3 \/www\/wwwroot\/cpeSecure\/index.php(2): require_once('...')\n#4 {main}",
|
||||
"method": "GET",
|
||||
"ip_address": "207.246.75.27",
|
||||
"user_agent": null,
|
||||
"referer": null,
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-25 20:32:01"
|
||||
},
|
||||
{
|
||||
"id": "err_69ed5cf5670d39.78662554",
|
||||
"userid": null,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "https:\/\/secure.creditpullengine.com\/cron\/jsonReports",
|
||||
"file": "\/www\/wwwroot\/cpeSecure\/public\/controllers\/cron.php",
|
||||
"line": 14,
|
||||
"fullerror": "Class \"Carbon\\Carbon\" not found",
|
||||
"trace": "#0 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(148): Cron->__construct()\n#1 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(63): Bootstrap->_loadExistingController()\n#2 \/www\/wwwroot\/cpeSecure\/public\/index.php(11): Bootstrap->init()\n#3 \/www\/wwwroot\/cpeSecure\/index.php(2): require_once('...')\n#4 {main}",
|
||||
"method": "GET",
|
||||
"ip_address": "206.62.143.66",
|
||||
"user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/147.0.0.0 Safari\/537.36",
|
||||
"referer": null,
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-25 20:31:49"
|
||||
},
|
||||
{
|
||||
"id": "err_69ed5cdaeef019.29989883",
|
||||
"userid": null,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "https:\/\/secure.creditpullengine.com\/cron\/jsonReports",
|
||||
"file": "\/www\/wwwroot\/cpeSecure\/public\/controllers\/cron.php",
|
||||
"line": 14,
|
||||
"fullerror": "Class \"Carbon\\Carbon\" not found",
|
||||
"trace": "#0 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(148): Cron->__construct()\n#1 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(63): Bootstrap->_loadExistingController()\n#2 \/www\/wwwroot\/cpeSecure\/public\/index.php(11): Bootstrap->init()\n#3 \/www\/wwwroot\/cpeSecure\/index.php(2): require_once('...')\n#4 {main}",
|
||||
"method": "GET",
|
||||
"ip_address": "206.62.143.66",
|
||||
"user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/147.0.0.0 Safari\/537.36",
|
||||
"referer": null,
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-25 20:31:22"
|
||||
},
|
||||
{
|
||||
"id": "err_69ed5cc5a99338.48739755",
|
||||
"userid": null,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "https:\/\/secure.creditpullengine.com\/cron\/jsonReports",
|
||||
"file": "\/www\/wwwroot\/cpeSecure\/public\/controllers\/cron.php",
|
||||
"line": 14,
|
||||
"fullerror": "Class \"Carbon\\Carbon\" not found",
|
||||
"trace": "#0 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(148): Cron->__construct()\n#1 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(63): Bootstrap->_loadExistingController()\n#2 \/www\/wwwroot\/cpeSecure\/public\/index.php(11): Bootstrap->init()\n#3 \/www\/wwwroot\/cpeSecure\/index.php(2): require_once('...')\n#4 {main}",
|
||||
"method": "GET",
|
||||
"ip_address": "207.246.75.27",
|
||||
"user_agent": null,
|
||||
"referer": null,
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-25 20:31:01"
|
||||
},
|
||||
{
|
||||
"id": "err_69ed5cc5a5d377.51767422",
|
||||
"userid": null,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "https:\/\/secure.creditpullengine.com\/cron\/jsonReports",
|
||||
"file": "\/www\/wwwroot\/cpeSecure\/public\/controllers\/cron.php",
|
||||
"line": 14,
|
||||
"fullerror": "Class \"Carbon\\Carbon\" not found",
|
||||
"trace": "#0 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(148): Cron->__construct()\n#1 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(63): Bootstrap->_loadExistingController()\n#2 \/www\/wwwroot\/cpeSecure\/public\/index.php(11): Bootstrap->init()\n#3 \/www\/wwwroot\/cpeSecure\/index.php(2): require_once('...')\n#4 {main}",
|
||||
"method": "GET",
|
||||
"ip_address": "140.82.26.192",
|
||||
"user_agent": "curl\/7.76.1",
|
||||
"referer": null,
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-25 20:31:01"
|
||||
},
|
||||
{
|
||||
"id": "err_69ed5c896b0de3.37548309",
|
||||
"userid": null,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "https:\/\/secure.creditpullengine.com\/cron\/jsonReports",
|
||||
"file": "\/www\/wwwroot\/cpeSecure\/public\/controllers\/cron.php",
|
||||
"line": 14,
|
||||
"fullerror": "Class \"App\\Core\\StripeService\" not found",
|
||||
"trace": "#0 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(148): Cron->__construct()\n#1 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(63): Bootstrap->_loadExistingController()\n#2 \/www\/wwwroot\/cpeSecure\/public\/index.php(11): Bootstrap->init()\n#3 \/www\/wwwroot\/cpeSecure\/index.php(2): require_once('...')\n#4 {main}",
|
||||
"method": "GET",
|
||||
"ip_address": "207.246.75.27",
|
||||
"user_agent": null,
|
||||
"referer": null,
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-25 20:30:01"
|
||||
},
|
||||
{
|
||||
"id": "err_69ed5c895c99d9.73562260",
|
||||
"userid": null,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "https:\/\/secure.creditpullengine.com\/cron\/jsonReports",
|
||||
"file": "\/www\/wwwroot\/cpeSecure\/public\/controllers\/cron.php",
|
||||
"line": 14,
|
||||
"fullerror": "Class \"App\\Core\\StripeService\" not found",
|
||||
"trace": "#0 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(148): Cron->__construct()\n#1 \/www\/wwwroot\/cpeSecure\/core\/Bootstrap.php(63): Bootstrap->_loadExistingController()\n#2 \/www\/wwwroot\/cpeSecure\/public\/index.php(11): Bootstrap->init()\n#3 \/www\/wwwroot\/cpeSecure\/index.php(2): require_once('...')\n#4 {main}",
|
||||
"method": "GET",
|
||||
"ip_address": "140.82.26.192",
|
||||
"user_agent": "curl\/7.76.1",
|
||||
"referer": null,
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-25 20:30:01"
|
||||
},
|
||||
{
|
||||
"id": "err_69e773f2990218.94993625",
|
||||
"userid": 2548,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "http:\/\/nsecure.creditpullengine.com\/",
|
||||
"file": "\/www\/wwwroot\/nSecure\/core\/View.php",
|
||||
"line": 19,
|
||||
"fullerror": "Failed opening required '\/www\/wwwroot\/nSecure\/public\/views\/index\/orgadmin.php' (include_path='.:')",
|
||||
"trace": "#0 \/www\/wwwroot\/nSecure\/public\/controllers\/index.php(25): View->render()\n#1 \/www\/wwwroot\/nSecure\/core\/Bootstrap.php(133): Index->index()\n#2 \/www\/wwwroot\/nSecure\/core\/Bootstrap.php(40): Bootstrap->_loadDefaultController()\n#3 \/www\/wwwroot\/nSecure\/public\/index.php(11): Bootstrap->init()\n#4 \/www\/wwwroot\/nSecure\/index.php(2): require_once('...')\n#5 {main}",
|
||||
"method": "GET",
|
||||
"ip_address": "172.70.55.166",
|
||||
"user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/147.0.0.0 Safari\/537.36",
|
||||
"referer": "https:\/\/nsecure.creditpullengine.com\/company\/consumer-shield-llc.ZhYbs5uFyhX2G7JfdVIGsmxCGaDRq2A91vcUedk5_yU",
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-21 08:56:18"
|
||||
},
|
||||
{
|
||||
"id": "err_69e77133a9dbc2.26211292",
|
||||
"userid": 3,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "http:\/\/nsecure.creditpullengine.com\/pulls\/view\/1427.f5CHVieZZZGJISi3HECOj9z-oRbIbCuYysAbz22Y9oI",
|
||||
"file": "\/www\/wwwroot\/nSecure\/public\/controllers\/pulls.php",
|
||||
"line": 104,
|
||||
"fullerror": "Call to undefined function redirect()",
|
||||
"trace": "#0 \/www\/wwwroot\/nSecure\/core\/Bootstrap.php(222): pulls->view()\n#1 \/www\/wwwroot\/nSecure\/core\/Bootstrap.php(64): Bootstrap->_callControllerMethod()\n#2 \/www\/wwwroot\/nSecure\/public\/index.php(11): Bootstrap->init()\n#3 \/www\/wwwroot\/nSecure\/index.php(2): require_once('...')\n#4 {main}",
|
||||
"method": "GET",
|
||||
"ip_address": "172.70.55.166",
|
||||
"user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/147.0.0.0 Safari\/537.36",
|
||||
"referer": null,
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-21 08:44:35"
|
||||
},
|
||||
{
|
||||
"id": "err_69e77014a27279.45734769",
|
||||
"userid": 2566,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "http:\/\/nsecure.creditpullengine.com\/",
|
||||
"file": "\/www\/wwwroot\/nSecure\/core\/View.php",
|
||||
"line": 19,
|
||||
"fullerror": "Failed opening required '\/www\/wwwroot\/nSecure\/public\/views\/index\/orgadmin.php' (include_path='.:')",
|
||||
"trace": "#0 \/www\/wwwroot\/nSecure\/public\/controllers\/index.php(25): View->render()\n#1 \/www\/wwwroot\/nSecure\/core\/Bootstrap.php(133): Index->index()\n#2 \/www\/wwwroot\/nSecure\/core\/Bootstrap.php(40): Bootstrap->_loadDefaultController()\n#3 \/www\/wwwroot\/nSecure\/public\/index.php(11): Bootstrap->init()\n#4 \/www\/wwwroot\/nSecure\/index.php(2): require_once('...')\n#5 {main}",
|
||||
"method": "GET",
|
||||
"ip_address": "104.23.237.20",
|
||||
"user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/147.0.0.0 Safari\/537.36",
|
||||
"referer": "https:\/\/nsecure.creditpullengine.com\/admin\/users",
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-21 08:39:48"
|
||||
},
|
||||
{
|
||||
"id": "err_69e76e93d1cc43.29318732",
|
||||
"userid": 3,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "http:\/\/nsecure.creditpullengine.com\/pulls\/view\/1427.f5CHVieZZZGJISi3HECOj9z-oRbIbCuYysAbz22Y9oI",
|
||||
"file": "\/www\/wwwroot\/nSecure\/public\/controllers\/pulls.php",
|
||||
"line": 104,
|
||||
"fullerror": "Call to undefined function redirect()",
|
||||
"trace": "#0 \/www\/wwwroot\/nSecure\/core\/Bootstrap.php(222): pulls->view()\n#1 \/www\/wwwroot\/nSecure\/core\/Bootstrap.php(64): Bootstrap->_callControllerMethod()\n#2 \/www\/wwwroot\/nSecure\/public\/index.php(11): Bootstrap->init()\n#3 \/www\/wwwroot\/nSecure\/index.php(2): require_once('...')\n#4 {main}",
|
||||
"method": "GET",
|
||||
"ip_address": "104.23.237.20",
|
||||
"user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/147.0.0.0 Safari\/537.36",
|
||||
"referer": "https:\/\/nsecure.creditpullengine.com\/reports\/pulls\/consumer-shield-llc.YAj8lpRtFakNZbbopBFBpJGCDUF7bXC5B3HzJg0I3Bw",
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-21 08:33:23"
|
||||
},
|
||||
{
|
||||
"id": "err_69e76bb0efcf58.05946519",
|
||||
"userid": 3,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "http:\/\/nsecure.creditpullengine.com\/pulls\/view\/1459.jDV7q5dcrBikg_9FMFi4k6ZMtZokNkCl9Uk6JMYOIZg",
|
||||
"file": "\/www\/wwwroot\/nSecure\/public\/controllers\/pulls.php",
|
||||
"line": 104,
|
||||
"fullerror": "Call to undefined function redirect()",
|
||||
"trace": "#0 \/www\/wwwroot\/nSecure\/core\/Bootstrap.php(222): pulls->view()\n#1 \/www\/wwwroot\/nSecure\/core\/Bootstrap.php(64): Bootstrap->_callControllerMethod()\n#2 \/www\/wwwroot\/nSecure\/public\/index.php(11): Bootstrap->init()\n#3 \/www\/wwwroot\/nSecure\/index.php(2): require_once('...')\n#4 {main}",
|
||||
"method": "GET",
|
||||
"ip_address": "198.41.231.17",
|
||||
"user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/147.0.0.0 Safari\/537.36",
|
||||
"referer": "https:\/\/nsecure.creditpullengine.com\/reports\/pulls\/limpia-deudas-llc._i0s98IqNv38bmtnqrE7eluqQNSKLtkOdaJu2qOk3-I",
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-21 08:21:04"
|
||||
},
|
||||
{
|
||||
"id": "err_69e76b1f397f19.04102361",
|
||||
"userid": 2565,
|
||||
"org_id": null,
|
||||
"errortype": "Exception",
|
||||
"errorcode": "1",
|
||||
"url": "http:\/\/nsecure.creditpullengine.com\/",
|
||||
"file": "\/www\/wwwroot\/nSecure\/core\/View.php",
|
||||
"line": 19,
|
||||
"fullerror": "Failed opening required '\/www\/wwwroot\/nSecure\/public\/views\/index\/orgadmin.php' (include_path='.:')",
|
||||
"trace": "#0 \/www\/wwwroot\/nSecure\/public\/controllers\/index.php(25): View->render()\n#1 \/www\/wwwroot\/nSecure\/core\/Bootstrap.php(133): Index->index()\n#2 \/www\/wwwroot\/nSecure\/core\/Bootstrap.php(40): Bootstrap->_loadDefaultController()\n#3 \/www\/wwwroot\/nSecure\/public\/index.php(11): Bootstrap->init()\n#4 \/www\/wwwroot\/nSecure\/index.php(2): require_once('...')\n#5 {main}",
|
||||
"method": "GET",
|
||||
"ip_address": "172.68.7.18",
|
||||
"user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/147.0.0.0 Safari\/537.36",
|
||||
"referer": "https:\/\/nsecure.creditpullengine.com\/admin\/users",
|
||||
"status": "unresolved",
|
||||
"createdate": "2026-04-21 08:18:39"
|
||||
}
|
||||
]
|
||||
[]
|
||||
|
|
|
|||
BIN
app/public/avatar-placeholder.png
Normal file
BIN
app/public/avatar-placeholder.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
app/public/fonts/fraunces-latin.woff2
Normal file
BIN
app/public/fonts/fraunces-latin.woff2
Normal file
Binary file not shown.
BIN
app/public/fonts/inter-latin.woff2
Normal file
BIN
app/public/fonts/inter-latin.woff2
Normal file
Binary file not shown.
BIN
app/public/fonts/jetbrains-mono-latin.woff2
Normal file
BIN
app/public/fonts/jetbrains-mono-latin.woff2
Normal file
Binary file not shown.
Loading…
Reference in a new issue