v0.4.8
This commit is contained in:
parent
52ae21cb57
commit
770fb33bb0
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "0.4.7",
|
||||
"version": "0.4.8",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "WEB: Vite (Chrome)",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/factuges-server",
|
||||
"version": "0.4.7",
|
||||
"version": "0.4.8",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "tsup src/index.ts --config tsup.config.ts",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@erp/factuges-web",
|
||||
"private": true,
|
||||
"version": "0.4.7",
|
||||
"version": "0.4.8",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --host --clearScreen false",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/auth",
|
||||
"version": "0.4.7",
|
||||
"version": "0.4.8",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/core",
|
||||
"version": "0.4.7",
|
||||
"version": "0.4.8",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,7 +1,13 @@
|
||||
import { createHash } from "node:crypto";
|
||||
|
||||
export class DocumentStorageKeyFactory {
|
||||
static fromMetadataRecord(metadata: Record<string, unknown>): string {
|
||||
return createHash("sha256").update(JSON.stringify(metadata)).digest("hex");
|
||||
static fromMetadataRecord(metadata: Record<string, unknown>): {
|
||||
paths: string[];
|
||||
storageKey: string;
|
||||
} {
|
||||
return {
|
||||
paths: [String(metadata.companySlug), String(metadata.documentType)],
|
||||
storageKey: createHash("sha256").update(JSON.stringify(metadata)).digest("hex"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ export interface IDocumentStorage {
|
||||
* - Best-effort
|
||||
* - Nunca lanza (errores se gestionan internamente)
|
||||
*/
|
||||
existsKeyStorage(storageKey: string): Promise<Boolean>;
|
||||
existsKeyStorage(storageKey: string, paths: string[]): Promise<Boolean>;
|
||||
|
||||
/**
|
||||
* Recupera un documento guardado.
|
||||
@ -17,7 +17,7 @@ export interface IDocumentStorage {
|
||||
* - Best-effort
|
||||
* - Nunca lanza (errores se gestionan internamente)
|
||||
*/
|
||||
readDocument(storageKey: string): Promise<IDocument | null>;
|
||||
readDocument(storageKey: string, paths: string[]): Promise<IDocument | null>;
|
||||
|
||||
/**
|
||||
* Persiste un documento generado.
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
import { buildSafePath } from "@repo/rdx-utils";
|
||||
|
||||
import {
|
||||
DocumentStorageKeyFactory,
|
||||
type IDocument,
|
||||
@ -15,11 +17,15 @@ import {
|
||||
* - No afecta al flujo del caso de uso
|
||||
*/
|
||||
export class FilesystemDocumentStorage implements IDocumentStorage {
|
||||
public constructor(private readonly basePath: string) {}
|
||||
public constructor(private readonly docRootPath: string) {}
|
||||
|
||||
async existsKeyStorage(storageKey: string, paths: string[]): Promise<Boolean> {
|
||||
// Ejemplo: .../signed-documents/770c138fc58548f72029c1ed4f3670e94be4cc7a0fab9f7f0b84d0aef77f43ae
|
||||
// paths: => [".../signed-documents"],
|
||||
// storageKey: => 770c138fc58548f72029c1ed4f3670e94be4cc7a0fab9f7f0b84d0aef77f43ae
|
||||
|
||||
async existsKeyStorage(storageKey: string): Promise<Boolean> {
|
||||
try {
|
||||
const dir = this.resolveDirFromStorageKey(storageKey);
|
||||
const dir = this.resolveDir(storageKey, paths);
|
||||
return (await stat(dir)).isDirectory();
|
||||
} catch {
|
||||
// Consistente con saveDocument: best-effort
|
||||
@ -27,12 +33,12 @@ export class FilesystemDocumentStorage implements IDocumentStorage {
|
||||
}
|
||||
}
|
||||
|
||||
async readDocument(storageKey: string) {
|
||||
async readDocument(storageKey: string, paths: string[]) {
|
||||
try {
|
||||
const dir = this.resolveDirFromStorageKey(storageKey);
|
||||
const dir = this.resolveDir(storageKey, paths);
|
||||
|
||||
const payload = await readFile(path.join(dir, "document.bin"));
|
||||
const metaRaw = JSON.parse(await readFile(path.join(dir, "document.meta.json"), "utf-8"));
|
||||
const metaRaw = await readFile(path.join(dir, "document.meta.json"), "utf-8");
|
||||
|
||||
const meta = JSON.parse(metaRaw) as {
|
||||
mimeType: string;
|
||||
@ -78,15 +84,15 @@ export class FilesystemDocumentStorage implements IDocumentStorage {
|
||||
}
|
||||
|
||||
private resolveDirFromMetadataRecord(metadataRecord: Record<string, unknown>): string {
|
||||
/**
|
||||
* El storage NO decide claves semánticas.
|
||||
* Se limita a generar un path técnico estable.
|
||||
*/
|
||||
const storageKey = DocumentStorageKeyFactory.fromMetadataRecord(metadataRecord);
|
||||
return this.resolveDirFromStorageKey(storageKey);
|
||||
const { paths, storageKey } = DocumentStorageKeyFactory.fromMetadataRecord(metadataRecord);
|
||||
|
||||
return this.resolveDir(storageKey, paths);
|
||||
}
|
||||
|
||||
private resolveDirFromStorageKey(storageKey: string): string {
|
||||
return path.join(this.basePath, storageKey);
|
||||
private resolveDir(storageKey: string, paths: string[]): string {
|
||||
return buildSafePath({
|
||||
basePath: this.docRootPath,
|
||||
segments: [...paths, storageKey],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/customer-invoices",
|
||||
"version": "0.4.7",
|
||||
"version": "0.4.8",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -21,23 +21,25 @@ export class IssuedInvoiceSignedDocumentCachePreProcessor implements IDocumentPr
|
||||
async tryResolve(metadata: IDocumentMetadata): Promise<IDocument | null> {
|
||||
const metadataRecord = metadata as unknown as Record<string, unknown>;
|
||||
try {
|
||||
const storageKey = DocumentStorageKeyFactory.fromMetadataRecord(metadataRecord);
|
||||
const { paths, storageKey } = DocumentStorageKeyFactory.fromMetadataRecord(metadataRecord);
|
||||
|
||||
if (!storageKey) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const exists = await this.docStorage.existsKeyStorage(storageKey);
|
||||
const exists = await this.docStorage.existsKeyStorage(storageKey, paths);
|
||||
|
||||
if (!exists) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const document = await this.docStorage.readDocument(storageKey);
|
||||
logger.info(`✅ Found Server cached document for key ${storageKey}`);
|
||||
|
||||
const document = await this.docStorage.readDocument(storageKey, paths);
|
||||
|
||||
if (!this.isValid(document)) {
|
||||
logger.warn(`Storage key ${storageKey} not exists!`, {
|
||||
lable: "IssuedInvoiceSignedDocumentCachePreProcessor",
|
||||
logger.warn(`Corrupted or invalid cached document for key ${storageKey}`, {
|
||||
label: "IssuedInvoiceSignedDocumentCachePreProcessor",
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/customers",
|
||||
"version": "0.4.7",
|
||||
"version": "0.4.8",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/doc-numbering",
|
||||
"version": "0.4.7",
|
||||
"version": "0.4.8",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@repo/rdx-criteria",
|
||||
"version": "0.4.7",
|
||||
"version": "0.4.8",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@repo/rdx-ddd",
|
||||
"version": "0.4.7",
|
||||
"version": "0.4.8",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@repo/rdx-logger",
|
||||
"version": "0.4.7",
|
||||
"version": "0.4.8",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@repo/rdx-utils",
|
||||
"version": "0.4.7",
|
||||
"version": "0.4.8",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user