Commit Graph

16 Commits

Author SHA1 Message Date
Patrick Plate d0c53a912c fix(service): DsgvoService getMembershipNumber + remove non-existent setPhone
Deploy to Production / test (push) Has been cancelled
Deploy to Production / deploy (push) Has been cancelled
2026-06-13 09:23:33 +02:00
Patrick Plate 61707ffe68 fix(service): add spring-boot-starter-websocket dep for SimpMessagingTemplate
Deploy to Production / test (push) Has been cancelled
Deploy to Production / deploy (push) Has been cancelled
2026-06-13 09:21:54 +02:00
Patrick Plate 599514c0db feat(sprint-6): Phase 6 — Notifications (WebSocket) + PWA
Deploy to Production / test (push) Has been cancelled
Deploy to Production / deploy (push) Has been cancelled
- WebSocket: Spring STOMP + SockJS, NotificationService, persistent notifications table
- NotificationController: GET/PUT endpoints for notification management
- Frontend: notification bell with unread badge, dropdown panel, real-time via STOMP
- PWA: manifest.json, service worker (manual sw.js), offline page, install prompt
- PWA icons (192+512), dark theme colors, standalone display
- Full i18n (de/en) for notifications and PWA
- Flyway V10 migration for notifications table
- spring-boot-starter-websocket dependency added
2026-06-12 23:02:44 +02:00
Patrick Plate 076fd6f9b3 feat(sprint-6): Phase 5 — Full grow calendar (sensors, photos, feeding, harvest traceability)
Deploy to Production / test (push) Has been cancelled
Deploy to Production / deploy (push) Has been cancelled
- V9 migration: grow_entries, grow_stage_logs, sensor_readings, grow_photos, feeding_logs
- 5 entities + GrowStage enum (7 stages) + SensorReadingType enum
- GrowCalendarService: CRUD + stage advancement + harvest-to-batch linking
- GrowCalendarController: 8 endpoints (/api/v1/grow/*)
- Frontend: /grow list + /grow/[id] detail (timeline, sensor charts, photo gallery, feeding log)
- Sensor chart (Recharts line: temp + humidity over time)
- Harvest completion links grow entry → batch (full traceability)
- React Query hooks for all grow operations
- Full i18n (de/en) with 7 grow stage labels
- Sidebar navigation updated with Anbau/Grow entry
2026-06-12 22:51:45 +02:00
Patrick Plate 05933a08ca feat(sprint-6): Phase 4 — Immutable audit log
Deploy to Production / test (push) Has been cancelled
Deploy to Production / deploy (push) Has been cancelled
- V8 migration: audit_events table (JSONB metadata, immutable by design)
- AuditEvent entity + AuditEventType enum (18 event types)
- AuditService: log events, paginated query, PDF export
- AuditController: GET /api/v1/audit (paginated, filtered), GET export
- AuditEventRepository with JPQL filtered queries
- Frontend: /audit-log page (read-only, filterable, timezone-aware)
- PDF export button for Behörde inspections
- Sidebar: 'Protokoll' under new Compliance section
- PdfReportGenerator: generateAuditReport method added
- 10-year retention, REVOKE DELETE documented
- Full i18n (de/en) with 18 event type translations
2026-06-12 22:40:40 +02:00
Patrick Plate 61e481b37b feat(sprint-6): Phase 3 — Stripe integration (SEPA + PayPal + Card)
Deploy to Production / test (push) Has been cancelled
Deploy to Production / deploy (push) Has been cancelled
- V7 migration: subscriptions table with plan tiers
- Subscription entity + PlanTier/SubscriptionStatus enums
- StripeService: customer creation, checkout, portal, webhook handling
- SubscriptionController: /api/v1/billing endpoints
- Webhook handler: invoice.paid, payment_failed, subscription.deleted/updated
- Plan enforcement: member limit interceptor, trial expiry check
- Frontend: /settings/billing page (plan card, usage, upgrade, portal link)
- Trial expired banner on all admin pages
- React Query hooks (useSubscriptionQuery, checkout/portal mutations)
- Stripe Java SDK 28.2.0
- Full i18n (de/en) for billing namespace
2026-06-12 22:31:03 +02:00
Patrick Plate 3232d2f7fd feat(sprint-6): Phase 2 — DSGVO consent management
Deploy to Production / test (push) Has been cancelled
Deploy to Production / deploy (push) Has been cancelled
- V6 migration: consents table with audit columns
- Consent entity, repository, service (grant/revoke/check)
- ConsentController: GET/POST/DELETE consent endpoints
- DSGVO export (Art. 15): full personal data JSON download
- DSGVO deletion (Art. 17): anonymization + account deactivation
- Frontend: consent banner (modal, cannot dismiss), privacy settings page
- React Query hooks for consent + DSGVO operations
- Full i18n (de/en) for consent and DSGVO namespaces
2026-06-12 22:22:48 +02:00
Patrick Plate 4f00872486 feat(sprint-3): Phase 6 — prevention officer capability
- PreventionOfficerService: limit enforcement, under-21 monitoring, monthly distribution tracking
- PUT /api/v1/staff/{id}/prevention-officer: assign/revoke with club limit check (409 on exceed)
- GET /api/v1/members/under-21: list under-21 members with quota data (prevention officer access)
- GET /api/v1/members/{id}/prevention-data: member prevention details (quota, distributions)
- PreventionOfficerLimitExceededException mapped to 409 in GlobalExceptionHandler
- StaffResponse extended with preventionOfficer field
- PreventionOfficerServiceTest: 10 unit tests covering assignment, revocation, limits, age calc
- MemberRepository.findByTenantIdAndUnder21True added
2026-06-12 10:20:20 +02:00
Patrick Plate 87568e5bfc feat(sprint-3): Phase 5 — member portal (session-based auth) 2026-06-12 10:11:58 +02:00
Patrick Plate 64927a3244 feat(sprint-3): Phase 4 — report controller + PDF/CSV generation
- Add report data models (MonthlyReport, MemberListReport, RecallReport)
- Implement ReportService with monthly aggregation, member list, recall batch tracing
- Add PdfReportGenerator using OpenPDF with minimal club branding
- Add PdfFooterHandler for timestamp + page numbers on every page
- Add CsvReportGenerator with UTF-8 BOM for Excel compatibility
- Create ReportController with 3 endpoints (monthly, members, recall)
  supporting JSON/PDF/CSV format negotiation via ?format= param
- Add DTO records (MonthlyReportResponse, MemberListResponse, RecallReportResponse)
- Extend DistributionRepository + MemberRepository with report queries
- Update Commons CSV from 1.11.0 to 1.12.0
- 10 unit tests (ReportServiceTest: 6, PdfReportGeneratorTest: 4) all passing

Endpoints:
  GET /api/v1/reports/monthly?month=YYYY-MM&format=json|pdf|csv
  GET /api/v1/reports/members?format=json|pdf|csv&status=ACTIVE
  GET /api/v1/reports/recall/{batchId}?format=json|pdf
2026-06-12 09:38:57 +02:00
Patrick Plate 302b7da8ca docs: add frontend UI shopping list PDF + OpenPDF/CSV deps in service POM
- Added OpenPDF 2.0.4 and Commons CSV 1.11.0 dependencies (Phase 4 prep)
- Generated frontend framework evaluation PDF with ranked templates and live demo links
2026-06-11 18:25:10 +02:00
Patrick Plate 6c66783b58 feat(sprint-3): Phase 3 — staff management + invite flow
- Step 3.1: Spring Boot Starter Mail dependency (api + service)
- Step 3.2: InviteToken JPA entity with 72h expiry
- Step 3.3: InviteTokenRepository with valid-token finder
- Step 3.4: EmailService (plain text invite email via JavaMailSender)
- Step 3.5: StaffService (CRUD + invite + email pattern validation + token revocation)
- Step 3.6: Staff DTOs (CreateStaffRequest, UpdateStaffRequest, StaffResponse)
- Step 3.7: SetPasswordRequest with password complexity (@Pattern: 1 digit + 1 special)
- Step 3.8: StaffController (6 endpoints, ADMIN-only via @PreAuthorize)
- Step 3.9: POST /api/v1/auth/set-password (public, generic error messages)
- Step 3.10: StaffTemplates (ausgabe, lager, vorstand predefined permission sets)
- Step 3.11: AuthService rejects inactive users with 'Account not activated'
- Step 3.12: Token revocation on permission change via revokeAllForUser()
- Step 3.13: invite-email.txt template (German, 72h expiry note)
- Step 3.14: Spring Mail config (Mailpit dev defaults, env var overrides)
- Step 3.15: Unit tests (StaffServiceTest, StaffControllerTest, EmailServiceTest)
- V5 Flyway migration for invite_tokens table

Security review findings incorporated:
- Password complexity: min 8 chars, 1 digit + 1 special char
- Generic 'invalid or expired token' error (no state leakage)
- SecureRandom 32-byte Base64 token generation
- Token values never logged
2026-06-11 18:03:12 +02:00
Patrick Plate 36deb72cf0 feat(sprint-3): Phase 2 — club settings controller 2026-06-11 16:56:44 +02:00
Patrick Plate 55d8434f35 feat(sprint-3): Phase 1 — staff permissions + token revocation
- StaffPermission enum (8 granular permissions)
- StaffAccount JPA entity with permissions collection
- RevokedToken entity for JWT blacklisting
- Flyway V3 migration (staff_accounts, staff_account_permissions, revoked_tokens)
- StaffAccountRepository + RevokedTokenRepository
- TokenRevocationService with Caffeine cache (60s TTL, 10k max)
- StaffPermissionChecker SpEL bean (@staffPermissions.has)
- PreventionOfficerChecker SpEL bean (@preventionOfficer.check)
- JwtService: added jti claim + generateStaffAccessToken + extractJti/extractPermissions
- JwtAuthFilter: token blacklist check via TokenRevocationService
- SecurityConfig: STAFF role added to endpoint matchers
- Controllers updated with @PreAuthorize for fine-grained access
- TokenCleanupScheduler (daily 03:00 cleanup of expired revoked tokens)
- Caffeine dependency added to cannamanage-service
- Unit tests: StaffPermissionCheckerTest (7), TokenRevocationServiceTest (9)
2026-06-11 16:45:21 +02:00
Patrick Plate 2ede872d11 feat: Sprint 2 REST API layer — full implementation
- Fix critical Hibernate @Filter activation bug (TenantFilterAspect)
- Rename UserRole.ROLE_MANAGER → ROLE_STAFF (future-proofing)
- SecurityConfig: ADMIN + MEMBER roles only for Sprint 2
- AuthController: POST /auth/login + POST /auth/refresh with JWT
- AuthService: login, refresh token rotation, hashed refresh storage
- MemberController: CRUD (GET/POST/PUT /members)
- DistributionController: list + record distributions (CanG §26)
- StockController: batch management (GET/POST /stock/batches)
- ComplianceController: quota check (GET /compliance/quota/{id})
- OpenAPI/Swagger config with bearer-jwt security scheme
- GlobalExceptionHandler: full RFC 9457 problem+json coverage
- UserRepository: findByEmail, findByEmailAndTenantId
- Flyway V2: role rename migration + login indexes
- Testcontainers + test profile infrastructure (integration tests deferred)
- Parent POM: Testcontainers BOM, entity scan via properties

Controllers use validated DTOs (Jakarta Bean Validation records).
Compliance checks run before distribution recording.
Tenant filter AOP aspect ensures multi-tenant data isolation.
2026-06-11 12:05:52 +02:00
Patrick Plate fa1eaf64e0 feat(sprint-1): CannaManage foundation — compliance engine, JPA entities, tests TC-001→TC-025
- Maven multi-module project (parent + domain + service + api)
- AbstractTenantEntity with Hibernate @Filter for multi-tenancy (explicit getters/setters, Java 25 compatible)
- TenantContext ThreadLocal for request-scoped tenant isolation
- 8 JPA entities: Club, Member, Strain, Batch, Distribution, MonthlyQuota, StockMovement, User
- ComplianceConstants with CanG §19 limits (25g/day adult, 50g/month adult, 30g/month under-21, 10% THC cap)
- ComplianceService: checkDistributionAllowed() with fail-fast sequential CanG checks
- Unit tests TC-001→TC-025: 25/25 passing, 100% line+branch coverage on ComplianceService (JaCoCo 0.8.13)
- Flyway V1__initial_schema.sql: all 8 tables + indexes
- docker-compose.yml: PostgreSQL 16 local dev
- application-local.properties: local profile configuration

Closes #1 #2 #3 #4 #5 #6 #7 #8 #9 #10
2026-04-12 20:30:12 +02:00