Frontend Service Skill
Crea un servicio Axios para el frontend siguiendo el patron establecido en company.service.ts.
When to Activate
- Crear un nuevo servicio frontend para comunicarse con la API
- Completar los servicios pendientes (employee, establishment, tramite, ocr, payroll)
- Agregar funciones de upload con FormData
- Conectar una pantalla con el backend
Patron Base (src/services/{modulo}.service.ts)
import api from "../lib/api";
// 1. Interfaces del modelo (mapean al schema Prisma)
export interface ModelName {
id: number;
nombre: string;
// campos del modelo segun schema.prisma
createdAt?: string;
updatedAt?: string;
}
// 2. DTO para creacion (sin id, timestamps)
export interface CreateModelDto {
nombre: string;
// campos requeridos para creacion
}
// 3. DTO para actualizacion (todos opcionales)
export type UpdateModelDto = Partial<CreateModelDto>;
// 4. Funciones CRUD
export const getModels = async (): Promise<ModelName[]> => {
const token = localStorage.getItem("accessToken");
const response = await api.get("/api/{modulo}", {
headers: { Authorization: `Bearer ${token}` },
});
return response.data.data;
};
export const getModelById = async (id: number): Promise<ModelName> => {
const token = localStorage.getItem("accessToken");
const response = await api.get(`/api/{modulo}/${id}`, {
headers: { Authorization: `Bearer ${token}` },
});
return response.data.data;
};
export const createModel = async (data: CreateModelDto): Promise<ModelName> => {
const token = localStorage.getItem("accessToken");
const response = await api.post("/api/{modulo}", data, {
headers: { Authorization: `Bearer ${token}` },
});
return response.data.data;
};
export const updateModel = async (id: number, data: UpdateModelDto): Promise<ModelName> => {
const token = localStorage.getItem("accessToken");
const response = await api.put(`/api/{modulo}/${id}`, data, {
headers: { Authorization: `Bearer ${token}` },
});
return response.data.data;
};
export const deleteModel = async (id: number): Promise<void> => {
const token = localStorage.getItem("accessToken");
await api.delete(`/api/{modulo}/${id}`, {
headers: { Authorization: `Bearer ${token}` },
});
};
Upload con FormData
export const uploadFile = async (id: number, file: File): Promise<any> => {
const token = localStorage.getItem("accessToken");
const formData = new FormData();
formData.append("file", file);
const response = await api.post(`/api/{modulo}/${id}/upload`, formData, {
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "multipart/form-data",
},
});
return response.data;
};
Servicios Pendientes de Crear
| Servicio |
Archivo |
Funciones principales |
| Employee |
employee.service.ts |
CRUD + darAlta() + darBaja() + consultarNSS() + checkDni() |
| Establishment |
establishment.service.ts |
CRUD con geocoding |
| Tramite |
tramite.service.ts |
listarTramites() + descargarDocumento() |
| OCR |
ocr.service.ts |
uploadForScan() (web + mobile vision) |
| Payroll |
payroll.service.ts |
CRUD de nominas |
Convenciones del Proyecto
| Concepto |
Convencion |
| Import Axios |
import api from "../lib/api" (instancia con baseURL) |
| Auth |
localStorage.getItem("accessToken") → header Authorization: Bearer |
| Response |
Backend: { success, data } → Servicio retorna response.data.data |
| Tipos |
Interfaces TypeScript que mapean al schema Prisma |
| Naming |
camelCase para funciones, PascalCase para interfaces |
| Ubicacion |
src/services/{modulo}.service.ts |
| IDs |
number (Prisma usa Int autoincrement) |
Checklist
1---2name: frontend-service3description: Crea servicios Axios para el frontend siguiendo el patron de company.service.ts. Usar para generar los servicios API faltantes (employee, establishment, tramite, ocr, payroll).4---56# Frontend Service Skill78Crea un servicio Axios para el frontend siguiendo el patron establecido en `company.service.ts`.910## When to Activate1112- Crear un nuevo servicio frontend para comunicarse con la API13- Completar los servicios pendientes (employee, establishment, tramite, ocr, payroll)14- Agregar funciones de upload con FormData15- Conectar una pantalla con el backend1617## Patron Base (`src/services/{modulo}.service.ts`)1819```typescript20import api from "../lib/api";2122// 1. Interfaces del modelo (mapean al schema Prisma)23export interface ModelName {24 id: number;25 nombre: string;26 // campos del modelo segun schema.prisma27 createdAt?: string;28 updatedAt?: string;29}3031// 2. DTO para creacion (sin id, timestamps)32export interface CreateModelDto {33 nombre: string;34 // campos requeridos para creacion35}3637// 3. DTO para actualizacion (todos opcionales)38export type UpdateModelDto = Partial<CreateModelDto>;3940// 4. Funciones CRUD41export const getModels = async (): Promise<ModelName[]> => {42 const token = localStorage.getItem("accessToken");43 const response = await api.get("/api/{modulo}", {44 headers: { Authorization: `Bearer ${token}` },45 });46 return response.data.data;47};4849export const getModelById = async (id: number): Promise<ModelName> => {50 const token = localStorage.getItem("accessToken");51 const response = await api.get(`/api/{modulo}/${id}`, {52 headers: { Authorization: `Bearer ${token}` },53 });54 return response.data.data;55};5657export const createModel = async (data: CreateModelDto): Promise<ModelName> => {58 const token = localStorage.getItem("accessToken");59 const response = await api.post("/api/{modulo}", data, {60 headers: { Authorization: `Bearer ${token}` },61 });62 return response.data.data;63};6465export const updateModel = async (id: number, data: UpdateModelDto): Promise<ModelName> => {66 const token = localStorage.getItem("accessToken");67 const response = await api.put(`/api/{modulo}/${id}`, data, {68 headers: { Authorization: `Bearer ${token}` },69 });70 return response.data.data;71};7273export const deleteModel = async (id: number): Promise<void> => {74 const token = localStorage.getItem("accessToken");75 await api.delete(`/api/{modulo}/${id}`, {76 headers: { Authorization: `Bearer ${token}` },77 });78};79```8081## Upload con FormData8283```typescript84export const uploadFile = async (id: number, file: File): Promise<any> => {85 const token = localStorage.getItem("accessToken");86 const formData = new FormData();87 formData.append("file", file);8889 const response = await api.post(`/api/{modulo}/${id}/upload`, formData, {90 headers: {91 Authorization: `Bearer ${token}`,92 "Content-Type": "multipart/form-data",93 },94 });95 return response.data;96};97```9899## Servicios Pendientes de Crear100101| Servicio | Archivo | Funciones principales |102|----------|---------|----------------------|103| Employee | `employee.service.ts` | CRUD + `darAlta()` + `darBaja()` + `consultarNSS()` + `checkDni()` |104| Establishment | `establishment.service.ts` | CRUD con geocoding |105| Tramite | `tramite.service.ts` | `listarTramites()` + `descargarDocumento()` |106| OCR | `ocr.service.ts` | `uploadForScan()` (web + mobile vision) |107| Payroll | `payroll.service.ts` | CRUD de nominas |108109## Convenciones del Proyecto110111| Concepto | Convencion |112|----------|-----------|113| Import Axios | `import api from "../lib/api"` (instancia con baseURL) |114| Auth | `localStorage.getItem("accessToken")` → header `Authorization: Bearer` |115| Response | Backend: `{ success, data }` → Servicio retorna `response.data.data` |116| Tipos | Interfaces TypeScript que mapean al schema Prisma |117| Naming | camelCase para funciones, PascalCase para interfaces |118| Ubicacion | `src/services/{modulo}.service.ts` |119| IDs | `number` (Prisma usa Int autoincrement) |120121## Checklist122123- [ ] Interfaces del modelo y DTO definidas124- [ ] Funciones CRUD exportadas (get, getById, create, update, delete)125- [ ] Token de auth en cada request126- [ ] Tipos de retorno correctos (Promise<T>)127- [ ] FormData para uploads si aplica128- [ ] Funciones especificas del dominio (alta, baja, consultarNSS, etc.)