-
Notifications
You must be signed in to change notification settings - Fork 0
Prompts Dogan
Tools used:
- Claude Code (Anthropic, Opus 4.7 / Sonnet 4.6) — primary AI pair programmer for backend feature implementation, refactors, race-condition analysis, and PR drafting throughout all three milestones.
- GitHub Copilot / GPT-5.2 Codex — inline completions, JPA query drafting, repetitive test scaffolding.
- ChatGPT — documentation drafting, prompt-log organization, release-note phrasing.
Usage pattern: Claude Code was used conversationally in the terminal/IDE. Prompts were given in natural language (English), ranging from high-level feature specs to pasted stack traces and Flyway errors. The assistant read the codebase, proposed changes, and explained reasoning before editing. All backend changes were verified locally with ./mvnw test and against the running Spring Boot service before being committed.
Prompt: "We're starting the backend from scratch. Set up Spring Boot with User/Mentor/Mentee entities matching the UML class diagram. I need PostgreSQL + Flyway migrations, JWT auth, and register/login endpoints. Also wire up Swagger UI so the rest of the team can try the API."
What it did: Bootstrapped the Spring Boot service: User, Mentor, Mentee entities matching the UML, Flyway V1 schema migration, AuthService with JWT issuance, register/login endpoints, password hashing, and Swagger/OpenAPI auto-configuration.
Prompt: "After registration, send the user a verification email and activate the account when they click the link. Read SMTP config from
.env; in dev profile just log the email instead of sending it."
What it did: Added EmailVerificationToken entity + Flyway migration, scheduled token cleanup job, EmailService with profile-gated SMTP, /auth/verify endpoint, and the verification email template.
Prompt: "Build the forgot-password flow. Send a reset link by email, the token should be single-use and time-bounded, and it must be invalidated after a successful reset."
What it did: Added PasswordResetToken table, /auth/forgot-password and /auth/reset-password endpoints, token TTL + single-use enforcement, and integration tests for the happy/expired/reused paths.
Prompt: "I need a matching algorithm that recommends mentors to a mentee. Score by interest overlap, availability fit, and remaining mentor capacity. Endpoint should be
/mentees/me/matches, paginated."
What it did: Implemented MatchingService scoring candidates by interest Jaccard overlap, availability overlap, and remaining capacity. Added pagination + sort, unit tests for each scoring branch, and OpenAPI examples.
Prompt (pasted log): "JWT verifies inside the container but the same token gets rejected locally. What could cause that?"
What it did: Identified that the JWT signing key was being read from a Docker-only env var that wasn't loaded by the local profile. Unified the key source via application.yml placeholder and added a startup assertion if the secret is unset.
Prompt: "We're deploying to production. Author a docker-compose, make the uploads volume persistent, fill in the env example. We'll ssh into a DigitalOcean droplet — write a deploy script too."
What it did: Authored docker-compose.prod.yml, persistent uploads volume, .env.production.example with all required keys documented, and a smoke-test checklist after deploy. Resulted in PR #214 (Production Ready Project).
Prompt: "If the JWT payload is missing
userIdorrole, we NPE downstream. Reject those tokens at the validation layer so they never reach a controller."
What it did: Hardened JwtAuthenticationFilter to reject tokens with missing/blank userId or role claims at the filter layer with a 401, before they reach any controller. Added unit tests for each malformed-claim shape.
Prompt: "Timestamp-sensitive services are inconsistent — some use
LocalDateTime, someInstant, some format against the system timezone. In the demo a scheduler fired at the wrong hour. Let's standardize on UTC everywhere."
What it did: Standardized the backend on OffsetDateTime with UTC. Migrated availability, mentorship lifecycle, notifications, and meetings services. Added a Flyway data migration to convert stored timestamps and pinned the JVM TZ=UTC in Docker.
Prompt: "
GET /availability/{userId}is open to any authenticated user. A mentor can read another mentor's availability — that's fine for mentees but not for mentor↔mentor. Add a per-role policy and document it."
What it did: Added a per-resource access policy: mentees can read any mentor's availability; mentors can only read their own. Documented the contract in OpenAPI and added regression tests for each role pair.
Prompt: "Two mentees can accept the same mentor concurrently. Both pass the capacity check and the mentor ends up over capacity. Fix with optimistic or pessimistic locking, whichever is cleaner."
What it did: Switched the accept-request path to optimistic locking on the Mentor.activeMentorshipCount field, retried on OptimisticLockingFailureException. Added an integration regression test (MentorshipEndRaceConditionTest) that simulates the concurrent acceptance.
Prompt: "The search endpoint loads all users into memory and filters in code — there's an N+1 and pagination is wrong. Rewrite with database-level filtering and indexes. JPA Specification or QueryDSL is fine."
What it did: Rewrote search using JPA Specification for composable filters, added composite indexes on (role, status, name), eliminated N+1 by adding @EntityGraph on the eager projections, and moved pagination to the SQL layer.
Prompt: "We don't test the STOMP SUBSCRIBE branches. Does an unauthorized SUBSCRIBE produce an ERROR frame? Are we only allowing the right topics? Cover both."
What it did: Added unit tests for StompAuthChannelInterceptor covering authorized/unauthorized SUBSCRIBE on personal, mentorship, and admin topics. Asserted that rejected SUBSCRIBE produces an ERROR frame instead of silently dropping.
Prompt: "Set up an acceptance test infra for the frontend. Use Playwright, start with AT-01 (auth + profile) and AT-03 (smoke). The CI workflow should bring up the backend with docker-compose so it's actually end-to-end."
What it did: Added Playwright config + AT-01/AT-03 specs, data-testid hooks on auth forms, e2e-ci.yml workflow that boots backend + Postgres + web in containers and runs the suite against them.
Prompt: "Write the full AT-02 spec: mentorship request → accept → meeting → task → review. The paginated
/receivedresponse needs unwrapping, and the login probe should bucket-scrub state first so it's stable."
What it did: Wrote AT-02 spec exercising the full mentorship lifecycle, scaffolded AT-04 (community) and AT-05 (abuse reporting), added admin fixture seeding, fixed paginated response handling and login UI failure surfacing.
Prompt: "Write AT-06 (messaging + reminders) and AT-07 (NFR — rate limit, security headers, latency SLA). Also fix the STOMP bootstrap and vite ws proxy so the suite runs stably against dev."
What it did: AT-06 covers send/receive + reminder fan-out via STOMP; AT-07 asserts rate-limit headers, HSTS, CSP, and a p95 latency budget. Added vite ws proxy config and tuned login wait budgets per browser.
Prompt: "A mentee should be able to cancel a mentorship, but we have to keep the audit trail. Add a cool-down before they can re-request the same mentor. Also add a cleanup job to close out stale cancelled/expired mentorships."
What it did: Added MentorshipCancellation audit table, cool-down enforcement on /mentorships POST, scheduled cleanup job for stale states, and integration tests for each cancellation path (mentor-initiated, mentee-initiated, system-initiated).
Prompt: "Close out the mentorship lifecycle: extend (push the deadline), end (manual close), auto-completion (when the deadline passes), and two-sided ratings once the mentorship closes. We also need rating read endpoints — a single mentee→mentor rating and an aggregated list for a mentor."
What it did: Implemented MentorshipLifecycleService covering extend/end/auto-complete state transitions, rating model with one-time write enforcement, scheduled auto-completion job, and read endpoints (#518) for individual + aggregated mentor ratings.
Prompt: "If a mentee keeps cancelling mentorships, auto-ban them temporarily. The duration should escalate — 3 cancels → 1 day, 5 cancels → 1 week, etc. Admins should be able to override (manual unban). A scheduled job should clear the ban when it expires."
What it did: Added UserBan entity with reason (SYSTEM_SPAM, SYSTEM_CANCEL_ESCALATION, ADMIN), escalation policy via config, admin override endpoints, scheduled expiry job, and a BanCheckInterceptor that 403s banned users with BANNED_UNTIL payload (consumed by mobile/web).
Prompt: "Mobile needs push notifications. Use Firebase Admin SDK for FCM. I want a device registry, per-user preferences (which events the user wants pushed), and a transport interface so email/in-app/push all flow through the same
NotificationService. WireREQUEST_SUBMITTEDfirst; the rest plug in afterwards."
What it did: Added Firebase Admin initialization, DeviceToken table for FCM tokens, NotificationPreference per-user settings, FcmNotificationTransport implementing the common NotificationTransport interface, and REQUEST_SUBMITTED wiring. Subsequent events plug into the same transport.
Prompt: "Admin console endpoints: user list with filters, ban/unban with a reason, and admin → user direct messaging. Admin messages should land in a separate thread/inbox where the user can't reply. Admins shouldn't be able to ban themselves."
What it did: Added admin-only endpoints under /admin/*, BanReason enum + BannedBy tracking, one-way admin messaging via a SYSTEM_ADMIN channel, and a self-action guard (#553 fix).
Prompt: "Show users follow suggestions. Two signals: shared interest count, and proximity in the follow graph (2nd-degree follows). We already have the follow edges in Neo4j — pull from there. Endpoint should be paginated and include a
viewerIsFollowingflag."
What it did: Added FollowRecommendationService blending two scores: interest Jaccard from Postgres and follow-graph proximity from Neo4j (2nd-degree neighbors weighted by mutual count). Exposed GET /users/me/follow-recommendations paginated with viewerIsFollowing.
Prompt: "The register endpoint is wide open to bot traffic. Layered defence: a server-issued form token with a short TTL, a hidden honeypot field (if filled in, it's a bot), and an IP-based rate heuristic. Bots get banned with reason
SYSTEM_SPAM. Important: the clear-bot-flag unban path must only targetSYSTEM_SPAMbans — it should never unban a regular admin ban."
What it did: Added FormTokenService issuing short-TTL signed tokens for the register form, honeypot field validation, IP-based rate heuristic, and SYSTEM_SPAM ban path. The clear-bot-flag admin action was scoped to BanReason = SYSTEM_SPAM only (#345 follow-up fix).
Prompt: "Features are tested in isolation but no single test covers the full mentee journey: register → match → request → accept → meeting → message → notification. Write an integration test for that end-to-end workflow, running against real Postgres + Neo4j."
What it did: Added CrossFeatureWorkflowTest under @SpringBootTest with Testcontainers Postgres + Neo4j, walking the full mentee journey and asserting state at each transition (DB rows, STOMP messages received, notifications dispatched).
Prompt: "The home screen shows dashboard stats for mentor and mentee, but the frontend is using hardcoded values. Add
/dashboard/mentor/statsand/dashboard/mentee/stats— active mentorship count, pending requests, completed sessions, average rating, etc."
What it did: Added DashboardService with role-specific aggregations (single SQL per role, no N+1), returning a typed MentorStatsResponse / MenteeStatsResponse. Wired into the existing /dashboard/* routes.
Prompt: "The match-found notification is firing from two paths — the mentee browse and a mentor-side branch. The mentor-side branch is wrong: every time a mentee browses, the mentor gets pinged. Remove the mentor-side branch entirely; only the mentee accept path should trigger it."
What it did: Removed the mentor-side notification emission path, kept the canonical mentee-accept trigger, and updated the unit + e2e tests. Re-triggered the AT-02 chromium e2e to confirm no regression (04ea641).
Prompt: "Wire Neo4j into the prod docker-compose properly. Document the follow-graph flags and
NEO4J_*vars in the env example so it reads like a runbook for whoever deploys."
What it did: Updated docker-compose.prod.yml Neo4j service with auth env wiring and persistent volume, documented NEO4J_* and FOLLOW_GRAPH_ENABLED flags in .env.production.example (current branch, chore/prod-neo4j-wiring).
| Category | How Claude Code Was Used |
|---|---|
| Feature implementation | Describe feature in natural language → Claude reads relevant services/entities, proposes data model + endpoints + tests, implements iteratively |
| Bug triage | Paste stack trace or describe symptom → Claude identifies root cause (race condition, null claim, timezone, etc.) and edits the offending file |
| Race-condition analysis | Describe the concurrent scenario → Claude reasons about happens-before, proposes optimistic/pessimistic lock, writes the regression test |
| Migration drafting | "Add column Y to table X, Flyway version Vn" → Claude writes the migration + entity field + repository projections |
| Test scaffolding | "Cover the branches of this service" → Claude generates JUnit + Mockito tests for each branch with realistic fixtures |
| PR drafting | "Turn these commits into a PR" → Claude reads git log + diff, writes the PR title, summary, and test-plan checklist |
| Merge conflict resolution | Paste conflict markers or branch state → Claude resolves preserving both sides' intent, especially migration version collisions |
| Code review | "Did I miss anything in this diff?" → Claude audits for regressions, missing tests, security implications |
- All backend changes suggested by Claude were verified locally with
./mvnw testand against the running Spring Boot service before being committed. - Flyway migration version numbers were bumped manually after Claude-proposed migrations to avoid collisions with concurrently-merged teammate migrations (e.g. mentee-affiliation V50 → V52, comment-like V50 → V51).
- Claude Code did not have direct write access to remote branches — all commits, pushes, and merges were performed manually by Beratcan Doğan.
- All prompts were given in English; Claude responded in the same language.
- For sensitive paths (auth, JWT validation, ban policy, admin endpoints) every change was reviewed line-by-line before merge, and tests were extended to cover the new branches.
- AI-generated code was never merged without an accompanying unit or integration test covering the new behavior.
Team Members
- Lab 1 Report (12/02/2026)
- Lab 2 Report (19/02/2026)
- Lab 3 Report (26/02/2026)
- Lab 4 Report (05/03/2026)
- Lab 5 Report (12/03/2026)
- Lab 6 Report (26/03/2026)
- Lab 7 Report (02/04/2026)
- Lab 8 Report (18/04/2026)
- Lab 9 Report (30/04/2026)
- Lab 10 Report (07/05/2026)
- Weekly Meeting Notes Template
- Lab Meeting 1 (12.02.2026)
- Weekly Meeting 1 (16.02.2026)
- Weekly Meeting 2 (24.02.2026)
- Weekly Meeting 3 (04.03.2026)
- Weekly Meeting 4 (11.03.2026)
- Weekly Meeting 5 (23.03.2026)
- Weekly Meeting 6 (29.03.2026)
- Weekly Meeting 7 (11.04.2026)
- Weekly Meeting 8 (28.04.2026)
- Weekly Meeting 9 (10.05.2026)
- Use Case Diagram 1 (New Mentor User for Mobile Scenario)
- Use Case Diagram 2 (Mentor-Mentee Matching Scenario)
- Use Case Diagram 3 (New Mentee User Scenario)
- Final Use Case Diagram
- MVP Use Case Diagram
- All Sequence Diagrams
- Sequence Diagram: Mentee Matching
- Sequence Diagram: Mentor Matching
- Sequence Diagram: Mentorship Management
- Sequence Diagram: Registration
- Sequence Diagram: Cancelling Mentorship Relationship and Auto Ban
- Sequence Diagram: Login-Logout
- Sequence Diagram: Reporting-User
- Sequence Diagram: Mentor Profile Management
- MVP Sequence Diagrams
- Test Plan & Coverage (MVP)
- Acceptance Testing Strategy
- Acceptance Tests
- Test Data Strategy
- Web Frontend Test Report
- Amin Abu-Hilga
- Övgü Su Afşar
- Muhammet Sami Çakmak
- Beratcan Doğan
- İbrahim Kayan
- Burak Ögüt
- Mehmet Bora Sarıoğlu
- Future Work (reference, not a deliverable)