Project Layout
Layout intra-módulo per linguagem: source root, tests location, fixtures/testdata, resources/assets, build artifacts (gitignored), generated code, config files, docs, examples. Tabela canônica per linguagem. Distinto de RFC-006 que cobre layout inter-módulo (sector → backend/app/engine/landing).
Spec — Project Layout
Facet *ode*do Koder Design.
Cobre *ayout intra-módulo*(dentro de um Sector). Layout inter
módulo (006.<domain>/<area>/<sector>/) é RFC
Princípio cross-cutting
Cada linguagem tem o seu *diom estabelecido*(Go cmd/+internal/, Rust src/+tests/, Dart lib/+test/, etc.). A Koder respeita o idiom — não inventa layout próprio que confunde tooling oficial.
Onde *niformizar*entre todas:
README.kmdna raiz do módulo (perreadmes/products.kmd)koder.tomlna raiz (perkoder-toml/format.kmd).editorconfigna raiz (percode/indentation.kmd)LICENSEna raizdocs/pra documentação intra-módulo (KMD/MD)backlog/pra tickets do módulo (perpolicies/backlog.kmd)dist/,build/,target/,out/*empre*gitignored
Tabela canônica per linguagem
Go
<module>/
├── README.kmd
├── koder.toml
├── .editorconfig
├── LICENSE
├── go.mod
├── go.sum
├── cmd/
│ └── <bin-name>/main.go ← um dir por binário
├── internal/ ← código não-exportável
│ ├── <pkg>/
│ └── ...
├── pkg/ ← código exportável (se library)
├── api/ ← spec proto/openapi (se relevante)
├── testdata/ ← fixtures pra _test.go
├── docs/
├── backlog/
├── examples/ ← se library
├── scripts/ ← bash auxiliares
└── dist/ ← gitignored: build outputs- Tests: arquivo
_test.go*exttosource*(idiom Go) - Fixtures:
testdata/(Go ignora por convenção)
Rust
<module>/
├── README.kmd
├── koder.toml
├── .editorconfig
├── LICENSE
├── Cargo.toml
├── Cargo.lock ← commit em binary; gitignore em library
├── src/
│ ├── lib.rs ← biblioteca
│ ├── main.rs ← binário
│ └── bin/<name>.rs ← múltiplos binários
├── tests/ ← integration tests (cada arquivo = crate)
├── benches/ ← benchmarks
├── examples/ ← idiom Cargo
├── docs/
├── backlog/
└── target/ ← gitignored- Unit tests:
#[cfg(test)] mod testsno mesmo arquivo (idiom Rust) - Integration:
tests/
Dart / Flutter
<module>/
├── README.kmd
├── koder.toml
├── .editorconfig
├── LICENSE
├── pubspec.yaml
├── pubspec.lock ← commit em app; gitignore em library
├── lib/
│ ├── <module>.dart ← entry público
│ └── src/ ← implementação (não exportada)
├── test/
├── integration_test/ ← Flutter integration tests
├── example/ ← se library
├── android/, ios/, ... ← se Flutter app
├── assets/ ← se Flutter app
├── docs/
├── backlog/
└── build/ ← gitignoredPython
<module>/
├── README.kmd
├── koder.toml
├── .editorconfig
├── LICENSE
├── pyproject.toml ← PEP 518; preferred sobre setup.py
├── <package_name>/ ← snake_case; src layout opcional (recomendado pra evitar import shadowing)
│ ├── __init__.py
│ └── ...
├── tests/ ← preferred sobre next-to-source
│ ├── conftest.py
│ └── test_*.py
├── docs/
├── examples/
├── backlog/
└── dist/, build/, .venv/ ← gitignored- src layout (
src/<package_name>/) recomendado pra projetospublicados — evita import shadowing.
Koda
<module>/
├── README.kmd
├── koder.toml
├── .editorconfig
├── LICENSE
├── lib/ ← código fonte
│ ├── <module>.kd
│ └── ...
├── test/
│ └── *_test.kd
├── docs/
├── examples/
├── backlog/
└── out/ ← gitignoredJS/TS
<module>/
├── README.kmd
├── koder.toml
├── .editorconfig
├── LICENSE
├── package.json
├── package-lock.json ← commit (npm) ou pnpm-lock.yaml (pnpm)
├── tsconfig.json ← se TS
├── src/ ← preferred
│ ├── index.ts
│ └── ...
├── test/ ← Jest/Vitest setup
│ └── *.test.ts
├── docs/
├── examples/
├── public/ ← se web app
├── backlog/
└── dist/, node_modules/ ← gitignoredShell scripts (módulo standalone)
<module>/
├── README.kmd
├── koder.toml
├── LICENSE
├── bin/ ← scripts executáveis (chmod +x)
│ └── <script>
├── lib/ ← funções source-able
│ └── <lib>.sh
├── test/ ← bats-core ou similar
├── docs/
└── backlog/R1 — Tests location
| Linguagem | Convenção |
|---|---|
| Go | nextfoo_test.go ao lado de foo.go) |
| Rust | unit: inline mod tests; integration: tests/ |
| Dart | test/ separado |
| Python | tests/ separado (preferred Koder) ou next-to (PEP 396 OK) |
| Koda | test/ separado |
| JS/TS | test/ ou src/__tests__/ (config Jest/Vitest) |
| Shell | test/ separado |
*rincípio* seguir idiom da linguagem. A Koder não força uniformidade contra o tooling oficial.
R2 — Fixtures / testdata
| Linguagem | Convenção |
|---|---|
| Go | testdata/ (ignorado pelo go build) |
| Rust | tests/fixtures/ |
| Dart | test/fixtures/ |
| Python | tests/fixtures/ ou tests/data/ |
| Koda | test/fixtures/ |
| JS/TS | test/fixtures/ |
R3 — Resources / assets
- *tatic assets*(imagens, fonts):
assets/(Flutter),static/(Go web),
public/(JS web) - *emplates*
templates/(PythonGo) ou `views` (Rails-like) - *igrations DB*
migrations/na raiz do módulo
R4 — Build artifacts (sempre gitignored)
| Diretório | Linguagem |
|---|---|
dist/ |
JS/TS, Python, Dart |
build/ |
Dart, Java, generic |
target/ |
Rust, Java/Maven |
out/ |
Koda, generic |
bin/ |
Go (output de go build) — exceção: scripts source-controlled |
*.pyc, __pycache__/ |
Python |
node_modules/ |
JS/TS |
.venv/, venv/, env/ |
Python |
.gitignore template canônico em meta/docs/stack/specs/code/gitignore.template.
R5 — Generated code
Quando código é gerado por tooling (protoc, openapi-generator, codegen Koder):
- *arker comment*no header:
// Code generated by <tool>. DO NOT EDIT. - *iretório*
gen/ou per-tool (protoc/) - *itignore*quando reproduzível trivialmente (build step rápido)
- *ommit*quando custoso/lento ou quando o gerador não é parte
do build padrão
R6 — Config files
- *roject config*
koder.tomlna raiz (sempre) - *anguage config*
.golangci.yml,pyproject.toml,analysis_options.yaml,tsconfig.json— na raiz - *ditor*
.editorconfigna raiz (sempre) - *nv*
.env.examplena raiz;.envgitignored - *I*
.gitea/workflows/(Gitea Actions)
R7 — Docs intra-módulo
README.kmdna raiz (overview, install, usage curto)docs/pra docs maiores (docs/getting-started.kmd,docs/api.kmd,docs/architecture.kmd)- ADRs em
docs/decisions/NNNN-<title>.kmd(perpolicies/content-location.kmd) - RFCs intra
módulo em `docsrfcsscopeRFCNNtitle.kmd`
R8 — Examples
Quando o módulo é library, examples/ com 1+ exemplos completos runnable. Cada exemplo standalone (não compartilha state com outros).
Audit deterministic
project-layout-audit.sh:
README.kmd,koder.toml,.editorconfig,LICENSEna raiz- Diretório de build na lista de gitignored
- Generated code com marker comment
- Tests em location idiomática (warning se inconsistente)
Cross-link
- RFC
006 (sector layout intermódulo) code/imports.kmd(import paths refletem layout)readmes/products.kmd(README format)koder-toml/format.kmd(config canônica)policies/backlog.kmd(backlog/directory)policies/content-location.kmd(where to put doc types)