195 lines
6.9 KiB
TypeScript
195 lines
6.9 KiB
TypeScript
import type {
|
|
KappaLoginPayload,
|
|
KappaLoginResponse,
|
|
KappaInitiative,
|
|
KappaUserStory,
|
|
KappaEpicDevelopment,
|
|
KappaCreateEpicPayload,
|
|
KappaLogbookMaster,
|
|
KappaLogbookEntry,
|
|
KappaPlanningMaster,
|
|
KappaPlanningEntry,
|
|
KappaBusinessRule,
|
|
KappaRequirement,
|
|
KappaEmployee,
|
|
PaginatedResponse,
|
|
} from '@/types/kappa'
|
|
|
|
const BASE = '/api'
|
|
|
|
class KappaAPI {
|
|
private token: string | null = null
|
|
|
|
constructor() {
|
|
this.token = localStorage.getItem('kappa_token')
|
|
}
|
|
|
|
private get headers(): Record<string, string> {
|
|
const h: Record<string, string> = {
|
|
'Content-Type': 'application/json',
|
|
}
|
|
if (this.token) {
|
|
h['Authorization'] = `Bearer ${this.token}`
|
|
}
|
|
return h
|
|
}
|
|
|
|
private async request<T>(
|
|
method: string,
|
|
path: string,
|
|
body?: unknown
|
|
): Promise<T> {
|
|
const opts: RequestInit = {
|
|
method,
|
|
headers: this.headers,
|
|
}
|
|
if (body && method !== 'GET') {
|
|
opts.body = JSON.stringify(body)
|
|
}
|
|
const res = await fetch(`${BASE}${path}`, opts)
|
|
if (!res.ok) {
|
|
const text = await res.text()
|
|
throw new Error(`KAPPA ${method} ${path}: ${res.status} — ${text.slice(0, 200)}`)
|
|
}
|
|
return res.json()
|
|
}
|
|
|
|
// ─── Auth ────────────────────────────────────────────
|
|
|
|
async login(payload: KappaLoginPayload): Promise<KappaLoginResponse> {
|
|
const data = await this.request<KappaLoginResponse>(
|
|
'POST',
|
|
'/users/login/',
|
|
payload
|
|
)
|
|
this.token = data.access || data.token || data.key || null
|
|
if (this.token) {
|
|
localStorage.setItem('kappa_token', this.token)
|
|
}
|
|
return data
|
|
}
|
|
|
|
logout() {
|
|
this.token = null
|
|
localStorage.removeItem('kappa_token')
|
|
}
|
|
|
|
get isAuthenticated(): boolean {
|
|
return !!this.token
|
|
}
|
|
|
|
// ─── Proyectos (Initiatives) ─────────────────────────
|
|
|
|
async getInitiatives(): Promise<KappaInitiative[]> {
|
|
return this.request<KappaInitiative[]>('GET', '/initiatives-all/')
|
|
}
|
|
|
|
// ─── User Stories ────────────────────────────────────
|
|
|
|
async createUserStory(story: KappaUserStory): Promise<KappaUserStory> {
|
|
return this.request<KappaUserStory>('POST', '/userstorys/create/', story)
|
|
}
|
|
|
|
// ─── Users ───────────────────────────────────────────
|
|
|
|
async getUsers(): Promise<unknown[]> {
|
|
return this.request<unknown[]>('GET', '/users/all/')
|
|
}
|
|
|
|
async getEmployees(page = 1): Promise<PaginatedResponse<KappaEmployee>> {
|
|
return this.request<PaginatedResponse<KappaEmployee>>('GET', `/employees/?page=${page}`)
|
|
}
|
|
|
|
async getUserStories(initiativeId?: number, page = 1, pageSize = 100): Promise<PaginatedResponse<KappaUserStory>> {
|
|
const params = new URLSearchParams()
|
|
if (initiativeId) params.set('initiative', String(initiativeId))
|
|
params.set('page', String(page))
|
|
params.set('page_size', String(pageSize))
|
|
return this.request<PaginatedResponse<KappaUserStory>>('GET', `/userstorys/?${params.toString()}`)
|
|
}
|
|
|
|
async getAllUserStories(initiativeId: number): Promise<KappaUserStory[]> {
|
|
const first = await this.getUserStories(initiativeId, 1, 100)
|
|
const all = [...first.results]
|
|
const totalPages = Math.ceil(first.count / 100)
|
|
for (let p = 2; p <= totalPages; p++) {
|
|
const page = await this.getUserStories(initiativeId, p, 100)
|
|
all.push(...page.results)
|
|
}
|
|
return all
|
|
}
|
|
|
|
async getEpicDevelopment(initiativeId: number, page = 1, pageSize = 50): Promise<PaginatedResponse<KappaEpicDevelopment>> {
|
|
return this.request<PaginatedResponse<KappaEpicDevelopment>>('GET', `/epicdevelopment/?initiative=${initiativeId}&page=${page}&page_size=${pageSize}`)
|
|
}
|
|
|
|
async getAllEpicDevelopment(initiativeId: number): Promise<KappaEpicDevelopment[]> {
|
|
const first = await this.getEpicDevelopment(initiativeId, 1, 100)
|
|
const all = [...first.results]
|
|
const totalPages = Math.ceil(first.count / 100)
|
|
for (let p = 2; p <= totalPages; p++) {
|
|
const page = await this.getEpicDevelopment(initiativeId, p, 100)
|
|
all.push(...page.results)
|
|
}
|
|
return all
|
|
}
|
|
|
|
async createEpicDevelopment(data: KappaCreateEpicPayload): Promise<KappaEpicDevelopment> {
|
|
return this.request<KappaEpicDevelopment>('POST', '/epicdevelopment/create/', data)
|
|
}
|
|
|
|
async getLogbooks(initiativeId?: number): Promise<KappaLogbookEntry[]> {
|
|
const path = initiativeId ? `/logbooks/?initiative=${initiativeId}` : '/logbooks/'
|
|
return this.request<KappaLogbookEntry[]>('GET', path)
|
|
}
|
|
|
|
async getPlannings(initiativeId?: number): Promise<KappaPlanningEntry[]> {
|
|
const path = initiativeId ? `/plannings/?initiative=${initiativeId}` : '/plannings/'
|
|
return this.request<KappaPlanningEntry[]>('GET', path)
|
|
}
|
|
|
|
async getBusinessRules(initiativeId?: number): Promise<KappaBusinessRule[]> {
|
|
const path = initiativeId ? `/business-rules/?initiative=${initiativeId}` : '/business-rules/'
|
|
return this.request<KappaBusinessRule[]>('GET', path)
|
|
}
|
|
|
|
async getRequirements(initiativeId?: number): Promise<KappaRequirement[]> {
|
|
const path = initiativeId ? `/functionalrequirements/?initiative=${initiativeId}` : '/functionalrequirements/'
|
|
return this.request<KappaRequirement[]>('GET', path)
|
|
}
|
|
|
|
// ─── Bitácoras (Logbooks) ────────────────────────────
|
|
|
|
async createLogbookMaster(data: KappaLogbookMaster): Promise<KappaLogbookMaster> {
|
|
return this.request<KappaLogbookMaster>('POST', '/logbooks_master/create/', data)
|
|
}
|
|
|
|
async createLogbookEntry(data: KappaLogbookEntry): Promise<KappaLogbookEntry> {
|
|
return this.request<KappaLogbookEntry>('POST', '/logbooks/create/', data)
|
|
}
|
|
|
|
// ─── Planeaciones (Plannings) ────────────────────────
|
|
|
|
async createPlanningMaster(data: KappaPlanningMaster): Promise<KappaPlanningMaster> {
|
|
return this.request<KappaPlanningMaster>('POST', '/plannings_master/create/', data)
|
|
}
|
|
|
|
async createPlanningEntry(data: KappaPlanningEntry): Promise<KappaPlanningEntry> {
|
|
return this.request<KappaPlanningEntry>('POST', '/plannings/create/', data)
|
|
}
|
|
|
|
// ─── Business Rules ──────────────────────────────────
|
|
|
|
async createBusinessRule(data: KappaBusinessRule): Promise<unknown> {
|
|
return this.request<unknown>('POST', '/business-rules/create/', data)
|
|
}
|
|
|
|
// ─── Requisitos ──────────────────────────────────────
|
|
|
|
async createRequirement(data: KappaRequirement): Promise<unknown> {
|
|
return this.request<unknown>('POST', '/functionalrequirements/create/', data)
|
|
}
|
|
}
|
|
|
|
export const kappa = new KappaAPI()
|