@muni-sanfer/types-gestor-documental 0.0.1-beta.40 → 0.0.1-beta.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/base/entities.d.ts +37 -1
  2. package/dist/base/entities.js +1 -0
  3. package/dist/contracts/document.contract.d.ts +5 -0
  4. package/dist/contracts/index.d.ts +17 -1
  5. package/dist/contracts/index.js +6 -0
  6. package/dist/contracts/internalReview.contract.d.ts +86 -0
  7. package/dist/contracts/internalReview.contract.js +12 -0
  8. package/dist/contracts/richImage.contract.d.ts +33 -0
  9. package/dist/contracts/richImage.contract.js +8 -0
  10. package/dist/entities/document/document.entity.d.ts +22 -2
  11. package/dist/entities/document/index.d.ts +1 -0
  12. package/dist/entities/document/index.js +1 -0
  13. package/dist/entities/document/richStyle.d.ts +160 -0
  14. package/dist/entities/document/richStyle.js +66 -0
  15. package/dist/entities/documentTemplate/documentTemplate.entity.d.ts +5 -0
  16. package/dist/entities/index.d.ts +1 -0
  17. package/dist/entities/index.js +1 -0
  18. package/dist/entities/internalReview/index.d.ts +1 -0
  19. package/dist/entities/internalReview/index.js +17 -0
  20. package/dist/entities/internalReview/internalReview.entity.d.ts +59 -0
  21. package/dist/entities/internalReview/internalReview.entity.js +2 -0
  22. package/package.json +1 -1
  23. package/src/base/entities.ts +41 -1
  24. package/src/contracts/document.contract.ts +5 -0
  25. package/src/contracts/index.ts +9 -1
  26. package/src/contracts/internalReview.contract.ts +66 -0
  27. package/src/contracts/richImage.contract.ts +23 -0
  28. package/src/entities/document/document.entity.ts +38 -6
  29. package/src/entities/document/index.ts +1 -0
  30. package/src/entities/document/richStyle.ts +141 -0
  31. package/src/entities/documentTemplate/documentTemplate.entity.ts +5 -0
  32. package/src/entities/index.ts +1 -0
  33. package/src/entities/internalReview/index.ts +1 -0
  34. package/src/entities/internalReview/internalReview.entity.ts +57 -0
@@ -231,7 +231,7 @@ export declare const DocumentAccessAction: {
231
231
  FileDownloaded: "FileDownloaded";
232
232
  TrailExported: "TrailExported";
233
233
  };
234
- export type AuditEntity = 'DocumentType' | 'IssuingEntity' | 'ArchivalSeries' | 'TextSnippet' | 'Holiday' | 'Procedure' | 'QualityMetric' | 'ServiceOutage' | 'Repository' | 'DataTreatment' | 'DocumentTemplate';
234
+ export type AuditEntity = 'DocumentType' | 'IssuingEntity' | 'ArchivalSeries' | 'TextSnippet' | 'Holiday' | 'Procedure' | 'QualityMetric' | 'ServiceOutage' | 'Repository' | 'DataTreatment' | 'DocumentTemplate' | 'DirectorateReviewer';
235
235
  export declare const AuditEntity: {
236
236
  DocumentType: "DocumentType";
237
237
  IssuingEntity: "IssuingEntity";
@@ -244,6 +244,7 @@ export declare const AuditEntity: {
244
244
  Repository: "Repository";
245
245
  DataTreatment: "DataTreatment";
246
246
  DocumentTemplate: "DocumentTemplate";
247
+ DirectorateReviewer: "DirectorateReviewer";
247
248
  };
248
249
  export type AuditAction = 'Created' | 'Updated' | 'Enabled' | 'Disabled' | 'Removed' | 'Exported';
249
250
  export declare const AuditAction: {
@@ -523,6 +524,7 @@ export interface DocumentEntity {
523
524
  comments?: DocumentCommentEntity[];
524
525
  draftReviews?: DocumentDraftReviewEntity[];
525
526
  draftingRequest?: DraftingRequestEntity | null;
527
+ internalNotes?: DocumentInternalNoteEntity[];
526
528
  accessRequestDeliveries?: AccessRequestDocumentEntity[];
527
529
  dispatch?: DocumentDispatchEntity | null;
528
530
  docDigitalInbound?: DocDigitalInboundEntity | null;
@@ -1417,6 +1419,40 @@ export interface DraftingRequestEventEntity {
1417
1419
  employeeFullName: string;
1418
1420
  createdAt: string;
1419
1421
  }
1422
+ export interface DirectorateReviewerEntity {
1423
+ id: string;
1424
+ directorateCode: number;
1425
+ directorateName: string;
1426
+ employeeId: string;
1427
+ fullName: string;
1428
+ createdAt: string;
1429
+ }
1430
+ export interface DocumentInternalNoteEntity {
1431
+ id: string;
1432
+ documentId: string;
1433
+ document?: DocumentEntity;
1434
+ directorateCode: number;
1435
+ directorateName: string;
1436
+ headEmployeeIds: string[];
1437
+ versionNumber: number;
1438
+ authorEmployeeId: string;
1439
+ authorFullName: string;
1440
+ authorRole: string;
1441
+ text: string;
1442
+ createdAt: string;
1443
+ }
1444
+ export interface RichImageEntity {
1445
+ id: string;
1446
+ fileId: string;
1447
+ name: string;
1448
+ mimeType: string;
1449
+ width: number;
1450
+ height: number;
1451
+ sha256: string;
1452
+ sizeBytes: number;
1453
+ employeeId: string;
1454
+ createdAt: string;
1455
+ }
1420
1456
  type JsonValue = string | number | boolean | {
1421
1457
  [key in string]?: JsonValue;
1422
1458
  } | Array<JsonValue> | null;
@@ -218,6 +218,7 @@ exports.AuditEntity = {
218
218
  Repository: 'Repository',
219
219
  DataTreatment: 'DataTreatment',
220
220
  DocumentTemplate: 'DocumentTemplate',
221
+ DirectorateReviewer: 'DirectorateReviewer',
221
222
  };
222
223
  exports.AuditAction = {
223
224
  Created: 'Created',
@@ -42,6 +42,11 @@ export interface DocumentActor {
42
42
  employeeId: string;
43
43
  directorateCodes: number[];
44
44
  departmentIds: string[];
45
+ /**
46
+ * Jefaturas para las que revisa (revisora de jefatura): ve los documentos que les esperan. Lo resuelve el gateway
47
+ * solo donde hace falta (el detalle y el PDF).
48
+ */
49
+ reviewFor?: string[];
45
50
  }
46
51
  /** Bandeja desde la que se lista. Todas son del funcionario (`actor`), salvo `all`. */
47
52
  export type DocumentBucket = 'created' | 'sent' | 'toVisa' | 'toSign' | 'participated' | 'toReview' | 'all';
@@ -24,6 +24,8 @@ import { type RegisterBookContract } from './registerBook.contract';
24
24
  import { type SignatureBatchContract } from './signatureBatch.contract';
25
25
  import { type WorkFolderContract } from './workFolder.contract';
26
26
  import { type DraftingRequestContract } from './draftingRequest.contract';
27
+ import { type InternalReviewContract } from './internalReview.contract';
28
+ import { type RichImageContract } from './richImage.contract';
27
29
  export * from './contract';
28
30
  export * from './document.contract';
29
31
  export * from './documentType.contract';
@@ -51,6 +53,8 @@ export * from './desk.contract';
51
53
  export * from './mailIntake.contract';
52
54
  export * from './push.contract';
53
55
  export * from './draftingRequest.contract';
56
+ export * from './internalReview.contract';
57
+ export * from './richImage.contract';
54
58
  /** Patrones NATS de gestor-documental-ms, por recurso: `gestorDocumental.<recurso>.<acción>`. */
55
59
  export declare const GestorDocumentalPatterns: {
56
60
  readonly documentType: {
@@ -307,6 +311,18 @@ export declare const GestorDocumentalPatterns: {
307
311
  readonly act: "gestorDocumental.draftingRequest.act";
308
312
  readonly getAttachmentFile: "gestorDocumental.draftingRequest.getAttachmentFile";
309
313
  };
314
+ readonly internalReview: {
315
+ readonly getReviewers: "gestorDocumental.internalReview.getReviewers";
316
+ readonly setReviewers: "gestorDocumental.internalReview.setReviewers";
317
+ readonly getAssignments: "gestorDocumental.internalReview.getAssignments";
318
+ readonly getQueue: "gestorDocumental.internalReview.getQueue";
319
+ readonly getNotes: "gestorDocumental.internalReview.getNotes";
320
+ readonly addNote: "gestorDocumental.internalReview.addNote";
321
+ };
322
+ readonly richImage: {
323
+ readonly register: "gestorDocumental.richImage.register";
324
+ readonly getFile: "gestorDocumental.richImage.getFile";
325
+ };
310
326
  };
311
327
  /** Contrato completo de gestor-documental-ms: la unión de los contratos de sus recursos. */
312
- export type GestorDocumentalContract = DocumentTypeContract & DocumentContract & ProcedureContract & IssuingEntityContract & CaseFileContract & PartsOfficeContract & RegisterBookContract & SignatureBatchContract & WorkFolderContract & ScanContract & ArchivalSeriesContract & TextSnippetContract & DocumentTemplateContract & HolidayContract & IndicatorsContract & AuditContract & SignatureCheckContract & RepositoryExportContract & RetentionContract & AccessRequestContract & TransparencyContract & DataProtectionContract & DeskContract & MailIntakeContract & PushContract & DraftingRequestContract;
328
+ export type GestorDocumentalContract = DocumentTypeContract & DocumentContract & ProcedureContract & IssuingEntityContract & CaseFileContract & PartsOfficeContract & RegisterBookContract & SignatureBatchContract & WorkFolderContract & ScanContract & ArchivalSeriesContract & TextSnippetContract & DocumentTemplateContract & HolidayContract & IndicatorsContract & AuditContract & SignatureCheckContract & RepositoryExportContract & RetentionContract & AccessRequestContract & TransparencyContract & DataProtectionContract & DeskContract & MailIntakeContract & PushContract & DraftingRequestContract & InternalReviewContract & RichImageContract;
@@ -41,6 +41,8 @@ const registerBook_contract_1 = require("./registerBook.contract");
41
41
  const signatureBatch_contract_1 = require("./signatureBatch.contract");
42
42
  const workFolder_contract_1 = require("./workFolder.contract");
43
43
  const draftingRequest_contract_1 = require("./draftingRequest.contract");
44
+ const internalReview_contract_1 = require("./internalReview.contract");
45
+ const richImage_contract_1 = require("./richImage.contract");
44
46
  __exportStar(require("./contract"), exports);
45
47
  __exportStar(require("./document.contract"), exports);
46
48
  __exportStar(require("./documentType.contract"), exports);
@@ -68,6 +70,8 @@ __exportStar(require("./desk.contract"), exports);
68
70
  __exportStar(require("./mailIntake.contract"), exports);
69
71
  __exportStar(require("./push.contract"), exports);
70
72
  __exportStar(require("./draftingRequest.contract"), exports);
73
+ __exportStar(require("./internalReview.contract"), exports);
74
+ __exportStar(require("./richImage.contract"), exports);
71
75
  /** Patrones NATS de gestor-documental-ms, por recurso: `gestorDocumental.<recurso>.<acción>`. */
72
76
  exports.GestorDocumentalPatterns = {
73
77
  documentType: documentType_contract_1.DocumentTypePatterns,
@@ -96,4 +100,6 @@ exports.GestorDocumentalPatterns = {
96
100
  mailIntake: mailIntake_contract_1.MailIntakePatterns,
97
101
  push: push_contract_1.PushPatterns,
98
102
  draftingRequest: draftingRequest_contract_1.DraftingRequestPatterns,
103
+ internalReview: internalReview_contract_1.InternalReviewPatterns,
104
+ richImage: richImage_contract_1.RichImagePatterns,
99
105
  };
@@ -0,0 +1,86 @@
1
+ import { type DirectorateReviewersEntity, type DocumentInternalNoteResponseEntity, type DocumentInternalNotesResponseEntity, type InternalReviewQueueItemEntity } from '../entities';
2
+ import { type AuditActorInput } from '../entities';
3
+ /** Patrones NATS de `internalReview`: revisoras de jefatura y sus observaciones internas. */
4
+ export declare const InternalReviewPatterns: {
5
+ readonly getReviewers: "gestorDocumental.internalReview.getReviewers";
6
+ readonly setReviewers: "gestorDocumental.internalReview.setReviewers";
7
+ readonly getAssignments: "gestorDocumental.internalReview.getAssignments";
8
+ readonly getQueue: "gestorDocumental.internalReview.getQueue";
9
+ readonly getNotes: "gestorDocumental.internalReview.getNotes";
10
+ readonly addNote: "gestorDocumental.internalReview.addNote";
11
+ };
12
+ /**
13
+ * Dirección para la que actúa quien consulta: como revisora de su jefatura o como la jefatura misma. La resuelve el
14
+ * gateway: quiénes la dirigen hoy (titular y subrogante) no los dice el navegador.
15
+ */
16
+ export interface InternalReviewScope {
17
+ directorateCode: number;
18
+ directorateName: string;
19
+ headEmployeeIds: string[];
20
+ role: 'Reviewer' | 'Head';
21
+ }
22
+ export interface InternalReviewContract {
23
+ [InternalReviewPatterns.getReviewers]: {
24
+ payload: Record<string, never>;
25
+ response: DirectorateReviewersEntity[];
26
+ };
27
+ /** Reemplaza las revisoras de una dirección (sin ninguna, la dirección queda sin revisoras). */
28
+ [InternalReviewPatterns.setReviewers]: {
29
+ payload: {
30
+ directorateCode: number;
31
+ directorateName: string;
32
+ reviewers: {
33
+ employeeId: string;
34
+ fullName: string;
35
+ }[];
36
+ auditActor?: AuditActorInput;
37
+ };
38
+ response: {
39
+ id: string;
40
+ ok: boolean;
41
+ };
42
+ };
43
+ /** Direcciones para cuya jefatura revisa una funcionaria. */
44
+ [InternalReviewPatterns.getAssignments]: {
45
+ payload: {
46
+ employeeId: string;
47
+ };
48
+ response: {
49
+ directorateCode: number;
50
+ directorateName: string;
51
+ }[];
52
+ };
53
+ /** Documentos que esperan a las jefaturas para las que revisa quien consulta. */
54
+ [InternalReviewPatterns.getQueue]: {
55
+ payload: {
56
+ actor: {
57
+ employeeId: string;
58
+ };
59
+ scopes: InternalReviewScope[];
60
+ };
61
+ response: InternalReviewQueueItemEntity[];
62
+ };
63
+ [InternalReviewPatterns.getNotes]: {
64
+ payload: {
65
+ documentId: string;
66
+ actor: {
67
+ employeeId: string;
68
+ };
69
+ scopes: InternalReviewScope[];
70
+ };
71
+ response: DocumentInternalNotesResponseEntity;
72
+ };
73
+ [InternalReviewPatterns.addNote]: {
74
+ payload: {
75
+ documentId: string;
76
+ directorateCode: number;
77
+ text: string;
78
+ actor: {
79
+ employeeId: string;
80
+ fullName: string;
81
+ };
82
+ scopes: InternalReviewScope[];
83
+ };
84
+ response: DocumentInternalNoteResponseEntity;
85
+ };
86
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InternalReviewPatterns = void 0;
4
+ /** Patrones NATS de `internalReview`: revisoras de jefatura y sus observaciones internas. */
5
+ exports.InternalReviewPatterns = {
6
+ getReviewers: 'gestorDocumental.internalReview.getReviewers',
7
+ setReviewers: 'gestorDocumental.internalReview.setReviewers',
8
+ getAssignments: 'gestorDocumental.internalReview.getAssignments',
9
+ getQueue: 'gestorDocumental.internalReview.getQueue',
10
+ getNotes: 'gestorDocumental.internalReview.getNotes',
11
+ addNote: 'gestorDocumental.internalReview.addNote',
12
+ };
@@ -0,0 +1,33 @@
1
+ import { type RichImageResponseEntity } from '../entities';
2
+ /** Patrones NATS de `richImage`: imágenes del editor (logos de membrete e imágenes del texto). */
3
+ export declare const RichImagePatterns: {
4
+ readonly register: "gestorDocumental.richImage.register";
5
+ readonly getFile: "gestorDocumental.richImage.getFile";
6
+ };
7
+ export interface RichImageContract {
8
+ /**
9
+ * Registra una imagen ya subida a Drive por el gateway (en la carpeta de los documentos). El ms descarga el archivo, comprueba que sea PNG o JPEG y de
10
+ * tamaño aceptable, y guarda sus medidas y su huella.
11
+ */
12
+ [RichImagePatterns.register]: {
13
+ payload: {
14
+ fileId: string;
15
+ name: string;
16
+ actor: {
17
+ employeeId: string;
18
+ };
19
+ };
20
+ response: RichImageResponseEntity;
21
+ };
22
+ /** El archivo de una imagen registrada, para mostrarla en el editor. */
23
+ [RichImagePatterns.getFile]: {
24
+ payload: {
25
+ id: string;
26
+ };
27
+ response: {
28
+ fileId: string;
29
+ fileName: string;
30
+ mimeType: string;
31
+ };
32
+ };
33
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RichImagePatterns = void 0;
4
+ /** Patrones NATS de `richImage`: imágenes del editor (logos de membrete e imágenes del texto). */
5
+ exports.RichImagePatterns = {
6
+ register: 'gestorDocumental.richImage.register',
7
+ getFile: 'gestorDocumental.richImage.getFile',
8
+ };
@@ -1,4 +1,5 @@
1
1
  import { type CommunicationMeans, DocumentAnnulledNumberEntity, DocumentAttachmentEntity, DocumentDeliveryEntity, DocumentEntity, DocumentParticipantEntity, DocumentRecipientEntity, type DocumentStatus, DocumentTrackingEntity, DocumentTypeEntity } from '../../base/entities';
2
+ import { type RichLetterhead, type RichPage, type RichSpacing, type RichTextStyle } from './richStyle';
2
3
  import { type DocumentDraftingRequestEntity } from '../draftingRequest/draftingRequest.entity';
3
4
  /** Tipo documental de un documento, con lo necesario para citarlo. */
4
5
  export interface DocumentTypeSummaryEntity {
@@ -407,8 +408,8 @@ export interface DocumentTrailExportEntity {
407
408
  }
408
409
  /** Plantilla oficial con que se redacta un documento en el sistema. */
409
410
  export type DocumentTemplateKind = 'Decree' | 'Office' | 'Memorandum' | 'General';
410
- /** Formato de un trozo de texto en el editor del gestor. */
411
- export type RichMark = 'bold' | 'italic' | 'underline';
411
+ /** Formato de un trozo de texto en el editor del gestor. Superíndice y subíndice no van juntos. */
412
+ export type RichMark = 'bold' | 'italic' | 'underline' | 'strike' | 'superscript' | 'subscript';
412
413
  /**
413
414
  * Texto con su formato, o un campo de la plantilla (`field`: su clave), que se reemplaza por su valor al armar el PDF.
414
415
  * Un salto de línea dentro del texto (`\n`) es un salto de línea del párrafo.
@@ -416,8 +417,11 @@ export type RichMark = 'bold' | 'italic' | 'underline';
416
417
  export type RichInline = {
417
418
  text: string;
418
419
  marks?: RichMark[];
420
+ style?: RichTextStyle;
419
421
  } | {
420
422
  field: string;
423
+ marks?: RichMark[];
424
+ style?: RichTextStyle;
421
425
  };
422
426
  export type RichAlign = 'left' | 'center' | 'right' | 'justify';
423
427
  /** Numeración de una lista: viñetas, «1.» o la de los decretos, «1.-». */
@@ -435,6 +439,7 @@ export type RichBlock = {
435
439
  id: string;
436
440
  type: 'paragraph';
437
441
  align?: RichAlign;
442
+ spacing?: RichSpacing;
438
443
  locked?: boolean;
439
444
  content: RichInline[];
440
445
  } | {
@@ -442,6 +447,7 @@ export type RichBlock = {
442
447
  type: 'heading';
443
448
  level: 1 | 2;
444
449
  align?: RichAlign;
450
+ spacing?: RichSpacing;
445
451
  locked?: boolean;
446
452
  content: RichInline[];
447
453
  } | {
@@ -449,9 +455,20 @@ export type RichBlock = {
449
455
  type: 'listItem';
450
456
  list: RichListStyle;
451
457
  level: number;
458
+ spacing?: RichSpacing;
452
459
  locked?: boolean;
453
460
  content: RichInline[];
454
461
  }
462
+ /** Imagen registrada en el gestor (`imageId`), con su ancho en puntos (sin pasar el del texto) y alineación. */
463
+ | {
464
+ id: string;
465
+ type: 'image';
466
+ imageId: string;
467
+ width: number;
468
+ align?: 'left' | 'center' | 'right';
469
+ caption?: string;
470
+ locked?: boolean;
471
+ }
455
472
  /** `rows[fila][columna]`: el contenido de cada celda. */
456
473
  | {
457
474
  id: string;
@@ -526,6 +543,9 @@ export type DocumentComposition = {
526
543
  blocks: RichBlock[];
527
544
  fields: RichField[];
528
545
  distribution: string[];
546
+ /** Página y membrete. En una plantilla propia los pone su versión: lo que mande el navegador no cuenta. */
547
+ page?: RichPage;
548
+ letterhead?: RichLetterhead;
529
549
  };
530
550
  /** PDF armado con una plantilla: para la vista previa (`contentBase64`) o ya subido (`fileId`). */
531
551
  export interface DocumentComposeResponseEntity {
@@ -1 +1,2 @@
1
1
  export * from './document.entity';
2
+ export * from './richStyle';
@@ -15,3 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./document.entity"), exports);
18
+ __exportStar(require("./richStyle"), exports);
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Formato del editor del gestor que comparten el navegador y el microservicio: tipografías, colores, tamaños de hoja y
3
+ * márgenes. Todo lo que el PDF muestra sale de aquí, así que el editor y el documento oficial se ven igual.
4
+ */
5
+ /**
6
+ * Tipografías incrustadas en el PDF (PDF/A exige fuentes incrustadas). Liberation Sans, Liberation Serif y Carlito
7
+ * miden igual que Arial, Times New Roman y Calibri: lo que se pegó desde Word ocupa lo mismo.
8
+ */
9
+ export declare const RICH_FONTS: {
10
+ readonly Roboto: "Roboto";
11
+ readonly LiberationSans: "Liberation Sans (Arial)";
12
+ readonly LiberationSerif: "Liberation Serif (Times New Roman)";
13
+ readonly Carlito: "Carlito (Calibri)";
14
+ };
15
+ export type RichFont = keyof typeof RICH_FONTS;
16
+ /** Tamaños de letra que se ofrecen, en puntos. */
17
+ export declare const RICH_FONT_SIZES: readonly [8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 24];
18
+ /** Colores de letra: una paleta acotada, sobria, para documentos oficiales. */
19
+ export declare const RICH_COLORS: {
20
+ readonly black: {
21
+ readonly label: "Negro";
22
+ readonly hex: "#111827";
23
+ };
24
+ readonly gray: {
25
+ readonly label: "Gris";
26
+ readonly hex: "#4B5563";
27
+ };
28
+ readonly blue: {
29
+ readonly label: "Azul";
30
+ readonly hex: "#1E40AF";
31
+ };
32
+ readonly red: {
33
+ readonly label: "Rojo";
34
+ readonly hex: "#B91C1C";
35
+ };
36
+ readonly green: {
37
+ readonly label: "Verde";
38
+ readonly hex: "#166534";
39
+ };
40
+ readonly brown: {
41
+ readonly label: "Café";
42
+ readonly hex: "#78350F";
43
+ };
44
+ };
45
+ export type RichColor = keyof typeof RICH_COLORS;
46
+ /** Resaltado del texto. */
47
+ export declare const RICH_HIGHLIGHTS: {
48
+ readonly yellow: {
49
+ readonly label: "Amarillo";
50
+ readonly hex: "#FEF08A";
51
+ };
52
+ readonly green: {
53
+ readonly label: "Verde";
54
+ readonly hex: "#BBF7D0";
55
+ };
56
+ readonly blue: {
57
+ readonly label: "Celeste";
58
+ readonly hex: "#BFDBFE";
59
+ };
60
+ readonly pink: {
61
+ readonly label: "Rosado";
62
+ readonly hex: "#FBCFE8";
63
+ };
64
+ readonly gray: {
65
+ readonly label: "Gris";
66
+ readonly hex: "#E5E7EB";
67
+ };
68
+ };
69
+ export type RichHighlight = keyof typeof RICH_HIGHLIGHTS;
70
+ /** Formato propio de un trozo de texto, además de sus marcas. Sin valor, el de la página. */
71
+ export interface RichTextStyle {
72
+ font?: RichFont;
73
+ size?: number;
74
+ color?: RichColor;
75
+ highlight?: RichHighlight;
76
+ }
77
+ /** Espaciado y sangría de un párrafo, título o punto de lista, en puntos (el interlineado, en veces la letra). */
78
+ export interface RichSpacing {
79
+ before?: number;
80
+ after?: number;
81
+ lineHeight?: number;
82
+ /** Sangría de la primera línea. */
83
+ firstLine?: number;
84
+ /** Sangría de todo el párrafo, desde el margen izquierdo. */
85
+ left?: number;
86
+ }
87
+ /** Límites del espaciado, en puntos. */
88
+ export declare const RICH_SPACING_LIMITS: {
89
+ readonly maxSpace: 72;
90
+ readonly maxIndent: 216;
91
+ readonly minLineHeight: 0.8;
92
+ readonly maxLineHeight: 3;
93
+ };
94
+ /** Tamaños de hoja, en puntos. Oficio es el chileno: 216 x 330 mm. */
95
+ export declare const RICH_PAGE_SIZES: {
96
+ readonly letter: {
97
+ readonly label: "Carta (216 x 279 mm)";
98
+ readonly width: 612;
99
+ readonly height: 792;
100
+ };
101
+ readonly oficio: {
102
+ readonly label: "Oficio (216 x 330 mm)";
103
+ readonly width: 612;
104
+ readonly height: 936;
105
+ };
106
+ };
107
+ export type RichPageSize = keyof typeof RICH_PAGE_SIZES;
108
+ export interface RichMargins {
109
+ top: number;
110
+ right: number;
111
+ bottom: number;
112
+ left: number;
113
+ }
114
+ /**
115
+ * Márgenes mínimos, en puntos: arriba van el membrete y el número con la fecha que estampa el sistema; abajo, la
116
+ * franja del QR en cada página; a los costados, los sellos. Con menos, lo estampado taparía el texto.
117
+ */
118
+ export declare const RICH_MIN_MARGINS: RichMargins;
119
+ /** Márgenes máximos, en puntos (unos 5 cm). */
120
+ export declare const RICH_MAX_MARGIN = 144;
121
+ /** Página de un documento: tamaño, márgenes y letra base. La define la plantilla; quien redacta no la cambia. */
122
+ export interface RichPage {
123
+ size: RichPageSize;
124
+ margins: RichMargins;
125
+ font: RichFont;
126
+ fontSize: number;
127
+ lineHeight: number;
128
+ }
129
+ /** Página de siempre: Carta, con el espacio del membrete y los sellos, en Roboto 11. */
130
+ export declare const RICH_DEFAULT_PAGE: RichPage;
131
+ /**
132
+ * Membrete de la plantilla, en el margen superior de cada página: un logo o escudo (opcional) y el nombre de la
133
+ * municipalidad y de la unidad que emite. Va a la izquierda: a la derecha el sistema estampa el número y la fecha.
134
+ */
135
+ export interface RichLetterhead {
136
+ /** Imagen registrada en el gestor (`RichImage`), no un archivo de Drive. */
137
+ imageId?: string | null;
138
+ /** Alto del logo, en puntos. */
139
+ imageHeight?: number;
140
+ showOrganName: boolean;
141
+ showUnitName: boolean;
142
+ /** Líneas propias bajo el nombre, como la dirección o el teléfono. */
143
+ lines?: string[];
144
+ }
145
+ export declare const RICH_DEFAULT_LETTERHEAD: RichLetterhead;
146
+ /** Límites de una imagen: formatos, peso y tamaño en el texto. */
147
+ export declare const RICH_IMAGE_LIMITS: {
148
+ readonly types: readonly ["image/png", "image/jpeg"];
149
+ readonly maxBytes: 2000000;
150
+ readonly minWidth: 24;
151
+ readonly maxLetterheadHeight: 56;
152
+ };
153
+ /** Imagen subida al gestor para el editor: se usa por su id; el archivo está en Drive. */
154
+ export interface RichImageResponseEntity {
155
+ id: string;
156
+ name: string;
157
+ mimeType: string;
158
+ width: number;
159
+ height: number;
160
+ }
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ /**
3
+ * Formato del editor del gestor que comparten el navegador y el microservicio: tipografías, colores, tamaños de hoja y
4
+ * márgenes. Todo lo que el PDF muestra sale de aquí, así que el editor y el documento oficial se ven igual.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.RICH_IMAGE_LIMITS = exports.RICH_DEFAULT_LETTERHEAD = exports.RICH_DEFAULT_PAGE = exports.RICH_MAX_MARGIN = exports.RICH_MIN_MARGINS = exports.RICH_PAGE_SIZES = exports.RICH_SPACING_LIMITS = exports.RICH_HIGHLIGHTS = exports.RICH_COLORS = exports.RICH_FONT_SIZES = exports.RICH_FONTS = void 0;
8
+ /**
9
+ * Tipografías incrustadas en el PDF (PDF/A exige fuentes incrustadas). Liberation Sans, Liberation Serif y Carlito
10
+ * miden igual que Arial, Times New Roman y Calibri: lo que se pegó desde Word ocupa lo mismo.
11
+ */
12
+ exports.RICH_FONTS = {
13
+ Roboto: 'Roboto',
14
+ LiberationSans: 'Liberation Sans (Arial)',
15
+ LiberationSerif: 'Liberation Serif (Times New Roman)',
16
+ Carlito: 'Carlito (Calibri)',
17
+ };
18
+ /** Tamaños de letra que se ofrecen, en puntos. */
19
+ exports.RICH_FONT_SIZES = [8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 24];
20
+ /** Colores de letra: una paleta acotada, sobria, para documentos oficiales. */
21
+ exports.RICH_COLORS = {
22
+ black: { label: 'Negro', hex: '#111827' },
23
+ gray: { label: 'Gris', hex: '#4B5563' },
24
+ blue: { label: 'Azul', hex: '#1E40AF' },
25
+ red: { label: 'Rojo', hex: '#B91C1C' },
26
+ green: { label: 'Verde', hex: '#166534' },
27
+ brown: { label: 'Café', hex: '#78350F' },
28
+ };
29
+ /** Resaltado del texto. */
30
+ exports.RICH_HIGHLIGHTS = {
31
+ yellow: { label: 'Amarillo', hex: '#FEF08A' },
32
+ green: { label: 'Verde', hex: '#BBF7D0' },
33
+ blue: { label: 'Celeste', hex: '#BFDBFE' },
34
+ pink: { label: 'Rosado', hex: '#FBCFE8' },
35
+ gray: { label: 'Gris', hex: '#E5E7EB' },
36
+ };
37
+ /** Límites del espaciado, en puntos. */
38
+ exports.RICH_SPACING_LIMITS = { maxSpace: 72, maxIndent: 216, minLineHeight: 0.8, maxLineHeight: 3 };
39
+ /** Tamaños de hoja, en puntos. Oficio es el chileno: 216 x 330 mm. */
40
+ exports.RICH_PAGE_SIZES = {
41
+ letter: { label: 'Carta (216 x 279 mm)', width: 612, height: 792 },
42
+ oficio: { label: 'Oficio (216 x 330 mm)', width: 612, height: 936 },
43
+ };
44
+ /**
45
+ * Márgenes mínimos, en puntos: arriba van el membrete y el número con la fecha que estampa el sistema; abajo, la
46
+ * franja del QR en cada página; a los costados, los sellos. Con menos, lo estampado taparía el texto.
47
+ */
48
+ exports.RICH_MIN_MARGINS = { top: 64, right: 42, bottom: 64, left: 42 };
49
+ /** Márgenes máximos, en puntos (unos 5 cm). */
50
+ exports.RICH_MAX_MARGIN = 144;
51
+ /** Página de siempre: Carta, con el espacio del membrete y los sellos, en Roboto 11. */
52
+ exports.RICH_DEFAULT_PAGE = {
53
+ size: 'letter',
54
+ margins: { top: 104, right: 64, bottom: 76, left: 72 },
55
+ font: 'Roboto',
56
+ fontSize: 11,
57
+ lineHeight: 1.2,
58
+ };
59
+ exports.RICH_DEFAULT_LETTERHEAD = { imageId: null, showOrganName: true, showUnitName: true };
60
+ /** Límites de una imagen: formatos, peso y tamaño en el texto. */
61
+ exports.RICH_IMAGE_LIMITS = {
62
+ types: ['image/png', 'image/jpeg'],
63
+ maxBytes: 2000000,
64
+ minWidth: 24,
65
+ maxLetterheadHeight: 56,
66
+ };
@@ -1,5 +1,6 @@
1
1
  import { type DocumentTemplateEntity } from '../../base/entities';
2
2
  import { type RichBlock, type RichField } from '../document/document.entity';
3
+ import { type RichLetterhead, type RichPage } from '../document/richStyle';
3
4
  /**
4
5
  * Contenido de una plantilla propia: los bloques del editor (con sus partes fijas) y los campos que completa quien
5
6
  * redacta (en la plantilla, sin valor).
@@ -7,6 +8,10 @@ import { type RichBlock, type RichField } from '../document/document.entity';
7
8
  export interface DocumentTemplateContent {
8
9
  blocks: RichBlock[];
9
10
  fields: RichField[];
11
+ /** Tamaño de hoja, márgenes y letra base. Sin valor, la página de siempre (`RICH_DEFAULT_PAGE`). */
12
+ page?: RichPage;
13
+ /** Membrete con logo. Sin valor, el nombre de la municipalidad y de la unidad. */
14
+ letterhead?: RichLetterhead;
10
15
  }
11
16
  /** Plantilla propia en el listado de quien las administra. */
12
17
  export interface DocumentTemplateGetAllResponseEntity {
@@ -24,3 +24,4 @@ export * from './mailIntake';
24
24
  export * from './push';
25
25
  export * from './documentTemplate';
26
26
  export * from './draftingRequest';
27
+ export * from './internalReview';
@@ -40,3 +40,4 @@ __exportStar(require("./mailIntake"), exports);
40
40
  __exportStar(require("./push"), exports);
41
41
  __exportStar(require("./documentTemplate"), exports);
42
42
  __exportStar(require("./draftingRequest"), exports);
43
+ __exportStar(require("./internalReview"), exports);
@@ -0,0 +1 @@
1
+ export * from './internalReview.entity';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./internalReview.entity"), exports);
@@ -0,0 +1,59 @@
1
+ import { type DocumentStatus } from '../../base/entities';
2
+ /** Revisoras asignadas a la jefatura de una dirección. */
3
+ export interface DirectorateReviewersEntity {
4
+ directorateCode: number;
5
+ directorateName: string;
6
+ reviewers: {
7
+ employeeId: string;
8
+ fullName: string;
9
+ }[];
10
+ }
11
+ /** Qué espera de la jefatura un documento de la cola de revisión. */
12
+ export type InternalReviewTurn = 'Visa' | 'Signature' | 'DraftReview';
13
+ /** Documento que espera a la jefatura para la que revisa la funcionaria. */
14
+ export interface InternalReviewQueueItemEntity {
15
+ documentId: string;
16
+ subject: string;
17
+ documentTypeName: string;
18
+ /** «D.E. N° 590/2026», o `null` mientras no tiene número. */
19
+ folio: string | null;
20
+ status: DocumentStatus;
21
+ createdByFullName: string;
22
+ directorateCode: number;
23
+ directorateName: string;
24
+ /** Quién de la jefatura tiene el turno (titular o subrogante). */
25
+ headFullName: string;
26
+ turn: InternalReviewTurn;
27
+ /** Ya le toca a la jefatura (si no, espera turnos anteriores). */
28
+ isCurrent: boolean;
29
+ /** Observaciones internas ya dejadas para esta jefatura. */
30
+ notes: number;
31
+ updatedAt: string;
32
+ }
33
+ /** Observación interna para la jefatura de una dirección. */
34
+ export interface InternalNoteResponseEntity {
35
+ id: string;
36
+ directorateCode: number;
37
+ directorateName: string;
38
+ authorFullName: string;
39
+ /** `Reviewer`: la revisora; `Head`: la jefatura que responde. */
40
+ authorRole: 'Reviewer' | 'Head';
41
+ versionNumber: number;
42
+ text: string;
43
+ createdAt: string;
44
+ }
45
+ export interface DocumentInternalNotesResponseEntity {
46
+ notes: InternalNoteResponseEntity[];
47
+ /** Direcciones para las que quien consulta puede dejar una observación en este documento. */
48
+ canAddFor: {
49
+ directorateCode: number;
50
+ directorateName: string;
51
+ }[];
52
+ }
53
+ export interface DocumentInternalNoteResponseEntity {
54
+ note: InternalNoteResponseEntity;
55
+ /** A quién avisar (lo usa el gateway): la jefatura, si escribió la revisora; las revisoras, si respondió la jefatura. */
56
+ notify: {
57
+ employeeIds: string[];
58
+ };
59
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@muni-sanfer/types-gestor-documental",
3
- "version": "0.0.1-beta.40",
3
+ "version": "0.0.1-beta.42",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
@@ -362,7 +362,8 @@ export type AuditEntity =
362
362
  | 'ServiceOutage'
363
363
  | 'Repository'
364
364
  | 'DataTreatment'
365
- | 'DocumentTemplate';
365
+ | 'DocumentTemplate'
366
+ | 'DirectorateReviewer';
366
367
 
367
368
  export const AuditEntity = {
368
369
  DocumentType: 'DocumentType',
@@ -376,6 +377,7 @@ export const AuditEntity = {
376
377
  Repository: 'Repository',
377
378
  DataTreatment: 'DataTreatment',
378
379
  DocumentTemplate: 'DocumentTemplate',
380
+ DirectorateReviewer: 'DirectorateReviewer',
379
381
  } satisfies Record<string, AuditEntity>;
380
382
 
381
383
  export type AuditAction = 'Created' | 'Updated' | 'Enabled' | 'Disabled' | 'Removed' | 'Exported';
@@ -727,6 +729,7 @@ export interface DocumentEntity {
727
729
  comments?: DocumentCommentEntity[];
728
730
  draftReviews?: DocumentDraftReviewEntity[];
729
731
  draftingRequest?: DraftingRequestEntity | null;
732
+ internalNotes?: DocumentInternalNoteEntity[];
730
733
  accessRequestDeliveries?: AccessRequestDocumentEntity[];
731
734
  dispatch?: DocumentDispatchEntity | null;
732
735
  docDigitalInbound?: DocDigitalInboundEntity | null;
@@ -1679,4 +1682,41 @@ export interface DraftingRequestEventEntity {
1679
1682
  createdAt: string;
1680
1683
  }
1681
1684
 
1685
+ export interface DirectorateReviewerEntity {
1686
+ id: string;
1687
+ directorateCode: number;
1688
+ directorateName: string;
1689
+ employeeId: string;
1690
+ fullName: string;
1691
+ createdAt: string;
1692
+ }
1693
+
1694
+ export interface DocumentInternalNoteEntity {
1695
+ id: string;
1696
+ documentId: string;
1697
+ document?: DocumentEntity;
1698
+ directorateCode: number;
1699
+ directorateName: string;
1700
+ headEmployeeIds: string[];
1701
+ versionNumber: number;
1702
+ authorEmployeeId: string;
1703
+ authorFullName: string;
1704
+ authorRole: string;
1705
+ text: string;
1706
+ createdAt: string;
1707
+ }
1708
+
1709
+ export interface RichImageEntity {
1710
+ id: string;
1711
+ fileId: string;
1712
+ name: string;
1713
+ mimeType: string;
1714
+ width: number;
1715
+ height: number;
1716
+ sha256: string;
1717
+ sizeBytes: number;
1718
+ employeeId: string;
1719
+ createdAt: string;
1720
+ }
1721
+
1682
1722
  type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array<JsonValue> | null;
@@ -80,6 +80,11 @@ export interface DocumentActor {
80
80
  employeeId: string;
81
81
  directorateCodes: number[];
82
82
  departmentIds: string[];
83
+ /**
84
+ * Jefaturas para las que revisa (revisora de jefatura): ve los documentos que les esperan. Lo resuelve el gateway
85
+ * solo donde hace falta (el detalle y el PDF).
86
+ */
87
+ reviewFor?: string[];
83
88
  }
84
89
 
85
90
  /** Bandeja desde la que se lista. Todas son del funcionario (`actor`), salvo `all`. */
@@ -24,6 +24,8 @@ import { RegisterBookPatterns, type RegisterBookContract } from './registerBook.
24
24
  import { SignatureBatchPatterns, type SignatureBatchContract } from './signatureBatch.contract';
25
25
  import { WorkFolderPatterns, type WorkFolderContract } from './workFolder.contract';
26
26
  import { DraftingRequestPatterns, type DraftingRequestContract } from './draftingRequest.contract';
27
+ import { InternalReviewPatterns, type InternalReviewContract } from './internalReview.contract';
28
+ import { RichImagePatterns, type RichImageContract } from './richImage.contract';
27
29
 
28
30
  export * from './contract';
29
31
  export * from './document.contract';
@@ -52,6 +54,8 @@ export * from './desk.contract';
52
54
  export * from './mailIntake.contract';
53
55
  export * from './push.contract';
54
56
  export * from './draftingRequest.contract';
57
+ export * from './internalReview.contract';
58
+ export * from './richImage.contract';
55
59
 
56
60
  /** Patrones NATS de gestor-documental-ms, por recurso: `gestorDocumental.<recurso>.<acción>`. */
57
61
  export const GestorDocumentalPatterns = {
@@ -81,6 +85,8 @@ export const GestorDocumentalPatterns = {
81
85
  mailIntake: MailIntakePatterns,
82
86
  push: PushPatterns,
83
87
  draftingRequest: DraftingRequestPatterns,
88
+ internalReview: InternalReviewPatterns,
89
+ richImage: RichImagePatterns,
84
90
  } as const;
85
91
 
86
92
  /** Contrato completo de gestor-documental-ms: la unión de los contratos de sus recursos. */
@@ -109,4 +115,6 @@ export type GestorDocumentalContract = DocumentTypeContract &
109
115
  DeskContract &
110
116
  MailIntakeContract &
111
117
  PushContract &
112
- DraftingRequestContract;
118
+ DraftingRequestContract &
119
+ InternalReviewContract &
120
+ RichImageContract;
@@ -0,0 +1,66 @@
1
+ import {
2
+ type DirectorateReviewersEntity,
3
+ type DocumentInternalNoteResponseEntity,
4
+ type DocumentInternalNotesResponseEntity,
5
+ type InternalReviewQueueItemEntity,
6
+ } from '../entities';
7
+ import { type AuditActorInput } from '../entities';
8
+
9
+ /** Patrones NATS de `internalReview`: revisoras de jefatura y sus observaciones internas. */
10
+ export const InternalReviewPatterns = {
11
+ getReviewers: 'gestorDocumental.internalReview.getReviewers',
12
+ setReviewers: 'gestorDocumental.internalReview.setReviewers',
13
+ getAssignments: 'gestorDocumental.internalReview.getAssignments',
14
+ getQueue: 'gestorDocumental.internalReview.getQueue',
15
+ getNotes: 'gestorDocumental.internalReview.getNotes',
16
+ addNote: 'gestorDocumental.internalReview.addNote',
17
+ } as const;
18
+
19
+ /**
20
+ * Dirección para la que actúa quien consulta: como revisora de su jefatura o como la jefatura misma. La resuelve el
21
+ * gateway: quiénes la dirigen hoy (titular y subrogante) no los dice el navegador.
22
+ */
23
+ export interface InternalReviewScope {
24
+ directorateCode: number;
25
+ directorateName: string;
26
+ headEmployeeIds: string[];
27
+ role: 'Reviewer' | 'Head';
28
+ }
29
+
30
+ export interface InternalReviewContract {
31
+ [InternalReviewPatterns.getReviewers]: { payload: Record<string, never>; response: DirectorateReviewersEntity[] };
32
+ /** Reemplaza las revisoras de una dirección (sin ninguna, la dirección queda sin revisoras). */
33
+ [InternalReviewPatterns.setReviewers]: {
34
+ payload: {
35
+ directorateCode: number;
36
+ directorateName: string;
37
+ reviewers: { employeeId: string; fullName: string }[];
38
+ auditActor?: AuditActorInput;
39
+ };
40
+ response: { id: string; ok: boolean };
41
+ };
42
+ /** Direcciones para cuya jefatura revisa una funcionaria. */
43
+ [InternalReviewPatterns.getAssignments]: {
44
+ payload: { employeeId: string };
45
+ response: { directorateCode: number; directorateName: string }[];
46
+ };
47
+ /** Documentos que esperan a las jefaturas para las que revisa quien consulta. */
48
+ [InternalReviewPatterns.getQueue]: {
49
+ payload: { actor: { employeeId: string }; scopes: InternalReviewScope[] };
50
+ response: InternalReviewQueueItemEntity[];
51
+ };
52
+ [InternalReviewPatterns.getNotes]: {
53
+ payload: { documentId: string; actor: { employeeId: string }; scopes: InternalReviewScope[] };
54
+ response: DocumentInternalNotesResponseEntity;
55
+ };
56
+ [InternalReviewPatterns.addNote]: {
57
+ payload: {
58
+ documentId: string;
59
+ directorateCode: number;
60
+ text: string;
61
+ actor: { employeeId: string; fullName: string };
62
+ scopes: InternalReviewScope[];
63
+ };
64
+ response: DocumentInternalNoteResponseEntity;
65
+ };
66
+ }
@@ -0,0 +1,23 @@
1
+ import { type RichImageResponseEntity } from '../entities';
2
+
3
+ /** Patrones NATS de `richImage`: imágenes del editor (logos de membrete e imágenes del texto). */
4
+ export const RichImagePatterns = {
5
+ register: 'gestorDocumental.richImage.register',
6
+ getFile: 'gestorDocumental.richImage.getFile',
7
+ } as const;
8
+
9
+ export interface RichImageContract {
10
+ /**
11
+ * Registra una imagen ya subida a Drive por el gateway (en la carpeta de los documentos). El ms descarga el archivo, comprueba que sea PNG o JPEG y de
12
+ * tamaño aceptable, y guarda sus medidas y su huella.
13
+ */
14
+ [RichImagePatterns.register]: {
15
+ payload: { fileId: string; name: string; actor: { employeeId: string } };
16
+ response: RichImageResponseEntity;
17
+ };
18
+ /** El archivo de una imagen registrada, para mostrarla en el editor. */
19
+ [RichImagePatterns.getFile]: {
20
+ payload: { id: string };
21
+ response: { fileId: string; fileName: string; mimeType: string };
22
+ };
23
+ }
@@ -10,6 +10,7 @@ import {
10
10
  DocumentTrackingEntity,
11
11
  DocumentTypeEntity,
12
12
  } from '../../base/entities';
13
+ import { type RichLetterhead, type RichPage, type RichSpacing, type RichTextStyle } from './richStyle';
13
14
  import { type DocumentDraftingRequestEntity } from '../draftingRequest/draftingRequest.entity';
14
15
 
15
16
  /** Tipo documental de un documento, con lo necesario para citarlo. */
@@ -453,14 +454,16 @@ export interface DocumentTrailExportEntity {
453
454
  /** Plantilla oficial con que se redacta un documento en el sistema. */
454
455
  export type DocumentTemplateKind = 'Decree' | 'Office' | 'Memorandum' | 'General';
455
456
 
456
- /** Formato de un trozo de texto en el editor del gestor. */
457
- export type RichMark = 'bold' | 'italic' | 'underline';
457
+ /** Formato de un trozo de texto en el editor del gestor. Superíndice y subíndice no van juntos. */
458
+ export type RichMark = 'bold' | 'italic' | 'underline' | 'strike' | 'superscript' | 'subscript';
458
459
 
459
460
  /**
460
461
  * Texto con su formato, o un campo de la plantilla (`field`: su clave), que se reemplaza por su valor al armar el PDF.
461
462
  * Un salto de línea dentro del texto (`\n`) es un salto de línea del párrafo.
462
463
  */
463
- export type RichInline = { text: string; marks?: RichMark[] } | { field: string };
464
+ export type RichInline =
465
+ | { text: string; marks?: RichMark[]; style?: RichTextStyle }
466
+ | { field: string; marks?: RichMark[]; style?: RichTextStyle };
464
467
 
465
468
  export type RichAlign = 'left' | 'center' | 'right' | 'justify';
466
469
 
@@ -478,9 +481,35 @@ export type RichTableVariant = 'grid' | 'labels' | 'labelsRight';
478
481
  * bloques seguidos del mismo estilo (su nivel es la sangría, desde 0); un título o un párrafo reinicia la numeración.
479
482
  */
480
483
  export type RichBlock =
481
- | { id: string; type: 'paragraph'; align?: RichAlign; locked?: boolean; content: RichInline[] }
482
- | { id: string; type: 'heading'; level: 1 | 2; align?: RichAlign; locked?: boolean; content: RichInline[] }
483
- | { id: string; type: 'listItem'; list: RichListStyle; level: number; locked?: boolean; content: RichInline[] }
484
+ | { id: string; type: 'paragraph'; align?: RichAlign; spacing?: RichSpacing; locked?: boolean; content: RichInline[] }
485
+ | {
486
+ id: string;
487
+ type: 'heading';
488
+ level: 1 | 2;
489
+ align?: RichAlign;
490
+ spacing?: RichSpacing;
491
+ locked?: boolean;
492
+ content: RichInline[];
493
+ }
494
+ | {
495
+ id: string;
496
+ type: 'listItem';
497
+ list: RichListStyle;
498
+ level: number;
499
+ spacing?: RichSpacing;
500
+ locked?: boolean;
501
+ content: RichInline[];
502
+ }
503
+ /** Imagen registrada en el gestor (`imageId`), con su ancho en puntos (sin pasar el del texto) y alineación. */
504
+ | {
505
+ id: string;
506
+ type: 'image';
507
+ imageId: string;
508
+ width: number;
509
+ align?: 'left' | 'center' | 'right';
510
+ caption?: string;
511
+ locked?: boolean;
512
+ }
484
513
  /** `rows[fila][columna]`: el contenido de cada celda. */
485
514
  | { id: string; type: 'table'; variant: RichTableVariant; locked?: boolean; rows: RichInline[][][] }
486
515
  | { id: string; type: 'rule'; locked?: boolean }
@@ -544,6 +573,9 @@ export type DocumentComposition =
544
573
  blocks: RichBlock[];
545
574
  fields: RichField[];
546
575
  distribution: string[];
576
+ /** Página y membrete. En una plantilla propia los pone su versión: lo que mande el navegador no cuenta. */
577
+ page?: RichPage;
578
+ letterhead?: RichLetterhead;
547
579
  };
548
580
 
549
581
  /** PDF armado con una plantilla: para la vista previa (`contentBase64`) o ya subido (`fileId`). */
@@ -1 +1,2 @@
1
1
  export * from './document.entity';
2
+ export * from './richStyle';
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Formato del editor del gestor que comparten el navegador y el microservicio: tipografías, colores, tamaños de hoja y
3
+ * márgenes. Todo lo que el PDF muestra sale de aquí, así que el editor y el documento oficial se ven igual.
4
+ */
5
+
6
+ /**
7
+ * Tipografías incrustadas en el PDF (PDF/A exige fuentes incrustadas). Liberation Sans, Liberation Serif y Carlito
8
+ * miden igual que Arial, Times New Roman y Calibri: lo que se pegó desde Word ocupa lo mismo.
9
+ */
10
+ export const RICH_FONTS = {
11
+ Roboto: 'Roboto',
12
+ LiberationSans: 'Liberation Sans (Arial)',
13
+ LiberationSerif: 'Liberation Serif (Times New Roman)',
14
+ Carlito: 'Carlito (Calibri)',
15
+ } as const;
16
+
17
+ export type RichFont = keyof typeof RICH_FONTS;
18
+
19
+ /** Tamaños de letra que se ofrecen, en puntos. */
20
+ export const RICH_FONT_SIZES = [8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 24] as const;
21
+
22
+ /** Colores de letra: una paleta acotada, sobria, para documentos oficiales. */
23
+ export const RICH_COLORS = {
24
+ black: { label: 'Negro', hex: '#111827' },
25
+ gray: { label: 'Gris', hex: '#4B5563' },
26
+ blue: { label: 'Azul', hex: '#1E40AF' },
27
+ red: { label: 'Rojo', hex: '#B91C1C' },
28
+ green: { label: 'Verde', hex: '#166534' },
29
+ brown: { label: 'Café', hex: '#78350F' },
30
+ } as const;
31
+
32
+ export type RichColor = keyof typeof RICH_COLORS;
33
+
34
+ /** Resaltado del texto. */
35
+ export const RICH_HIGHLIGHTS = {
36
+ yellow: { label: 'Amarillo', hex: '#FEF08A' },
37
+ green: { label: 'Verde', hex: '#BBF7D0' },
38
+ blue: { label: 'Celeste', hex: '#BFDBFE' },
39
+ pink: { label: 'Rosado', hex: '#FBCFE8' },
40
+ gray: { label: 'Gris', hex: '#E5E7EB' },
41
+ } as const;
42
+
43
+ export type RichHighlight = keyof typeof RICH_HIGHLIGHTS;
44
+
45
+ /** Formato propio de un trozo de texto, además de sus marcas. Sin valor, el de la página. */
46
+ export interface RichTextStyle {
47
+ font?: RichFont;
48
+ size?: number;
49
+ color?: RichColor;
50
+ highlight?: RichHighlight;
51
+ }
52
+
53
+ /** Espaciado y sangría de un párrafo, título o punto de lista, en puntos (el interlineado, en veces la letra). */
54
+ export interface RichSpacing {
55
+ before?: number;
56
+ after?: number;
57
+ lineHeight?: number;
58
+ /** Sangría de la primera línea. */
59
+ firstLine?: number;
60
+ /** Sangría de todo el párrafo, desde el margen izquierdo. */
61
+ left?: number;
62
+ }
63
+
64
+ /** Límites del espaciado, en puntos. */
65
+ export const RICH_SPACING_LIMITS = { maxSpace: 72, maxIndent: 216, minLineHeight: 0.8, maxLineHeight: 3 } as const;
66
+
67
+ /** Tamaños de hoja, en puntos. Oficio es el chileno: 216 x 330 mm. */
68
+ export const RICH_PAGE_SIZES = {
69
+ letter: { label: 'Carta (216 x 279 mm)', width: 612, height: 792 },
70
+ oficio: { label: 'Oficio (216 x 330 mm)', width: 612, height: 936 },
71
+ } as const;
72
+
73
+ export type RichPageSize = keyof typeof RICH_PAGE_SIZES;
74
+
75
+ export interface RichMargins {
76
+ top: number;
77
+ right: number;
78
+ bottom: number;
79
+ left: number;
80
+ }
81
+
82
+ /**
83
+ * Márgenes mínimos, en puntos: arriba van el membrete y el número con la fecha que estampa el sistema; abajo, la
84
+ * franja del QR en cada página; a los costados, los sellos. Con menos, lo estampado taparía el texto.
85
+ */
86
+ export const RICH_MIN_MARGINS: RichMargins = { top: 64, right: 42, bottom: 64, left: 42 };
87
+
88
+ /** Márgenes máximos, en puntos (unos 5 cm). */
89
+ export const RICH_MAX_MARGIN = 144;
90
+
91
+ /** Página de un documento: tamaño, márgenes y letra base. La define la plantilla; quien redacta no la cambia. */
92
+ export interface RichPage {
93
+ size: RichPageSize;
94
+ margins: RichMargins;
95
+ font: RichFont;
96
+ fontSize: number;
97
+ lineHeight: number;
98
+ }
99
+
100
+ /** Página de siempre: Carta, con el espacio del membrete y los sellos, en Roboto 11. */
101
+ export const RICH_DEFAULT_PAGE: RichPage = {
102
+ size: 'letter',
103
+ margins: { top: 104, right: 64, bottom: 76, left: 72 },
104
+ font: 'Roboto',
105
+ fontSize: 11,
106
+ lineHeight: 1.2,
107
+ };
108
+
109
+ /**
110
+ * Membrete de la plantilla, en el margen superior de cada página: un logo o escudo (opcional) y el nombre de la
111
+ * municipalidad y de la unidad que emite. Va a la izquierda: a la derecha el sistema estampa el número y la fecha.
112
+ */
113
+ export interface RichLetterhead {
114
+ /** Imagen registrada en el gestor (`RichImage`), no un archivo de Drive. */
115
+ imageId?: string | null;
116
+ /** Alto del logo, en puntos. */
117
+ imageHeight?: number;
118
+ showOrganName: boolean;
119
+ showUnitName: boolean;
120
+ /** Líneas propias bajo el nombre, como la dirección o el teléfono. */
121
+ lines?: string[];
122
+ }
123
+
124
+ export const RICH_DEFAULT_LETTERHEAD: RichLetterhead = { imageId: null, showOrganName: true, showUnitName: true };
125
+
126
+ /** Límites de una imagen: formatos, peso y tamaño en el texto. */
127
+ export const RICH_IMAGE_LIMITS = {
128
+ types: ['image/png', 'image/jpeg'],
129
+ maxBytes: 2_000_000,
130
+ minWidth: 24,
131
+ maxLetterheadHeight: 56,
132
+ } as const;
133
+
134
+ /** Imagen subida al gestor para el editor: se usa por su id; el archivo está en Drive. */
135
+ export interface RichImageResponseEntity {
136
+ id: string;
137
+ name: string;
138
+ mimeType: string;
139
+ width: number;
140
+ height: number;
141
+ }
@@ -1,5 +1,6 @@
1
1
  import { type DocumentTemplateEntity } from '../../base/entities';
2
2
  import { type RichBlock, type RichField } from '../document/document.entity';
3
+ import { type RichLetterhead, type RichPage } from '../document/richStyle';
3
4
 
4
5
  /**
5
6
  * Contenido de una plantilla propia: los bloques del editor (con sus partes fijas) y los campos que completa quien
@@ -8,6 +9,10 @@ import { type RichBlock, type RichField } from '../document/document.entity';
8
9
  export interface DocumentTemplateContent {
9
10
  blocks: RichBlock[];
10
11
  fields: RichField[];
12
+ /** Tamaño de hoja, márgenes y letra base. Sin valor, la página de siempre (`RICH_DEFAULT_PAGE`). */
13
+ page?: RichPage;
14
+ /** Membrete con logo. Sin valor, el nombre de la municipalidad y de la unidad. */
15
+ letterhead?: RichLetterhead;
11
16
  }
12
17
 
13
18
  /** Plantilla propia en el listado de quien las administra. */
@@ -24,3 +24,4 @@ export * from './mailIntake';
24
24
  export * from './push';
25
25
  export * from './documentTemplate';
26
26
  export * from './draftingRequest';
27
+ export * from './internalReview';
@@ -0,0 +1 @@
1
+ export * from './internalReview.entity';
@@ -0,0 +1,57 @@
1
+ import { type DocumentStatus } from '../../base/entities';
2
+
3
+ /** Revisoras asignadas a la jefatura de una dirección. */
4
+ export interface DirectorateReviewersEntity {
5
+ directorateCode: number;
6
+ directorateName: string;
7
+ reviewers: { employeeId: string; fullName: string }[];
8
+ }
9
+
10
+ /** Qué espera de la jefatura un documento de la cola de revisión. */
11
+ export type InternalReviewTurn = 'Visa' | 'Signature' | 'DraftReview';
12
+
13
+ /** Documento que espera a la jefatura para la que revisa la funcionaria. */
14
+ export interface InternalReviewQueueItemEntity {
15
+ documentId: string;
16
+ subject: string;
17
+ documentTypeName: string;
18
+ /** «D.E. N° 590/2026», o `null` mientras no tiene número. */
19
+ folio: string | null;
20
+ status: DocumentStatus;
21
+ createdByFullName: string;
22
+ directorateCode: number;
23
+ directorateName: string;
24
+ /** Quién de la jefatura tiene el turno (titular o subrogante). */
25
+ headFullName: string;
26
+ turn: InternalReviewTurn;
27
+ /** Ya le toca a la jefatura (si no, espera turnos anteriores). */
28
+ isCurrent: boolean;
29
+ /** Observaciones internas ya dejadas para esta jefatura. */
30
+ notes: number;
31
+ updatedAt: string;
32
+ }
33
+
34
+ /** Observación interna para la jefatura de una dirección. */
35
+ export interface InternalNoteResponseEntity {
36
+ id: string;
37
+ directorateCode: number;
38
+ directorateName: string;
39
+ authorFullName: string;
40
+ /** `Reviewer`: la revisora; `Head`: la jefatura que responde. */
41
+ authorRole: 'Reviewer' | 'Head';
42
+ versionNumber: number;
43
+ text: string;
44
+ createdAt: string;
45
+ }
46
+
47
+ export interface DocumentInternalNotesResponseEntity {
48
+ notes: InternalNoteResponseEntity[];
49
+ /** Direcciones para las que quien consulta puede dejar una observación en este documento. */
50
+ canAddFor: { directorateCode: number; directorateName: string }[];
51
+ }
52
+
53
+ export interface DocumentInternalNoteResponseEntity {
54
+ note: InternalNoteResponseEntity;
55
+ /** A quién avisar (lo usa el gateway): la jefatura, si escribió la revisora; las revisoras, si respondió la jefatura. */
56
+ notify: { employeeIds: string[] };
57
+ }