refactor(14-01): extract DKV inbox providers into shared inbox/ module
- Move ImapProvider, ExchangeInboxProvider, InboxProvider into apps/api/src/inbox/ - Move InboxConfig/InboxAttachment/InboxEmail into new inbox.types.ts - dkv.types.ts re-exports the moved types so existing DKV imports keep compiling - DKV switches import paths to ../inbox/... and imports InboxModule - Pure move + import-path swap: fetchPdfAttachments and all DKV logic unchanged (D-01/D-02) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import { Logger, Module, OnModuleInit } from '@nestjs/common';
|
|||||||
import { ModuleRegistryModule } from '../module-registry/module-registry.module';
|
import { ModuleRegistryModule } from '../module-registry/module-registry.module';
|
||||||
import { ModuleRegistryService } from '../module-registry/module-registry.service';
|
import { ModuleRegistryService } from '../module-registry/module-registry.service';
|
||||||
import { CalendarModule } from '../calendar/calendar.module';
|
import { CalendarModule } from '../calendar/calendar.module';
|
||||||
|
import { InboxModule } from '../inbox/inbox.module';
|
||||||
import { SettingsModule } from '../settings/settings.module';
|
import { SettingsModule } from '../settings/settings.module';
|
||||||
import { DkvController } from './dkv.controller';
|
import { DkvController } from './dkv.controller';
|
||||||
import { DkvExportService } from './dkv-export.service';
|
import { DkvExportService } from './dkv-export.service';
|
||||||
@@ -9,8 +10,6 @@ import { DkvMailService } from './dkv-mail.service';
|
|||||||
import { DkvParserService } from './dkv-parser.service';
|
import { DkvParserService } from './dkv-parser.service';
|
||||||
import { DkvSchedulerService } from './dkv-scheduler.service';
|
import { DkvSchedulerService } from './dkv-scheduler.service';
|
||||||
import { DkvService } from './dkv.service';
|
import { DkvService } from './dkv.service';
|
||||||
import { ExchangeInboxProvider } from './providers/exchange-inbox.provider';
|
|
||||||
import { ImapProvider } from './providers/imap.provider';
|
|
||||||
import { seedDkvModule } from './dkv.seed';
|
import { seedDkvModule } from './dkv.seed';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,12 +21,15 @@ import { seedDkvModule } from './dkv.seed';
|
|||||||
* - DkvParserService: pdf-parse v2 text extraction + DKV-specific regex
|
* - DkvParserService: pdf-parse v2 text extraction + DKV-specific regex
|
||||||
* - DkvExportService: xlsx buffer generation + user-files/ management
|
* - DkvExportService: xlsx buffer generation + user-files/ management
|
||||||
* - DkvMailService: nodemailer.createTransport() at send time
|
* - DkvMailService: nodemailer.createTransport() at send time
|
||||||
* - ImapProvider / ExchangeInboxProvider: inbox access providers
|
* - ImapProvider / ExchangeInboxProvider: inbox access providers, now imported
|
||||||
|
* from the shared InboxModule (D-01, Phase 14 inbox extraction)
|
||||||
*
|
*
|
||||||
* Imports:
|
* Imports:
|
||||||
* - ModuleRegistryModule: for registry self-seed on init
|
* - ModuleRegistryModule: for registry self-seed on init
|
||||||
* - CalendarModule: provides CalendarCryptoService (AES-256-GCM encryption)
|
* - CalendarModule: provides CalendarCryptoService (AES-256-GCM encryption)
|
||||||
* re-exported from CalendarModule.exports — no re-declaration needed here.
|
* re-exported from CalendarModule.exports — no re-declaration needed here.
|
||||||
|
* - InboxModule: exports ImapProvider / ExchangeInboxProvider (shared connection
|
||||||
|
* mechanics — DKV's own mailbox config stays independent, D-03)
|
||||||
*
|
*
|
||||||
* PrismaModule is global (no explicit import needed).
|
* PrismaModule is global (no explicit import needed).
|
||||||
* ScheduleModule.forRoot() was registered in AppModule by Plan 01.
|
* ScheduleModule.forRoot() was registered in AppModule by Plan 01.
|
||||||
@@ -40,6 +42,7 @@ import { seedDkvModule } from './dkv.seed';
|
|||||||
imports: [
|
imports: [
|
||||||
ModuleRegistryModule,
|
ModuleRegistryModule,
|
||||||
CalendarModule,
|
CalendarModule,
|
||||||
|
InboxModule,
|
||||||
SettingsModule,
|
SettingsModule,
|
||||||
],
|
],
|
||||||
controllers: [DkvController],
|
controllers: [DkvController],
|
||||||
@@ -49,8 +52,6 @@ import { seedDkvModule } from './dkv.seed';
|
|||||||
DkvParserService,
|
DkvParserService,
|
||||||
DkvExportService,
|
DkvExportService,
|
||||||
DkvMailService,
|
DkvMailService,
|
||||||
ImapProvider,
|
|
||||||
ExchangeInboxProvider,
|
|
||||||
],
|
],
|
||||||
exports: [DkvService],
|
exports: [DkvService],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import { DkvMailService } from './dkv-mail.service';
|
|||||||
import { DkvParserService } from './dkv-parser.service';
|
import { DkvParserService } from './dkv-parser.service';
|
||||||
import { DkvConfigDto } from './dto/dkv-config.dto';
|
import { DkvConfigDto } from './dto/dkv-config.dto';
|
||||||
import { CreateVehicleDto, UpdateVehicleDto } from './dto/dkv-vehicle.dto';
|
import { CreateVehicleDto, UpdateVehicleDto } from './dto/dkv-vehicle.dto';
|
||||||
import { ExchangeInboxProvider } from './providers/exchange-inbox.provider';
|
import { ExchangeInboxProvider } from '../inbox/exchange-inbox.provider';
|
||||||
import { ImapProvider } from './providers/imap.provider';
|
import { ImapProvider } from '../inbox/imap.provider';
|
||||||
import type { DkvVehicleBlock, InboxConfig, InboxEmail } from './dkv.types';
|
import type { DkvVehicleBlock, InboxConfig, InboxEmail } from './dkv.types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -41,50 +41,12 @@ export interface DkvVehicleBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inbox connection configuration (supports IMAP and Exchange).
|
* Inbox connection types (InboxConfig/InboxAttachment/InboxEmail) moved to
|
||||||
* Mirrors DkvModuleConfig from Prisma but with decrypted credentials.
|
* the shared apps/api/src/inbox/ module (D-01, Phase 14 inbox extraction).
|
||||||
|
* Re-exported here so every existing DKV import path keeps compiling
|
||||||
|
* unchanged — DKV behavior is byte-identical after the move.
|
||||||
*/
|
*/
|
||||||
export interface InboxConfig {
|
export type { InboxConfig, InboxAttachment, InboxEmail } from '../inbox/inbox.types';
|
||||||
/** 'imap' | 'exchange' */
|
|
||||||
protocol: string;
|
|
||||||
host: string;
|
|
||||||
port: number;
|
|
||||||
/** Optional username (may be empty for anonymous or Exchange-with-integrated-auth) */
|
|
||||||
username?: string;
|
|
||||||
/** Decrypted password (never persisted in this form) */
|
|
||||||
password?: string;
|
|
||||||
/** 'none' | 'starttls' | 'ssl-tls' */
|
|
||||||
encryption: string;
|
|
||||||
/** IMAP folder to monitor (e.g., "INBOX") */
|
|
||||||
folder: string;
|
|
||||||
/** Sender filter: only process emails from this address */
|
|
||||||
senderFilter?: string;
|
|
||||||
/** Exchange only: Windows domain (e.g. "CONTOSO") */
|
|
||||||
domain?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A single email attachment, already downloaded as a Buffer.
|
|
||||||
*/
|
|
||||||
export interface InboxAttachment {
|
|
||||||
filename: string;
|
|
||||||
contentType: string;
|
|
||||||
buffer: Buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A fetched email message with its PDF attachments.
|
|
||||||
*/
|
|
||||||
export interface InboxEmail {
|
|
||||||
/** IMAP UID or Exchange item ID */
|
|
||||||
uid: number | string;
|
|
||||||
/** RFC 2822 Message-ID header */
|
|
||||||
messageId: string;
|
|
||||||
subject: string;
|
|
||||||
from: string;
|
|
||||||
date: Date;
|
|
||||||
attachments: InboxAttachment[];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A single row in the Excel export (5 columns per D-13).
|
* A single row in the Excel export (5 columns per D-13).
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import { InboxAttachment, InboxConfig, InboxEmail } from '../dkv.types';
|
import { InboxAttachment, InboxConfig, InboxEmail } from './inbox.types';
|
||||||
|
|
||||||
// Re-export types for downstream consumers that import from this module
|
// Re-export types for downstream consumers that import from this module
|
||||||
export type { InboxAttachment, InboxConfig, InboxEmail };
|
export type { InboxAttachment, InboxConfig, InboxEmail };
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { ExchangeInboxProvider } from './exchange-inbox.provider';
|
||||||
|
import { ImapProvider } from './imap.provider';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared inbox-connection module (IMAP/Exchange).
|
||||||
|
*
|
||||||
|
* Extracted out of DKV (D-01, 14-CONTEXT.md) so any module that needs to
|
||||||
|
* poll a mailbox — e.g. the Phase-14 EmailAlertAdapter (Plan 14-03) — can
|
||||||
|
* import InboxModule and inject ImapProvider / ExchangeInboxProvider without
|
||||||
|
* depending on DKV. DKV imports this module unchanged in behavior; each
|
||||||
|
* module keeps its own, independent mailbox configuration (D-03) — only the
|
||||||
|
* connection code is shared.
|
||||||
|
*/
|
||||||
|
@Module({
|
||||||
|
providers: [ImapProvider, ExchangeInboxProvider],
|
||||||
|
exports: [ImapProvider, ExchangeInboxProvider],
|
||||||
|
})
|
||||||
|
export class InboxModule {}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* Shared types for the inbox module (IMAP/Exchange connection mechanics).
|
||||||
|
*
|
||||||
|
* Moved verbatim out of apps/api/src/dkv/dkv.types.ts as part of the
|
||||||
|
* Phase 14 inbox-module extraction (D-01/D-02, 14-CONTEXT.md). DKV re-exports
|
||||||
|
* these from ../inbox/inbox.types so existing DKV imports keep compiling.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inbox connection configuration (supports IMAP and Exchange).
|
||||||
|
* Mirrors DkvModuleConfig from Prisma but with decrypted credentials.
|
||||||
|
*/
|
||||||
|
export interface InboxConfig {
|
||||||
|
/** 'imap' | 'exchange' */
|
||||||
|
protocol: string;
|
||||||
|
host: string;
|
||||||
|
port: number;
|
||||||
|
/** Optional username (may be empty for anonymous or Exchange-with-integrated-auth) */
|
||||||
|
username?: string;
|
||||||
|
/** Decrypted password (never persisted in this form) */
|
||||||
|
password?: string;
|
||||||
|
/** 'none' | 'starttls' | 'ssl-tls' */
|
||||||
|
encryption: string;
|
||||||
|
/** IMAP folder to monitor (e.g., "INBOX") */
|
||||||
|
folder: string;
|
||||||
|
/** Sender filter: only process emails from this address */
|
||||||
|
senderFilter?: string;
|
||||||
|
/** Exchange only: Windows domain (e.g. "CONTOSO") */
|
||||||
|
domain?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A single email attachment, already downloaded as a Buffer.
|
||||||
|
*/
|
||||||
|
export interface InboxAttachment {
|
||||||
|
filename: string;
|
||||||
|
contentType: string;
|
||||||
|
buffer: Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fetched email message with its PDF attachments.
|
||||||
|
*/
|
||||||
|
export interface InboxEmail {
|
||||||
|
/** IMAP UID or Exchange item ID */
|
||||||
|
uid: number | string;
|
||||||
|
/** RFC 2822 Message-ID header */
|
||||||
|
messageId: string;
|
||||||
|
subject: string;
|
||||||
|
from: string;
|
||||||
|
date: Date;
|
||||||
|
attachments: InboxAttachment[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A single fetched message with subject + HTML/text body (no attachments).
|
||||||
|
*
|
||||||
|
* Added additively (D-02) as the seam Plan 14-03's EmailAlertAdapter consumes
|
||||||
|
* via InboxProvider.fetchMessages — DKV's fetchPdfAttachments is unaffected.
|
||||||
|
*/
|
||||||
|
export interface InboxMessage {
|
||||||
|
/** IMAP UID or Exchange item ID */
|
||||||
|
uid: number | string;
|
||||||
|
/** RFC 2822 Message-ID header */
|
||||||
|
messageId: string;
|
||||||
|
subject: string;
|
||||||
|
from: string;
|
||||||
|
date: Date;
|
||||||
|
/** HTML body part, or null when the message has no text/html part */
|
||||||
|
bodyHtml: string | null;
|
||||||
|
/** Plain-text body part; empty string when the message has no text/plain part */
|
||||||
|
bodyText: string;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user