Skip to content

Project Layout

A standard Fountain service has the structure below. ftkit init scaffolds most of it; a few entries (noted) are added by you or by other ftkit commands. The annotations describe each top-level entry; the directories marked REQUIRED are the ones ftkit verify insists on (server, biz, biz/core, biz/dal). Everything else is optional and verified only when present.

text
.
├── main.go                 # Entry point: fountain bootstrap → server.NewServer() → .Serving()
├── go.mod                  # Go module definition
├── config.yaml             # you provide this — runtime config (config.example.yaml also accepted); not generated by init

├── server/                 # REQUIRED — transport & lifecycle layer
│   ├── server.go           #   server struct, NewServer(), Initialize/Serving/Destroy/Info
│   ├── route.go            #   HTTP route wiring (initHTTPHandle, API versioning, groups)
│   ├── conf.go             #   server configuration loading
│   ├── server_callback.go  #   cross-controller callbacks for the server
│   └── version_migrate.go  #   schema/version migration hooks

├── biz/                    # REQUIRED — business layer root
│   ├── biz.go              #   blank-imports controller packages so they self-register
│   ├── core/               # REQUIRED — controllers, one package per business domain
│   │   └── core.go         #     shared controller interfaces / base types
│   └── dal/                # REQUIRED — data access layer
│       ├── dao/            #     data access objects + managers.go registry  (optional)
│       │   └── managers.go #       DAO factory registration, cache/db/storage constants
│       ├── models/         #     persistence models for databases             (optional)
│       └── do/             #     data objects used by the cache/Redis layer   (optional)

├── pkg/                    # Shared, reusable internal packages                (optional)
├── internal/               # Framework-private / non-exported packages
├── cmd/                    # Additional command entry points  (optional — not scaffolded by init)
├── docs/                   # Service documentation                            (optional)
├── scripts/                # Build, test and tooling scripts (build.sh, tidy.sh, …)  (optional)
├── tests/                  # Test suites and fixtures
├── tools/                  # Developer tooling
├── examples/               # Runnable usage examples
├── data/                   # Static data / seed files
├── public/                 # Public static assets
├── deployment/             # Deployment manifests (docker/, k8s/)

├── Dockerfile              # Container build
├── docker-compose.yml      # Local multi-service environment
├── start_dev_env.sh        # Bring up the local dev environment
├── .env.example            # Example environment variables
├── .github/                # GitHub config, instructions and skills
├── .gitlab/                # GitLab config
├── .gitlab-ci.yml          # GitLab CI pipeline
├── .pre-commit-config.yaml # Pre-commit hooks (gitleaks, gitlint, …)
├── .vscode/                # Editor settings
├── .editorconfig           # Editor formatting rules
├── .gitignore              # Git ignore rules
├── .gitattributes          # Git attributes
├── .dockerignore           # Docker ignore rules
├── CODEOWNERS              # Code ownership map
└── LICENSE                 # License

The <service>_client/ package — the typed client library other services import — is not part of the initial scaffold; it is generated later for the service and lives at the repository root next to main.go.