Commit Graph

43 Commits

Author SHA1 Message Date
Paddy c2ddb11c4c Fix silent newsletter validation drops, surface skipped-sync visibility, consolidate duplicated helpers
Three fixes from the earlier review, plus cleanup:

- submissions.service.ts: a newsletter opt-in present but failing
  validation (e.g. malformed email) was silently dropped with no signal
  to the client - the rest of the submission saved, but the visitor had
  no way to know their newsletter signup didn't go through. Added
  newsletterDropped to the submit response so the frontend can tell them.

- reports.admin.service.ts: the newsletter summary tracked
  total/sent/pending/failed but silently omitted SKIPPED (stub-mode)
  signups from any bucket - every current signup showed total>0 with
  every bucket reading 0, indistinguishable from "we don't know what
  happened". Added a skipped count.

- Consolidated two things duplicated across the module: sendServerError
  (reimplemented ~11 times, three of those as identical local copies of
  the same function) into feedback.errors.ts, and formatDatetime/
  toMysqlDatetime (the same local-time formatting logic under two names,
  in csv.service.ts and events.admin.service.ts respectively) into
  feedback.dates.ts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 17:45:37 +02:00
Paddy 080b987914 Add unit tests for the Salesforce integration
Covers integrations/salesforce.service.ts: disabled-mode logging-only
path, signup-not-found, success (token fetch + POST + mark SENT), token
reuse across calls, retry-once-on-401, failure marks FAILED with the
error message, and a missing-client-credentials configuration error.
100% statement coverage on the file.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 17:45:06 +02:00
Paddy 1a51b37097 Wire up the Salesforce newsletter sync integration
Implements integrations/salesforce.service.ts per the plan's §5.6 seam
(syncNewsletterSignup(signupId)), against the real contract now that the
Salesforce side exists (see the nk-salesforce repo's
feature/newsletter-signup-integration branch): OAuth2 client-credentials
auth, POST to /services/apexrest/newsletter/signup with
{firstName, lastName, email, eventName}, response gives back which object
(Lead or Person Account) and its id. Token is cached in memory with a
conservative TTL and refreshed on a 401 rather than trusting expires_in,
which Salesforce's client-credentials token response doesn't reliably
return.

submissions.service.ts now captures the newsletter_signups insert's id
and fires syncNewsletterSignup after commit, fire-and-forget - the one
piece that was previously entirely missing, so flipping
SALESFORCE_ENABLED=true would have left every signup stuck at PENDING
forever with nothing to process it (found during an earlier review pass).

Replaced the placeholder SALESFORCE_API_TOKEN env var with
SALESFORCE_CLIENT_ID/SALESFORCE_CLIENT_SECRET in .env.example and
CLAUDE.md, matching the real auth mechanism instead of the static-token
guess from before the contract was known. Also fixed CLAUDE.md's stale
"still scaffolding-only" note about the Feedback domain.

Not yet covered by tests - the Salesforce-side contract was validated
end-to-end against a real sandbox, but this file has no unit tests yet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 19:56:01 +02:00
Paddy 01a914f31e Paginate and add search to the newsletter signups endpoint
Unlike guest book and free-text, newsletter signups had no LIMIT at all and the frontend rendered every row in one plain table. Newsletter opt-in is a single checkbox rather than typed text, so it's plausibly the largest per-event list - fix it the same way as guest book: paginated (page/pageSize, capped at 200/page) plus an optional ?search= over first name, last name, and email.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 21:49:00 +02:00
Paddy 2988a70d8f Add search to the admin guest book endpoint
At scale (many submissions after a concert), paging through the guest book 20 entries at a time with no way to find a specific person is impractical. Add an optional ?search= query param that filters entries whose name or message contains the term (case-insensitive), with LIKE wildcards escaped so a literal % or _ in a search term can't be misinterpreted as a pattern.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 21:32:32 +02:00
Paddy 07d757e9af Remove hardcoded USE statement from feedback schema migration
001_init.sql opened with USE `nachklang-feedback`, contradicting its own
documented apply instructions (mysql ... <FEEDBACK_DB> < 001_init.sql,
which already selects the database via the command line). Following the
file's own usage note literally would fail unless a database happened to
be named exactly nachklang-feedback rather than whatever FEEDBACK_DB is
configured to in .env.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 21:02:47 +02:00
Patrick Müller 56074d4441 Allow dev CORS from LAN IPs; add submission deletion
The dev-only CORS bypass in app.ts only ever matched
http://localhost:<port>, never the LAN IP a phone actually connects
through over WiFi - so testing the feedback form from a real device
against a local dev API had its submissions silently rejected by CORS.
Extended the bypass to also allow private LAN ranges (192.168.x.x,
10.x.x.x, 172.16-31.x.x), dev-only as before.

Also adds DELETE /feedback/admin/submissions/:submissionId (cascades
to the submission's answers, guest book entry, and newsletter signup
in explicit dependency order, single-path by submission_id) so an
admin can remove an individual abusive/inappropriate entry - decided
in IMPLEMENTATION_PLAN.md §7 item 8. getGuestBookEntries now also
returns submissionId so the admin UI can target the delete call.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 22:55:32 +02:00
Paddy 7488ac673f Add example .env 2026-08-05 23:37:17 +02:00
Paddy 17ca6399e0 Add Feedback domain module: public submission flow, admin CRUD, reporting
New /feedback API domain backed by its own FEEDBACK_DB, mirroring the
Calendar domain's router -> service -> DB pool layering:

- Public endpoints (no auth): eligible-events listing, event config,
  submission with honeypot + rate limiting (in-memory + DB backstop).
- Admin endpoints (session-header auth, reusing Calendar's users/sessions
  via a swappable feedback.auth.ts boundary): events/songs/questions CRUD,
  bulk reorder/assignment, aggregated reporting, CSV export.
- Schema in sql/feedback/001_init.sql (8 tables), applied and verified
  against the real FEEDBACK_DB.
- 64 Jest tests covering validation, auth, rate limiting, CSV escaping,
  and report aggregation (pure functions, no DB needed).

Includes fixes from a security review: path traversal defense doesn't
apply here (that's the frontend proxy, separate repo), but the
rate-limiter cluster does - recordSubmission now counts every processed
request (not just successful ones), the in-memory Map evicts empty
entries instead of growing unbounded, FEEDBACK_IP_SALT is required at
boot instead of silently degrading to unsalted hashing, and submission
answer/rating arrays are capped and de-duplicated to bound insert
amplification.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 23:32:22 +02:00
Paddy e7621b8290 Merge pull request 'Add claude init file + refactor some security issues' (#6) from feature/aiRefactoring20260502 into master
Jenkins Production Deployment
Reviewed-on: #6
2026-06-28 11:25:23 +00:00
Patrick Müller da85d1487c Add claude init file + refactor some security issues 2026-05-02 12:22:03 +02:00
Paddy dc65b49219 Add possibility to add birthdays + repeating events to the API
Jenkins Production Deployment
2025-09-07 18:15:15 +02:00
Paddy 9c45fb11ee Add last modified information to event GET endpoints
Jenkins Production Deployment
2025-05-29 12:51:51 +02:00
Paddy 45dfc22c60 Add endpoint for getting upcoming event and adding swagger docs to all endpoints
Jenkins Production Deployment
2025-04-18 15:05:32 +02:00
Paddy a38fb20e5a Add endpoint that allows to move an event to a different calendar
Jenkins Production Deployment
2024-06-04 11:55:30 +02:00
Paddy cb85e81d67 Add new "choir" calendar and add cascading functionality for calendars
Jenkins Production Deployment
2024-06-04 11:17:28 +02:00
Paddy 59fee19a76 Fix issue with sending mails
Jenkins Production Deployment
2023-12-30 23:11:50 +01:00
Paddy a79e2186a2 Fix activation endpoint HTTP method
Jenkins Production Deployment
2023-12-30 22:55:40 +01:00
Paddy 8f93e1ab7d Add password reset endpoints and mail service for user activation
Jenkins Production Deployment
2023-12-30 22:50:47 +01:00
Paddy 34a4a6664f Fix bug where some fields were not sent back via the api
Jenkins Production Deployment
2023-05-15 20:50:50 +02:00
Paddy 76e6bbdbbf Add event versioning capabilities
Jenkins Production Deployment
2023-05-15 20:28:42 +02:00
Paddy 5e84eaea70 Future-proof admin interface of the api, make the api fully capable of handling event status 2023-05-15 19:40:44 +02:00
Paddy b8a68c2480 Add status column for events
Jenkins Production Deployment
2023-05-14 21:26:55 +02:00
Paddy 95983021ed Rework user interface field API names
Jenkins Production Deployment
2023-05-14 21:09:34 +02:00
Paddy 02f7424b56 Upgrade to proper user management 2023-05-14 19:17:30 +02:00
Paddy 93c70b0e1d #1: Add possibility to create whole-day events
Jenkins Production Deployment
2022-12-28 12:15:01 +01:00
Paddy d85f9a992b #2: Remove empty fields from generated ical
Jenkins Production Deployment
2022-12-28 11:34:25 +01:00
Paddy fc071096d8 Fix URL null error when no url is given in event
Jenkins Production Deployment
2022-12-28 01:20:06 +01:00
Paddy a34a5df5a3 Interface change to return eventId after POST call
Jenkins Production Deployment
2022-12-26 15:58:24 +01:00
Paddy 65a5e91ad1 Making createdBy field required
Jenkins Production Deployment
2022-12-25 21:50:21 +01:00
Paddy 6cb7f0d59b Interface adjustments
Jenkins Production Deployment
2022-12-25 20:53:09 +01:00
Paddy ccfa28877c Adjust privileges mgmt
Jenkins Production Deployment
2022-12-25 18:24:18 +01:00
Paddy a8f7189cb3 git add . is a difficult command to execute
Jenkins Production Deployment
2022-12-25 15:43:37 +01:00
Paddy 83c9d090e1 Add methods to insert, update and delete events
Jenkins Production Deployment
2022-12-25 15:38:13 +01:00
Paddy 0348d89121 Add credentials check and rework request structure 2022-12-25 13:49:38 +01:00
Paddy ed9b7dafe0 Update mariadb library
Jenkins Production Deployment
2022-12-24 20:51:31 +01:00
Paddy e76dc7405b Change mariadb connector version
Jenkins Production Deployment
2022-12-24 20:48:54 +01:00
Paddy 9c6befc7b5 More debugging
Jenkins Production Deployment
2022-12-24 20:42:32 +01:00
Paddy 5dd3953542 Debug DB connection
Jenkins Production Deployment
2022-12-24 20:40:02 +01:00
Paddy e08cd70eef Proper error handling
Jenkins Production Deployment
2022-12-24 20:32:29 +01:00
Paddy b00a37eb17 Add iCal converter
Jenkins Production Deployment
2022-12-24 17:44:28 +01:00
Paddy 96f04c6de4 Add JSON Endpoint for events 2022-12-24 15:03:37 +01:00
Paddy 3996e37682 Initial commit 2022-12-24 14:32:13 +01:00