Commit Graph

172 Commits

Author SHA1 Message Date
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
schalli c65ada0ba9 feat(06-02): add native desktop features — tray, window-state, autostart, version check
- Add GET /health/version public endpoint to API
- Extend Tauri with 4 plugins: notification, autostart, window-state, store
- Implement close-to-tray with prevent_close + prevent_exit (Pitfall 2)
- Tray menu with Oeffnen/Beenden (German labels)
- Async startup version check against server /health/version
- Generate Tessera-branded icons (yellow T on dark bg, OKLCH palette)
- Update capabilities for notification, autostart, window-state permissions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 14:01:12 +02:00
schalli 4d94a254fd fix(06-03): add .gitkeep to apps/web/public for Docker build
Tessera CI/CD / Lint & Type Check (push) Successful in 45s
Tessera CI/CD / Tests (push) Successful in 47s
Tessera CI/CD / Build & Deploy (push) Successful in 1m58s
Git doesn't track empty directories, so apps/web/public is missing
in CI checkout. The web Dockerfile COPY --from=builder fails when
public dir doesn't exist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 13:19:33 +02:00
schalli c48e61f95d fix(06-03): make prisma postinstall conditional for Docker multi-stage build
Tessera CI/CD / Lint & Type Check (push) Successful in 48s
Tessera CI/CD / Tests (push) Successful in 46s
Tessera CI/CD / Build & Deploy (push) Failing after 1m42s
In Docker deps stage only package.json files are copied (no schema),
causing prisma generate to fail. Builder stage already runs explicit
prisma generate with full source.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 13:15:15 +02:00
schalli e81dbb0e69 docs(06): pause work — 06-01 complete, 06-03 pending CI verification
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 12:37:49 +02:00
schalli faff50b1ee fix(06-03): add prisma generate postinstall for CI type-check
Tessera CI/CD / Lint & Type Check (push) Successful in 43s
Tessera CI/CD / Tests (push) Successful in 46s
Tessera CI/CD / Build & Deploy (push) Failing after 51s
CI environment lacks generated Prisma types after pnpm install.
Adding postinstall script ensures prisma generate runs automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 11:56:16 +02:00
schalli e5d45e121b fix(06-03): replace pnpm/action-setup with corepack for Gitea Actions compatibility
Tessera CI/CD / Lint & Type Check (push) Failing after 49s
Tessera CI/CD / Tests (push) Has been skipped
Tessera CI/CD / Build & Deploy (push) Has been skipped
pnpm/action-setup@v4 fails in Gitea Actions runners. Use corepack (built into Node.js)
to activate pnpm@9.15.0 matching the packageManager field.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 11:38:04 +02:00
schalli 2e4d499730 docs(06-03): complete CI/CD pipeline plan
Tessera CI/CD / Lint & Type Check (push) Failing after 1m10s
Tessera CI/CD / Tests (push) Has been skipped
Tessera CI/CD / Build & Deploy (push) Has been skipped
2026-06-25 11:01:55 +02:00
schalli 756925bd25 feat(06-03): create Gitea Actions multi-stage CI/CD pipeline
- Three chained jobs: quality (lint+type-check) -> test (vitest) -> build-deploy
- Uses plain docker compose build/up (not build-push-action, avoids Pitfall 4)
- Triggers on push to main branch only (D-11, D-12)
- No hardcoded secrets in workflow (T-06-08)
2026-06-25 10:58:50 +02:00
schalli c0e32939e7 feat(06-03): add act_runner compose definition and CI/CD setup runbook
- docker-compose.ci.yml with act_runner service (ephemeral mode, Docker socket mount)
- docs/ci-cd-setup.md runbook covering Gitea remote, runner setup, secrets, security
- Registration token referenced from environment, never hardcoded (T-06-08)
2026-06-25 10:57:45 +02:00
schalli f41e673dd5 docs(06-01): complete desktop Tauri scaffold plan 2026-06-25 10:17:22 +02:00
schalli d944aaa5a0 feat(06-01): add first-run setup page with server URL input and validation
- Create setup.html with centered card on dark OKLCH background
- Validate URL via URL constructor, reject malformed input (T-06-01)
- Warn on non-HTTPS non-localhost URLs but allow (internal LAN support)
- Persist server_url to tauri-plugin-store config.json
- Navigate WebView to configured server after save
- All visible strings in German (Verbinden, Server-URL eingeben, etc.)
- Design tokens match Tessera OKLCH color system (primary, dark bg)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 10:14:17 +02:00
schalli 48e3a693aa feat(06-01): scaffold apps/desktop as @tessera/desktop Tauri 2.x project
- Create Tauri project structure with Cargo.toml, tauri.conf.json, build.rs
- Implement lib.rs with store plugin and server URL navigation on startup
- Configure capabilities with core:default and store:default permissions
- Set frontendDist to ../src for local setup page (no bundled frontend)
- Add placeholder icons for build compatibility (to be replaced in 06-02)
- Add Cargo target/ to .gitignore
- Window config: 1280x800, centered, native decorations, resizable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 10:13:20 +02:00
schalli 943cc32da7 docs(06): create phase plan 2026-06-25 09:27:16 +02:00
schalli 44154a4697 docs(06-desktop-client-ci-cd): create phase plan
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 09:25:24 +02:00
schalli 3d8c0660f7 docs(06): research phase domain - Tauri 2.x desktop wrapper + Gitea Actions CI/CD 2026-06-25 09:15:43 +02:00