fix: zamijeni auth polling health endpointom
Dodaje backend /api/health/ endpoint i prebacuje frontend heartbeat sa /api/token/ OPTIONS na /api/health/ GET kako bi se izbjeglo periodicko gadanje auth rute. Dodaje TTL cache za clientStore (lastFetchedAt + force opcija) kako bi se smanjili redundantni crm/clients pozivi pri navigaciji. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -2,14 +2,19 @@
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
from django.contrib import admin
|
||||
from django.http import JsonResponse
|
||||
from django.urls import path, include
|
||||
from rest_framework_simplejwt.views import (
|
||||
TokenObtainPairView,
|
||||
TokenRefreshView,
|
||||
)
|
||||
|
||||
def api_health(_request):
|
||||
return JsonResponse({'status': 'ok'})
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('api/health/', api_health, name='api_health'),
|
||||
|
||||
# Uključujemo rute iz modula (svaki modul ima svoj urls.py)
|
||||
path('api/crm/', include('modules.crm.urls')),
|
||||
|
||||
@@ -8,12 +8,25 @@ export const $clients = atom([]);
|
||||
export const $clientsLoading = atom(false);
|
||||
export const $clientsError = atom(null);
|
||||
|
||||
export async function fetchClients(signal) {
|
||||
let _lastClientsFetchAt = 0;
|
||||
const CLIENTS_FETCH_TTL_MS = 30_000; // 30 sekundi
|
||||
|
||||
export async function fetchClients(arg) {
|
||||
const options = (arg && typeof arg === 'object' && !('aborted' in arg))
|
||||
? arg
|
||||
: { signal: arg };
|
||||
const { signal, force = false } = options;
|
||||
|
||||
if (!force && $clients.get().length > 0 && Date.now() - _lastClientsFetchAt < CLIENTS_FETCH_TTL_MS) {
|
||||
return;
|
||||
}
|
||||
|
||||
$clientsLoading.set(true);
|
||||
$clientsError.set(null);
|
||||
try {
|
||||
const data = await api.get('crm/clients/', { signal });
|
||||
$clients.set(Array.isArray(data) ? data : (data.results ?? []));
|
||||
_lastClientsFetchAt = Date.now();
|
||||
} catch (err) {
|
||||
if (err?.name !== 'AbortError') $clientsError.set(err.message ?? 'Greška');
|
||||
} finally {
|
||||
@@ -24,16 +37,19 @@ export async function fetchClients(signal) {
|
||||
export async function createClient(payload) {
|
||||
const data = await api.post('crm/clients/', payload);
|
||||
$clients.set([...$clients.get(), data]);
|
||||
_lastClientsFetchAt = Date.now();
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function updateClient(id, payload) {
|
||||
const data = await api.patch(`crm/clients/${id}/`, payload);
|
||||
$clients.set($clients.get().map((c) => (c.id === id ? data : c)));
|
||||
_lastClientsFetchAt = Date.now();
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function deleteClient(id) {
|
||||
await api.delete(`crm/clients/${id}/`);
|
||||
$clients.set($clients.get().filter((c) => c.id !== id));
|
||||
_lastClientsFetchAt = Date.now();
|
||||
}
|
||||
|
||||
@@ -4,14 +4,14 @@ export const $isOffline = atom(false);
|
||||
|
||||
const API_BASE = import.meta.env.PUBLIC_API_URL || 'http://localhost:8001/api/';
|
||||
|
||||
// Heartbeat endpoint: OPTIONS /api/token/
|
||||
// DRF odgovara bez 405 greške i dovoljno je za provjeru dostupnosti backenda.
|
||||
const HEARTBEAT_URL = new URL('token/', API_BASE).toString();
|
||||
// Heartbeat endpoint: GET /api/health/
|
||||
// Time izbjegavamo periodično gađanje auth/token endpointa.
|
||||
const HEARTBEAT_URL = new URL('health/', API_BASE).toString();
|
||||
|
||||
async function provjeriStvarnuVezu() {
|
||||
try {
|
||||
const response = await fetch(HEARTBEAT_URL, {
|
||||
method: 'OPTIONS',
|
||||
method: 'GET',
|
||||
cache: 'no-store',
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user