# Kickoff Java Project — Quick Reference

Quick reference tables for scaffolding. Single source of truth for versions, AWS values, naming, and copy-mappings.

Primary reference: **Janus** (Spring Boot 4.0.3, Java 25, jOOQ).

---

## Dependency Versions

All versions from Janus root `pom.xml`. Use these when scaffolding parent POM `dependencyManagement`.

| Property / Artifact | Version |
|---------------------|---------|
| `java.version` | 25 |
| `spring.boot.version` | 4.0.3 |
| `co.humand.libraries.version` | 2.1.0 |
| `jspecify` | 1.0.0 |
| `jacoco.version` | 0.8.14 |
| `lombok.version` | 1.18.42 |
| `spotless.version` | 3.0.0 |
| `testcontainers.version` | 2.0.3 |
| `surefire.version` | 3.2.5 |
| `maven-compiler-plugin` | 3.14.1 |
| `build-helper.version` | 3.6.1 |
| `postgresql.version` | 42.7.8 |
| `commons-io.version` | 2.20.0 |
| `spring-retry.version` | 2.0.12 |
| `grpc.version` | 1.75.0 |
| `dd-trace-api.version` | 1.60.2 |
| `springdoc-openapi` | 3.0.2 |
| `jooq.version` (if jOOQ) | 3.20.10 |
| `testcontainers-jooq-codegen` (if jOOQ) | 0.0.4 |
| `aws-advanced-jdbc-wrapper` | 3.2.0 |
| `aws-msk-iam-auth` | 2.3.4 |
| `awssdk-bom` | 2.36.0 |
| `httpclient5` | 5.5.1 |
| `ulid-java` | 0.2.0 |
| `jakarta.annotation-api` | 3.0.0 |
| `palantir-java-format` | 2.81.0 |

### Docker / Testcontainers Images

| Image | Version | Used In |
|-------|---------|---------|
| `amazoncorretto` | 25 | Dockerfile (build + runtime) |
| `postgres` | 17.7 | TestContainersConfiguration |
| `confluentinc/cp-kafka` | 7.8.0 | TestContainersConfiguration |

---

## AWS Environment Table

Shared across all Java services (Cerberus, Argus, Janus, etc.).

| Env | AWS Account | VPC ID | host_condition | server_domain_url |
|-----|-------------|--------|----------------|-------------------|
| dev | 923929101992 | `vpc-0ca675a5ccd7a6bcf` | `api.dev.humand.co` | `api.dev.humand.co` |
| stg | 302630094508 | `vpc-0d7fdc859a78c20d4` | `api.stg.humand.co` | `api.stg.humand.co` |
| prd | 887841176879 | `vpc-0b49d2aaa00ecc5f7` | `api-prd.humand.co` | `api-prd.humand.co` |
| testslot1 | 836513903801 | `vpc-038d4e6243997b3b6` | `api.slot1.humand.co` | `api.slot1.humand.co` |
| testslot2 | 058264267871 | `vpc-0b8cab5e160e52538` | `api.slot2.humand.co` | `api.slot2.humand.co` |

Note: `prd` uses `api-prd.humand.co` (hyphen, not dot).

### ECS Cluster Naming

| Type | Pattern | Example (dev) |
|------|---------|---------------|
| Public (API) | `public-{env}-services` | `public-dev-services` |
| Private (Worker) | `private-{env}-services` | `private-dev-services` |

### S3 Backend Pattern

| Property | Pattern |
|----------|---------|
| `bucket` | `humand-terraform-state-{env}` |
| `key` | `service/humand-<project>-service/terraform.tfstate` |
| `region` | `us-east-1` |
| `dynamodb_table` | `humand-terraform-locks-{env}` |
| `encrypt` | `true` |

### ECS Module

| Property | Value |
|----------|-------|
| Source | `terraform-aws-modules/ecs/aws//modules/service` |
| Version | `5.12.0` |

### LB Rule Priorities (Assigned)

| Service | Priority |
|---------|----------|
| Cerberus | 194 |
| Argus | 195 |
| Janus | 196 |

---

## Naming Conventions

| Artifact | Convention | Example |
|----------|-----------|---------|
| Domain entity | `@Data @Builder` POJO | `User`, `FeatureFlag` |
| Repository interface | `{Entity}Repository` | `UserRepository` |
| Repository impl | `{Entity}RepositoryImpl` (`@Repository`, jOOQ) | `UserRepositoryImpl` |
| Service | `{Entity}Service` | `UserService` |
| Controller | `{Entity}Controller` | `UserController` |
| API interface | `{Entity}Api` | `UserApi` |
| Response DTO | `{Entity}Response` or `{Scope}{Entity}Dto` | `FeatureFlagsResponse` |
| CDC event | `{Entity}CdcEvent` (extends `BaseCdcEvent<{Entity}Data>`) | `UserCdcEvent` |
| CDC data payload | `{Entity}Data` | `UserData` |
| CDC event service | `{Entity}CdcEventService` (extends `BaseCrudCdcEventListener`) | `UserCdcEventService` |
| Exception | `{Entity}NotFoundException` | `UserNotFoundException` |
| Package | lowercase domain name | `user`, `featureflag` |

---

## repos.json Entry Shape

```json
{
  "<repo-key>": {
    "github": "HumandDev/<repo-name>",
    "platform": "backend",
    "role": "Java Spring Boot 4 service (Maven)",
    "branch_model": "explicit",
    "dependency_order": 99,
    "depends_on": ["humand-backend-java-libraries"],
    "base_branch": "main",
    "pr_base": "main",
    "package_manager": "maven",
    "lint_cmd": "mvn spotless:check",
    "lint_fix_cmd": "mvn spotless:apply",
    "type_check_cmd": null,
    "test_cmd": "mvn verify",
    "pr_labels": [],
    "has_translations": false
  }
}
```

---

## Copy-Mapping Tables

### Root Files

| Source (Janus) | Target | Substitutions |
|----------------|--------|---------------|
| `.gitignore` | `.gitignore` | None |
| `.mvn/jvm.config` | `.mvn/jvm.config` | None |
| `.mvn/settings.xml` | `.mvn/settings.xml` | None |
| `.mvn/wrapper/maven-wrapper.properties` | `.mvn/wrapper/maven-wrapper.properties` | None |
| `mvnw` | `mvnw` | None (make executable) |
| `Dockerfile` | `Dockerfile` | Artifact path: `janus-webapp` → `<prefix>-webapp` |

### GitHub Workflows

All 9 workflows are copied from Janus with substitutions.

| Source | Target | Substitutions |
|--------|--------|---------------|
| `ci.yml` | `ci.yml` | Repo name, ECR repo, JDK version, service name |
| `ci-infra.yml` | `ci-infra.yml` | Repo name |
| `ci-terraform-init.yml` | `ci-terraform-init.yml` | Repo name |
| `deployment.yml` | `deployment.yml` | Repo name, ECR repo, service name, container images |
| `dev.yml` | `dev.yml` | Repo name |
| `prd.yml` | `prd.yml` | Repo name |
| `stg.yml` | `stg.yml` | Repo name |
| `testslot1.yml` | `testslot1.yml` | Repo name |
| `testslot2.yml` | `testslot2.yml` | Repo name |

If **Expose gRPC = Yes**, also copy `publish-libs.yml`.

**Substitution rules:**
- `humand-janus` → `humand-<project>`
- `janus-webapp` → `<prefix>-webapp`
- ECR repository name → new ECR repo
- JDK → `25` (already correct)
- `postgres:17.7` → `postgres:17.7` (keep)
- `cp-kafka:7.8.0` → `cp-kafka:7.8.0` (keep)

### Infrastructure Modules

| Source (Janus) | Target | Substitutions |
|----------------|--------|---------------|
| `modules/datadog/` | `modules/datadog/` | None (copy as-is) |
| `modules/db/` | `modules/db/` | `janus` → `<project>` in all identifiers |
| `modules/janus/` | `modules/<project>/` | `janus` → `<project>`, variables, env vars |
| `modules/janus/modules/lb/` | `modules/<project>/modules/lb/` | Path pattern: `/api/v1/janus/` → `/api/v1/<project>/` |
| `modules/service/` | `modules/service/` | `janus` → `<project>` in module names, variables |

### Infrastructure Root Files

| Source | Target | Substitutions |
|--------|--------|---------------|
| `tflint.hcl` | `tflint.hcl` | None (copy byte-for-byte) |
| `generate-terraform-docs.sh` | `generate-terraform-docs.sh` | None (make executable) |
| `AGENTS.md` | `AGENTS.md` | Project name, module structure |

### Infrastructure Env Files

For each of `dev`, `stg`, `prd`, `testslot1`, `testslot2`:

| File | Substitutions |
|------|---------------|
| `main.tf` | ECS cluster names, VPC ID, service module call, project name |
| `providers.tf` | Default tags (Name, Repository) |
| `variables.tf` | Docker image variable name |
| `versions.tf` | S3 backend key, DynamoDB table |
| `outputs.tf` | DB endpoint output name (if DB) |

---

## Subnet Auto-Discovery

Do not pass subnets as a variable. Auto-discover inside the project module:

```hcl
data "aws_subnets" "private" {
  filter {
    name   = "vpc-id"
    values = [var.humand_vpc_id]
  }
  filter {
    name   = "map-public-ip-on-launch"
    values = [false]
  }
}
```

---

## API/Worker Dual Deployment

When Worker = Yes, the service module creates two instances of the project module:
- `module "<project>"` with `type = "api"` on the **public** ECS cluster — serves HTTP traffic, LB attached
- `module "<project>-worker"` with `type = "worker"` on the **private** ECS cluster — runs background tasks (Kafka CDC consumers), no LB

The project module uses `type_environments` local to toggle behavior (e.g. Kafka listener enabled/disabled). Datadog is integrated inside the project module (not called from service).
