Base api connection requirements and models

This commit is contained in:
Marta Borgia Leiva 2026-02-09 20:13:12 +01:00
parent 9ab0505ed4
commit 2cf0856db5
Signed by: a-mayb3
GPG key ID: 293AAC4FED165CE3
7 changed files with 226 additions and 0 deletions

View file

@ -0,0 +1,8 @@
/**
* Environment configuration
* Update these values based on your environment (development, production, etc.)
*/
export const environment = {
production: false,
apiBaseUrl: 'http://localhost:8000',
};

View file

@ -0,0 +1,19 @@
import { inject } from '@angular/core';
import { CanActivateFn, Router, UrlTree } from '@angular/router';
import { AuthService } from '../services/auth.service';
/**
* Auth guard to protect routes that require authentication
* Usage: Add to route definition with canActivate: [authGuard]
*/
export const authGuard: CanActivateFn = (): boolean | UrlTree => {
const authService = inject(AuthService);
const router = inject(Router);
if (authService.isAuthenticated()) {
return true;
} else {
// Redirect to login page
return router.createUrlTree(['/login']);
}
};

View file

@ -0,0 +1,30 @@
/**
* Authentication-related type definitions
*/
import { Project } from "./projects.models";
export interface LoginRequest {
email: string;
password: string;
}
export interface LoginResponse {
success: boolean;
message?: string;
user?: User;
token?: string; // Optional: if you need the JWT on client side
}
export interface User {
id: string | number;
name: string;
email: string;
projects?: Project[]; // Add project type if available
// Add other user properties as needed
}
export interface AuthState {
isAuthenticated: boolean;
user: User | null;
}

View file

@ -0,0 +1,26 @@
import { User } from "./auth.models";
import { Task } from "./tasks.models";
export interface Project {
id: number;
name: string;
description?: string;
}
export interface ProjectFull {
id: number;
name: string;
description?: string;
tasks: Task[];
users: User[];
}
export interface CreateProjectRequest {
name: string;
description?: string;
}
export interface UpdateProjectRequest {
name?: string;
description?: string;
}

View file

@ -0,0 +1,7 @@
export interface Task{
id: number;
title: string;
description?: string;
status: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'STASHED' | 'FAILED';
}

View file

@ -0,0 +1,44 @@
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from '../config/environment';
/**
* Base API service that provides common HTTP operations
* Other services can inject this for reusable API patterns
*/
@Injectable({
providedIn: 'root'
})
export class ApiService {
private http = inject(HttpClient);
protected readonly baseUrl = environment.apiBaseUrl;
/**
* HTTP GET request
*/
get<T>(endpoint: string): Observable<T> {
return this.http.get<T>(`${this.baseUrl}${endpoint}`);
}
/**
* HTTP POST request
*/
post<T>(endpoint: string, body: any): Observable<T> {
return this.http.post<T>(`${this.baseUrl}${endpoint}`, body);
}
/**
* HTTP PUT request
*/
put<T>(endpoint: string, body: any): Observable<T> {
return this.http.put<T>(`${this.baseUrl}${endpoint}`, body);
}
/**
* HTTP DELETE request
*/
delete<T>(endpoint: string): Observable<T> {
return this.http.delete<T>(`${this.baseUrl}${endpoint}`);
}
}

View file

@ -0,0 +1,92 @@
import { Injectable, inject, signal, computed } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, tap } from 'rxjs';
import { Router } from '@angular/router';
import { LoginRequest, LoginResponse, User, AuthState } from '../models/auth.models';
import { environment } from '../config/environment';
/**
* Authentication service that manages user login, logout, and session state
* Uses signals for reactive state management
*/
@Injectable({
providedIn: 'root'
})
export class AuthService {
private http = inject(HttpClient);
private router = inject(Router);
// Reactive auth state using signals
private authState = signal<AuthState>({
isAuthenticated: false,
user: null
});
// Public computed signals for components to consume
readonly isAuthenticated = computed(() => this.authState().isAuthenticated);
readonly currentUser = computed(() => this.authState().user);
/**
* Login with credentials
* The JWT will be set as an HTTP-only cookie by the backend
*/
login(credentials: LoginRequest): Observable<LoginResponse> {
return this.http.post<LoginResponse>(
`${environment.apiBaseUrl}/auth/login`,
credentials
).pipe(
tap(response => {
if (response.success && response.user) {
// Update auth state
this.authState.set({
isAuthenticated: true,
user: response.user
});
}
})
);
}
/**
* Logout the current user
* Clears the session cookie on the backend
*/
logout(): Observable<any> {
return this.http.post(`${environment.apiBaseUrl}/me/logout`, {}).pipe(
tap(() => {
// Clear auth state
this.authState.set({
isAuthenticated: false,
user: null
});
// Redirect to login
this.router.navigate(['/login']);
})
);
}
/**
* Check current session / get current user
* Call this on app initialization to restore session state
*/
checkSession(): Observable<User> {
return this.http.get<User>(`${environment.apiBaseUrl}/me`).pipe(
tap(user => {
this.authState.set({
isAuthenticated: true,
user: user
});
})
);
}
/**
* Clear auth state (use when session expires or on error)
*/
clearAuthState(): void {
this.authState.set({
isAuthenticated: false,
user: null
});
}
}