import { Injectable } from '@angular/core'; import { HttpClient, HttpParams } from '@angular/common/http'; import { Observable } from 'rxjs'; // Types export interface IOrganization { id: string; name: string; displayName: string; description?: string; avatarUrl?: string; isPublic: boolean; memberCount: number; createdAt: string; } export interface IRepository { id: string; organizationId: string; name: string; displayName: string; description?: string; protocols: string[]; isPublic: boolean; packageCount: number; createdAt: string; } export interface IPackage { id: string; name: string; description?: string; protocol: string; organizationId: string; repositoryId: string; latestVersion?: string; isPrivate: boolean; downloadCount: number; updatedAt: string; } export interface ITokenScope { protocol: string; organizationId?: string; repositoryId?: string; actions: string[]; } export interface IToken { id: string; name: string; tokenPrefix: string; protocols: string[]; scopes?: ITokenScope[]; organizationId?: string; createdById?: string; expiresAt?: string; lastUsedAt?: string; usageCount: number; createdAt: string; } export interface IAuditLog { id: string; actorId?: string; actorType: string; action: string; resourceType: string; resourceId?: string; resourceName?: string; success: boolean; timestamp: string; } @Injectable({ providedIn: 'root' }) export class ApiService { private readonly baseUrl = '/api/v1'; constructor(private http: HttpClient) {} // Organizations getOrganizations(): Observable<{ organizations: IOrganization[] }> { return this.http.get<{ organizations: IOrganization[] }>( `${this.baseUrl}/organizations` ); } getOrganization(id: string): Observable { return this.http.get(`${this.baseUrl}/organizations/${id}`); } createOrganization(data: { name: string; displayName?: string; description?: string; isPublic?: boolean; }): Observable { return this.http.post(`${this.baseUrl}/organizations`, data); } updateOrganization( id: string, data: Partial ): Observable { return this.http.put( `${this.baseUrl}/organizations/${id}`, data ); } deleteOrganization(id: string): Observable<{ message: string }> { return this.http.delete<{ message: string }>( `${this.baseUrl}/organizations/${id}` ); } // Repositories getRepositories(orgId: string): Observable<{ repositories: IRepository[] }> { return this.http.get<{ repositories: IRepository[] }>( `${this.baseUrl}/organizations/${orgId}/repositories` ); } getRepository(id: string): Observable { return this.http.get(`${this.baseUrl}/repositories/${id}`); } createRepository( orgId: string, data: { name: string; displayName?: string; description?: string; protocols?: string[]; isPublic?: boolean; } ): Observable { return this.http.post( `${this.baseUrl}/organizations/${orgId}/repositories`, data ); } updateRepository( id: string, data: Partial ): Observable { return this.http.put(`${this.baseUrl}/repositories/${id}`, data); } deleteRepository(id: string): Observable<{ message: string }> { return this.http.delete<{ message: string }>( `${this.baseUrl}/repositories/${id}` ); } // Packages searchPackages(params?: { q?: string; protocol?: string; organizationId?: string; limit?: number; offset?: number; }): Observable<{ packages: IPackage[]; total: number }> { let httpParams = new HttpParams(); if (params?.q) httpParams = httpParams.set('q', params.q); if (params?.protocol) httpParams = httpParams.set('protocol', params.protocol); if (params?.organizationId) httpParams = httpParams.set('organizationId', params.organizationId); if (params?.limit) httpParams = httpParams.set('limit', params.limit.toString()); if (params?.offset) httpParams = httpParams.set('offset', params.offset.toString()); return this.http.get<{ packages: IPackage[]; total: number }>( `${this.baseUrl}/packages`, { params: httpParams } ); } getPackage(id: string): Observable { return this.http.get( `${this.baseUrl}/packages/${encodeURIComponent(id)}` ); } deletePackage(id: string): Observable<{ message: string }> { return this.http.delete<{ message: string }>( `${this.baseUrl}/packages/${encodeURIComponent(id)}` ); } // Tokens getTokens(organizationId?: string): Observable<{ tokens: IToken[] }> { let httpParams = new HttpParams(); if (organizationId) { httpParams = httpParams.set('organizationId', organizationId); } return this.http.get<{ tokens: IToken[] }>(`${this.baseUrl}/tokens`, { params: httpParams, }); } createToken(data: { name: string; organizationId?: string; protocols: string[]; scopes: ITokenScope[]; expiresInDays?: number; }): Observable { return this.http.post( `${this.baseUrl}/tokens`, data ); } revokeToken(id: string): Observable<{ message: string }> { return this.http.delete<{ message: string }>(`${this.baseUrl}/tokens/${id}`); } // Audit getAuditLogs(params?: { organizationId?: string; resourceType?: string; startDate?: string; endDate?: string; limit?: number; offset?: number; }): Observable<{ logs: IAuditLog[]; total: number }> { let httpParams = new HttpParams(); if (params?.organizationId) httpParams = httpParams.set('organizationId', params.organizationId); if (params?.resourceType) httpParams = httpParams.set('resourceType', params.resourceType); if (params?.startDate) httpParams = httpParams.set('startDate', params.startDate); if (params?.endDate) httpParams = httpParams.set('endDate', params.endDate); if (params?.limit) httpParams = httpParams.set('limit', params.limit.toString()); if (params?.offset) httpParams = httpParams.set('offset', params.offset.toString()); return this.http.get<{ logs: IAuditLog[]; total: number }>( `${this.baseUrl}/audit`, { params: httpParams } ); } }