Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/quiet-badgers-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rawsql-ts/ztd-cli": major
---

Remove the scaffold's `tables/` and `views/` folders and update the docs, AGENTS guidance, and tests so `1 SQL file / 1 QuerySpec / 1 repository entrypoint / 1 DTO` is the only query-unit storage rule.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ See the [Core Package Documentation](./packages/core/README.md) for usage exampl

## Intent and Procedure

Treat each query as one unit: 1 SQL file / 1 QuerySpec / 1 repository entrypoint / 1 DTO.

Keep handwritten SQL assets in `src/sql/` as the single human-owned source location for query logic.

Use this repo by treating DDL and SQL as source assets, and generated specs, repositories, and tests as downstream artifacts that must stay in sync.

Procedure: `DDL -> SQL -> generate -> wire -> test`.
Expand Down
52 changes: 0 additions & 52 deletions packages/ztd-cli/src/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,6 @@ type FileKey =
| 'internalAgentsZtd'
| 'ztdDocsReadme'
| 'sqlReadme'
| 'viewsRepoReadme'
| 'tablesRepoReadme'
| 'jobsReadme'
| 'domainReadme'
| 'applicationReadme'
Expand Down Expand Up @@ -227,10 +225,6 @@ interface InitScaffoldLayout {
sqlClientTemplate: string;
sqlClientAdaptersTemplate: string;
testkitClientTemplate: string;
viewsRepoReadmeTemplate: string;
tablesRepoReadmeTemplate: string;
viewsRepoReadmePath: string;
tablesRepoReadmePath: string;
jobsReadmePath: string | null;
jobsReadmeTemplate: string | null;
domainReadmePath: string | null;
Expand Down Expand Up @@ -312,15 +306,11 @@ const REPOSITORY_TELEMETRY_TYPES_TEMPLATE = 'src/infrastructure/telemetry/types.
const REPOSITORY_TELEMETRY_CONSOLE_TEMPLATE = 'src/infrastructure/telemetry/consoleRepositoryTelemetry.ts';
const REPOSITORY_TELEMETRY_ENTRY_TEMPLATE = 'src/infrastructure/telemetry/repositoryTelemetry.ts';
const SQL_README_TEMPLATE = 'src/sql/README.md';
const VIEWS_REPO_README_TEMPLATE = 'src/repositories/views/README.md';
const TABLES_REPO_README_TEMPLATE = 'src/repositories/tables/README.md';
const WEBAPI_DOMAIN_README_TEMPLATE = 'src/domain/README.md';
const WEBAPI_APPLICATION_README_TEMPLATE = 'src/application/README.md';
const WEBAPI_PRESENTATION_HTTP_README_TEMPLATE = 'src/presentation/http/README.md';
const WEBAPI_INFRASTRUCTURE_README_TEMPLATE = 'src/infrastructure/README.md';
const WEBAPI_PERSISTENCE_README_TEMPLATE = 'src/infrastructure/persistence/README.md';
const WEBAPI_VIEWS_REPO_README_TEMPLATE = 'src/infrastructure/persistence/repositories/views/README.md';
const WEBAPI_TABLES_REPO_README_TEMPLATE = 'src/infrastructure/persistence/repositories/tables/README.md';
const JOBS_README_TEMPLATE = 'src/jobs/README.md';
const ZTD_README_TEMPLATE = 'ztd/README.md';
const ZTD_DDL_DEMO_TEMPLATE = 'ztd/ddl/demo.sql';
Expand All @@ -347,10 +337,6 @@ function resolveInitScaffoldLayout(rootDir: string, appShape: InitAppShape): Ini
sqlClientTemplate: SQL_CLIENT_WEBAPI_TEMPLATE,
sqlClientAdaptersTemplate: SQL_CLIENT_ADAPTERS_WEBAPI_TEMPLATE,
testkitClientTemplate: TESTKIT_CLIENT_WEBAPI_TEMPLATE,
viewsRepoReadmeTemplate: WEBAPI_VIEWS_REPO_README_TEMPLATE,
tablesRepoReadmeTemplate: WEBAPI_TABLES_REPO_README_TEMPLATE,
viewsRepoReadmePath: path.join(rootDir, 'src', 'infrastructure', 'persistence', 'repositories', 'views', 'README.md'),
tablesRepoReadmePath: path.join(rootDir, 'src', 'infrastructure', 'persistence', 'repositories', 'tables', 'README.md'),
jobsReadmePath: null,
jobsReadmeTemplate: null,
domainReadmePath: path.join(rootDir, 'src', 'domain', 'README.md'),
Expand All @@ -377,10 +363,6 @@ function resolveInitScaffoldLayout(rootDir: string, appShape: InitAppShape): Ini
sqlClientTemplate: SQL_CLIENT_TEMPLATE,
sqlClientAdaptersTemplate: SQL_CLIENT_ADAPTERS_TEMPLATE,
testkitClientTemplate: TESTKIT_CLIENT_TEMPLATE,
viewsRepoReadmeTemplate: VIEWS_REPO_README_TEMPLATE,
tablesRepoReadmeTemplate: TABLES_REPO_README_TEMPLATE,
viewsRepoReadmePath: path.join(rootDir, 'src', 'repositories', 'views', 'README.md'),
tablesRepoReadmePath: path.join(rootDir, 'src', 'repositories', 'tables', 'README.md'),
jobsReadmePath: path.join(rootDir, 'src', 'jobs', 'README.md'),
jobsReadmeTemplate: JOBS_README_TEMPLATE,
domainReadmePath: null,
Expand Down Expand Up @@ -568,8 +550,6 @@ export async function runInitCommand(prompter: Prompter, options?: InitCommandOp
internalAgentsTests: path.join(rootDir, '.ztd', 'agents', 'tests.md'),
internalAgentsZtd: path.join(rootDir, '.ztd', 'agents', 'ztd.md'),
sqlReadme: path.join(rootDir, 'src', 'sql', 'README.md'),
viewsRepoReadme: scaffoldLayout.viewsRepoReadmePath,
tablesRepoReadme: scaffoldLayout.tablesRepoReadmePath,
jobsReadme: scaffoldLayout.jobsReadmePath ?? path.join(rootDir, 'src', 'jobs', 'README.md'),
domainReadme: scaffoldLayout.domainReadmePath ?? path.join(rootDir, 'src', 'domain', 'README.md'),
applicationReadme: scaffoldLayout.applicationReadmePath ?? path.join(rootDir, 'src', 'application', 'README.md'),
Expand Down Expand Up @@ -775,32 +755,6 @@ export async function runInitCommand(prompter: Prompter, options?: InitCommandOp
summaries.sqlReadme = sqlReadmeSummary;
}

const viewsRepoReadmeSummary = await writeTemplateFile(
rootDir,
absolutePaths.viewsRepoReadme,
relativePath('viewsRepoReadme'),
scaffoldLayout.viewsRepoReadmeTemplate,
dependencies,
prompter,
overwritePolicy
);
if (viewsRepoReadmeSummary) {
summaries.viewsRepoReadme = viewsRepoReadmeSummary;
}

const tablesRepoReadmeSummary = await writeTemplateFile(
rootDir,
absolutePaths.tablesRepoReadme,
relativePath('tablesRepoReadme'),
scaffoldLayout.tablesRepoReadmeTemplate,
dependencies,
prompter,
overwritePolicy
);
if (tablesRepoReadmeSummary) {
summaries.tablesRepoReadme = tablesRepoReadmeSummary;
}

if (scaffoldLayout.jobsReadmeTemplate) {
const jobsReadmeSummary = await writeTemplateFile(
rootDir,
Expand Down Expand Up @@ -2121,8 +2075,6 @@ function buildSummaryLines(
'internalAgentsZtd',
'ztdDocsReadme',
'sqlReadme',
'viewsRepoReadme',
'tablesRepoReadme',
'jobsReadme',
'domainReadme',
'applicationReadme',
Expand Down Expand Up @@ -2247,11 +2199,7 @@ function buildInitDryRunPlan(rootDir: string, options: {
files.push('src/presentation/http/README.md');
files.push('src/infrastructure/README.md');
files.push('src/infrastructure/persistence/README.md');
files.push('src/infrastructure/persistence/repositories/views/README.md');
files.push('src/infrastructure/persistence/repositories/tables/README.md');
} else {
files.push('src/repositories/views/README.md');
files.push('src/repositories/tables/README.md');
files.push('src/jobs/README.md');
}

Expand Down
4 changes: 0 additions & 4 deletions packages/ztd-cli/src/utils/agents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ const VISIBLE_AGENT_TEMPLATES: readonly VisibleAgentTemplate[] = [
{ relativePath: 'src/catalog/specs/AGENTS.md', templateName: 'src/catalog/specs/AGENTS.md', scope: 'src-catalog-specs', purposeTags: ['catalog', 'specs'], requiredDirectory: 'src/catalog/specs' },
{ relativePath: 'src/sql/AGENTS.md', templateName: 'src/sql/AGENTS.md', scope: 'src-sql', purposeTags: ['sql', 'authoring'], requiredDirectory: 'src/sql' },
{ relativePath: 'src/repositories/AGENTS.md', templateName: 'src/repositories/AGENTS.md', scope: 'src-repositories', purposeTags: ['repositories', 'runtime'], requiredDirectory: 'src/repositories' },
{ relativePath: 'src/repositories/views/AGENTS.md', templateName: 'src/repositories/views/AGENTS.md', scope: 'src-repositories-views', purposeTags: ['repositories', 'views'], requiredDirectory: 'src/repositories/views' },
{ relativePath: 'src/repositories/tables/AGENTS.md', templateName: 'src/repositories/tables/AGENTS.md', scope: 'src-repositories-tables', purposeTags: ['repositories', 'tables'], requiredDirectory: 'src/repositories/tables' },
{ relativePath: 'src/jobs/AGENTS.md', templateName: 'src/jobs/AGENTS.md', scope: 'src-jobs', purposeTags: ['jobs', 'runtime'], requiredDirectory: 'src/jobs' },
{ relativePath: 'src/domain/AGENTS.md', templateName: 'src/domain/AGENTS.md', scope: 'src-domain', purposeTags: ['domain', 'layer'], requiredDirectory: 'src/domain' },
{ relativePath: 'src/application/AGENTS.md', templateName: 'src/application/AGENTS.md', scope: 'src-application', purposeTags: ['application', 'layer'], requiredDirectory: 'src/application' },
Expand All @@ -72,8 +70,6 @@ const VISIBLE_AGENT_TEMPLATES: readonly VisibleAgentTemplate[] = [
{ relativePath: 'src/infrastructure/telemetry/AGENTS.md', templateName: 'src/infrastructure/telemetry/AGENTS.md', scope: 'src-infrastructure-telemetry', purposeTags: ['infrastructure', 'telemetry'], requiredDirectory: 'src/infrastructure/telemetry' },
{ relativePath: 'src/infrastructure/persistence/AGENTS.md', templateName: 'src/infrastructure/persistence/AGENTS.md', scope: 'src-infrastructure-persistence', purposeTags: ['infrastructure', 'persistence'], requiredDirectory: 'src/infrastructure/persistence' },
{ relativePath: 'src/infrastructure/persistence/repositories/AGENTS.md', templateName: 'src/infrastructure/persistence/repositories/AGENTS.md', scope: 'src-infrastructure-persistence-repositories', purposeTags: ['repositories', 'persistence'], requiredDirectory: 'src/infrastructure/persistence/repositories' },
{ relativePath: 'src/infrastructure/persistence/repositories/views/AGENTS.md', templateName: 'src/infrastructure/persistence/repositories/views/AGENTS.md', scope: 'src-infrastructure-persistence-repositories-views', purposeTags: ['repositories', 'views', 'persistence'], requiredDirectory: 'src/infrastructure/persistence/repositories/views' },
{ relativePath: 'src/infrastructure/persistence/repositories/tables/AGENTS.md', templateName: 'src/infrastructure/persistence/repositories/tables/AGENTS.md', scope: 'src-infrastructure-persistence-repositories-tables', purposeTags: ['repositories', 'tables', 'persistence'], requiredDirectory: 'src/infrastructure/persistence/repositories/tables' },
{ relativePath: 'tests/AGENTS.md', templateName: 'tests/AGENTS.md', scope: 'tests', purposeTags: ['tests', 'root'], requiredDirectory: 'tests' },
{ relativePath: 'tests/support/AGENTS.md', templateName: 'tests/support/AGENTS.md', scope: 'tests-support', purposeTags: ['tests', 'support'], requiredDirectory: 'tests/support' },
{ relativePath: 'tests/generated/AGENTS.md', templateName: 'tests/generated/AGENTS.md', scope: 'tests-generated', purposeTags: ['tests', 'generated'], requiredDirectory: 'tests/generated' }
Expand Down
11 changes: 8 additions & 3 deletions packages/ztd-cli/templates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,20 @@ Quick boundary table:

Key folders:
- ztd/ddl: schema files (source of truth)
- src: application SQL and repositories
- src/sql: handwritten SQL assets, one query unit at a time
- src/catalog: QuerySpec contracts and runtime wiring
- src/repositories: repository entrypoints and DTO mappings
- tests: ZTD tests, smoke checks, and the QuerySpec-first example sample

Think in query units: 1 SQL file / 1 QuerySpec / 1 repository entrypoint / 1 DTO.
Keep handwritten SQL assets in `src/sql/` as the single human-owned source location for query logic.

Next steps:
1. Update `ztd/ddl/<schema>.sql` if needed.
2. Add or edit your first SQL asset under `src/sql/`.
2. Add or edit your first SQL asset under `src/sql/` as the human-owned source for one query unit.
3. Run `npx ztd ztd-config` to regenerate DDL-derived test rows and layout metadata.
4. Run `npx ztd model-gen --probe-mode ztd <sql-file> --out <spec-file>` to scaffold a QuerySpec from that SQL file.
5. Review `src/catalog/specs/_smoke.spec.ts`, `tests/queryspec.example.test.ts`, and `src/db/sql-client.ts` so the first SQL-backed repository has both a minimal gate and a QuerySpec-first sample to copy.
5. Review `src/catalog/specs/_smoke.spec.ts`, `tests/queryspec.example.test.ts`, and `src/db/sql-client.ts` so the first SQL-backed repository keeps 1 SQL file / 1 QuerySpec / 1 repository entrypoint / 1 DTO aligned.
6. Run tests (`npm run test` or `npx vitest run`) to pass the generated smoke test before adding SQL-backed coverage.

If this fails:
Expand Down
12 changes: 8 additions & 4 deletions packages/ztd-cli/templates/README.webapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@ Quick boundary table:
- `--url` / complete `--db-*`: explicit target inspection only

Key folders:
- `src/domain`: domain types and business rules with no direct ZTD dependency
- `src/domain`: domain types and business rules with no direct SQL dependency
- `src/application`: use cases and orchestration over domain-facing ports
- `src/presentation/http`: HTTP handlers, request parsing, and response shaping
- `src/infrastructure/persistence`: repositories, SQL assets, and QuerySpec wiring
- `src/sql`, `src/catalog`, `ztd/ddl`: ZTD-owned persistence assets
- `src/infrastructure/persistence`: repositories, DTO mappings, and QuerySpec wiring for one query unit at a time
- `src/sql`: handwritten SQL assets, one query unit at a time
- `src/catalog`, `ztd/ddl`: human-owned support assets that feed those query units
- `tests`: smoke tests, support files, and the QuerySpec-first example sample

Think in query units: 1 SQL file / 1 QuerySpec / 1 repository entrypoint / 1 DTO.
Keep handwritten SQL assets in `src/sql/` as the single human-owned source location for query logic.

Prompt dogfooding:
- See `PROMPT_DOGFOOD.md` when you want to verify that generic WebAPI requests stay out of persistence-specific ZTD guidance unless repository or SQL work is explicitly requested.

Expand All @@ -29,7 +33,7 @@ Next steps:
2. Add or edit your first SQL asset under `src/sql/`, while keeping `src/domain`, `src/application`, and `src/presentation/http` free from direct SQL or DDL concerns.
3. Run `npx ztd ztd-config` to regenerate DDL-derived test rows and layout metadata.
4. Run `npx ztd model-gen --probe-mode ztd <sql-file> --out <spec-file>` to scaffold a QuerySpec from that SQL file.
5. Review `src/catalog/specs/_smoke.spec.ts`, `tests/queryspec.example.test.ts`, and `src/infrastructure/db/sql-client.ts` so the first SQL-backed repository has both a minimal gate and a QuerySpec-first sample to copy.
5. Review `src/catalog/specs/_smoke.spec.ts`, `tests/queryspec.example.test.ts`, and `src/infrastructure/db/sql-client.ts` so the first SQL-backed repository keeps 1 SQL file / 1 QuerySpec / 1 repository entrypoint / 1 DTO aligned.
6. Run tests (`npm run test` or `npx vitest run`) to pass the generated smoke test before adding SQL-backed coverage.

If this fails:
Expand Down
1 change: 1 addition & 0 deletions packages/ztd-cli/templates/src/catalog/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# Policy
## REQUIRED
- Catalog entrypoints MUST bind SQL assets, parameter contracts, output contracts, and runtime validation/mapping.
- Each catalog spec MUST stay aligned with 1 SQL file / 1 QuerySpec / 1 repository entrypoint / 1 DTO.
- `src/catalog/specs` MUST be treated as human-owned contracts.
- `src/catalog/runtime` MUST implement runtime wiring only.
- Code in `src/catalog` MUST remain independent from `tests`, `tests/generated`, and `ztd` imports.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Package Scope
- Applies to `packages/ztd-cli/templates/src/infrastructure/persistence`.
- Defines persistence-layer rules for WebAPI-oriented scaffolds.
- Defines persistence-layer rules for WebAPI-oriented scaffolds and their query units.

# Policy
## REQUIRED
- Persistence repositories MUST keep 1 SQL file / 1 QuerySpec / 1 repository entrypoint / 1 DTO aligned.
- ZTD-specific workflow rules apply here and in the related `src/sql`, `src/catalog`, and `ztd` assets.
- Persistence adapters MUST keep handwritten SQL, QuerySpecs, and DDL aligned.
- Repository code MUST rely on explicit contracts and generated/runtime helpers instead of hidden driver behavior.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Package Scope
- Applies to `packages/ztd-cli/templates/src/infrastructure/persistence/repositories`.
- Defines repository responsibilities for WebAPI-oriented persistence infrastructure.
- Defines repository responsibilities for WebAPI-oriented persistence query units.

# Policy
## REQUIRED
- Persistence repositories MUST keep 1 SQL file / 1 QuerySpec / 1 repository entrypoint / 1 DTO aligned.
- Repositories MUST load SQL assets from `src/sql` through shared loader infrastructure.
- Repository CUD behavior MUST follow contract rules for `RETURNING`, rowCount handling, and explicit unsupported-driver failures.
- Repositories MUST reference SQL by stable logical keys.
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

5 changes: 2 additions & 3 deletions packages/ztd-cli/templates/src/repositories/AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Package Scope
- Applies to `packages/ztd-cli/templates/src/repositories`.
- Defines runtime repository responsibilities for SQL execution orchestration.
- Defines runtime repository responsibilities for one query unit: 1 SQL file / 1 QuerySpec / 1 repository entrypoint / 1 DTO.

# Policy
## REQUIRED
- Repositories MUST keep 1 SQL file / 1 QuerySpec / 1 repository entrypoint / 1 DTO aligned.
- Repositories MUST load SQL assets from `src/sql` through shared loader infrastructure.
- Repositories MUST use catalog runtime helpers (`ensure*`, `map*`) for input/output validation.
- Repository CUD behavior MUST follow contract rules for `RETURNING`, rowCount handling, and explicit unsupported-driver failures.
Expand All @@ -27,5 +28,3 @@
- Error messages MUST include operation identifiers and relevant parameters.

# References
- Tables repository policy: [./tables/AGENTS.md](./tables/AGENTS.md)
- Views repository policy: [./views/AGENTS.md](./views/AGENTS.md)
Loading
Loading