Aplicación web de Devolución a Proveedores para SAP Business One
Reemplaza al addon .NET Framework (SolucionLibros). Genera Devoluciones de mercancías enlazadas a sus Entradas por compra a partir de un listado pegado desde Excel. - libs/shared (@dp/shared): modelos y lógica de dominio pura (FIFO, consolidación por proveedor, parseo del portapapeles), portada del addon. - apps/api (NestJS): cliente del Service Layer con cola por sesión, login con la sesión de SAP, metadatos (UDT/UDF/UDO) y botón Reconstruir, catálogos, planificaciones (pegar, procesar, reprocesar, marcar líneas, crear Devoluciones, cerrar), listado paginado con filtros y descarga de PDF de la Guía de despacho desde BES. Sirve también la web compilada, con HTTPS opcional. - apps/web (Angular): login, Configuración → Metadatos y Planificaciones (listado, nueva, detalle). - deploy/windows y scripts/publicar.mjs: despliegue como servicio de Windows con WinSW. Verificado contra el Service Layer de SQL Server. Sin probar aún: SAP HANA y la instalación del servicio en Windows (ver CLAUDE.md, sección "Sin verificar"). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
287b187c14
126 files changed
+20033
No files matched your search
@@ -0,0 +1,64 @@
|
||||
import { Body, Controller, Get, HttpCode, Post, Req, Res } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import type { InfoConexion, UsuarioSesion } from '@dp/shared';
|
||||
import type { Request, Response } from 'express';
|
||||
import { AppConfig } from '../config/configuration.js';
|
||||
import { ServiceLayerClient } from '../service-layer/service-layer.client.js';
|
||||
import { SessionStore } from '../service-layer/session.store.js';
|
||||
import type { SapSession } from '../service-layer/session.store.js';
|
||||
import { LoginDto } from './dto/login.dto.js';
|
||||
import { CurrentSession, Public, SESSION_COOKIE } from './session.guard.js';
|
||||
|
||||
function aUsuario(sesion: SapSession): UsuarioSesion {
|
||||
return { userName: sesion.userName, companyDb: sesion.companyDb, version: sesion.version };
|
||||
}
|
||||
|
||||
@Controller('auth')
|
||||
export class AuthController {
|
||||
constructor(
|
||||
private readonly serviceLayer: ServiceLayerClient,
|
||||
private readonly sessions: SessionStore,
|
||||
private readonly config: ConfigService<AppConfig, true>,
|
||||
) {}
|
||||
|
||||
@Public()
|
||||
@Get('info')
|
||||
info(): InfoConexion {
|
||||
return {
|
||||
companyDb: this.config.get('serviceLayer', { infer: true }).companyDb,
|
||||
dbType: this.config.get('dbType', { infer: true }),
|
||||
};
|
||||
}
|
||||
|
||||
@Public()
|
||||
@Post('login')
|
||||
@HttpCode(200)
|
||||
async login(@Body() dto: LoginDto, @Res({ passthrough: true }) res: Response): Promise<UsuarioSesion> {
|
||||
const sesion = await this.serviceLayer.login(dto.userName, dto.password);
|
||||
|
||||
res.cookie(SESSION_COOKIE, sesion.id, {
|
||||
httpOnly: true,
|
||||
sameSite: 'strict',
|
||||
secure: this.config.get('cookieSecure', { infer: true }),
|
||||
path: '/',
|
||||
});
|
||||
|
||||
return aUsuario(sesion);
|
||||
}
|
||||
|
||||
@Public()
|
||||
@Post('logout')
|
||||
@HttpCode(204)
|
||||
async logout(@Req() req: Request, @Res({ passthrough: true }) res: Response): Promise<void> {
|
||||
const sesion = this.sessions.obtener(req.cookies?.[SESSION_COOKIE] as string | undefined);
|
||||
if (sesion) {
|
||||
await this.serviceLayer.logout(sesion);
|
||||
}
|
||||
res.clearCookie(SESSION_COOKIE, { path: '/' });
|
||||
}
|
||||
|
||||
@Get('me')
|
||||
me(@CurrentSession() sesion: SapSession): UsuarioSesion {
|
||||
return aUsuario(sesion);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user