This markdown file outlines a detailed task list for building the URL Shortener project from initial creation to production deployment. The structure is organized into Pull Requests (PRs) as high-level milestones, each containing Epics (feature groups), and each Epic broken down into Commits (granular, atomic tasks). Each task is presented as a TODO checkbox for easy tracking.
This is designed for a solo developer or team using Git for version control. Assume you're working on a main branch, with feature branches for each Epic (e.g., feature/project-setup). Commits should be small and focused, with descriptive messages. After completing an Epic, create a PR to merge into main.
Use tools like GitHub Issues or a simple TODO app to track progress. Estimated times are rough (assuming 4-8 hours/day for a novice).
This PR focuses on bootstrapping the project, setting up the environment, and basic architecture. Goal: A runnable skeleton app.
- Commit: Generate base project structure using Spring Initializr. (Setup: Select Gradle Kotlin DSL, Java 17, Spring Boot 3.x, dependencies for web, data-jpa, postgresql, test, lombok, springdoc-openapi, security. Download and unzip.) – Est. 30 min.
- Commit: Initialize Git repository and commit initial files. (
git init,git add .,git commit -m "Initial project setup with Spring Initializr") – Est. 10 min. - Commit: Configure basic application.properties (datasource URL, username, password, hibernate ddl-auto=update, server port). – Est. 15 min.
- Commit: Add .gitignore file (ignore build/, .gradle/, etc.). – Est. 5 min.
- Commit: Run and verify basic app startup (
./gradlew bootRun). – Est. 10 min.
- Commit: Create entity package and add Url entity class with fields (id, originalUrl, shortCode, clickCount, createdAt) using JPA annotations and Lombok. – Est. 20 min.
- Commit: Create repository package and add UrlRepository extending JpaRepository<Url, Long>. – Est. 10 min.
- Commit: Create service package and add UrlService class with placeholder methods (e.g., shortenUrl, findByShortCode). – Est. 15 min.
- Commit: Create controller package and add UrlController with a test endpoint (e.g., GET /health). – Est. 15 min.
- Commit: Add global exception handler using @ControllerAdvice for basic errors. – Est. 20 min.
This PR implements the main business logic: shortening, redirection, and analytics. Goal: Functional API endpoints.
- Commit: Implement shortenUrl method in UrlService: Validate input URL, save to DB, generate shortCode using base62 (add helper method), return short URL. – Est. 45 min.
- Commit: Add POST /api/shorten endpoint in UrlController: Accept JSON, call service, return 201 with shortUrl. – Est. 30 min.
- Commit: Add URL validation (e.g., using java.net.URL or regex) to prevent invalid inputs. – Est. 20 min.
- Commit: Handle duplicate URLs (optional: return existing short if URL already shortened). – Est. 30 min.
- Commit: Implement findAndRedirect in UrlService: Find by shortCode, increment clickCount, save, return originalUrl. – Est. 30 min.
- Commit: Add GET /{shortCode} endpoint in UrlController: Call service, return HttpServletResponse with 302 redirect. – Est. 25 min.
- Commit: Add 404 handling if shortCode not found. – Est. 15 min.
- Commit: Implement getAnalytics in UrlService: Find by shortCode, return DTO with originalUrl, clicks, createdAt. – Est. 20 min.
- Commit: Add GET /api/analytics/{shortCode} endpoint in UrlController: Call service, return JSON. – Est. 20 min.
- Commit: Add basic security (e.g., Spring Security with basic auth) for analytics endpoint. – Est. 40 min.
This PR ensures reliable data persistence and initial setup. Goal: Working DB integration.
- Commit: Set up H2 in-memory DB for testing (profile-based in application.properties). – Est. 20 min.
- Commit: Integrate Flyway for migrations: Add dependency, create V1__init.sql with urls table schema. – Est. 30 min.
- Commit: Run migrations and verify table creation (
./gradlew bootRun). – Est. 15 min.
- Commit: Add CommandLineRunner to seed sample data (e.g., 2-3 test URLs). – Est. 20 min.
- Commit: Implement base62 encoding/decoding utils if needed (though encoding on save is sufficient). – Est. 25 min.
This PR adds tests for reliability. Goal: High coverage and error-free code.
- Commit: Add unit tests for UrlService (shorten, redirect, analytics) using JUnit and Mockito. – Est. 45 min.
- Commit: Add tests for base62 helper methods. – Est. 20 min.
- Commit: Add integration tests for controllers using @SpringBootTest and MockMvc (test endpoints). – Est. 50 min.
- Commit: Set up JaCoCo for coverage: Configure in build.gradle.kts, run
./gradlew jacocoTestReport. – Est. 20 min. - Commit: Create Postman collection for manual E2E testing (export as JSON). – Est. 30 min.
- Commit: Fix any test failures and aim for 80% coverage. – Est. 1 hour.
This PR prepares for deployment with Docker. Goal: Runnable in containers.
- Commit: Create Dockerfile for the app (FROM openjdk:17, COPY build/libs/*.jar, ENTRYPOINT). – Est. 20 min.
- Commit: Create docker-compose.yml (services: app and db, with env vars). – Est. 25 min.
- Commit: Build and run with Docker (
docker-compose up), verify app connects to DB. – Est. 30 min.
- Commit: Configure Swagger/OpenAPI: Access at /swagger-ui/index.html, add descriptions to endpoints. – Est. 30 min.
This PR deploys to prod and adds final touches. Goal: Live app.
- Commit: Set up GitHub repo (push code, create remote). – Est. 15 min.
- Commit: Add GitHub Actions workflow (.github/workflows/ci.yml: build, test, deploy to Heroku). – Est. 40 min.
- Commit: Configure secrets (e.g., HEROKU_API_KEY). – Est. 10 min.
- Commit: Create Heroku app, add Postgres add-on, set config vars (datasource URL, etc.). – Est. 30 min.
- Commit: Deploy via Git or Actions (
git push heroku main), verify live endpoints. – Est. 20 min. - Commit: Set up monitoring (Heroku dashboard) and test prod redirects/analytics. – Est. 25 min.
- Commit: Enable HTTPS (Heroku handles), add input sanitization. – Est. 20 min.
- Commit: Scan dependencies for vulnerabilities (
./gradlew dependencies). – Est. 10 min.
This final PR adds extras for portfolio quality. Goal: Complete, professional project.
- Commit: Create README.md: Project overview, setup instructions, API usage, deployment guide. – Est. 45 min.
- Commit: Update PRD if needed (e.g., version history). – Est. 15 min.
- Commit: Add TODO comments for extensions (e.g., Redis caching, user auth). – Est. 10 min.
- Commit: Final code cleanup, comments, and commit. – Est. 20 min.
Once all PRs are merged, tag the release (e.g., git tag v1.0) and celebrate! Total est. time: 1-2 weeks.