# Lg5 New Service

> Step-by-step recipe to scaffold a brand-new lg5-spring microservice by copying and renaming the blank-service template. Load this skill when the user asks to "create a new service", "bootstrap a microservice", "generate a μ-service", or wants to start a new bounded context on top of lg5-spring.

- **Type:** Skill
- **Install:** `agentstack add skill-lg-labs-pentagon-lg5-spring-agent-os-lg5-new-service`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [lg-labs-pentagon](https://agentstack.voostack.com/s/lg-labs-pentagon)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [lg-labs-pentagon](https://github.com/lg-labs-pentagon)
- **Source:** https://github.com/lg-labs-pentagon/lg5-spring-agent-os/tree/main/skills/lg5-new-service
- **Website:** https://lg-labs-pentagon.github.io/lg5-spring-agent-os/

## Install

```sh
agentstack add skill-lg-labs-pentagon-lg5-spring-agent-os-lg5-new-service
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Recipe: Create a new lg5-spring microservice

> Source template: `https://github.com/lg-labs/blank-service` (locally at `/tmp/lg5-study/blank-service/`).
> Reference implementation to imitate: `/tmp/lg5-study/food-ordering-system/order-service/`.

## Prerequisites

- JDK **21**, Maven **3.9+**, Docker, `make`.
- `lg5-spring-parent` published to local `.m2` at version `1.0.0-alpha.` (run `make publish-local` in `/tmp/lg5-study/lg5-spring`).
- The blank-service repo cloned. If missing:
  ```bash
  git clone --depth 1 https://github.com/lg-labs/blank-service.git /tmp/lg5-study/blank-service
  ```

## Decisions to confirm with the user before generating code

1. **Service name** (kebab-case, e.g. `inventory-service`).
2. **Java base package** (e.g. `com.acme.inventory`).
3. **Aggregate root name** (e.g. `Inventory`, `Reservation`).
4. **Does it consume Kafka events?** (yes → needs `-message`).
5. **Does it produce Kafka events?** (yes → needs Outbox + scheduler).
6. **Does it call third-party HTTP APIs?** (yes → needs `-external` with Feign).
7. **Persistence**: PostgreSQL via JPA (default). Other → discuss.

## Step 1 — Copy the skeleton

```bash
TARGET=/path/to/workspace/-service
cp -R /tmp/lg5-study/blank-service "$TARGET"
cd "$TARGET"
rm -rf .git
```

## Step 2 — Rename modules and packages

For each occurrence of `blank` substitute the new service name; for each occurrence of `com.blanksystem` substitute the chosen base package.

| What to rename | Where |
|---|---|
| Directories `blank-*` → `-*` | top level |
| `blank-*` | every `pom.xml` |
| `com.blanksystem` → new groupId | every `pom.xml` |
| Java packages `com.blanksystem.*` → `.*` | every `.java` source |
| `BlankApplication` → `Application` | `-container/src/main/java/.../BlankApplication.java` |
| `application.yaml` keys `blank-service.*` → `-service.*` | `-container/src/main/resources/application*.yaml` |

Do this with a scripted sed/find-replace pass. Verify with `grep -ri "blank" .` afterward — only the README/CHANGELOG should mention the origin.

## Step 3 — Pin the lg5-spring parent SHA

In root `pom.xml`:
```xml

  com.lg5.spring
  lg5-spring-parent
  1.0.0-alpha.
  

```
Get the SHA via:
```bash
git -C /tmp/lg5-study/lg5-spring log -1 --format=%h
```

## Step 4 — Define the domain (no Spring!)

In `-domain/-domain-core/src/main/java//domain/`:

- **Aggregate root**: extend `com.labs.lg.pentagon.common.domain.entity.AggregateRoot>`.
- **Identity**: extend `BaseId`.
- **Value Objects**: immutable, override `equals`/`hashCode`. Use Java `record` when no behavior is needed.
- **Domain events**: implement `DomainEvent`, named `edEvent` (past tense).
- **Domain services**: stateless, named `DomainService` with an interface + `Impl`.
- **Domain exceptions**: `DomainException extends DomainException`.

Package layout:
```
domain/
├── entity/
├── valueobject/
├── event/
├── exception/
└── service/
```

## Step 5 — Define ports in application-service

In `-domain/-application-service/src/main/java//application/`:

```
ports/
├── input/
│   ├── service/      # Use case interfaces (e.g. ApplicationService)
│   └── message/listener//   # Kafka response listener interfaces
└── output/
    ├── repository/   # Aggregate repository ports
    ├── message/publisher//  # Kafka publisher ports
    └── outbox//              # Outbox port (read/save)
```

Implement input ports in `.application.service` package (e.g. `ApplicationServiceImpl`).

## Step 6 — Adapters

| Layer | Module | Implements |
|---|---|---|
| REST in | `-api` | input port `ApplicationService` via `@RestController` |
| JPA out | `-data-access` | output port repositories via `@Repository` adapters wrapping Spring Data |
| Kafka out | `-message/-message-core` | output port publishers via `KafkaProducer` |
| Kafka in | `-message/-message-core` | input port listeners via `@KafkaListener` |
| Feign out | `-external` | output port HTTP clients via `@FeignClient(configuration = FeignClientConfiguration.class)` |

Always:
- Use `final` on locals & params.
- Use records for `*Command` / `*Response` DTOs.
- Map between adapter DTOs and domain via dedicated `*DataMapper` beans.
- REST controllers `produces = "application/vnd.api.v1+json"`.

## Step 7 — Container module (the only Spring Boot app)

`-container/`:

- `pom.xml` depends on **all** sibling modules + `lg5-spring-starter` + `lg5-spring-logger` + `jib-maven-plugin`.
- `Application.java` annotated `@SpringBootApplication`, `@EnableJpaRepositories`, `@EntityScan` pointing at `.dataaccess`.
- `application.yaml` includes:
  ```yaml
  server:
    port: 8181
  spring:
    datasource:
      url: jdbc:postgresql://localhost:5432/?currentSchema=&binaryTransfer=true&reWriteBatchedInserts=true&stringtype=unspecified
      username: postgres
      password: admin
    jpa:
      hibernate.ddl-auto: validate
      open-in-view: false
  scheduling:
    enabled: true
  -service:
    outbox-scheduler-fixed-rate: 10000
    outbox-scheduler-initial-delay: 10000
    # topic names…
  kafka-config:
    bootstrap-servers: localhost:19092,localhost:29092,localhost:39092
    schema-registry-url-key: schema.registry.url
    schema-registry-url: http://localhost:8081
  kafka-producer-config: …
  kafka-consumer-config: …
  ```
- `application-test.yaml` and `application-local.yaml` for ATDD profile overrides.

## Step 8 — Wire Kafka & Outbox (only if needed)

- Add Avro schemas in `-message-model/src/main/resources/avro/.avsc` with namespace `.message.model.avro`.
- `make run-avro-model` regenerates classes.
- Implement Outbox per `lg5-outbox` skill.
- Implement publisher/listener per `lg5-kafka-avro` skill.
- Implement Sagas (if multi-step orchestration) per `lg5-saga` skill.

## Step 9 — Local infra

In `-support/` mirror `food-ordering-system/infrastructure/`:
- `docker-compose-kafka.yml`
- `docker-compose-postgres.yml`
- `docker-compose-schema-registry.yml`

Wire Make targets `kafka-up`, `ddbb-up`, `docker-up`, `docker-down`.

## Step 10 — ATDD bootstrap

Per `lg5-atdd` skill:
- Create `-acceptance-test/src/test/java//acceptance/boot/`:
  - `AcceptanceTestCase.java` (JUnit Platform Suite)
  - `CucumberHooks.java` extending `Lg5TestBootPortNone`, `@Import(TestContainersLoader.class)`, `@CucumberContextConfiguration`.
  - `TestContainersLoader.java` `@Import`ing the four `*ContainerCustomConfig`s plus dynamic env wiring.
- `src/test/resources/features/*.feature` (Gherkin).
- `src/test/resources/application-test.yaml` enabling required testcontainers.

## Step 11 — Build & smoke test

```bash
make install-skip-test
make docker-up
make run-app           # or run-apps if multi-service
curl -i -X POST http://localhost:8181/ -H 'Content-Type: application/vnd.api.v1+json' -d '{…}'
```

## Step 12 — CI / hooks

- Copy `hooks/pre-push` from blank-service (runs `mvn clean test`).
- Optionally copy `checkstyle.xml` and the maven-checkstyle-plugin config.

## Common pitfalls

- ❌ Adding `@Component` / `@Service` in `-domain-core` — domain must stay Spring-free.
- ❌ Forgetting `@Version` on outbox JPA entities → race conditions in saga.
- ❌ Rethrowing `OptimisticLockingFailureException` from Kafka listener → infinite redelivery.
- ❌ Inventing a non-existent SHA for `lg5-spring-parent` version.
- ❌ Putting `@SpringBootApplication` outside `-container`.
- ❌ Producing Kafka payloads as JSON / POJO instead of Avro `SpecificRecordBase`.
- ❌ Skipping `produces = "application/vnd.api.v1+json"` on controllers.

## Validation checklist before declaring "done"

- [ ] `mvn clean install` green from project root.
- [ ] `mvn -pl -container spring-boot:run` starts without errors against local infra.
- [ ] `make run-acceptance-test` green (at least one happy-path feature).
- [ ] `-domain-core/pom.xml` has zero Spring dependencies.
- [ ] No `blank` / `com.blanksystem` strings remain in source.
- [ ] All controllers produce `application/vnd.api.v1+json`.
- [ ] Outbox tables include `version` column with `@Version`.
- [ ] Saga steps catch `OptimisticLockingFailureException` and short-circuit on missing outbox row.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [lg-labs-pentagon](https://github.com/lg-labs-pentagon)
- **Source:** [lg-labs-pentagon/lg5-spring-agent-os](https://github.com/lg-labs-pentagon/lg5-spring-agent-os)
- **License:** MIT
- **Homepage:** https://lg-labs-pentagon.github.io/lg5-spring-agent-os/

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-lg-labs-pentagon-lg5-spring-agent-os-lg5-new-service
- Seller: https://agentstack.voostack.com/s/lg-labs-pentagon
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
