feat(07-01): install DKV deps, add Prisma models, wire ScheduleModule + crypto export
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 37s
Tessera CI/CD / Tests (push) Waiting to run

- pnpm add imapflow@^1.4.3, pdf-parse@^2.4.5, xlsx@^0.18.5 to @tessera/api
- Append DkvModuleConfig, DkvVehicleMaster, DkvInvoiceHistory, SmtpConfig models to schema.prisma (15 models total)
- Add ScheduleModule.forRoot() to AppModule imports (prerequisite for DkvSchedulerService)
- Export CalendarCryptoService from CalendarModule (needed by DkvModule + SettingsModule)
- Create apps/api/src/dkv/dkv.types.ts with DkvVehicleBlock, DkvTransaction, InboxConfig, InboxEmail, InboxAttachment, ExportRow interfaces
This commit is contained in:
2026-06-26 19:25:42 +02:00
parent de06794e67
commit c4b39ccd1b
6 changed files with 527 additions and 8 deletions
+2
View File
@@ -1,6 +1,7 @@
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { ScheduleModule } from '@nestjs/schedule';
import { AuthModule } from './auth/auth.module';
import { JwtAuthGuard } from './auth/guards/jwt-auth.guard';
import { RolesGuard } from './auth/guards/roles.guard';
@@ -20,6 +21,7 @@ import { UserModule } from './user/user.module';
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
ScheduleModule.forRoot(),
PrismaModule,
AuthModule,
UserModule,
+1 -1
View File
@@ -28,6 +28,6 @@ import { ExchangeProvider } from './providers/exchange.provider';
ICSProvider,
ExchangeProvider,
],
exports: [CalendarService],
exports: [CalendarService, CalendarCryptoService],
})
export class CalendarModule {}
+101
View File
@@ -0,0 +1,101 @@
/**
* Shared types for the DKV Fleet Module.
*
* These interfaces are the single source of truth for data shapes exchanged
* between the parser, scheduler, export, and mail services.
*/
/**
* A single fuel transaction row extracted from a DKV E-Rechnung PDF.
*/
export interface DkvTransaction {
/** Date string in German format "DD.MM.YYYY" */
lieferdatum: string;
/** Service station city / location */
ort: string;
/** Odometer reading at time of fuelling (numeric, German thousands-dots stripped) */
kilometerstand: number;
/** Product name (e.g., "Diesel", "AdBlue") */
produkt: string;
/** Quantity dispensed (German decimal notation converted to JS float) */
menge: number;
/** Unit of measure (e.g., "L") */
einheit: string;
/** Net amount in EUR */
netto: number;
/** Gross amount in EUR */
brutto: number;
}
/**
* A vehicle section extracted from a DKV E-Rechnung PDF.
* Each block corresponds to one VEHICLE: ... CARD NO.: ... section.
*/
export interface DkvVehicleBlock {
/** License plate (Kennzeichen), e.g. "GP-JL 728E" */
kennzeichen: string;
/** DKV card number */
cardNumber: string;
/** All fuel transactions for this vehicle in the invoice */
transactions: DkvTransaction[];
}
/**
* 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;
}
/**
* 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).
*/
export interface ExportRow {
/** "DD.MM.YYYY" */
lieferdatum: string;
/** Resolved from format string, e.g. "{Marke}/{Modell}/{Kennzeichen}" */
fahrzeug: string;
/** "Vorname Nachname" from vehicle master */
fahrer: string;
/** Service station city from PDF */
ort: string;
/** Numeric odometer reading */
kilometerstand: number;
}