Files
tessera-ctl/.planning/phases/07-dkv-fleet-module/07-02-SUMMARY.md
T
schalli c7b0103a10
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 43s
Tessera CI/CD / Tests (push) Waiting to run
docs(07-02): complete DKV inbox-access layer plan
- 07-02-SUMMARY.md: interface + IMAP + Exchange providers, all 3 DTOs, self-check passed
- STATE.md: advance to Plan 3/6, record 3 decisions, update session to 2026-06-27
- ROADMAP.md: mark 07-01 and 07-02 complete, Phase 7 progress 2/6
2026-06-27 00:06:24 +02:00

6.9 KiB

phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
phase plan subsystem tags dependency_graph tech_stack key_files decisions metrics
07-dkv-fleet-module 02 dkv-inbox-access-layer
dkv
imap
ews
exchange
imapflow
inbox-provider
dto
class-validator
requires provides affects
dkv.types.ts (Plan 01)
CalendarModule (ews-javascript-api installed)
InboxProvider interface
ImapProvider
ExchangeInboxProvider
DkvConfigDto
CreateVehicleDto
UpdateVehicleDto
DkvHistoryQueryDto
apps/api/src/dkv/providers/inbox-provider.interface.ts
apps/api/src/dkv/providers/imap.provider.ts
apps/api/src/dkv/providers/exchange-inbox.provider.ts
apps/api/src/dkv/dto/dkv-config.dto.ts
apps/api/src/dkv/dto/dkv-vehicle.dto.ts
apps/api/src/dkv/dto/dkv-history.dto.ts
added patterns
imapflow: fetchAll() before any download() — avoids IMAP connection deadlock (Pitfall 1)
imapflow: logger:false in ImapFlow constructor — credential safety (T-07-03)
imapflow: collectPdfParts() recursive MIME tree traversal for application/pdf parts
ews-javascript-api: dynamic import as any, WellKnownFolderName.Inbox + FindItems (not FindAppointments)
ews-javascript-api: SearchFilter.ContainsSubstring for server-side sender filtering
25MB MAX_ATTACHMENT_BYTES guard in both providers — PDF-bomb mitigation (T-07-05)
export type { ... } required for isolatedModules TypeScript setting
class-validator: @IsEmail() on senderFilter/exportRecipient, @Min(5) on pollIntervalMin, @IsInt @Min(1) on pagination
created modified
apps/api/src/dkv/providers/inbox-provider.interface.ts
apps/api/src/dkv/providers/imap.provider.ts
apps/api/src/dkv/providers/exchange-inbox.provider.ts
apps/api/src/dkv/dto/dkv-config.dto.ts
apps/api/src/dkv/dto/dkv-vehicle.dto.ts
apps/api/src/dkv/dto/dkv-history.dto.ts
Max attachment size limit set to 25MB (26_214_400 bytes) — covers all realistic DKV invoices; larger files are skipped with a warning log
ExchangeInboxProvider uses server-side SearchFilter.ContainsSubstring for sender filtering plus client-side verification (handles case-insensitivity differences)
InboxProvider re-exports dkv.types.ts shapes using export type {} (isolatedModules requirement)
EWS attachment download: attachment.Load() then Buffer.from(attachment.Content) — no streaming interface available in ews-javascript-api
ExchangeInboxProvider buildService() uses WebCredentials with empty string fallback (avoids undefined credential error when username/password absent)
duration completed tasks files_created files_modified
5min 2026-06-27T00:05:00Z 3 6 0

Phase 07 Plan 02: DKV Inbox Access Layer — Interface + IMAP + Exchange Providers Summary

Interchangeable inbox-access layer built: InboxProvider interface contract, ImapProvider (imapflow with fetchAll-before-download deadlock avoidance, logger:false credential safety, 25MB PDF-bomb guard) and ExchangeInboxProvider (dynamic ews-javascript-api import, WellKnownFolderName.Inbox + FindItems — not FindAppointments, SearchFilter sender filtering, same 25MB guard). All three class-validator DTOs defined with security constraints from Research V5.

Tasks Completed

Task Name Commit Key Files
1 InboxProvider interface + config/vehicle/history DTOs 86ec896 inbox-provider.interface.ts, dkv-config.dto.ts, dkv-vehicle.dto.ts, dkv-history.dto.ts
2 ImapProvider (imapflow) b3f21a8 providers/imap.provider.ts
3 ExchangeInboxProvider (ews-javascript-api) 924de76 providers/exchange-inbox.provider.ts

Verification Results

  • pnpm --filter @tessera/api type-check exits 0: PASS
  • grep -q "fetchAll" imap.provider.ts: PASS
  • grep -q "logger: false" imap.provider.ts: PASS
  • grep -q "WellKnownFolderName.Inbox" exchange-inbox.provider.ts: PASS
  • grep -q "import('ews-javascript-api')" exchange-inbox.provider.ts: PASS
  • grep -q "IsEmail" dkv-config.dto.ts: PASS
  • grep -q "InboxProvider" inbox-provider.interface.ts: PASS
  • Both providers > 40 lines: imap.provider.ts (224 lines), exchange-inbox.provider.ts (228 lines): PASS
  • No download() inside fetch() async iterator: PASS (fetchAll pattern used)
  • 25MB attachment size guard present in both providers: PASS

Deviations from Plan

Auto-fixed Issues

1. [Rule 1 - Bug] export type required for isolatedModules TypeScript setting

  • Found during: Task 1 type-check
  • Issue: inbox-provider.interface.ts used export { InboxAttachment, InboxConfig, InboxEmail } (value export syntax). The TypeScript project has isolatedModules: true, which requires export type { ... } for type-only re-exports (TS1205 error).
  • Fix: Changed to export type { InboxAttachment, InboxConfig, InboxEmail }
  • Files modified: apps/api/src/dkv/providers/inbox-provider.interface.ts
  • Commit: 86ec896

EWS Adjustments vs Calendar ExchangeProvider

Aspect CalendarExchangeProvider ExchangeInboxProvider
Folder WellKnownFolderName.Calendar WellKnownFolderName.Inbox
Find method FindAppointments + CalendarView FindItems + ItemView
Bind method Direct from findResults.Items EmailMessage.Bind with PropertySet
Sender filter Not applicable (calendar) SearchFilter.ContainsSubstring (server) + client-side verification
Attachment handling Not applicable (calendar) FileAttachment.Load() + Content → Buffer
Error path returns [] returns [] (consistent)

Known Stubs

None — all functionality in this plan is fully implemented. Neither provider contains placeholder comments or TODO items that would block Plan 04 orchestration.

Threat Flags

None. All STRIDE threats in this plan's threat register were mitigated:

  • T-07-03: logger: false in ImapFlow constructor; generic error messages in all catch blocks; credentials never appear in log strings
  • T-07-04: senderFilter validated with @IsEmail(), port with @Min(1)@Max(65535), protocol/encryption with @IsIn()
  • T-07-05: MAX_ATTACHMENT_BYTES = 25MB guard applied before buffering in both ImapProvider (streamToBuffer) and ExchangeInboxProvider (extractPdfAttachments)
  • T-07-06: DkvHistoryQueryDto exposes page and limit with @IsInt() @Min(1)

Self-Check: PASSED

Files verified present:

  • apps/api/src/dkv/providers/inbox-provider.interface.ts ✓
  • apps/api/src/dkv/providers/imap.provider.ts ✓
  • apps/api/src/dkv/providers/exchange-inbox.provider.ts ✓
  • apps/api/src/dkv/dto/dkv-config.dto.ts ✓
  • apps/api/src/dkv/dto/dkv-vehicle.dto.ts ✓
  • apps/api/src/dkv/dto/dkv-history.dto.ts ✓

Commits verified in git log:

  • 86ec896 ✓ (feat(07-02): InboxProvider interface + config/vehicle/history DTOs)
  • b3f21a8 ✓ (feat(07-02): ImapProvider — IMAP inbox access via imapflow)
  • 924de76 ✓ (feat(07-02): ExchangeInboxProvider — EWS email inbox access)