Files
condado-newsletter/CLAUDE.md

5.8 KiB

Condado Newsletter Bot

A newsletter bot built with Kotlin and Spring Boot. This file gives Claude persistent instructions and context about the project so every session starts with the right knowledge.


Project Overview

  • Language: Kotlin (JVM)
  • Framework: Spring Boot 3.x
  • Purpose: Automate the creation, management, and delivery of newsletters
  • Architecture: REST API backend with scheduled jobs for sending newsletters

Tech Stack

Layer Technology
Language Kotlin
Framework Spring Boot 3.x
Build Tool Gradle (Kotlin DSL - build.gradle.kts)
Database PostgreSQL (via Spring Data JPA)
Email Spring Mail (SMTP / JavaMailSender)
Scheduler Spring @Scheduled tasks
Testing JUnit 5 + MockK
Docs Springdoc OpenAPI (Swagger UI)

Project Structure

src/
├── main/
│   ├── kotlin/com/condado/newsletter/
│   │   ├── CondadoNewsletterApplication.kt   # App entry point
│   │   ├── config/                           # Spring configuration classes
│   │   ├── controller/                       # REST controllers
│   │   ├── service/                          # Business logic
│   │   ├── repository/                       # Spring Data JPA repositories
│   │   ├── model/                            # JPA entities
│   │   ├── dto/                              # Data Transfer Objects
│   │   └── scheduler/                        # Scheduled tasks
│   └── resources/
│       ├── application.yml                   # Main config
│       ├── application-dev.yml               # Dev profile config
│       └── templates/                        # Email HTML templates (Thymeleaf)
└── test/
    └── kotlin/com/condado/newsletter/        # Tests mirror main structure

Build & Run Commands

# Build the project
./gradlew build

# Run the application (dev profile)
./gradlew bootRun --args='--spring.profiles.active=dev'

# Run all tests
./gradlew test

# Run a specific test class
./gradlew test --tests "com.condado.newsletter.service.NewsletterServiceTest"

# Generate OpenAPI docs (served at /swagger-ui.html when running)
./gradlew bootRun

Coding Standards

  • Use Kotlin idiomatic style: data classes, extension functions, and null-safety operators.
  • Prefer val over var wherever possible.
  • Use constructor injection for dependencies (never field injection with @Autowired).
  • All DTOs must be data classes with validation annotations (javax.validation).
  • Controller methods must return ResponseEntity<T> with explicit HTTP status codes.
  • Services must be annotated with @Service and never depend on controllers.
  • Repositories must extend JpaRepository<Entity, IdType>.
  • Use @Transactional on service methods that modify data.
  • All public functions must have KDoc comments.
  • Use snake_case for database columns and camelCase for Kotlin properties.
  • Keep controllers thin — business logic belongs in services.

Naming Conventions

Artifact Convention Example
Classes PascalCase NewsletterService
Functions camelCase sendNewsletter()
Variables camelCase subscriberList
Constants SCREAMING_SNAKE_CASE MAX_RETRIES
DB tables snake_case (plural) newsletter_subscribers
REST endpoints kebab-case /api/v1/newsletter-issues
Packages lowercase com.condado.newsletter

Testing Guidelines

  • Every service class must have a corresponding unit test class.
  • Use MockK for mocking (not Mockito).
  • Integration tests use @SpringBootTest and an H2 in-memory database.
  • Test method names follow the pattern: should_[expectedBehavior]_when_[condition].
  • Minimum 80% code coverage for service classes.

Environment Variables

Variable Description
SPRING_DATASOURCE_URL PostgreSQL connection URL
SPRING_DATASOURCE_USERNAME DB username
SPRING_DATASOURCE_PASSWORD DB password
MAIL_HOST SMTP host
MAIL_PORT SMTP port
MAIL_USERNAME SMTP username
MAIL_PASSWORD SMTP password

⚠️ Never hardcode credentials. Always use environment variables or a .env file (gitignored).


Key Domain Concepts

  • Subscriber: A person who opted in to receive newsletters.
  • NewsletterIssue: A single newsletter edition with a subject and HTML body.
  • Campaign: A scheduled or triggered dispatch of a NewsletterIssue to a group of subscribers.
  • SendLog: A record of each email send attempt (status: PENDING / SENT / FAILED).

Git Workflow

  • Branch naming: feature/<short-description>, fix/<short-description>, chore/<short-description>
  • Commit messages follow Conventional Commits: feat:, fix:, chore:, docs:, test:
  • PRs require at least one passing CI check before merging.
  • Never commit directly to main.