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 { const h: Record = { 'Content-Type': 'application/json', } if (this.token) { h['Authorization'] = `Bearer ${this.token}` } return h } private async request( method: string, path: string, body?: unknown ): Promise { 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 { const data = await this.request( '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 { return this.request('GET', '/initiatives-all/') } // ─── User Stories ──────────────────────────────────── async createUserStory(story: KappaUserStory): Promise { return this.request('POST', '/userstorys/create/', story) } // ─── Users ─────────────────────────────────────────── async getUsers(): Promise { return this.request('GET', '/users/all/') } async getEmployees(page = 1): Promise> { return this.request>('GET', `/employees/?page=${page}`) } async getUserStories(initiativeId?: number, page = 1, pageSize = 100): Promise> { 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>('GET', `/userstorys/?${params.toString()}`) } async getAllUserStories(initiativeId: number): Promise { 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> { return this.request>('GET', `/epicdevelopment/?initiative=${initiativeId}&page=${page}&page_size=${pageSize}`) } async getAllEpicDevelopment(initiativeId: number): Promise { 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 { return this.request('POST', '/epicdevelopment/create/', data) } async getLogbooks(initiativeId?: number): Promise { const path = initiativeId ? `/logbooks/?initiative=${initiativeId}` : '/logbooks/' return this.request('GET', path) } async getPlannings(initiativeId?: number): Promise { const path = initiativeId ? `/plannings/?initiative=${initiativeId}` : '/plannings/' return this.request('GET', path) } async getBusinessRules(initiativeId?: number): Promise { const path = initiativeId ? `/business-rules/?initiative=${initiativeId}` : '/business-rules/' return this.request('GET', path) } async getRequirements(initiativeId?: number): Promise { const path = initiativeId ? `/functionalrequirements/?initiative=${initiativeId}` : '/functionalrequirements/' return this.request('GET', path) } // ─── Bitácoras (Logbooks) ──────────────────────────── async createLogbookMaster(data: KappaLogbookMaster): Promise { return this.request('POST', '/logbooks_master/create/', data) } async createLogbookEntry(data: KappaLogbookEntry): Promise { return this.request('POST', '/logbooks/create/', data) } // ─── Planeaciones (Plannings) ──────────────────────── async createPlanningMaster(data: KappaPlanningMaster): Promise { return this.request('POST', '/plannings_master/create/', data) } async createPlanningEntry(data: KappaPlanningEntry): Promise { return this.request('POST', '/plannings/create/', data) } // ─── Business Rules ────────────────────────────────── async createBusinessRule(data: KappaBusinessRule): Promise { return this.request('POST', '/business-rules/create/', data) } // ─── Requisitos ────────────────────────────────────── async createRequirement(data: KappaRequirement): Promise { return this.request('POST', '/functionalrequirements/create/', data) } } export const kappa = new KappaAPI()