chore: durcit la configuration pour la production

- mobile: externalise l'URL d'API via EXPO_PUBLIC_API_URL (repli localhost en dev)
- backend: .env.example adapté au projet (PostgreSQL, JWT, FRONTEND_URL, Redis)
- frontend/mobile: ajoute .env.example (+ exception gitignore front)
- mobile: supprime les 4 `any` (helper getApiError, type Feed, glyphMap Ionicons)
- backend: normalise le style PSR-12 via Pint (13 fichiers)

Tests backend 15/15, mobile tsc 0, Pint pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Azmog
2026-06-17 17:00:33 +02:00
parent 052e2f22cd
commit 6f5b8182ca
22 changed files with 122 additions and 95 deletions
+34 -44
View File
@@ -1,65 +1,55 @@
APP_NAME=Laravel
APP_NAME=CESIZen
APP_ENV=local
APP_KEY=
APP_DEBUG=false
APP_URL=http://localhost
APP_DEBUG=true
APP_URL=http://localhost:8000
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US
# Passer APP_ENV=production et APP_DEBUG=false en production.
# Générer les clés au déploiement : `php artisan key:generate` puis `php artisan jwt:secret`.
APP_MAINTENANCE_DRIVER=file
# APP_MAINTENANCE_STORE=database
# PHP_CLI_SERVER_WORKERS=4
BCRYPT_ROUNDS=12
APP_LOCALE=fr
APP_FALLBACK_LOCALE=fr
APP_FAKER_LOCALE=fr_FR
LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=
# Base de données — PostgreSQL 16
DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=cesizen
DB_USERNAME=cesizen
DB_PASSWORD=
SESSION_DRIVER=database
# Authentification JWT (tymon/jwt-auth)
JWT_SECRET=
JWT_TTL=60
JWT_REFRESH_TTL=20160
# CORS — origine autorisée du frontend web
FRONTEND_URL=http://localhost:3000
# Cache / sessions / files d'attente — Redis en production
CACHE_STORE=redis
SESSION_DRIVER=redis
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=null
BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
QUEUE_CONNECTION=database
CACHE_STORE=database
# CACHE_PREFIX=
MEMCACHED_HOST=127.0.0.1
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
QUEUE_CONNECTION=redis
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
BCRYPT_ROUNDS=12
FILESYSTEM_DISK=local
BROADCAST_CONNECTION=log
MAIL_MAILER=log
MAIL_SCHEME=null
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_ADDRESS="no-reply@cesizen.fr"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
VITE_APP_NAME="${APP_NAME}"
@@ -12,7 +12,7 @@ class AdminEmotionController extends Controller
public function index(): JsonResponse
{
$emotions = Emotion::niveau(1)
->with(['enfants' => fn($q) => $q->orderBy('nom')])
->with(['enfants' => fn ($q) => $q->orderBy('nom')])
->orderBy('nom')
->get();
@@ -39,7 +39,7 @@ class AdminFeedController extends Controller
$feed = Feed::findOrFail($id);
$data = $request->validated();
if (isset($data['titre']) && !isset($data['slug'])) {
if (isset($data['titre']) && ! isset($data['slug'])) {
$data['slug'] = Str::slug($data['titre']);
}
@@ -3,9 +3,8 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Utilisateur;
use App\Models\Role;
use App\Models\Tracker;
use App\Models\Utilisateur;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -19,13 +18,13 @@ class AdminUtilisateurController extends Controller
$search = $request->search;
$query->where(function ($q) use ($search) {
$q->where('nom', 'like', "%{$search}%")
->orWhere('prenom', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%");
->orWhere('prenom', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%");
});
}
if ($request->filled('role')) {
$query->whereHas('role', fn($q) => $q->where('nom', $request->role));
$query->whereHas('role', fn ($q) => $q->where('nom', $request->role));
}
$utilisateurs = $query->orderBy('created_at', 'desc')->paginate(15);
@@ -88,7 +87,7 @@ class AdminUtilisateurController extends Controller
public function toggleActive(int $id): JsonResponse
{
$utilisateur = Utilisateur::findOrFail($id);
$utilisateur->update(['est_actif' => !$utilisateur->est_actif]);
$utilisateur->update(['est_actif' => ! $utilisateur->est_actif]);
return response()->json([
'message' => $utilisateur->est_actif ? 'Compte activé' : 'Compte désactivé',
@@ -2,11 +2,11 @@
namespace App\Http\Controllers;
use App\Http\Requests\RegisterRequest;
use App\Http\Requests\LoginRequest;
use App\Models\Utilisateur;
use App\Http\Requests\RegisterRequest;
use App\Models\Role;
use App\Models\Tracker;
use App\Models\Utilisateur;
use Illuminate\Http\JsonResponse;
use Tymon\JWTAuth\Facades\JWTAuth;
@@ -44,7 +44,7 @@ class AuthController extends Controller
{
$credentials = $request->only('email', 'password');
if (!$token = auth()->attempt($credentials)) {
if (! $token = auth()->attempt($credentials)) {
return response()->json([
'message' => 'Identifiants incorrects',
], 401);
@@ -52,8 +52,9 @@ class AuthController extends Controller
$utilisateur = auth()->user();
if (!$utilisateur->est_actif) {
if (! $utilisateur->est_actif) {
auth()->logout();
return response()->json([
'message' => 'Votre compte a été désactivé',
], 403);
@@ -35,7 +35,7 @@ class ProfilController extends Controller
{
$utilisateur = auth()->user();
if (!Hash::check($request->ancien_mot_de_passe, $utilisateur->password)) {
if (! Hash::check($request->ancien_mot_de_passe, $utilisateur->password)) {
return response()->json([
'message' => 'L\'ancien mot de passe est incorrect',
], 422);
@@ -3,7 +3,6 @@
namespace App\Http\Controllers;
use App\Http\Requests\StoreSaisieRequest;
use App\Models\SaisieTracker;
use App\Services\RapportService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -14,7 +13,7 @@ class SaisieTrackerController extends Controller
{
$tracker = auth()->user()->tracker;
if (!$tracker) {
if (! $tracker) {
return response()->json([]);
}
@@ -39,7 +38,7 @@ class SaisieTrackerController extends Controller
{
$tracker = auth()->user()->tracker;
if (!$tracker) {
if (! $tracker) {
$tracker = auth()->user()->tracker()->create(['nom' => 'Mon journal']);
}
@@ -4,10 +4,10 @@ namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Facades\JWTAuth;
class JwtMiddleware
{
@@ -11,7 +11,7 @@ class RoleMiddleware
{
$user = auth()->user();
if (!$user || !$user->role || !in_array($user->role->nom, $roles)) {
if (! $user || ! $user->role || ! in_array($user->role->nom, $roles)) {
return response()->json(['message' => 'Accès non autorisé'], 403);
}
+5 -7
View File
@@ -3,9 +3,7 @@
namespace App\Services;
use App\Models\Utilisateur;
use App\Models\SaisieTracker;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
class RapportService
{
@@ -13,7 +11,7 @@ class RapportService
{
$tracker = $user->tracker;
if (!$tracker) {
if (! $tracker) {
return $this->rapportVide();
}
@@ -35,7 +33,7 @@ class RapportService
$intensiteMoyenne = round($saisies->avg('intensite'), 1);
$emotionsDominantes = $saisies->groupBy('emotion_id')
->map(fn($group) => [
->map(fn ($group) => [
'emotion' => $group->first()->emotion,
'count' => $group->count(),
'intensite_moyenne' => round($group->avg('intensite'), 1),
@@ -47,7 +45,7 @@ class RapportService
$evolution = $this->getEvolution($saisies, $period, $dateDebut, $dateFin);
$repartition = $emotionsDominantes->map(fn($item) => [
$repartition = $emotionsDominantes->map(fn ($item) => [
'nom' => $item['emotion']->nom,
'couleur' => $item['emotion']->couleur,
'icone' => $item['emotion']->icone,
@@ -96,7 +94,7 @@ class RapportService
default => 'Y-m-d',
};
$grouped = $saisies->groupBy(fn($saisie) => $saisie->date_saisie->format($format));
$grouped = $saisies->groupBy(fn ($saisie) => $saisie->date_saisie->format($format));
$labels = [];
$dataIntensiteMoyenne = [];
@@ -108,7 +106,7 @@ class RapportService
$emotionDatasets = $saisies->groupBy('emotion_id')->map(function ($emotionGroup) use ($format, $grouped) {
$emotion = $emotionGroup->first()->emotion;
$byPeriod = $emotionGroup->groupBy(fn($s) => $s->date_saisie->format($format));
$byPeriod = $emotionGroup->groupBy(fn ($s) => $s->date_saisie->format($format));
$data = [];
foreach ($grouped->keys() as $label) {
+6 -3
View File
@@ -1,5 +1,8 @@
<?php
use App\Http\Middleware\ForceJsonResponse;
use App\Http\Middleware\JwtMiddleware;
use App\Http\Middleware\RoleMiddleware;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
@@ -13,12 +16,12 @@ return Application::configure(basePath: dirname(__DIR__))
)
->withMiddleware(function (Middleware $middleware): void {
$middleware->alias([
'jwt.auth' => \App\Http\Middleware\JwtMiddleware::class,
'role' => \App\Http\Middleware\RoleMiddleware::class,
'jwt.auth' => JwtMiddleware::class,
'role' => RoleMiddleware::class,
]);
$middleware->api(prepend: [
\App\Http\Middleware\ForceJsonResponse::class,
ForceJsonResponse::class,
]);
})
->withExceptions(function (Exceptions $exceptions): void {
+8 -8
View File
@@ -1,14 +1,14 @@
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\ProfilController;
use App\Http\Controllers\FeedController;
use App\Http\Controllers\EmotionController;
use App\Http\Controllers\SaisieTrackerController;
use App\Http\Controllers\Admin\AdminUtilisateurController;
use App\Http\Controllers\Admin\AdminFeedController;
use App\Http\Controllers\Admin\AdminEmotionController;
use App\Http\Controllers\Admin\AdminFeedController;
use App\Http\Controllers\Admin\AdminUtilisateurController;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\EmotionController;
use App\Http\Controllers\FeedController;
use App\Http\Controllers\ProfilController;
use App\Http\Controllers\SaisieTrackerController;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
@@ -14,8 +14,11 @@ class AdminUtilisateurTest extends TestCase
use RefreshDatabase;
protected Utilisateur $admin;
protected Utilisateur $membre;
protected string $tokenAdmin;
protected string $tokenMembre;
protected function setUp(): void
+2
View File
@@ -16,7 +16,9 @@ class TrackerTest extends TestCase
use RefreshDatabase;
protected Utilisateur $utilisateur;
protected Emotion $emotion;
protected string $token;
protected function setUp(): void