> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gocopper.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Feature Packages

Every feature in a Copper application lives in its own package under `pkg/`, named after the domain it owns: `pkg/rockets`, `pkg/launches`, `pkg/telemetry`. A package holds everything the feature needs — its models, business logic, database access, and routes — organized into a small set of conventional files.

You may scaffold a new package with the CLI, which creates the essentials and registers the package with the app:

```
copper scaffold:pkg rockets
```

### The Conventional Files

Not every package needs every file; start small and add files as the feature grows.

| File         | Contents                                                           |
| ------------ | ------------------------------------------------------------------ |
| `models.go`  | Structs, sentinel errors, and constants for the domain             |
| `svc.go`     | The business logic: a single `Svc` struct                          |
| `queries.go` | Database access: a single `Queries` struct wrapping `csql.Querier` |
| `router.go`  | HTTP routes: a single `Router` struct                              |
| `client.go`  | Integration with an external service: a single `Client` struct     |
| `config.go`  | The package's `Config` struct and `LoadConfig`                     |
| `utils.go`   | Pure package-level functions with no injected dependencies         |
| `wire.go`    | The package's `WireModule`, registering its constructors           |

### The Single-Struct Rule

`svc.go`, `router.go`, `queries.go`, and `client.go` each contain exactly one struct, its constructor, and its methods. This keeps every file's purpose obvious: when you open `svc.go`, you are looking at the feature's business logic and nothing else. If a second service is growing inside a package, that is usually a sign it wants to be its own package.

### Services

Business logic lives in the `Svc` struct, constructed like every other Copper component with a params struct:

```go pkg/rockets/svc.go theme={null}
type NewSvcParams struct {
	Queries *Queries
	Logger  clogger.Logger
}

func NewSvc(p NewSvcParams) *Svc {
	return &Svc{
		queries: p.Queries,
		logger:  p.Logger,
	}
}

type Svc struct {
	queries *Queries
	logger  clogger.Logger
}

func (s *Svc) LaunchRocket(ctx context.Context, id int64) (*Launch, error) {
	rocket, err := s.queries.GetRocket(ctx, id)
	if err != nil {
		return nil, cerrors.New(err, "failed to get rocket", map[string]any{
			"id": id,
		})
	}

	if rocket.Fuel < minLaunchFuel {
		return nil, ErrInsufficientFuel
	}

	return s.queries.InsertLaunch(ctx, rocket.ID)
}
```

The layering reads top to bottom: **routers** translate HTTP to and from Go (read the request, call the service, write the response), **services** own the business rules, and **queries** own the SQL. For simple pass-through endpoints, a router may call `Queries` directly; a service earns its place as soon as there are rules to enforce.

<Note>
  If other packages depend on your service, consider defining a `Svc` interface and returning it from `NewSvc`, keeping the implementation unexported. A hand-written mock in a `rocketstest` sibling package then drops in anywhere the interface is used — see [Testing](/digging-deeper/testing).
</Note>

### Utilities

`utils.go` is for pure functions: helpers that take arguments and return results, with no injected dependencies and no state. Anything that needs a logger, a querier, or config belongs on one of the structs instead.

### Wiring It Together

Each constructor is registered in the package's `wire.go`, and the module is added to `pkg/app/wire.go` (the scaffold does this for you):

```go pkg/rockets/wire.go theme={null}
var WireModule = wire.NewSet(
	LoadConfig,
	wire.Struct(new(NewSvcParams), "*"),
	NewSvc,
	NewQueries,
	wire.Struct(new(NewRouterParams), "*"),
	NewRouter,
)
```

To learn how the pieces are provided to each other, see [Dependency Injection](/architecture/dependency-injection).
