Skip to main content
GET
/
api
/
audit
Audit Log
curl --request GET \
  --url https://api.example.com/api/audit
{
  "id": 123,
  "accion": "<string>",
  "entidad": "<string>",
  "entidad_id": "<string>",
  "usuario_id": 123,
  "usuario_nombre": "<string>",
  "usuario_apellido": "<string>",
  "cambios": "<string>",
  "fecha": "<string>"
}

Overview

Retrieve audit log entries showing all system actions including creates, updates, and deletes. The audit log provides a complete history of data changes.
All CUD (Create, Update, Delete) operations are automatically logged with user ID, timestamp, and change details.

Authentication

Requires valid JWT token. Viewing audit logs requires admin or calidad role.
Authorization: Bearer <token>

Query Parameters

fecha_inicio
string
Start date filter (YYYY-MM-DD format)
fecha_fin
string
End date filter (YYYY-MM-DD format)
usuario_id
number
Filter by user ID
accion
string
Filter by action type: crear, editar, eliminar, exportar, importar
entidad
string
Filter by entity/table name (e.g., pesaje, usuarios, areas)
limit
number
default:1000
Maximum number of records to return

Request Example

curl -X GET "http://localhost:3001/api/audit?limit=100" \
  -H "Authorization: Bearer YOUR_TOKEN"

Response

id
number
Unique audit entry ID
accion
string
Action performed: crear, editar, eliminar, exportar, importar
entidad
string
Entity/table affected (e.g., pesaje, usuarios, areas)
entidad_id
string
ID of the affected record
usuario_id
number
ID of user who performed the action
usuario_nombre
string
User’s first name (from JOIN)
usuario_apellido
string
User’s last name (from JOIN)
cambios
string
JSON string containing the changes made
fecha
string
Timestamp when action occurred

Success Response Example

[
  {
    "id": 1523,
    "accion": "crear",
    "entidad": "pesaje",
    "entidad_id": "1234",
    "usuario_id": 5,
    "usuario_nombre": "Carlos",
    "usuario_apellido": "Ramírez",
    "cambios": "{\"AREA\":\"Ensamble\",\"NP\":\"12345678\",\"COSTO\":45.75}",
    "fecha": "2024-03-15T14:30:25.000Z"
  },
  {
    "id": 1522,
    "accion": "editar",
    "entidad": "usuarios",
    "entidad_id": "8",
    "usuario_id": 1,
    "usuario_nombre": "Juan",
    "usuario_apellido": "Pérez",
    "cambios": "{\"area\":\"Moldeo\",\"turno\":\"B\"}",
    "fecha": "2024-03-15T14:15:10.000Z"
  },
  {
    "id": 1521,
    "accion": "eliminar",
    "entidad": "pesaje",
    "entidad_id": "1230",
    "usuario_id": 2,
    "usuario_nombre": "María",
    "usuario_apellido": "García",
    "cambios": "{\"ELIMINADO\":1}",
    "fecha": "2024-03-15T13:45:00.000Z"
  }
]

Audit Log Viewer

const AuditLogViewer: React.FC = () => {
  const [entries, setEntries] = useState<AuditEntry[]>([]);
  const [filters, setFilters] = useState<AuditFilters>({
    limit: 100
  });
  
  useEffect(() => {
    getAuditLog(filters).then(setEntries);
  }, [filters]);
  
  const getActionIcon = (accion: string) => {
    switch (accion) {
      case 'crear': return '➕';
      case 'editar': return '✏️';
      case 'eliminar': return '🗑️';
      case 'exportar': return '📤';
      case 'importar': return '📥';
      default: return 'ℹ️';
    }
  };
  
  const formatChanges = (cambios: string) => {
    try {
      const parsed = JSON.parse(cambios);
      return Object.entries(parsed)
        .map(([key, value]) => `${key}: ${value}`)
        .join(', ');
    } catch {
      return cambios;
    }
  };
  
  return (
    <div>
      <h2>Audit Log</h2>
      
      {/* Filters */}
      <div className="filters">
        <input
          type="date"
          onChange={e => setFilters({ ...filters, fecha_inicio: e.target.value })}
        />
        <select onChange={e => setFilters({ ...filters, accion: e.target.value as any })}>
          <option value="">All Actions</option>
          <option value="crear">Create</option>
          <option value="editar">Edit</option>
          <option value="eliminar">Delete</option>
        </select>
      </div>
      
      {/* Log Table */}
      <table>
        <thead>
          <tr>
            <th>Date/Time</th>
            <th>Action</th>
            <th>Entity</th>
            <th>User</th>
            <th>Changes</th>
          </tr>
        </thead>
        <tbody>
          {entries.map(entry => (
            <tr key={entry.id}>
              <td>{new Date(entry.fecha).toLocaleString()}</td>
              <td>
                <span title={entry.accion}>
                  {getActionIcon(entry.accion)} {entry.accion}
                </span>
              </td>
              <td>{entry.entidad} #{entry.entidad_id}</td>
              <td>{entry.usuario_nombre} {entry.usuario_apellido}</td>
              <td className="changes">{formatChanges(entry.cambios)}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
};

Activity Summary

const getUserActivitySummary = async (userId, startDate, endDate) => {
  const entries = await getAuditLog({
    usuario_id: userId,
    fecha_inicio: startDate,
    fecha_fin: endDate
  });
  
  const summary = {
    totalActions: entries.length,
    byAction: {},
    byEntity: {},
    firstAction: entries[entries.length - 1]?.fecha,
    lastAction: entries[0]?.fecha
  };
  
  entries.forEach(entry => {
    // Count by action
    summary.byAction[entry.accion] = (summary.byAction[entry.accion] || 0) + 1;
    
    // Count by entity
    summary.byEntity[entry.entidad] = (summary.byEntity[entry.entidad] || 0) + 1;
  });
  
  return summary;
};

// Generate weekly report for user
const weekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
const today = new Date().toISOString().split('T')[0];
const summary = await getUserActivitySummary(5, weekAgo, today);

console.log(`User performed ${summary.totalActions} actions this week`);
console.log('Breakdown:', summary.byAction);

Export Audit Log

const exportAuditLog = async (filters = {}) => {
  const entries = await getAuditLog(filters);
  
  // Convert to CSV
  const csv = [
    ['Date', 'Time', 'Action', 'Entity', 'Record ID', 'User', 'Changes'].join(','),
    ...entries.map(entry => {
      const date = new Date(entry.fecha);
      return [
        date.toLocaleDateString(),
        date.toLocaleTimeString(),
        entry.accion,
        entry.entidad,
        entry.entidad_id,
        `${entry.usuario_nombre} ${entry.usuario_apellido}`,
        `\"${entry.cambios.replace(/"/g, '"")}\"`
      ].join(',');
    })
  ].join('\n');
  
  // Download
  const blob = new Blob([csv], { type: 'text/csv' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `audit-log-${new Date().toISOString().split('T')[0]}.csv`;
  a.click();
};

TypeScript Interface

export interface AuditEntry {
  id: number;
  accion: 'crear' | 'editar' | 'eliminar' | 'exportar' | 'importar';
  entidad: string;
  entidad_id: string;
  usuario_id: number;
  cambios: string; // JSON string
  fecha: string; // ISO timestamp
  usuario_nombre?: string; // From JOIN
  usuario_apellido?: string; // From JOIN
}

Build docs developers (and LLMs) love