# 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 ```bash # 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` with explicit HTTP status codes. - Services must be annotated with `@Service` and **never** depend on controllers. - Repositories must extend `JpaRepository`. - 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/`, `fix/`, `chore/` - Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/): `feat:`, `fix:`, `chore:`, `docs:`, `test:` - PRs require at least one passing CI check before merging. - Never commit directly to `main`.