feat: phase 6 — dashboard widgets, sales & stock reports, user management, activity log

This commit is contained in:
sean
2026-08-25 19:25:40 +07:00
parent 28937a786e
commit feba1ec839
18 changed files with 1011 additions and 5 deletions
+32
View File
@@ -13,12 +13,20 @@ class InsForgeFake
/** @var list<array{function: string, args: array<string, mixed>}> */
public static array $rpcCalls = [];
/** @var array<string, string> email => auth uuid */
public static array $authUsersByEmail = [];
/** @var list<string> */
public static array $rawSqlQueries = [];
public static string $accessToken = '';
public static function reset(): void
{
self::$store = [];
self::$rpcCalls = [];
self::$authUsersByEmail = [];
self::$rawSqlQueries = [];
}
public static function seed(string $table, array $row): void
@@ -71,6 +79,30 @@ class InsForgeFake
{
Http::fake([
'*/api/auth/refresh' => Http::response(['accessToken' => self::$accessToken], 200),
'*/api/auth/users' => function (Request $request) {
if (strtoupper($request->method()) === 'POST') {
$payload = $request->data();
self::$authUsersByEmail[$payload['email'] ?? ''] = 'auth-'.md5((string) ($payload['email'] ?? ''));
return Http::response(['accessToken' => null, 'requireEmailVerification' => true], 200);
}
return Http::response([], 200);
},
'*/api/database/advance/rawsql*' => function (Request $request) {
$query = (string) ($request->data()['query'] ?? '');
self::$rawSqlQueries[] = $query;
if (str_contains($query, 'FROM auth.users') && str_contains(strtoupper($query), 'SELECT')) {
preg_match("/email = '([^']+)'/", $query, $m);
$id = self::$authUsersByEmail[$m[1] ?? ''] ?? null;
return Http::response(['rows' => $id ? [['id' => $id]] : []], 200);
}
return Http::response(['rows' => []], 200);
},
'*/api/database/rpc/*' => function (Request $request) {
$function = str_replace('/api/database/rpc/', '', (string) parse_url($request->url(), PHP_URL_PATH));
$args = $request->data();