Skip to content

Latest commit

 

History

History
43 lines (35 loc) · 3.83 KB

File metadata and controls

43 lines (35 loc) · 3.83 KB

AGENTS.md

Project Snapshot

  • Spring Boot 3.5 API wrapper around LeetCode GraphQL with a local SQLite cache/database.
  • Main app entry: src/main/java/com/rajat_singh/leetcode_api/LeetcodeApiApplication.java (@EnableCaching, @EnableScheduling).
  • Runtime config: src/main/resources/application.yml (DB path, rate limits, scheduler toggle, Swagger, actuator).

Architecture You Need To Follow

  • Request flow is controller -> service -> client/repository -> DTO, with controllers staying thin (see controller/UserController.java).
  • Outbound LeetCode calls are centralized in client/LeetCodeClient.java; GraphQL query strings live in graphql/GraphQlQueries.java.
  • Contest history uses a DB-first fallback pattern: read contest_history; if missing, fetch from LeetCode and persist (see service/LeetCodeContestService.java#getUserContestRankingHistory).
  • Questions endpoints are local-DB-backed; data is refreshed by scheduler jobs, not by direct fetch in request handlers (service/LeetCodeQuestionsService.java, scheduler/LeetCodeSyncScheduler.java).
  • Mapping between persistence and API DTOs is MapStruct-based (mappers/QuestionMapper.java, mappers/ContestMapper.java).

Data & Persistence Patterns

  • SQLite file DB at ./data/leetcode.db; JPA auto-update is enabled (spring.jpa.hibernate.ddl-auto: update).
  • Core tables/entities: leetcode_questions (entity/QuestionEntity.java), contest_history (entity/UserContestHistoryEntity.java), contest_data + sponsors (entity/ContestDataEntity.java, entity/SponsorEntity.java).
  • Topic tags are stored via @ElementCollection in question_topic_tags; queries join this collection (repository/QuestionsRepository.java).
  • Repository layer contains important native SQL/business queries (for example findBiggestRatingJump CTE in repository/ContestHistoryRepository.java).

Caching, Scheduling, and Rate Limits

  • Contest endpoints are cached with Caffeine (contestHistoryCache, contestRankingCache, contestRankingWithHistoryCache) in config/CacheConfig.java.
  • Cache eviction triggers DB cleanup through ContestHistoryCleanupService (removal listener in CacheConfig).
  • Scheduler jobs are guarded by scheduler.enabled; they sync full questions weekly, AC rates daily, POTD daily, contests monthly (scheduler/LeetCodeSyncScheduler.java).
  • Outbound LeetCode calls are throttled via Resilience4j @RateLimiter(name = "leetcode-api") on client methods.
  • Inbound API throttling for question endpoints is configured with Bucket4j in application.yml.

API/Error Conventions

  • Errors are standardized as ApiErrorResponse from exceptions/GlobalExceptionHandler.java.
  • Custom validation exceptions are expected for domain filters (InvalidTrendDirection, InvalidContestTime, BadRequestException).
  • DELETE /api/v1/users/{username}/contests/evictUserData requires local request origin or valid X-API-KEY matched to app.api.secret (controller/UserContestInfoController.java).

Developer Workflows (verified)

  • Run app: ./mvnw spring-boot:run
  • Run tests: ./mvnw -q test (currently only context-load test in src/test/java/.../LeetcodeApiApplicationTests.java).
  • API docs: /swagger-ui/index.html; health/metrics endpoints are exposed under /actuator per application.yml.

Practical Agent Tips For This Repo

  • When adding a new LeetCode-backed endpoint, first add GraphQL in GraphQlQueries, then a typed client method, then service orchestration, then controller route.
  • Reuse existing DTO/entity naming style (*Response, *DTO, *Entity) and keep business logic in services, not controllers.
  • For question search features, implement filters in QuestionSpecificationService before touching controller logic.
  • If changing contest cache behavior, verify both cache TTL logic and DB eviction side effects in CacheConfig/ContestHistoryCleanupService.