docs: add initial project documentation for Condado Newsletter Bot
This commit is contained in:
147
CLAUDE.md
Normal file
147
CLAUDE.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# 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<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](https://www.conventionalcommits.org/): `feat:`, `fix:`, `chore:`, `docs:`, `test:`
|
||||
- PRs require at least one passing CI check before merging.
|
||||
- Never commit directly to `main`.
|
||||
Reference in New Issue
Block a user