Skip to content

Project Retrospective

Can Emir Bora edited this page Apr 16, 2026 · 5 revisions

Project Retrospective

This page reflects on the work and process of Group 9 (Social Event Mapper) from the beginning of the semester through the MVP Milestone (April 9, 2026). It covers what went well, what did not, and what we would do differently.


1. Project Overview

Social Event Mapper is a three-platform application — a FastAPI backend, a Next.js web frontend, and a Kotlin/Jetpack Compose Android app — that allows users to discover, create, and manage community events on a map-centric interface.

The semester was structured around two milestones:

Milestone Due Issues Closed PRs Merged
Design and Requirements Engineering ~Week 5 55
MVP Milestone April 7, 2026 80 ~50
Final Milestone ~May 14, 2026 0 (in progress)

The team began with 7 members. Two original members (Emre Bektaş and Tuğçe Yücel) left around week 2–3, and Battal Hazar joined as a new member around the same time (first appearing in Weekly Meeting 3, February 25). The final active team was 6 members (8 unique contributors across the full semester):

Member Primary Role Merged PRs Lines Added
Can Emir Bora Backend (Discovery & Social APIs), Mobile, DevOps, Documentation 17 +7,346
Faik İhsan Südüpak Backend (Full API, 209 tests), DevOps / Deployment, Mobile 13 +11,300
İbrahim Fırat Yoğurtçu Web Frontend (Discovery, Event Detail, Notifications) 8 +17,122
Muhittin Köybaşı Web Frontend (Init, Auth, Event Creation) 12 +26,932
Battal Hazar Mobile (API Client, Event Creation Flow) 5 +3,793
Mustafa Koyuncu Mobile (Project Init), Meeting Coordination 1 +82

2. What Went Well

2.1 Full MVP Delivered On Schedule

All 12 core feature areas (auth, event lifecycle, discovery, access control, private events, bookmarks, attendance, comments, host profiles, ratings, notifications, categories) were completed across all three platforms by the April 7 deadline. The feature matrix in D6.2 shows every item marked as complete on backend, web, and mobile — this is not a given for a 6-person student team working on three codebases simultaneously, especially after losing 2 members before implementation began.

2.2 Integration-First Backend Testing Strategy

The decision to test against a real Supabase PostgreSQL database — rather than SQLite stubs or mocks — proved to be one of the most valuable technical choices of the semester. With 209 tests across 17 test files, this strategy:

  • Caught cascade behaviors and constraint violations that in-memory mocks would have silently passed (e.g., host self-accept rejection for invites, max_uses enforcement, rating eligibility check)
  • Maintained 0 test failures on main throughout the entire MVP development sprint
  • Gave the team high confidence when deploying, since CI passing on the real DB genuinely reflected production behavior

2.3 CI/CD Pipeline as a Safety Net

The GitHub Actions CI pipeline (backend-ci.yml, deploy.yml, android-build.yml) blocked at least two PRs that introduced regressions before they reached main. The auto-deploy to EC2 on every push to main meant the live deployment always reflected the latest merged code, which was essential for end-to-end manual testing.

2.4 High-Quality Code Reviews

PR review quality was genuinely high throughout the sprint. Examples from the PR history:

  • PR #138 (host profile, bookmarks, attendance): Reviewer left a detailed multi-section review noting an N+1 batch-fetching problem, which was fixed before merge.
  • PR #134 (frontend init): Two reviewers noted color palette alignment, linting strictness, and design token mapping — all addressed.
  • PR #103 (discovery API): Reviewer caught that private events were not appearing with limited info for guests — addressed before merge.
  • PR #135 (session management): Reviewer praised the security design (access token in memory, refresh in httpOnly cookie) and noted specific edge cases.

The review-before-merge discipline held throughout the sprint and improved code quality measurably.

2.5 High-Quality Requirements Elicitation

The structured elicitation questions produced concrete, unambiguous answers that directly drove implementation decisions. Six question clusters were especially impactful (Q3.3.1–3.3.3 on private event visibility, Q2.1.1–2.1.2 on publish requirements, Q9.2.2–9.2.3 on cancelled event behavior, Q2.4.1 on multi-location, Q6.3.1 on rating eligibility, Q3.1.1–3.1.2 on roles and permissions). Translating elicitation answers into FRU/FRS identifiers gave the whole team a shared vocabulary and prevented ambiguous implementation decisions later.

2.6 Well-Defined Team Policies and Git Workflow

The Team Policies document established clear conventions early (conventional commits, branch naming, PR review requirements, issue acceptance criteria, deadline communication expectations). In practice, the team followed these throughout the MVP sprint:

  • All changes to main went through pull requests with at least one reviewer
  • Branch protection rules prevented direct pushes to main
  • Commit messages consistently followed feat:, fix:, docs:, hotfix: prefixes
  • Issues were created for every piece of work, enabling clear task tracking

2.7 Transparent PR Descriptions with Known Gaps Documented

PR authors explicitly documented known gaps and deferred items in PR descriptions before merging. For example, PR #169 (event detail page) listed four specific unfinished items with checkboxes before merging. This transparency allowed reviewers to merge with clear understanding of what remained, and created a natural follow-up issue list rather than hidden half-done features.

2.8 Proactive Security Hardening (Post-MVP)

PR #155 ("Apply non-blocking backend improvements") addressed several important security gaps after the core MVP was stable: refresh tokens and email verification tokens were changed from plaintext storage to SHA-256 hashes, all select("*") queries were replaced with explicit column lists (preventing leakage of hashed_password and google_id fields), and event create/update flows were wrapped in atomic Supabase RPC stored procedures. These were treated as non-blocking and deferred correctly — the MVP was not held for them — but the team proactively addressed them before the milestone review.

2.9 Effective Demo Preparation

The team held a dedicated 60-minute rehearsal meeting (Weekly Meeting 9) the evening before the demo — the only 60-minute meeting of the entire sprint. They developed a detailed 8-minute script with assigned roles (Web Presenter, Web Controller, Mobile Presenter, Mobile Controller, Time Keeper, Customer Observer). The instructor's positive reaction and the TA's praise for the equipment/materials feature validate the preparation effort.

2.10 Proactive Pre-Demo Bug Detection

In the 48 hours before the MVP demo, 10 detailed bug reports were filed and fully resolved covering map view action button bypass (#213), age-restricted event invisibility in discovery (#210), unrestricted host rating (#216), wrong publish redirect (#197), past dates allowed in event creation (#198), underage users creating 18+ events (#199), inconsistent card heights (#200), missing cursor pointers (#202), comment scroll issue (#203), and responsive layout breakage (#206). Filing these as proper GitHub issues with root cause analysis — rather than quietly fixing them — created a complete record of pre-release QA.


3. What Went Badly or Unexpectedly

3.1 Two Team Members Left Before Implementation Began

The team started with 7 members (confirmed by the Meeting 1 participant table: Can Emir, Emre Bektaş, Mustafa, Muhittin, Faik İhsan, İbrahim, Tuğçe). Emre Bektaş and Tuğçe Yücel left around week 2–3; Battal Hazar joined as a replacement around the same time (first appears in Meeting 3, February 25). The net result was a 6-person team for the entire implementation sprint. This reduced the mobile sub-team from the initially planned 3–4 people to effectively 2 active contributors (Battal and Faik İhsan/Can Emir stepping in), since Mustafa's code contributions were minimal.

3.2 Mobile Tech Stack Changed After Initial Decision — Without Documentation

Issue #90's body text explicitly specifies "Set up the base mobile project using React Native", and Weekly Meeting 6 (March 18) records the team choosing React Native. However, the final implementation used Kotlin/Jetpack Compose — a completely different language and framework. This pivot happened between Meeting 6 and the first mobile PR (#137, merged March 29) without any recorded decision in meeting notes or a GitHub issue.

The same Meeting 6 also specified Vercel as the hosting platform, but the team ultimately deployed to AWS EC2 with nginx. Again, no documented decision.

While both pivots led to better outcomes (Compose is more appropriate for the feature complexity; EC2 gives more deployment control than Vercel for a multi-service app), the undocumented switches created confusion about the project's intended stack.

Lesson: Technology decisions with implementation implications must be documented — even when made asynchronously on WhatsApp.

3.3 Severe Contribution Imbalance

The pull request data reveals a significant and measurable imbalance:

Member Merged PRs Lines Added Share of code
Muhittin Köybaşı 12 +26,932 40%
İbrahim Fırat Yoğurtçu 8 +17,122 25%
Faik İhsan Südüpak 13 +11,300 17%
Can Emir Bora 17 +7,346 11%
Battal Hazar 5 +3,793 6%
Mustafa Koyuncu 1 +82 <1%

Mustafa Koyuncu's only merged PR was a stub-app button (+82 lines). His assigned mobile implementation issues (#112 discovery, #116 event detail, #117 bookmark/going) were all completed by Can Emir Bora and Faik İhsan Südüpak. His non-code contributions were meeting notes and planning discussions. This imbalance was acknowledged in D7 and the Final Milestone assignments have been revised (#159, #160, #161), but the cost was felt during the MVP sprint when two backend/mobile contributors had to absorb the mobile gap.

Note: Muhittin's line count is inflated by the large Next.js boilerplate in PR #134 (+12,226 lines) and Ibrahim's by web mockup HTML files in PR #104 (+9,775 lines), so these numbers should be read in context. The imbalance is still real and significant even accounting for this.

3.4 No Automated Frontend and Mobile Tests for MVP

Both platforms relied entirely on manual testing against the live deployment. The 10 pre-demo bug reports filed in 48 hours demonstrate that manual testing does catch bugs — but it is not reproducible, not scalable, and not integrated into CI. The web has 16 Vitest tests covering only auth/routing; the mobile has zero automated tests. This technical debt must be addressed in the Final Milestone.

3.5 Production Crash from Naive Datetime Payloads

The datetime handling issue was more serious than a minor edge case: PR #143's comment confirms "Prod logs confirmed the live failure path: timezone-naive datetimes reaching POST /events caused a Python naive/aware datetime comparison crash." Users were receiving 500 Internal Server Error responses when creating events from the mobile or web clients. This was discovered on April 1, after both frontend and mobile had been sending payloads for days. The fix required coordinating a UTC standard across three codebases simultaneously.

Lesson: End-to-end integration testing (mobile/web → backend) should start earlier, before both sides are in production.

3.6 Mobile BASE_URL Was Localhost in First Deployed Version

PR #167 (mobile auth rebuild + discovery, merged April 4) fixed an issue where the mobile app was pointing to localhost as its API base URL rather than the production domain (thesocialeventmapper.social). This meant the mobile app was broken against the live deployment until that PR was merged — three days before the demo. The fix commit message states: "Point BASE_URL to https://thesocialeventmapper.social/ (was localhost)".

This is a deployment coordination failure: the mobile app was developed against a local backend without a clear process for switching to production.

3.7 Security Gap: Refresh Tokens Stored Plaintext Until Late in MVP Sprint

Until PR #155 (merged April 2), refresh tokens and email verification tokens were stored in the database as plaintext values. This means anyone with read access to the database (e.g., via Supabase's SQL editor or a misconfigured RLS policy) could extract valid session tokens. PR #155 retroactively hashed all stored tokens to SHA-256 before the demo, but the gap existed for the entire development period. The team correctly identified and fixed it, but it should have been part of the initial auth implementation.

3.8 Last-Minute Infrastructure Hotfixes

Several deployment issues were discovered only in the final 48 hours, not during development:

PR Issue
#165 Frontend Docker build failing — public/ directory had no tracked files after placeholder SVGs were removed
#168 Event editor routes conflicting with Next.js /events path on the live server
#175 Race condition + infinite re-render on event detail page (dev server didn't surface this)
#186 /notifications URL intercepted by nginx before reaching Next.js, requiring rename to /inbox
#196 Missing React Suspense boundary — broke production build but not dev server

The common thread: production-only issues that only appeared when running against EC2. Earlier deployment of even a minimal skeleton would have surfaced all of these at low cost.

3.9 Private Event Flow Was More Complex Than Planned

The dual access mechanism (token-based invites AND user-initiated access requests, each with independent state machines) took significantly more time than scoped. Edge cases — host self-accept rejection, max_uses enforcement, idempotent acceptance, separate state for invite vs. request — were not anticipated during planning. Both backend and UI required multiple iterations.

3.10 Backend Test Suite Required Mid-Sprint Refactoring

The test suite grew organically and became slow enough to impact productivity. Issue #133 required restructuring the pyramid, adding autouse cleanup fixtures, and adding CI sharding — all mid-sprint work that interrupted feature delivery.

3.11 Frontend Init Had a Duplicate PR That Confused the History

PR #139's merge comment confirms: "Since the init branch wasn't merged separately, this PR brings both #134 and #135 into main together." PR #134 (frontend init) and PR #135 (session management) were developed in sequence on related branches, but because #134 was never cleanly merged, #139 re-applied both. This left the git history with two apparent init PRs and confused the baseline state for subsequent contributors.


4. Process and Management Reflection

4.1 Meeting Cadence Was Consistent but Notes Were Thin

Weekly sync meetings were held consistently throughout the semester. However, most meetings lasted 30 minutes with brief recorded discussions. The exception was Meeting 9 (60 minutes for demo rehearsal). Meetings functioned as lightweight sync points rather than decision-making forums. Several important decisions (tech stack pivots, hosting changes) were made off-meeting and never recorded.

4.2 Rotation System Was Defined but Not Consistently Applied

Meeting 2 defined a structured note-taker/moderator rotation by reverse-alphabetical order. By Meeting 3 this had changed, and by Meeting 4 it changed again. In practice the note-taker role was carried by whoever was most active. The rotation system was well-intentioned but never reliably followed.

4.3 GitHub Projects Board Was Visible but Not Used for Capacity Planning

The kanban board provided good task visibility but was not used for effort estimation. Issues were created and assigned but not point-estimated. This meant the team had no signal to identify overloaded sprints in advance. The Final Milestone's 24 open issues represent a larger workload than MVP, and sprint planning with story points would prevent end-of-sprint crunch.

4.4 Issue Closure Policy Was Not Consistently Followed

The Team Policies specify that the assignee does not close their own issue. In practice, several issues were closed via PR merge without a separate reviewer comment confirming acceptance criteria. This is a minor process gap but undermines the definition-of-done mechanism.

4.5 Documentation Was Produced but Often Last-Minute

Lab 8 report shows all Individual Contributions sections empty at lab time (only Can Emir Bora had written his). This pattern of last-minute documentation — visible across several lab reports — concentrates documentation work at the most stressful times and reduces its quality.

4.6 Code Review Quality Was Good But Inconsistent Between Phases

During the implementation phase (March–April), code reviews were substantive — reviewers caught real issues (N+1 queries, security gaps, missing guest/auth field differentiation). During the planning phase (stub-app, Lab 5), reviews were effectively absent — authors merged their own PRs with one-line comments. The team's review culture improved significantly once stakes were higher, but earlier discipline would have set better habits.


5. Technical Reflection

5.1 Tech Stack Assessment

Component Chosen Initial Plan Assessment
Backend FastAPI + Python FastAPI Correct — fast to develop, excellent auto-docs, easy to test
Database Supabase (PostgreSQL) Supabase Good for MVP; EU region was a mistake
Web Frontend Next.js 16 + TypeScript Next.js Correct; App Router footguns added friction
Mobile Kotlin/Jetpack Compose React Native Pivot was undocumented but correct outcome
Hosting AWS EC2 + nginx Vercel Pivot was undocumented; EC2 migration needed in Final
CI GitHub Actions GitHub Actions Excellent throughout

5.2 Features Correctly Deferred to Final Milestone

The following were explicitly deferred and the decision was correct:

  • GPS-based location in discovery (FRU-2.1.1.1)
  • Multi-location itinerary UI (FRS-8.2) — backend data model already supports it
  • Admin moderation dashboard (FRS-9)
  • Automated frontend and mobile test suites
  • Location search in event creation (#224) — TA-flagged
  • Clickable profile navigation everywhere (#229) — TA-flagged
  • Detailed post-event reviews — instructor-requested

5.2.1 Internal Documentation Inconsistency: Test Framework

The Test Plan & Coverage wiki page specifies "Jest + React Testing Library" for the Final Milestone web tests. However, frontend/package.json already has vitest installed (not Jest), and the Milestone Review (D6) correctly refers to "Vitest + React Testing Library" with 16 existing Vitest tests. The wiki Test Plan page was written before the framework was finalized and never updated. This is a minor but concrete example of documentation drifting out of sync with the actual codebase.

5.3 Technical Debt Carried Into Final Milestone

Debt Impact Priority
No frontend automated tests Regressions reach main undetected High
No mobile automated tests Same High
Supabase EU region latency UX degradation for Turkish users High
AWS EC2 migration needed Cost/reliability risk Medium
Location search missing in event creation TA-flagged UX gap High
Clickable profile navigation incomplete TA-flagged UX gap Medium
Detailed post-event review system Instructor-requested feature Medium

6. Key Lessons Learned

# Lesson Evidence
L1 Document technology pivots formally React Native → Kotlin/Compose and Vercel → EC2 happened without any recorded decision
L2 Deploy a skeleton as early as possible nginx conflict, Suspense boundary, gitkeep, localhost BASE_URL — all production-only issues found late
L3 Monitor contribution balance at mid-sprint Mustafa's imbalance was only addressed post-MVP; catching it at week 3 would have allowed course correction
L4 Two members leaving mid-project changes workload significantly Team went from 8 to 6; mobile sub-team felt this acutely
L5 Security fundamentals must be in the initial design Plaintext token storage in auth foundation was a gap from day one, fixed weeks later
L6 Production crashes are more likely when e2e integration testing starts late Naive datetime 500 errors and localhost BASE_URL both stem from this
L7 Test infrastructure must be designed, not grown Mid-sprint test refactor (#133→#140) interrupted feature delivery
L8 Dual-path access control is two features, not one Private invite + request-to-join each have independent state machines; scope them separately
L9 Manual-only client tests do not scale 10 bug reports filed 48h before demo; Final Milestone scope requires automation
L10 Stakeholder answers may need re-validation through structured elicitation "Completely invisible" private events was later revised to "visible with limited preview"
L11 Rubber-stamp reviews from day one set a bad precedent Stub-app PRs approved with one-liners by a single reviewer established a culture that required active correction later
L12 Infrastructure choices have long-tail costs Supabase region and AWS decisions require migration work in Final Milestone

7. Looking Forward to the Final Milestone

Based on this retrospective, the team has identified the following priorities:

  1. Automated test suites for web and mobile — Vitest + React Testing Library (~42 tests), JUnit + Compose Testing (~58 tests), both in CI
  2. Earlier deployment testing — deploy to staging before the final sprint to catch infrastructure issues while cost is low
  3. Sprint planning with effort estimation — story points on the 24 open Final Milestone issues to avoid end-of-sprint crunch
  4. Incremental documentation — update milestone deliverables as work completes, not in the final 48 hours
  5. Distributed mobile ownership — revised assignments (#159, #160, #161) address the MVP contribution imbalance
  6. Infrastructure migration — Supabase region (#226) and AWS replacement (#225) scheduled for Final Milestone
  7. Customer feedback implementation — detailed post-event reviews (instructor), location search (#224), clickable profile navigation (#229) — all flagged at the MVP demo
  8. Formal documentation of architecture decisions — tech pivots and hosting changes must be recorded in meeting notes or GitHub issues
Team Members
Project Cores
Scenarios
Use Case Diagrams
Class Diagram
Sequence Diagrams
Meetings
Lab Reports

Clone this wiki locally