Patrick Plate
3211ade5be
feat(sprint8): Phase 2 — Treasury frontend + PDF receipts
...
Backend:
- ReceiptPdfService: Generates Quittung PDF per payment (OpenPDF, A4)
- FinancialReportService: Annual financial report PDF (Jahresabschluss)
- FinanceController: Added receipt download, annual report, CSV export endpoints
- Portal receipt download with member ownership verification
Frontend:
- src/services/finance.ts: Complete React Query service (types, hooks, mutations)
- /finance: Dashboard with KPI cards, recent transactions, outstanding members
- /finance/payments: Payment list with filtering, void, receipt download
- /finance/kassenbuch: Kassenbuch ledger with date range, CSV export
- /finance/fee-schedules: Fee schedule CRUD with interval management
- /finance/reports: Annual report PDF download
- /portal/finance: Member self-service balance + payment history + receipts
Navigation & i18n:
- Added Finanzen (Wallet icon) to admin sidebar
- Portal finance page for member payments
- Comprehensive de.json + en.json finance keys (~100 translations)
2026-06-15 08:24:43 +02:00
Patrick Plate
721503b231
feat(sprint8): Phase 1 — Treasury backend (fee schedules, payments, Kassenbuch)
...
- Extend StaffPermission with MANAGE_FINANCES, VIEW_FINANCES
- Extend AuditEventType with PAYMENT_RECORDED, PAYMENT_VOIDED, FEE_SCHEDULE_CREATED, FEE_SCHEDULE_UPDATED, EXPENSE_RECORDED
- Extend NotificationType with PAYMENT_REMINDER, PAYMENT_OVERDUE, PAYMENT_RECEIVED
- New enums: PaymentMethod, PaymentStatus, TransactionType, FeeInterval, ExpenseCategory
- V18 Flyway migration: fee_schedules, member_fee_assignments, payments, ledger_entries tables
- Entities: FeeSchedule, MemberFeeAssignment, Payment, LedgerEntry
- Repositories with financial queries (balance, outstanding, period sums)
- FinanceService: fee schedule CRUD, record/void payments, expenses, Kassenbuch, summaries
- FinanceController: 14 admin endpoints + 2 portal self-service endpoints
- LedgerEntry is append-only per §147 AO (no update/delete)
- All amounts in cents (Integer) to avoid floating-point precision issues
2026-06-15 08:00:04 +02:00
Patrick Plate
aabde17532
feat(sprint7): Phase 4 — Integration (SMTP, tier enforcement, WebSocket)
...
Phase 4 implementation:
- 4.1 IONOS SMTP email configuration (production + docker profiles)
- 4.2 Portal navigation update (info board, events, forum links)
- 4.3 Tier enforcement: PlanTierService (forum=Pro+, info board limits)
- 4.4 WebSocket real-time updates (WebSocketEventPublisher)
- 4.5 EmailService: notification, event reminder, info board templates + rate limiting
- 4.6 Enterprise custom FROM: CustomMailDomain entity, DNS verification, controller
New files:
- PlanTierService: tier checks for forum/info board/enterprise features
- NotificationDispatchService: EMAIL channel dispatch via preferences
- WebSocketEventPublisher: STOMP topic push for forum/info board/events
- CustomMailDomainService: DNS TXT record verification for custom FROM
- MailSettingsController: Enterprise custom domain API endpoints
- CustomMailDomain entity + repository
- V16 migration: email dispatch index
- V17 migration: custom_mail_domains table
- Frontend: use-forum-subscription + use-info-board-subscription hooks
- Portal navbar: added info board, events, forum navigation items
- i18n: added portal nav translations (de + en)
Also fixed pre-existing Phase 2.5/3 compilation issues:
- Member entity: added userId field
- AuditService: added convenience overloads (logEvent, 4-param log)
- AuditEventType: added INFO_BOARD_POST_UPDATED, INFO_BOARD_POST_DELETED
- QuotaViolationCode: added TIER_UPGRADE_REQUIRED
- StaffPermissionChecker: added requirePermission(UserDetails, ...)
- TenantContext: added getCurrentTenantId() alias
- MemberRepository: added findByUserId, findByClubId, findAllByClubId
- EmailServiceTest: updated for new constructor signature
2026-06-13 20:51:10 +02:00
Patrick Plate
a539ed9eb2
feat(sprint7): Phase 3 — Forum MVP
...
- Flyway V15: forum_topics, forum_replies, forum_reactions, forum_reports tables
- Enums: ForumTargetType, ReactionType, ReportStatus
- Extended AuditEventType with FORUM_REPLY_CREATED, FORUM_REPORT_REVIEWED
- Entities: ForumTopic, ForumReply, ForumReaction, ForumReport
- Repositories: ForumTopicRepository, ForumReplyRepository, ForumReactionRepository, ForumReportRepository
- ForumService: full CRUD, moderation (lock/pin/delete), 60-min edit window,
toggle reactions, content reporting, notifications on new topics/replies
- ForumController: admin + portal endpoints (topics, replies, reactions, reports, moderation)
- Frontend: forum.ts service with React Query hooks (admin + portal)
- Frontend: Admin forum page with topic list, moderation actions (lock/pin/delete)
- Frontend: Portal forum page with topic list, reply thread, reactions, report
- Navigation: added Forum with MessageSquare icon
- i18n: forum.* keys in de.json and en.json
2026-06-13 20:31:17 +02:00
Patrick Plate
05fd679c4d
feat(sprint7): Phase 2.5 — Club Event Calendar
...
- Flyway V14: club_events + event_rsvps tables with reminder_sent tracking
- Enums: EventType, RsvpStatus, RecurrenceRule + extend AuditEventType/NotificationType
- Entities: ClubEvent (extends AbstractTenantEntity), EventRsvp (unique event+member)
- Repositories: ClubEventRepository, EventRsvpRepository with date-range and status queries
- EventService: CRUD, RSVP with maxAttendees enforcement (409 if full), iCal RFC 5545 generation, recurring event virtual expansion, notifications on create/cancel, auto-post to Info Board
- EventReminderScheduler: hourly check, 24h reminder to ACCEPTED/MAYBE attendees
- EventController: admin CRUD (MANAGE_INFO_BOARD permission), portal upcoming events, RSVP endpoint, iCal download (text/calendar), attendee list
- Frontend: events.ts service (React Query hooks matching apiClient pattern), admin calendar page (month grid with event dots, create dialog, event cards), portal events page (RSVP buttons, capacity display)
- Navigation: added Kalender with Calendar icon
- i18n: events.* keys in de.json and en.json
- UI: added @radix-ui/react-switch + Switch component
2026-06-13 20:16:56 +02:00
Patrick Plate
4aa27cd4f9
feat(sprint7): Phase 2 — Info Board (Schwarzes Brett)
...
Backend:
- V13 Flyway migration: info_board_posts, post_attachments, post_read_status tables
- InfoBoardPost entity with category enum (EVENT, RULE, GENERAL, MAINTENANCE)
- PostAttachment entity (table created, upload deferred to later)
- PostReadStatus entity with composite key (post_id, member_id)
- InfoBoardPostRepository with paginated queries + unread count
- InfoBoardService: CRUD, pin/archive, mark-as-read, notification dispatch
- InfoBoardController: admin CRUD + portal read/unread endpoints
- Integration with NotificationService and AuditService
Frontend:
- info-board.ts service with React Query hooks for all endpoints
- Admin Info Board page at /info-board with create dialog, filters, pin/archive/delete
- Navigation: added 'Schwarzes Brett' to admin sidebar
- i18n: added infoBoard.* keys to de.json and en.json
- Fixed pre-existing prettier issues in notification-compose.ts
- Fixed BufferSource type issue in push-subscription.ts
2026-06-13 19:41:20 +02:00
Patrick Plate
706a6e257b
feat(sprint7): Phase 1 — notifications enhancement + push infrastructure
...
Phase 1 (Notification Enhancement):
- Extended NotificationType enum (ADMIN_MESSAGE, INFO_BOARD_POST, FORUM_REPLY, FORUM_MENTION)
- Extended StaffPermission enum (SEND_NOTIFICATIONS, MANAGE_INFO_BOARD, MODERATE_FORUM)
- Extended AuditEventType with Sprint 7 events
- Flyway V11: notification_sends + notification_send_recipients tables
- NotificationSend + NotificationSendRecipient entities
- NotificationSendRepository + NotificationSendRecipientRepository
- Extended NotificationService with sendBroadcast() and sendToSelected()
- NotificationComposeController (POST /compose, GET /sends)
- ComposeNotificationRequest DTO
Phase 1B (Push Infrastructure):
- Flyway V12: device_tokens + notification_preferences tables
- DeviceToken entity + DevicePlatform enum
- NotificationPreference entity + NotificationChannel enum
- DeviceTokenRepository + NotificationPreferenceRepository
- DeviceRegistrationService (register/unregister/list devices, max 10 per user)
- NotificationPreferenceService (get/create defaults, update, IN_APP always on)
- NotificationDispatchService (multi-channel fan-out: WebSocket, Web Push, FCM, Email)
- WebPushSender (VAPID-based, simplified for MVP)
- FcmPushSender (graceful degradation if not configured)
- PushPayload DTO
- DeviceRegistrationController (POST/GET/DELETE /devices, GET /vapid-key)
- NotificationPreferenceController (GET/PUT /preferences)
- ConsentType extended (NOTIFICATION_PUSH, NOTIFICATION_EMAIL)
- TargetType enum (ALL, SELECTED)
Frontend:
- Updated sw.js with push event handler + notification click handler
- push-subscription.ts (subscribeToPush, unsubscribe, permission helpers)
- notification-compose.ts service (compose, sends, devices, preferences APIs)
- i18n keys (de.json + en.json) for compose, preferences, push, devices
Configuration:
- application-docker.properties: VAPID + FCM push config properties
- MemberRepository: added findAllActiveUserIds() for broadcast
2026-06-13 19:25:19 +02:00
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