schalli
8320a34035
fix(07): replace TenantMiddleware with TenantGuard to fix tenant context
...
Tessera CI/CD / Lint & Type Check (push) Waiting to run
Tessera CI/CD / Tests (push) Blocked by required conditions
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Middleware runs before guards in NestJS — req.user was always undefined
when TenantMiddleware executed, so req.tenantId was never set.
Convert to TenantGuard (APP_GUARD, registered after JwtAuthGuard) so it
runs after JWT validation and can read req.user.tenantId correctly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-27 20:57:03 +02:00
schalli
dd5bc90395
fix(07): DKV/Settings module wiring and missing cron dep
...
Tessera CI/CD / Lint & Type Check (push) Waiting to run
Tessera CI/CD / Tests (push) Blocked by required conditions
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
- Add `cron@4.4.0` as direct dep (pnpm strict isolation blocks transitive access)
- Import SettingsModule in DkvModule so DkvMailService can inject SettingsService
- Fix dkv.service.ts return key: `count` → `imported` to match declared return type
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-27 20:28:06 +02:00
schalli
5d6024569a
test(07): begin UAT — 1 issue (cold start DB P1001), 8 tests pending
Tessera CI/CD / Lint & Type Check (push) Waiting to run
Tessera CI/CD / Tests (push) Blocked by required conditions
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
2026-06-27 18:02:15 +02:00
schalli
071531f880
docs(07): add code review fix report
Tessera CI/CD / Lint & Type Check (push) Waiting to run
Tessera CI/CD / Tests (push) Blocked by required conditions
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
2026-06-27 17:23:37 +02:00
schalli
d2d224cdd5
fix(07): WR-05 add 5 MB file size limit to CSV vehicle import endpoint
...
Tessera CI/CD / Lint & Type Check (push) Waiting to run
Tessera CI/CD / Tests (push) Blocked by required conditions
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
FileInterceptor used multer's default memory storage with no size limit.
An oversized file could exhaust Node.js heap before parsing begins.
Add fileSize: 5*1024*1024 (5 MB) — sufficient for any realistic vehicle list.
2026-06-27 17:22:27 +02:00
schalli
9de16babe4
fix(07): WR-04 sanitise Exchange UniqueId in invoice number fallback
...
Tessera CI/CD / Lint & Type Check (push) Waiting to run
Tessera CI/CD / Tests (push) Blocked by required conditions
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Exchange EWS UniqueIds are base64-encoded and can contain +, /, = characters.
When used as the fallback rechnungsnummer (email-{uid}), a slash would cause
path.join() to resolve into a subdirectory, making writeFileSync fail silently.
Sanitise uid to [a-zA-Z0-9-] before it reaches the filesystem write path.
2026-06-27 17:22:09 +02:00
schalli
338655c57b
fix(07): WR-03 replace dead try/catch in formatDateTime with isNaN guard
...
Tessera CI/CD / Lint & Type Check (push) Waiting to run
Tessera CI/CD / Tests (push) Blocked by required conditions
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
new Date() never throws so the catch was unreachable. Invalid dates rendered
as NaN.NaN.NaN, NaN:NaN Uhr. Use isNaN(d.getTime()) guard to fall back to
the raw string instead.
2026-06-27 17:21:51 +02:00
schalli
49eab55abe
fix(07): WR-02 add @Type(Number) coercion to pagination DTO fields
...
Tessera CI/CD / Lint & Type Check (push) Waiting to run
Tessera CI/CD / Tests (push) Blocked by required conditions
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
HTTP query params arrive as strings. Without @Type(() => Number),
class-transformer never coerces page/limit before @IsInt() runs,
causing HTTP 400 for any request that explicitly passes ?page or ?limit.
Also adds @Max(100) on limit to bound result-set size.
2026-06-27 17:21:28 +02:00
schalli
ded652382d
fix(07): WR-01 close nodemailer transport in finally to prevent pool leak
...
Tessera CI/CD / Lint & Type Check (push) Waiting to run
Tessera CI/CD / Tests (push) Blocked by required conditions
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Each sendExportEmail call created a new nodemailer transport which was never
closed, leaving the internal SMTP connection pool alive. With 3-retry backoff,
up to 3 leaked transports per invoice accumulate over time and can exhaust OS
socket limits. Add transport.close() in a finally block.
2026-06-27 17:21:01 +02:00
schalli
cb0d378ded
fix(07): CR-03 close IMAP connection when getMailboxLock throws
...
Tessera CI/CD / Lint & Type Check (push) Waiting to run
Tessera CI/CD / Tests (push) Blocked by required conditions
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
If getMailboxLock() failed (e.g. folder not found) the try/finally cleanup
block was never entered, leaving the ImapFlow connection open and leaking.
Move the lock acquisition inside the try block and use lock?.release() in
finally so client.logout() is always called regardless of lock success.
2026-06-27 17:20:39 +02:00
schalli
955a94638c
fix(07): CR-02 correct cron expression for pollIntervalMin >= 60
...
Tessera CI/CD / Tests (push) Blocked by required conditions
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Has started running
Values >=60 in the cron minute field silently misbehave (*/60 fires once per
hour, */90 fires once per hour, etc.). Use the hours field for intervals >=60:
<60 min → */N * * * *
>=60 min → 0 */H * * * (H = floor(N/60))
Also adds @Max(1440) to DkvConfigDto to bound the field at 24 h.
2026-06-27 17:20:11 +02:00
schalli
f3f610f9e1
fix(07): CR-01 rename import return field imported→count to match frontend
...
Tessera CI/CD / Lint & Type Check (push) Failing after 37s
Tessera CI/CD / Tests (push) Has been skipped
Tessera CI/CD / Build & Deploy (push) Has been skipped
Backend dkv.service.ts returned { imported } but frontend read result.count,
causing the success toast to always display "undefined Fahrzeuge importiert".
Align backend field name to count and update the dkv-api.ts return type to
include mode for completeness.
2026-06-27 17:19:44 +02:00
schalli
d93819fa27
docs(07): add code review report
Tessera CI/CD / Lint & Type Check (push) Failing after 35s
Tessera CI/CD / Tests (push) Has been skipped
Tessera CI/CD / Build & Deploy (push) Has been skipped
2026-06-27 17:14:44 +02:00
schalli
d3e8e6400a
docs(07-06): complete SMTP settings UI plan
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 38s
Tessera CI/CD / Tests (push) Waiting to run
2026-06-27 17:06:04 +02:00
schalli
75aec38dae
feat(07-06): extend SettingsSidebar with Allgemein > SMTP category
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 40s
Tessera CI/CD / Tests (push) Waiting to run
- Add 'Allgemein' category section ABOVE existing Dashboard category
- Single SMTP link to /settings/general/smtp with identical active/inactive styling and aria-current
- isActive('/settings/general/smtp') works via pathname.startsWith branch
- Existing Dashboard/Widgets/Calendar items unchanged
2026-06-27 17:04:25 +02:00
schalli
fd2dda69cb
feat(07-06): settings-api client + SmtpSettingsForm + SMTP page (DKV-05)
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 41s
Tessera CI/CD / Tests (push) Waiting to run
- settings-api.ts: fetchSmtp/saveSmtp/testSmtp with credentials:'include'; SmtpConfig exposes only hasPassword (T-07-17)
- smtp-settings-form.tsx: Surface C form with show/hide password toggle, test-feedback auto-clears 6s
- settings/general/smtp/page.tsx: SmtpSettingsPage heading + SmtpSettingsForm
- de.json + en.json: add smtp.showPassword/hidePassword/testTesting/testSuccess/testFailed keys
- TDD GREEN: 5/5 tests pass; aria-hidden* on required markers removed for correct getByLabelText matching
2026-06-27 17:03:57 +02:00
schalli
a96d79ad52
test(07-06): add failing SMTP settings form tests (RED — DKV-05)
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 38s
Tessera CI/CD / Tests (push) Waiting to run
- 5 Vitest tests for SmtpSettingsForm: load config, save, test success/failure, password toggle
- Mocks @/lib/settings-api (fetchSmtp/saveSmtp/testSmtp) and next-intl
- Mirrors calendar-settings.test.tsx mocking pattern
- RED: SmtpSettingsForm does not yet exist
2026-06-27 17:00:27 +02:00
schalli
5c191c8d10
docs(07-05): complete DKV fleet module frontend plan
Tessera CI/CD / Lint & Type Check (push) Failing after 41s
Tessera CI/CD / Tests (push) Has been skipped
Tessera CI/CD / Build & Deploy (push) Has been skipped
2026-06-27 00:43:55 +02:00
schalli
4d81b8b2d5
feat(07-05): VehicleTable + CsvImportButton + vehicles page — GREEN (DKV-03)
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 42s
Tessera CI/CD / Tests (push) Waiting to run
- VehicleTable: list, inline edit, create row, delete with confirm dialog
- All 4 UI-SPEC aria-labels on icon-only buttons (Rule 2: accessibility correctness)
- CsvImportButton: merge/replace modes, destructive confirm, importVehiclesCsv
- vehicles/page.tsx: heading + back link to settings + VehicleTable
- VehicleTable.test.tsx: fix mock sequencing bug (mockResolvedValueOnce for init load)
- All 5 Vitest tests pass (GREEN)
2026-06-27 00:41:03 +02:00
schalli
c739d2788b
test(07-05): add failing VehicleTable tests (RED — DKV-03)
...
Tessera CI/CD / Lint & Type Check (push) Failing after 39s
Tessera CI/CD / Tests (push) Has been skipped
Tessera CI/CD / Build & Deploy (push) Has been skipped
- Covers: render list, empty state, delete with confirm, inline edit + save
- Mocks @/lib/dkv-api + next-intl (mirrors calendar-settings.test.tsx pattern)
- Verifies all 4 UI-SPEC aria-labels on icon-only action buttons
2026-06-27 00:38:38 +02:00
schalli
45e9a3591f
feat(07-05): settings page + InboxConfigForm — Surface B inbox tab (DKV-01)
...
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
- settings/page.tsx: tab bar (Posteingang / Fahrzeuge), Vehicles tab links to /vehicles
- InboxConfigForm: all UI-SPEC Tab-1 fields in order, show/hide password (T-07-12)
- Active toggle: role=switch, pill shape, primary/muted colors
- testConnection + saveConfig wired; inline green/destructive feedback
- Password never pre-filled from server (hasPassword only) per T-07-12
2026-06-27 00:37:50 +02:00
schalli
2fe7bca6e8
feat(07-05): dkv-api client + Surface A — history table + export list + check-now
...
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
- dkv-api.ts: typed fetch client for all /dkv/* routes (credentials: include)
- StatusBadge: OKLCH inline styles per status (T-07-14: React text nodes only)
- InvoiceHistoryTable: 6-column table, 5 skeleton rows, pagination >25, refreshKey
- ExportFileList: up to 10 unique export filenames derived from history (T-07-13)
- page.tsx: Jetzt prüfen trigger, error banner, refreshKey lift, DKV-04/DKV-01
2026-06-27 00:36:28 +02:00
schalli
316f8353b7
docs(07-04): complete DKV integration plane plan
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 38s
Tessera CI/CD / Tests (push) Waiting to run
SUMMARY: DkvService pipeline, DkvSchedulerService dynamic cron, DkvController 12 routes,
DkvModule registry seed, AppModule DkvModule registration, dkvFleet + settings i18n keys.
Deviation: CronJob via require() workaround (pnpm transitive dep isolation).
2026-06-27 00:32:19 +02:00
schalli
2a3d1c1e85
feat(07-04): DkvModule + registry seed + AppModule registration + i18n keys
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 40s
Tessera CI/CD / Tests (push) Waiting to run
- dkv.seed.ts: seedDkvModule with slug=dkv-fleet, category=fleet, isSystem=true
- dkv.module.ts: imports ModuleRegistryModule + CalendarModule (CalendarCryptoService)
provides all 7 DKV services + 2 providers + controller; OnModuleInit seeds registry
- app.module.ts: DkvModule added to imports (ScheduleModule + SettingsModule from Plans 01/03)
- de.json + en.json: complete dkvFleet namespace (50+ keys incl. status, col, form, errors)
- settings namespace extended with categoryGeneral, categorySmtp, smtp sub-object
2026-06-27 00:30:08 +02:00
schalli
c22d36758c
feat(07-04): DkvSchedulerService + DkvController — dynamic cron + REST surface
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 36s
Tessera CI/CD / Tests (push) Waiting to run
- DkvSchedulerService: SchedulerRegistry.addCronJob (dynamic interval, not static @Cron)
- onModuleInit loads first active config (v1 single-tenant, documented in SUMMARY)
- setInterval() replaces existing job and registers new one with */ cron expression
- stopJob() removes job when config.isActive=false
- cron package resolved via require() workaround (pnpm strict isolation: transitive dep)
- DkvController: 12 handlers all carrying @Roles(Role.ADMIN, Role.SUPER_ADMIN)
- Routes: GET/PUT config, POST check-now, POST test-connection, GET history,
GET exports/:filename, GET/POST/PUT/DELETE vehicles, POST vehicles/import
- vehicles/import uses FileInterceptor('file') for CSV multipart upload
- exports/:filename streams file as attachment; traversal guard in DkvService
- Controller coordinates scheduler after PUT /dkv/config (no circular dep)
2026-06-27 00:28:18 +02:00
schalli
c40a023321
feat(07-04): DkvService — pipeline orchestration + vehicle/config/history logic
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 38s
Tessera CI/CD / Tests (push) Waiting to run
- Single-flight guard (processing flag) prevents concurrent inbox processing
- processInbox: poll → 3-retry parse → driver-map → xlsx → 3-retry SMTP send → history
- Parse failure (D-10): records Fehler history row with errorMessage
- SMTP failure (D-16): exponential backoff 2s/4s, records Versand fehlgeschlagen
- CONFIG_SAFE_SELECT excludes encryptedInboxCreds (T-07-12)
- getExportFile rejects filenames with path separators or outside DKV_*.xlsx pattern (T-07-09)
- CSV import: merge (upsert by tenantId+kennzeichen) and replace (deleteMany then createMany) modes
- Invoice number extracted from email subject via regex; falls back to email-{uid}
- Vehicle format string resolved via DkvExportService.resolveFahrzeug (D-19)
2026-06-27 00:24:47 +02:00
schalli
4ed1889c8d
docs(07-03): complete DKV export + SMTP settings plan
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 39s
Tessera CI/CD / Tests (push) Waiting to run
- 07-03-SUMMARY.md: all 4 tasks documented, threat mitigations verified,
user-files/ path resolution and MailModule factory priority chain explained
- STATE.md: advanced to Plan 4 of 6, added 5 new decisions, metrics row
- ROADMAP.md: 07-03 checked complete, Phase 7 progress 3/6
2026-06-27 00:16:05 +02:00
schalli
de48e35c74
feat(07-03): Migrate MailModule to DB-sourced SMTP transport with env fallback (D-06)
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 38s
Tessera CI/CD / Tests (push) Waiting to run
- MailerModule.forRootAsync factory now async; injects SettingsService + ConfigService
- Priority 1: getStartupSmtpConfig() reads first SmtpConfig DB row (single-tenant default)
— T-07-11: decrypted password used only to build transport, never logged
- Priority 2: env vars MAIL_HOST/MAIL_PORT/MAIL_USER/MAIL_PASS
- Priority 3: legacy TESSERA_SMTP_* env vars (backward compat)
- Priority 4: localhost:1025 hardcoded final fallback (Mailhog dev default)
- imports SettingsModule; no circular import (MailModule → SettingsModule → CalendarModule)
- mail.service.ts unchanged — still injects @nestjs-modules/mailer MailerService
2026-06-27 00:12:43 +02:00
schalli
4deefb52de
feat(07-03): DkvMailService — runtime nodemailer transport with xlsx attachment (DKV-04)
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 38s
Tessera CI/CD / Tests (push) Waiting to run
- createTransport() called per-send from DB SmtpConfig (Pitfall 3 mitigation — not at startup)
- Injects SettingsService to load decrypted SMTP config per tenant
- secure/requireTLS mapped from encryption field (ssl-tls / starttls / none)
- Auth omitted when username absent (anonymous relay support)
- Attachment contentType: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
- Error path rethrows after generic log (T-07-10) so DkvService can run 3-retry backoff (D-16)
- Does not import @nestjs-modules/mailer abstractions
2026-06-27 00:11:59 +02:00
schalli
6b76ca9633
feat(07-03): DkvExportService — xlsx generation + user-files/ prune (DKV-04)
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 41s
Tessera CI/CD / Tests (push) Waiting to run
- buildExcelBuffer: 5-column xlsx per D-13 (Lieferdatum as string, never Date), SheetJS aoa_to_sheet
- resolveFahrzeug: replaces {Marke}/{Modell}/{Kennzeichen}/{Fahrer} tokens in format string (D-19)
- writeAndPrune: server-side filename DKV_YYYY-MM_<nr>.xlsx (T-07-09 path-traversal prevention),
writes to user-files/ (resolved from monorepo root, not request input), prunes to last 10 DKV_*.xlsx
files sorted by mtime ascending (D-15, Pitfall 7 atomicity)
2026-06-27 00:10:56 +02:00
schalli
1bec0e76ee
feat(07-03): SettingsModule — SMTP config backend + connection test (DKV-05)
...
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
- SmtpConfigDto: host/port/encryption/username/password/fromAddress with class-validator
- SettingsService: getSmtpConfig (SMTP_SAFE_SELECT, no password), saveSmtpConfig (AES-256-GCM
encryption via CalendarCryptoService, preserve existing password on empty), getDecryptedSmtpConfig
(internal, used by DkvMailService), testSmtpConfig (nodemailer.verify(), returns boolean, T-07-16),
getStartupSmtpConfig (tenant-agnostic, used by MailModule factory, D-06)
- SettingsController: GET/PUT /settings/smtp + POST /settings/smtp/test, all @Roles(ADMIN, SUPER_ADMIN)
- SettingsModule: imports CalendarModule, exports SettingsService
- AppModule: imports SettingsModule
2026-06-27 00:09:47 +02:00
schalli
c7b0103a10
docs(07-02): complete DKV inbox-access layer plan
...
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
- 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
schalli
924de76f93
feat(07-02): ExchangeInboxProvider — EWS email inbox access
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 41s
Tessera CI/CD / Tests (push) Waiting to run
- Implements InboxProvider contract (fetchPdfAttachments + testConnection)
- Uses WellKnownFolderName.Inbox + FindItems + EmailMessage.Bind — NOT FindAppointments (Pitfall 6)
- Dynamic import('ews-javascript-api') following ExchangeProvider calendar pattern
- Server-side sender filter via SearchFilter.ContainsSubstring with client-side verification
- 25MB attachment size guard in extractPdfAttachments — PDF-bomb mitigation (T-07-05)
- Generic error messages only in all catch blocks — no credential values (T-07-03)
- Returns [] on error (consistent with calendar ExchangeProvider error path)
2026-06-27 00:03:56 +02:00
schalli
b3f21a8747
feat(07-02): ImapProvider — IMAP inbox access via imapflow
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 39s
Tessera CI/CD / Tests (push) Waiting to run
- Implements InboxProvider contract (fetchPdfAttachments + testConnection)
- fetchAll() called before any download() — avoids IMAP connection deadlock (Pitfall 1)
- ImapFlow constructed with logger:false — credential safety (T-07-03)
- 25MB attachment size guard in streamToBuffer — PDF-bomb mitigation (T-07-05)
- collectPdfParts() recursively traverses MIME tree for application/pdf parts
- Generic error messages only — no credential values in logs (T-07-03)
- secure/requireTLS flags derived from encryption field (ssl-tls vs starttls)
2026-06-27 00:02:00 +02:00
schalli
86ec8966d0
feat(07-02): InboxProvider interface + config/vehicle/history DTOs
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 40s
Tessera CI/CD / Tests (push) Waiting to run
- inbox-provider.interface.ts: InboxProvider contract with fetchPdfAttachments + testConnection; re-exports InboxConfig/InboxEmail/InboxAttachment with export type (isolatedModules)
- dkv-config.dto.ts: DkvConfigDto with @IsEmail() senderFilter/exportRecipient, @Min(5) pollIntervalMin, @IsIn() protocol/encryption (T-07-04)
- dkv-vehicle.dto.ts: CreateVehicleDto (all required @IsNotEmpty) + UpdateVehicleDto (all optional)
- dkv-history.dto.ts: DkvHistoryQueryDto with @IsInt @Min(1) page/limit pagination (T-07-06)
- Fix: export type re-exports required for isolatedModules TypeScript setting
2026-06-27 00:00:14 +02:00
schalli
6bf032ef94
docs(07-01): complete DKV backend foundation plan
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 39s
Tessera CI/CD / Tests (push) Waiting to run
- 07-01-SUMMARY.md: execution record with PDF parser analysis, regex deviation, DB push method
- STATE.md: plan counter advanced to 2/6, decisions added, session updated
2026-06-26 19:39:18 +02:00
schalli
6235aaf31c
feat(07-01): DKV PDF parser validated against real invoice + injectable service
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 41s
Tessera CI/CD / Tests (push) Waiting to run
- dkv-parser.validate.ts: empirical validation script against user-files/invoice.pdf
- 27 vehicle blocks, 66 transactions extracted (matches expected count)
- Handles two PDF extraction formats: single-tx (tab-separated) + multi-tx (columnar)
- German number parsing: replace(/\./g,'').replace(',','.') applied to km and menge
- Exits 1 with full raw text dump if zero vehicle blocks parsed (assertion guard)
- dkv-parser.service.ts: @Injectable() NestJS service wrapping validated logic
- parsePdf(buffer: Buffer): Promise<DkvVehicleBlock[]>
- Uses pdf-parse v2 class API: new PDFParse({data:buffer}) — NOT v1 pdfParse()
- Calls destroy() after extraction (T-07-01 memory safety)
- Generic error messages only on parse failure (T-07-02 info disclosure)
Regex adjustment vs Research Pattern 4: space-based regex replaced with
tab-split (single-tx) + columnar transpose (multi-tx) after empirical analysis
of actual invoice.pdf text extraction output.
2026-06-26 19:36:45 +02:00
schalli
c4b39ccd1b
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
2026-06-26 19:25:42 +02:00
schalli
de06794e67
docs(07): create phase 7 execution plans for DKV fleet module
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 38s
Tessera CI/CD / Tests (push) Waiting to run
6 plans covering full pipeline: PDF parsing foundation (Wave 0),
inbox providers + export/SMTP services (Wave 1), pipeline
orchestration + frontend pages + settings UI (Wave 2). Includes
D-06 MailModule DB-config migration and Nyquist validation strategy.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-26 18:56:59 +02:00
schalli
e9f4f2dcad
docs(07): UI design contract and validation strategy for DKV fleet module
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 40s
Tessera CI/CD / Tests (push) Waiting to run
2026-06-26 14:55:41 +02:00
schalli
baf502d967
docs(07): fix blocking typography and spacing issues in UI-SPEC
...
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 40s
Tessera CI/CD / Tests (push) Waiting to run
Collapse Display h1 weight from 700 to 600 (font-semibold) to keep
declared weights at exactly two (400 + 600). Remove 12px md token from
named spacing scale; move px-3/py-1.5 to Component Exceptions subsection.
Apply non-blocking recommendations: focal point sentence, aria-labels for
icon-only AKTIONEN buttons, and more specific form CTA copy.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-26 14:53:49 +02:00
schalli
0c33fd6a34
docs(07): UI design contract for DKV Fleet Module
...
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
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-26 14:49:10 +02:00
schalli
741feb5946
docs(07): research phase DKV fleet module
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 39s
Tessera CI/CD / Tests (push) Waiting to run
2026-06-26 14:37:51 +02:00
schalli
4ee23bd9a4
docs(state): record phase 7 context session
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 39s
Tessera CI/CD / Tests (push) Waiting to run
2026-06-26 14:22:38 +02:00
schalli
34f06c9aa6
docs(07): capture phase context for DKV Fleet Module
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
2026-06-26 14:22:34 +02:00
schalli
c69c7b2900
wip: pause — UI-Umbau fertig, DKV-Modul-Planung ausstehend
Tessera CI/CD / Lint & Type Check (push) Successful in 44s
Tessera CI/CD / Tests (push) Failing after 12m53s
Tessera CI/CD / Build & Deploy (push) Has been skipped
2026-06-26 12:16:05 +02:00
schalli
ba02b25cba
refactor(ui): restructure sidebar and admin navigation
...
Tessera CI/CD / Lint & Type Check (push) Successful in 43s
Tessera CI/CD / Tests (push) Failing after 45s
Tessera CI/CD / Build & Deploy (push) Has been skipped
- Sidebar: remove footer (user info, settings, locale switcher), remove admin section, make category headers static with per-category collapse toggle
- Header dropdown: replace inline admin links with single "Administrator" entry
- Admin section: dedicated layout with AdminSidebar (mirrors Settings pattern) at /admin/*
- Disable self-delete button in user management (backend already rejects with 403)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-26 08:34:19 +02:00
schalli
02652362f3
docs: pause work — v1.0 complete, next session: new modules
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-25 15:58:38 +02:00
schalli
9f78580606
feat(domaincheck): support all TLDs with suggestion alternatives
...
Tessera CI/CD / Lint & Type Check (push) Successful in 1m8s
Tessera CI/CD / Tests (push) Successful in 1m13s
Tessera CI/CD / Build & Deploy (push) Successful in 2m39s
- Accept full domains (e.g. "example.xyz") not just labels
- Check the entered TLD as primary result
- Show .de, .com, .net, .org as alternative suggestions below
- Primary result highlighted with accent border
- Input without TLD still works (shows all 4 suggestions)
- Updated i18n placeholders and added "suggestions" label
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-25 14:54:30 +02:00
schalli
95423497ad
docs(06): complete Phase 06 — desktop wrapper + CI/CD pipeline verified
...
Tessera CI/CD / Lint & Type Check (push) Successful in 46s
Tessera CI/CD / Tests (push) Successful in 45s
Tessera CI/CD / Build & Deploy (push) Successful in 39s
- 06-01: Tauri scaffold complete
- 06-02: Native features (tray, window-state, autostart, version check, AppImage)
- 06-03: Gitea CI/CD pipeline green (Run #89 — all 3 jobs pass)
- Clean up handoff and continue-here files
- Update STATE.md to 100% (all 6 phases complete)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-25 14:09:17 +02:00