@tailor-platform/erp-kit 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +10 -10
- package/dist/cli.mjs +407 -69
- package/package.json +1 -1
- package/skills/erp-kit-app-1-requirements/SKILL.md +33 -17
- package/skills/erp-kit-app-2-requirements-review/SKILL.md +12 -0
- package/skills/erp-kit-app-3-plan/SKILL.md +18 -4
- package/skills/erp-kit-app-3-plan/references/resolver-extraction.md +1 -1
- package/skills/erp-kit-app-3-plan/references/screen-extraction.md +1 -1
- package/skills/erp-kit-app-4-plan-review/SKILL.md +12 -0
- package/skills/erp-kit-app-5-impl-backend/SKILL.md +12 -0
- package/skills/erp-kit-app-6-impl-frontend/SKILL.md +12 -0
- package/skills/erp-kit-app-7-impl-review/SKILL.md +13 -1
- package/skills/erp-kit-app-shared/references/progress-protocol.md +77 -0
- package/skills/erp-kit-mock-scenario/SKILL.md +1 -1
- package/skills/erp-kit-module-1-requirements/SKILL.md +1 -1
- package/skills/erp-kit-module-3-plan/SKILL.md +3 -3
- package/skills/erp-kit-module-3-update-plan/SKILL.md +3 -3
- package/skills/erp-kit-module-5-impl/SKILL.md +1 -1
- package/src/commands/app/index.ts +2 -0
- package/src/commands/app/progress/git-context.ts +16 -0
- package/src/commands/app/progress/index.ts +45 -0
- package/src/commands/app/progress/log.ts +49 -0
- package/src/commands/app/progress/progress.test.ts +128 -0
- package/src/commands/app/progress/schema-cmd.ts +10 -0
- package/src/commands/check.test.ts +4 -4
- package/src/commands/lib/discovery.test.ts +5 -7
- package/src/commands/lib/discovery.ts +8 -8
- package/src/commands/lib/sync-check-source.test.ts +1 -1
- package/src/commands/lib/sync-check-source.ts +6 -1
- package/src/commands/lib/sync-check-tests.test.ts +43 -0
- package/src/commands/lib/sync-check-tests.ts +20 -2
- package/src/commands/sync-check.ts +3 -0
- package/src/generator/generate-app-code.test.ts +0 -6
- package/src/generator/generate-app-code.ts +3 -13
- package/src/generator/generate-code.test.ts +10 -40
- package/src/generator/generate-code.ts +6 -12
- package/src/generator/stub-templates.test.ts +0 -7
- package/src/generator/stub-templates.ts +0 -14
- package/src/modules/finance-ledger/README.md +50 -0
- package/src/modules/finance-ledger/command/.gitkeep +0 -0
- package/src/modules/finance-ledger/command/addJournalLine.generated.ts +6 -0
- package/src/modules/finance-ledger/command/addJournalLine.test.ts +438 -0
- package/src/modules/finance-ledger/command/addJournalLine.ts +122 -0
- package/src/modules/finance-ledger/command/approveAndLockPeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/approveAndLockPeriod.test.ts +107 -0
- package/src/modules/finance-ledger/command/approveAndLockPeriod.ts +72 -0
- package/src/modules/finance-ledger/command/beginClose.generated.ts +6 -0
- package/src/modules/finance-ledger/command/beginClose.test.ts +106 -0
- package/src/modules/finance-ledger/command/beginClose.ts +58 -0
- package/src/modules/finance-ledger/command/closePeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/closePeriod.test.ts +87 -0
- package/src/modules/finance-ledger/command/closePeriod.ts +44 -0
- package/src/modules/finance-ledger/command/createAccountingPeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/createAccountingPeriod.test.ts +425 -0
- package/src/modules/finance-ledger/command/createAccountingPeriod.ts +133 -0
- package/src/modules/finance-ledger/command/createFiscalYear.generated.ts +6 -0
- package/src/modules/finance-ledger/command/createFiscalYear.test.ts +197 -0
- package/src/modules/finance-ledger/command/createFiscalYear.ts +70 -0
- package/src/modules/finance-ledger/command/createJournalEntry.generated.ts +6 -0
- package/src/modules/finance-ledger/command/createJournalEntry.test.ts +261 -0
- package/src/modules/finance-ledger/command/createJournalEntry.ts +121 -0
- package/src/modules/finance-ledger/command/deleteAccountingPeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/deleteAccountingPeriod.test.ts +71 -0
- package/src/modules/finance-ledger/command/deleteAccountingPeriod.ts +55 -0
- package/src/modules/finance-ledger/command/deleteFiscalYear.generated.ts +6 -0
- package/src/modules/finance-ledger/command/deleteFiscalYear.test.ts +38 -0
- package/src/modules/finance-ledger/command/deleteFiscalYear.ts +34 -0
- package/src/modules/finance-ledger/command/deleteJournalEntry.generated.ts +6 -0
- package/src/modules/finance-ledger/command/deleteJournalEntry.test.ts +58 -0
- package/src/modules/finance-ledger/command/deleteJournalEntry.ts +43 -0
- package/src/modules/finance-ledger/command/executeYearEndClose.generated.ts +6 -0
- package/src/modules/finance-ledger/command/executeYearEndClose.test.ts +239 -0
- package/src/modules/finance-ledger/command/executeYearEndClose.ts +415 -0
- package/src/modules/finance-ledger/command/finalCloseAndLockPeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/finalCloseAndLockPeriod.test.ts +102 -0
- package/src/modules/finance-ledger/command/finalCloseAndLockPeriod.ts +76 -0
- package/src/modules/finance-ledger/command/finalizeFinancialStatement.generated.ts +6 -0
- package/src/modules/finance-ledger/command/finalizeFinancialStatement.test.ts +73 -0
- package/src/modules/finance-ledger/command/finalizeFinancialStatement.ts +73 -0
- package/src/modules/finance-ledger/command/generateFinancialStatement.generated.ts +6 -0
- package/src/modules/finance-ledger/command/generateFinancialStatement.test.ts +311 -0
- package/src/modules/finance-ledger/command/generateFinancialStatement.ts +275 -0
- package/src/modules/finance-ledger/command/generatePreliminaryStatements.generated.ts +6 -0
- package/src/modules/finance-ledger/command/generatePreliminaryStatements.test.ts +152 -0
- package/src/modules/finance-ledger/command/generatePreliminaryStatements.ts +140 -0
- package/src/modules/finance-ledger/command/generateTrialBalance.generated.ts +6 -0
- package/src/modules/finance-ledger/command/generateTrialBalance.test.ts +439 -0
- package/src/modules/finance-ledger/command/generateTrialBalance.ts +268 -0
- package/src/modules/finance-ledger/command/initiatePeriodClose.generated.ts +6 -0
- package/src/modules/finance-ledger/command/initiatePeriodClose.test.ts +153 -0
- package/src/modules/finance-ledger/command/initiatePeriodClose.ts +84 -0
- package/src/modules/finance-ledger/command/openForAdvanceEntry.generated.ts +6 -0
- package/src/modules/finance-ledger/command/openForAdvanceEntry.test.ts +87 -0
- package/src/modules/finance-ledger/command/openForAdvanceEntry.ts +44 -0
- package/src/modules/finance-ledger/command/openPeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/openPeriod.test.ts +90 -0
- package/src/modules/finance-ledger/command/openPeriod.ts +44 -0
- package/src/modules/finance-ledger/command/permanentlyClosePeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/permanentlyClosePeriod.test.ts +87 -0
- package/src/modules/finance-ledger/command/permanentlyClosePeriod.ts +48 -0
- package/src/modules/finance-ledger/command/postAdjustingEntries.generated.ts +6 -0
- package/src/modules/finance-ledger/command/postAdjustingEntries.test.ts +392 -0
- package/src/modules/finance-ledger/command/postAdjustingEntries.ts +156 -0
- package/src/modules/finance-ledger/command/postJournalEntry.generated.ts +6 -0
- package/src/modules/finance-ledger/command/postJournalEntry.test.ts +346 -0
- package/src/modules/finance-ledger/command/postJournalEntry.ts +160 -0
- package/src/modules/finance-ledger/command/processInventoryHandoff.generated.ts +6 -0
- package/src/modules/finance-ledger/command/processInventoryHandoff.test.ts +211 -0
- package/src/modules/finance-ledger/command/processInventoryHandoff.ts +133 -0
- package/src/modules/finance-ledger/command/processManufacturingHandoff.generated.ts +6 -0
- package/src/modules/finance-ledger/command/processManufacturingHandoff.test.ts +221 -0
- package/src/modules/finance-ledger/command/processManufacturingHandoff.ts +133 -0
- package/src/modules/finance-ledger/command/processPurchaseHandoff.generated.ts +6 -0
- package/src/modules/finance-ledger/command/processPurchaseHandoff.test.ts +222 -0
- package/src/modules/finance-ledger/command/processPurchaseHandoff.ts +133 -0
- package/src/modules/finance-ledger/command/processSalesHandoff.generated.ts +6 -0
- package/src/modules/finance-ledger/command/processSalesHandoff.test.ts +257 -0
- package/src/modules/finance-ledger/command/processSalesHandoff.ts +135 -0
- package/src/modules/finance-ledger/command/regenerateFinancialStatement.generated.ts +6 -0
- package/src/modules/finance-ledger/command/regenerateFinancialStatement.test.ts +129 -0
- package/src/modules/finance-ledger/command/regenerateFinancialStatement.ts +186 -0
- package/src/modules/finance-ledger/command/removeJournalLine.generated.ts +6 -0
- package/src/modules/finance-ledger/command/removeJournalLine.test.ts +65 -0
- package/src/modules/finance-ledger/command/removeJournalLine.ts +39 -0
- package/src/modules/finance-ledger/command/reopenPeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/reopenPeriod.test.ts +87 -0
- package/src/modules/finance-ledger/command/reopenPeriod.ts +44 -0
- package/src/modules/finance-ledger/command/reverseJournalEntry.generated.ts +6 -0
- package/src/modules/finance-ledger/command/reverseJournalEntry.test.ts +337 -0
- package/src/modules/finance-ledger/command/reverseJournalEntry.ts +140 -0
- package/src/modules/finance-ledger/command/revertSoftLock.generated.ts +6 -0
- package/src/modules/finance-ledger/command/revertSoftLock.test.ts +96 -0
- package/src/modules/finance-ledger/command/revertSoftLock.ts +67 -0
- package/src/modules/finance-ledger/command/updateFiscalYear.generated.ts +6 -0
- package/src/modules/finance-ledger/command/updateFiscalYear.test.ts +138 -0
- package/src/modules/finance-ledger/command/updateFiscalYear.ts +85 -0
- package/src/modules/finance-ledger/command/updateJournalEntry.generated.ts +6 -0
- package/src/modules/finance-ledger/command/updateJournalEntry.test.ts +195 -0
- package/src/modules/finance-ledger/command/updateJournalEntry.ts +86 -0
- package/src/modules/finance-ledger/command/updateJournalLine.generated.ts +6 -0
- package/src/modules/finance-ledger/command/updateJournalLine.test.ts +385 -0
- package/src/modules/finance-ledger/command/updateJournalLine.ts +155 -0
- package/src/modules/finance-ledger/command/verifySubledgerTransfers.generated.ts +6 -0
- package/src/modules/finance-ledger/command/verifySubledgerTransfers.test.ts +201 -0
- package/src/modules/finance-ledger/command/verifySubledgerTransfers.ts +113 -0
- package/src/modules/finance-ledger/command/verifyTrialBalance.generated.ts +6 -0
- package/src/modules/finance-ledger/command/verifyTrialBalance.test.ts +136 -0
- package/src/modules/finance-ledger/command/verifyTrialBalance.ts +97 -0
- package/src/modules/finance-ledger/db/.gitkeep +0 -0
- package/src/modules/finance-ledger/db/accountingPeriod.ts +58 -0
- package/src/modules/finance-ledger/db/financialStatement.ts +92 -0
- package/src/modules/finance-ledger/db/financialStatementLineItem.ts +76 -0
- package/src/modules/finance-ledger/db/fiscalYear.ts +41 -0
- package/src/modules/finance-ledger/db/journalEntry.ts +101 -0
- package/src/modules/finance-ledger/db/journalLine.ts +64 -0
- package/src/modules/finance-ledger/db/periodClose.ts +97 -0
- package/src/modules/finance-ledger/db/trialBalance.ts +63 -0
- package/src/modules/finance-ledger/db/trialBalanceLine.ts +63 -0
- package/src/modules/finance-ledger/docs/commands/AddJournalLine.md +74 -0
- package/src/modules/finance-ledger/docs/commands/ApproveAndLockPeriod.md +53 -0
- package/src/modules/finance-ledger/docs/commands/BeginClose.md +47 -0
- package/src/modules/finance-ledger/docs/commands/ClosePeriod.md +45 -0
- package/src/modules/finance-ledger/docs/commands/CreateAccountingPeriod.md +69 -0
- package/src/modules/finance-ledger/docs/commands/CreateFiscalYear.md +56 -0
- package/src/modules/finance-ledger/docs/commands/CreateJournalEntry.md +63 -0
- package/src/modules/finance-ledger/docs/commands/DeleteAccountingPeriod.md +46 -0
- package/src/modules/finance-ledger/docs/commands/DeleteFiscalYear.md +40 -0
- package/src/modules/finance-ledger/docs/commands/DeleteJournalEntry.md +44 -0
- package/src/modules/finance-ledger/docs/commands/ExecuteYearEndClose.md +81 -0
- package/src/modules/finance-ledger/docs/commands/FinalCloseAndLockPeriod.md +49 -0
- package/src/modules/finance-ledger/docs/commands/FinalizeFinancialStatement.md +43 -0
- package/src/modules/finance-ledger/docs/commands/GenerateFinancialStatement.md +86 -0
- package/src/modules/finance-ledger/docs/commands/GeneratePreliminaryStatements.md +53 -0
- package/src/modules/finance-ledger/docs/commands/GenerateTrialBalance.md +75 -0
- package/src/modules/finance-ledger/docs/commands/InitiatePeriodClose.md +58 -0
- package/src/modules/finance-ledger/docs/commands/OpenForAdvanceEntry.md +44 -0
- package/src/modules/finance-ledger/docs/commands/OpenPeriod.md +45 -0
- package/src/modules/finance-ledger/docs/commands/PermanentlyClosePeriod.md +45 -0
- package/src/modules/finance-ledger/docs/commands/PostAdjustingEntries.md +61 -0
- package/src/modules/finance-ledger/docs/commands/PostJournalEntry.md +81 -0
- package/src/modules/finance-ledger/docs/commands/ProcessInventoryHandoff.md +72 -0
- package/src/modules/finance-ledger/docs/commands/ProcessManufacturingHandoff.md +68 -0
- package/src/modules/finance-ledger/docs/commands/ProcessPurchaseHandoff.md +68 -0
- package/src/modules/finance-ledger/docs/commands/ProcessSalesHandoff.md +71 -0
- package/src/modules/finance-ledger/docs/commands/RegenerateFinancialStatement.md +60 -0
- package/src/modules/finance-ledger/docs/commands/RemoveJournalLine.md +42 -0
- package/src/modules/finance-ledger/docs/commands/ReopenPeriod.md +45 -0
- package/src/modules/finance-ledger/docs/commands/ReverseJournalEntry.md +62 -0
- package/src/modules/finance-ledger/docs/commands/RevertSoftLock.md +49 -0
- package/src/modules/finance-ledger/docs/commands/UpdateFiscalYear.md +60 -0
- package/src/modules/finance-ledger/docs/commands/UpdateJournalEntry.md +50 -0
- package/src/modules/finance-ledger/docs/commands/UpdateJournalLine.md +61 -0
- package/src/modules/finance-ledger/docs/commands/VerifySubledgerTransfers.md +59 -0
- package/src/modules/finance-ledger/docs/commands/VerifyTrialBalance.md +53 -0
- package/src/modules/finance-ledger/docs/features/accounting-period-management.md +110 -0
- package/src/modules/finance-ledger/docs/features/financial-statement-generation.md +115 -0
- package/src/modules/finance-ledger/docs/features/journal-entry-management.md +138 -0
- package/src/modules/finance-ledger/docs/features/period-end-close.md +102 -0
- package/src/modules/finance-ledger/docs/features/subledger-integration.md +141 -0
- package/src/modules/finance-ledger/docs/features/trial-balance.md +99 -0
- package/src/modules/finance-ledger/docs/features/year-end-close.md +84 -0
- package/src/modules/finance-ledger/docs/models/AccountingPeriod.md +71 -0
- package/src/modules/finance-ledger/docs/models/FinancialStatement.md +76 -0
- package/src/modules/finance-ledger/docs/models/FinancialStatementLineItem.md +41 -0
- package/src/modules/finance-ledger/docs/models/FiscalYear.md +41 -0
- package/src/modules/finance-ledger/docs/models/JournalEntry.md +80 -0
- package/src/modules/finance-ledger/docs/models/JournalLine.md +47 -0
- package/src/modules/finance-ledger/docs/models/PeriodClose.md +83 -0
- package/src/modules/finance-ledger/docs/models/TrialBalance.md +56 -0
- package/src/modules/finance-ledger/docs/models/TrialBalanceLine.md +37 -0
- package/src/modules/finance-ledger/docs/queries/GetAccountingPeriod.md +35 -0
- package/src/modules/finance-ledger/docs/queries/GetFinancialStatement.md +38 -0
- package/src/modules/finance-ledger/docs/queries/GetFiscalYear.md +35 -0
- package/src/modules/finance-ledger/docs/queries/GetJournalEntry.md +37 -0
- package/src/modules/finance-ledger/docs/queries/GetPeriodByDate.md +38 -0
- package/src/modules/finance-ledger/docs/queries/GetPeriodClose.md +36 -0
- package/src/modules/finance-ledger/docs/queries/GetSubledgerTransferStatus.md +45 -0
- package/src/modules/finance-ledger/docs/queries/GetTrialBalance.md +38 -0
- package/src/modules/finance-ledger/docs/queries/ListAccountingPeriods.md +46 -0
- package/src/modules/finance-ledger/docs/queries/ListFinancialStatements.md +46 -0
- package/src/modules/finance-ledger/docs/queries/ListFiscalYears.md +42 -0
- package/src/modules/finance-ledger/docs/queries/ListJournalEntries.md +48 -0
- package/src/modules/finance-ledger/docs/queries/ListPeriodCloses.md +46 -0
- package/src/modules/finance-ledger/docs/queries/ListTrialBalances.md +51 -0
- package/src/modules/finance-ledger/executor/.gitkeep +0 -0
- package/src/modules/finance-ledger/generated/enums.ts +109 -0
- package/src/modules/finance-ledger/generated/kysely-tailordb.ts +202 -0
- package/src/modules/finance-ledger/index.ts +2 -0
- package/src/modules/finance-ledger/lib/_db_deps.ts +56 -0
- package/src/modules/finance-ledger/lib/errors.generated.ts +332 -0
- package/src/modules/finance-ledger/lib/permissions.generated.ts +41 -0
- package/src/modules/finance-ledger/lib/types.ts +66 -0
- package/src/modules/finance-ledger/module.ts +262 -0
- package/src/modules/finance-ledger/package.json +26 -0
- package/src/modules/finance-ledger/permissions.ts +3 -0
- package/src/modules/finance-ledger/query/.gitkeep +0 -0
- package/src/modules/finance-ledger/query/getAccountingPeriod.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getAccountingPeriod.test.ts +31 -0
- package/src/modules/finance-ledger/query/getAccountingPeriod.ts +21 -0
- package/src/modules/finance-ledger/query/getFinancialStatement.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getFinancialStatement.test.ts +35 -0
- package/src/modules/finance-ledger/query/getFinancialStatement.ts +29 -0
- package/src/modules/finance-ledger/query/getFiscalYear.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getFiscalYear.test.ts +31 -0
- package/src/modules/finance-ledger/query/getFiscalYear.ts +21 -0
- package/src/modules/finance-ledger/query/getJournalEntry.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getJournalEntry.test.ts +35 -0
- package/src/modules/finance-ledger/query/getJournalEntry.ts +29 -0
- package/src/modules/finance-ledger/query/getPeriodByDate.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getPeriodByDate.test.ts +53 -0
- package/src/modules/finance-ledger/query/getPeriodByDate.ts +27 -0
- package/src/modules/finance-ledger/query/getPeriodClose.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getPeriodClose.test.ts +31 -0
- package/src/modules/finance-ledger/query/getPeriodClose.ts +21 -0
- package/src/modules/finance-ledger/query/getSubledgerTransferStatus.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getSubledgerTransferStatus.test.ts +101 -0
- package/src/modules/finance-ledger/query/getSubledgerTransferStatus.ts +68 -0
- package/src/modules/finance-ledger/query/getTrialBalance.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getTrialBalance.test.ts +33 -0
- package/src/modules/finance-ledger/query/getTrialBalance.ts +30 -0
- package/src/modules/finance-ledger/query/listAccountingPeriods.generated.ts +5 -0
- package/src/modules/finance-ledger/query/listAccountingPeriods.test.ts +81 -0
- package/src/modules/finance-ledger/query/listAccountingPeriods.ts +61 -0
- package/src/modules/finance-ledger/query/listFinancialStatements.generated.ts +5 -0
- package/src/modules/finance-ledger/query/listFinancialStatements.test.ts +76 -0
- package/src/modules/finance-ledger/query/listFinancialStatements.ts +62 -0
- package/src/modules/finance-ledger/query/listFiscalYears.generated.ts +5 -0
- package/src/modules/finance-ledger/query/listFiscalYears.test.ts +63 -0
- package/src/modules/finance-ledger/query/listFiscalYears.ts +45 -0
- package/src/modules/finance-ledger/query/listJournalEntries.generated.ts +5 -0
- package/src/modules/finance-ledger/query/listJournalEntries.test.ts +91 -0
- package/src/modules/finance-ledger/query/listJournalEntries.ts +64 -0
- package/src/modules/finance-ledger/query/listPeriodCloses.generated.ts +5 -0
- package/src/modules/finance-ledger/query/listPeriodCloses.test.ts +63 -0
- package/src/modules/finance-ledger/query/listPeriodCloses.ts +64 -0
- package/src/modules/finance-ledger/query/listTrialBalances.generated.ts +5 -0
- package/src/modules/finance-ledger/query/listTrialBalances.test.ts +78 -0
- package/src/modules/finance-ledger/query/listTrialBalances.ts +56 -0
- package/src/modules/finance-ledger/seed/index.ts +19 -0
- package/src/modules/finance-ledger/tailor.config.ts +13 -0
- package/src/modules/finance-ledger/tailor.d.ts +13 -0
- package/src/modules/finance-ledger/testing/commandTestUtils.ts +35 -0
- package/src/modules/finance-ledger/testing/fixtures.ts +382 -0
- package/src/modules/finance-ledger/tsconfig.json +16 -0
- package/src/progress/schema.test.ts +161 -0
- package/src/progress/schema.ts +316 -0
- package/templates/scaffold/app/backend/package.json +1 -3
- package/templates/scaffold/app/backend/vitest.config.ts +4 -21
- package/src/generator/generate-stubs.ts +0 -35
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { execFileSync } from "node:child_process";
|
|
5
|
+
import { describe, it, expect, vi, afterEach } from "vitest";
|
|
6
|
+
import { runProgressLog } from "./log";
|
|
7
|
+
import { runProgressSchema } from "./schema-cmd";
|
|
8
|
+
|
|
9
|
+
function makeTmpApp(): string {
|
|
10
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "progress-test-"));
|
|
11
|
+
execFileSync("git", ["init"], { cwd: dir });
|
|
12
|
+
execFileSync("git", ["config", "user.email", "test@test.com"], { cwd: dir });
|
|
13
|
+
execFileSync("git", ["config", "user.name", "test"], { cwd: dir });
|
|
14
|
+
execFileSync("git", ["commit", "--allow-empty", "-m", "init"], { cwd: dir });
|
|
15
|
+
return dir;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe("runProgressLog", () => {
|
|
19
|
+
let tmpDir: string;
|
|
20
|
+
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
if (tmpDir) {
|
|
23
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("creates .erp-kit/progress.jsonl and appends a valid entry", () => {
|
|
28
|
+
tmpDir = makeTmpApp();
|
|
29
|
+
const input = JSON.stringify({
|
|
30
|
+
v: 1,
|
|
31
|
+
sessionId: "s1",
|
|
32
|
+
prompt: "test prompt",
|
|
33
|
+
event: "note",
|
|
34
|
+
data: { message: "test", tags: [] },
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const result = runProgressLog(input, false, tmpDir);
|
|
38
|
+
expect(result.exitCode).toBe(0);
|
|
39
|
+
|
|
40
|
+
const logFile = path.join(tmpDir, ".erp-kit", "progress.jsonl");
|
|
41
|
+
expect(fs.existsSync(logFile)).toBe(true);
|
|
42
|
+
|
|
43
|
+
const lines = fs.readFileSync(logFile, "utf-8").trim().split("\n");
|
|
44
|
+
expect(lines).toHaveLength(1);
|
|
45
|
+
|
|
46
|
+
const entry = JSON.parse(lines[0]) as Record<string, unknown>;
|
|
47
|
+
expect(entry.sessionId).toBe("s1");
|
|
48
|
+
expect(entry.timestamp).toBeDefined();
|
|
49
|
+
expect(entry.git).toBeDefined();
|
|
50
|
+
expect(entry.conversation).toEqual([]);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("appends multiple entries", () => {
|
|
54
|
+
tmpDir = makeTmpApp();
|
|
55
|
+
const input1 = JSON.stringify({
|
|
56
|
+
v: 1,
|
|
57
|
+
sessionId: "s1",
|
|
58
|
+
prompt: "test prompt",
|
|
59
|
+
event: "note",
|
|
60
|
+
data: { message: "first", tags: [] },
|
|
61
|
+
});
|
|
62
|
+
const input2 = JSON.stringify({
|
|
63
|
+
v: 1,
|
|
64
|
+
sessionId: "s1",
|
|
65
|
+
prompt: "test prompt",
|
|
66
|
+
event: "note",
|
|
67
|
+
data: { message: "second", tags: [] },
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
runProgressLog(input1, false, tmpDir);
|
|
71
|
+
runProgressLog(input2, false, tmpDir);
|
|
72
|
+
|
|
73
|
+
const logFile = path.join(tmpDir, ".erp-kit", "progress.jsonl");
|
|
74
|
+
const lines = fs.readFileSync(logFile, "utf-8").trim().split("\n");
|
|
75
|
+
expect(lines).toHaveLength(2);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("rejects invalid JSON", () => {
|
|
79
|
+
tmpDir = makeTmpApp();
|
|
80
|
+
const result = runProgressLog("not json", false, tmpDir);
|
|
81
|
+
expect(result.exitCode).toBe(1);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("rejects invalid schema (missing prompt)", () => {
|
|
85
|
+
tmpDir = makeTmpApp();
|
|
86
|
+
const input = JSON.stringify({
|
|
87
|
+
v: 1,
|
|
88
|
+
sessionId: "s1",
|
|
89
|
+
event: "note",
|
|
90
|
+
data: { message: "x", tags: [] },
|
|
91
|
+
});
|
|
92
|
+
const result = runProgressLog(input, false, tmpDir);
|
|
93
|
+
expect(result.exitCode).toBe(1);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("dry-run does not write to file", () => {
|
|
97
|
+
tmpDir = makeTmpApp();
|
|
98
|
+
const input = JSON.stringify({
|
|
99
|
+
v: 1,
|
|
100
|
+
sessionId: "s1",
|
|
101
|
+
prompt: "test prompt",
|
|
102
|
+
event: "note",
|
|
103
|
+
data: { message: "test", tags: [] },
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const result = runProgressLog(input, true, tmpDir);
|
|
107
|
+
expect(result.exitCode).toBe(0);
|
|
108
|
+
|
|
109
|
+
const logFile = path.join(tmpDir, ".erp-kit", "progress.jsonl");
|
|
110
|
+
expect(fs.existsSync(logFile)).toBe(false);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe("runProgressSchema", () => {
|
|
115
|
+
it("outputs valid JSON Schema", () => {
|
|
116
|
+
const spy = vi.spyOn(console, "log").mockImplementation(() => undefined);
|
|
117
|
+
|
|
118
|
+
const result = runProgressSchema();
|
|
119
|
+
|
|
120
|
+
expect(result.exitCode).toBe(0);
|
|
121
|
+
expect(spy).toHaveBeenCalledOnce();
|
|
122
|
+
|
|
123
|
+
const schema = JSON.parse(String(spy.mock.calls[0]?.[0])) as Record<string, unknown>;
|
|
124
|
+
expect(schema).toHaveProperty("anyOf");
|
|
125
|
+
|
|
126
|
+
spy.mockRestore();
|
|
127
|
+
});
|
|
128
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ProgressInput } from "../../../progress/schema";
|
|
3
|
+
import type { CommandResult } from "../../lib/command-result";
|
|
4
|
+
import { success } from "../../lib/command-result";
|
|
5
|
+
|
|
6
|
+
export function runProgressSchema(): CommandResult {
|
|
7
|
+
const jsonSchema = z.toJSONSchema(ProgressInput);
|
|
8
|
+
console.log(JSON.stringify(jsonSchema, null, 2));
|
|
9
|
+
return success();
|
|
10
|
+
}
|
|
@@ -13,14 +13,14 @@ describe("buildCheckTargets", () => {
|
|
|
13
13
|
]);
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
it("generates app targets when appRoot is set", () => {
|
|
17
|
-
const targets = buildCheckTargets({ modulesRoot: undefined, appRoot: "apps" });
|
|
18
|
-
expect(targets[0].glob).toBe("apps/
|
|
16
|
+
it("generates app-compose targets when appRoot is set", () => {
|
|
17
|
+
const targets = buildCheckTargets({ modulesRoot: undefined, appRoot: "apps/myapp" });
|
|
18
|
+
expect(targets[0].glob).toBe("apps/myapp/README.md");
|
|
19
19
|
expect(targets).toHaveLength(6);
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
it("generates both when both roots are set", () => {
|
|
23
|
-
const targets = buildCheckTargets({ modulesRoot: "modules", appRoot: "examples" });
|
|
23
|
+
const targets = buildCheckTargets({ modulesRoot: "modules", appRoot: "examples/app1" });
|
|
24
24
|
expect(targets).toHaveLength(11);
|
|
25
25
|
});
|
|
26
26
|
|
|
@@ -29,10 +29,10 @@ describe("moduleCategories", () => {
|
|
|
29
29
|
|
|
30
30
|
describe("appComposeCategories", () => {
|
|
31
31
|
it("produces resolver category", () => {
|
|
32
|
-
const cats = appComposeCategories("apps");
|
|
32
|
+
const cats = appComposeCategories("apps/myapp");
|
|
33
33
|
expect(cats).toHaveLength(1);
|
|
34
34
|
expect(cats[0].name).toBe("resolver");
|
|
35
|
-
expect(cats[0].docPattern).toBe("apps
|
|
35
|
+
expect(cats[0].docPattern).toBe("apps/myapp/docs/resolver/*.md");
|
|
36
36
|
});
|
|
37
37
|
});
|
|
38
38
|
|
|
@@ -69,16 +69,14 @@ describe("buildCheckTargets", () => {
|
|
|
69
69
|
});
|
|
70
70
|
|
|
71
71
|
it("builds app check targets", () => {
|
|
72
|
-
const targets = buildCheckTargets({ appRoot: "apps" });
|
|
72
|
+
const targets = buildCheckTargets({ appRoot: "apps/myapp" });
|
|
73
73
|
expect(targets).toHaveLength(6);
|
|
74
74
|
expect(targets.map((t) => t.schemaKey)).toContain("screen");
|
|
75
|
-
expect(targets.find((t) => t.schemaKey === "screen")!.glob).toBe(
|
|
76
|
-
"apps/[a-zA-Z]*/docs/screen/*.md",
|
|
77
|
-
);
|
|
75
|
+
expect(targets.find((t) => t.schemaKey === "screen")!.glob).toBe("apps/myapp/docs/screen/*.md");
|
|
78
76
|
});
|
|
79
77
|
|
|
80
78
|
it("builds both when both roots provided", () => {
|
|
81
|
-
const targets = buildCheckTargets({ modulesRoot: "modules", appRoot: "apps" });
|
|
79
|
+
const targets = buildCheckTargets({ modulesRoot: "modules", appRoot: "apps/myapp" });
|
|
82
80
|
expect(targets).toHaveLength(11);
|
|
83
81
|
});
|
|
84
82
|
});
|
|
@@ -45,8 +45,8 @@ export function appComposeCategories(root: string): CategoryConfig[] {
|
|
|
45
45
|
return [
|
|
46
46
|
{
|
|
47
47
|
name: "resolver",
|
|
48
|
-
sourcePattern: `${root}
|
|
49
|
-
docPattern: `${root}
|
|
48
|
+
sourcePattern: `${root}/backend/src/resolvers/*.ts`,
|
|
49
|
+
docPattern: `${root}/${APP_PATHS.docs.resolver}/*.md`,
|
|
50
50
|
exclusions: [/\.test\.ts$/, /^index\.ts$/],
|
|
51
51
|
},
|
|
52
52
|
];
|
|
@@ -95,18 +95,18 @@ export function buildCheckTargets(config: {
|
|
|
95
95
|
if (config.appRoot) {
|
|
96
96
|
const a = config.appRoot;
|
|
97
97
|
targets.push(
|
|
98
|
-
{ glob: `${a}/
|
|
99
|
-
{ glob: `${a}
|
|
98
|
+
{ glob: `${a}/README.md`, schemaKey: "app" },
|
|
99
|
+
{ glob: `${a}/${APP_PATHS.docs.actors}/*.md`, schemaKey: "actors" },
|
|
100
100
|
{
|
|
101
|
-
glob: `${a}
|
|
101
|
+
glob: `${a}/${APP_PATHS.docs.businessFlow}/*/README.md`,
|
|
102
102
|
schemaKey: "business-flow",
|
|
103
103
|
},
|
|
104
104
|
{
|
|
105
|
-
glob: `${a}
|
|
105
|
+
glob: `${a}/${APP_PATHS.docs.businessFlow}/*/${APP_PATHS.docs.story}/*.md`,
|
|
106
106
|
schemaKey: "story",
|
|
107
107
|
},
|
|
108
|
-
{ glob: `${a}
|
|
109
|
-
{ glob: `${a}
|
|
108
|
+
{ glob: `${a}/${APP_PATHS.docs.screen}/*.md`, schemaKey: "screen" },
|
|
109
|
+
{ glob: `${a}/${APP_PATHS.docs.resolver}/*.md`, schemaKey: "resolver" },
|
|
110
110
|
);
|
|
111
111
|
}
|
|
112
112
|
|
|
@@ -104,7 +104,7 @@ describe("runSourceSyncCheck", () => {
|
|
|
104
104
|
fs.writeFileSync(path.join(srcDir, "myResolver.ts"), "export {}");
|
|
105
105
|
fs.writeFileSync(path.join(docDir, "myResolver.md"), "# MyResolver");
|
|
106
106
|
|
|
107
|
-
const result = await runSourceSyncCheck({ appRoot: "apps" }, tmpDir);
|
|
107
|
+
const result = await runSourceSyncCheck({ appRoot: "apps/app1" }, tmpDir);
|
|
108
108
|
expect(result.exitCode).toBe(0);
|
|
109
109
|
expect(result.summary.totalSources).toBe(1);
|
|
110
110
|
});
|
|
@@ -3,7 +3,12 @@ import fg from "fast-glob";
|
|
|
3
3
|
import { moduleCategories, appComposeCategories, type CategoryConfig } from "./discovery";
|
|
4
4
|
|
|
5
5
|
export interface CheckError {
|
|
6
|
-
type:
|
|
6
|
+
type:
|
|
7
|
+
| "missing-doc"
|
|
8
|
+
| "orphaned-doc"
|
|
9
|
+
| "missing-test-case"
|
|
10
|
+
| "extra-test-case"
|
|
11
|
+
| "missing-test-file";
|
|
7
12
|
category: string;
|
|
8
13
|
sourcePath?: string;
|
|
9
14
|
docPath?: string;
|
|
@@ -153,6 +153,29 @@ describe("runModuleTestCaseSyncCheck", () => {
|
|
|
153
153
|
expect(tcErrors).toHaveLength(0);
|
|
154
154
|
});
|
|
155
155
|
|
|
156
|
+
it("reports missing-test-file when test file does not exist", async () => {
|
|
157
|
+
const docDir = path.join(tmpDir, "modules", "foo", "docs", "commands");
|
|
158
|
+
const testDir = path.join(tmpDir, "modules", "foo", "command");
|
|
159
|
+
fs.mkdirSync(docDir, { recursive: true });
|
|
160
|
+
fs.mkdirSync(testDir, { recursive: true });
|
|
161
|
+
|
|
162
|
+
fs.writeFileSync(
|
|
163
|
+
path.join(docDir, "CreateOrder.md"),
|
|
164
|
+
"# CreateOrder\n\n## Test Cases\n\n- creates order\n- validates input\n",
|
|
165
|
+
);
|
|
166
|
+
fs.writeFileSync(path.join(testDir, "createOrder.ts"), "export {}");
|
|
167
|
+
// No createOrder.test.ts file
|
|
168
|
+
|
|
169
|
+
const errors = await runModuleTestCaseSyncCheck("modules", tmpDir);
|
|
170
|
+
expect(errors).toContainEqual(
|
|
171
|
+
expect.objectContaining({
|
|
172
|
+
type: "missing-test-file",
|
|
173
|
+
category: "command-test-case",
|
|
174
|
+
expectedBasename: "createOrder.test.ts",
|
|
175
|
+
}),
|
|
176
|
+
);
|
|
177
|
+
});
|
|
178
|
+
|
|
156
179
|
it("skips test-case check when doc has no Test Cases section", async () => {
|
|
157
180
|
const docDir = path.join(tmpDir, "modules", "foo", "docs", "commands");
|
|
158
181
|
const testDir = path.join(tmpDir, "modules", "foo", "command");
|
|
@@ -243,6 +266,26 @@ describe("runAppTestCaseSyncCheck", () => {
|
|
|
243
266
|
expect(errors).toHaveLength(0);
|
|
244
267
|
});
|
|
245
268
|
|
|
269
|
+
it("reports missing-test-file when story test file does not exist", async () => {
|
|
270
|
+
const flow = "item-lifecycle";
|
|
271
|
+
const storyDir = path.join(tmpDir, "apps", "my-app", "docs", "business-flow", flow, "story");
|
|
272
|
+
fs.mkdirSync(storyDir, { recursive: true });
|
|
273
|
+
// No test file created
|
|
274
|
+
fs.writeFileSync(
|
|
275
|
+
path.join(storyDir, "admin--create-item.md"),
|
|
276
|
+
"# Create Item\n\n## Test Cases\n\n- creates item\n- validates input\n",
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
const errors = await runAppTestCaseSyncCheck("apps", tmpDir);
|
|
280
|
+
expect(errors).toContainEqual(
|
|
281
|
+
expect.objectContaining({
|
|
282
|
+
type: "missing-test-file",
|
|
283
|
+
category: "story-test-case",
|
|
284
|
+
expectedBasename: "admin--create-item.test.ts",
|
|
285
|
+
}),
|
|
286
|
+
);
|
|
287
|
+
});
|
|
288
|
+
|
|
246
289
|
it("skips when story doc has no Test Cases section", async () => {
|
|
247
290
|
setupStoryFixture(
|
|
248
291
|
"admin--view-items",
|
|
@@ -31,7 +31,16 @@ export async function runModuleTestCaseSyncCheck(root: string, cwd: string): Pro
|
|
|
31
31
|
const testPath = path.join(modulePath, category.testDir, testFileName);
|
|
32
32
|
const testFullPath = path.join(cwd, testPath);
|
|
33
33
|
|
|
34
|
-
if (!fs.existsSync(testFullPath))
|
|
34
|
+
if (!fs.existsSync(testFullPath)) {
|
|
35
|
+
errors.push({
|
|
36
|
+
type: "missing-test-file",
|
|
37
|
+
category: category.name,
|
|
38
|
+
docPath,
|
|
39
|
+
sourcePath: testPath,
|
|
40
|
+
expectedBasename: testFileName,
|
|
41
|
+
});
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
35
44
|
|
|
36
45
|
const testContent = fs.readFileSync(testFullPath, "utf-8");
|
|
37
46
|
const itDescriptions = parseItDescriptionsFromTest(testContent);
|
|
@@ -92,7 +101,16 @@ export async function runAppTestCaseSyncCheck(appRoot: string, cwd: string): Pro
|
|
|
92
101
|
if (!testPath) continue;
|
|
93
102
|
|
|
94
103
|
const testFullPath = path.join(cwd, testPath);
|
|
95
|
-
if (!fs.existsSync(testFullPath))
|
|
104
|
+
if (!fs.existsSync(testFullPath)) {
|
|
105
|
+
errors.push({
|
|
106
|
+
type: "missing-test-file",
|
|
107
|
+
category: config.name,
|
|
108
|
+
docPath,
|
|
109
|
+
sourcePath: testPath,
|
|
110
|
+
expectedBasename: path.basename(testPath),
|
|
111
|
+
});
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
96
114
|
|
|
97
115
|
const testContent = fs.readFileSync(testFullPath, "utf-8");
|
|
98
116
|
const itDescriptions = parseItDescriptionsFromTest(testContent);
|
|
@@ -54,6 +54,9 @@ export function formatSyncCheckReport(result: SyncCheckResult): string {
|
|
|
54
54
|
lines.push(
|
|
55
55
|
` ${chalk.yellow("Extra test case:")} "${error.expectedBasename}" is in test but not in doc`,
|
|
56
56
|
);
|
|
57
|
+
} else if (error.type === "missing-test-file") {
|
|
58
|
+
lines.push(` ${chalk.red(error.docPath)}`);
|
|
59
|
+
lines.push(` ${chalk.yellow("Missing test file:")} ${error.expectedBasename}`);
|
|
57
60
|
}
|
|
58
61
|
lines.push("");
|
|
59
62
|
}
|
|
@@ -62,9 +62,7 @@ Gets profile.
|
|
|
62
62
|
|
|
63
63
|
const files = fs.readdirSync(resolverDir).sort();
|
|
64
64
|
// Template scaffolding may copy additional files (e.g. createUser.ts)
|
|
65
|
-
expect(files).toContain("createItem.test.ts");
|
|
66
65
|
expect(files).toContain("createItem.ts");
|
|
67
|
-
expect(files).toContain("getMyProfile.test.ts");
|
|
68
66
|
expect(files).toContain("getMyProfile.ts");
|
|
69
67
|
expect(files).not.toContain("createItem.generated.ts");
|
|
70
68
|
|
|
@@ -73,10 +71,6 @@ Gets profile.
|
|
|
73
71
|
expect(stub).toContain("createResolver");
|
|
74
72
|
expect(stub).toContain('name: "createItem"');
|
|
75
73
|
expect(stub).toContain('getDB("main-db")');
|
|
76
|
-
|
|
77
|
-
// Test stub exists
|
|
78
|
-
const test = fs.readFileSync(path.join(resolverDir, "createItem.test.ts"), "utf-8");
|
|
79
|
-
expect(test).toContain('describe("createItem"');
|
|
80
74
|
});
|
|
81
75
|
|
|
82
76
|
it("does not overwrite existing stubs on re-run", () => {
|
|
@@ -3,11 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import { parseTestCasesFromDoc } from "../commands/parse-doc-test-cases";
|
|
4
4
|
import { APP_PATHS } from "../commands/lib/paths";
|
|
5
5
|
import { parseResolverDoc } from "./parse-resolver-doc";
|
|
6
|
-
import {
|
|
7
|
-
generateResolverStub,
|
|
8
|
-
generateResolverTestStub,
|
|
9
|
-
generateStoryTestStub,
|
|
10
|
-
} from "./generate-stubs";
|
|
6
|
+
import { renderStub } from "./stub-templates";
|
|
11
7
|
import { scaffoldAppBoilerplate } from "./scaffold";
|
|
12
8
|
|
|
13
9
|
export function runGenerateAppCode(appPath: string): number {
|
|
@@ -38,16 +34,10 @@ function generateResolverStubs(appPath: string, appName: string): void {
|
|
|
38
34
|
|
|
39
35
|
const implFile = path.join(resolverDir, `${doc.resolverName}.ts`);
|
|
40
36
|
if (!fs.existsSync(implFile)) {
|
|
41
|
-
fs.writeFileSync(implFile,
|
|
37
|
+
fs.writeFileSync(implFile, renderStub("resolver", doc.resolverName));
|
|
42
38
|
console.log(` scaffolded ${path.relative(appPath, implFile)}`);
|
|
43
39
|
generated++;
|
|
44
40
|
}
|
|
45
|
-
|
|
46
|
-
const testFile = path.join(resolverDir, `${doc.resolverName}.test.ts`);
|
|
47
|
-
if (!fs.existsSync(testFile)) {
|
|
48
|
-
fs.writeFileSync(testFile, generateResolverTestStub(doc.resolverName));
|
|
49
|
-
console.log(` scaffolded ${path.relative(appPath, testFile)}`);
|
|
50
|
-
}
|
|
51
41
|
}
|
|
52
42
|
|
|
53
43
|
if (generated > 0) {
|
|
@@ -75,7 +65,7 @@ function generateStoryTestStubs(appPath: string, appName: string): void {
|
|
|
75
65
|
if (fs.existsSync(testFile)) continue;
|
|
76
66
|
|
|
77
67
|
fs.mkdirSync(testDir, { recursive: true });
|
|
78
|
-
fs.writeFileSync(testFile,
|
|
68
|
+
fs.writeFileSync(testFile, renderStub("storyTest", storyName, testCases));
|
|
79
69
|
console.log(` scaffolded ${path.relative(appPath, testFile)}`);
|
|
80
70
|
generated++;
|
|
81
71
|
}
|
|
@@ -2,13 +2,7 @@ import { describe, expect, it } from "vitest";
|
|
|
2
2
|
import { moduleNameToPrefix, generateErrors } from "./generate-errors";
|
|
3
3
|
import { generatePermissions } from "./generate-permissions";
|
|
4
4
|
import { generateCommandShell, generateQueryShell } from "./generate-shells";
|
|
5
|
-
import {
|
|
6
|
-
generateQueryStub,
|
|
7
|
-
generateQueryTestStub,
|
|
8
|
-
generateDbStub,
|
|
9
|
-
generateResolverStub,
|
|
10
|
-
generateResolverTestStub,
|
|
11
|
-
} from "./generate-stubs";
|
|
5
|
+
import { renderStub } from "./stub-templates";
|
|
12
6
|
import type { ParsedCommandDoc } from "./parse-command-doc";
|
|
13
7
|
|
|
14
8
|
describe("moduleNameToPrefix", () => {
|
|
@@ -174,15 +168,9 @@ describe("generateQueryShell", () => {
|
|
|
174
168
|
});
|
|
175
169
|
});
|
|
176
170
|
|
|
177
|
-
describe("
|
|
171
|
+
describe("renderStub query", () => {
|
|
178
172
|
it("generates a stub implementation with ReadonlyDB and input interface", () => {
|
|
179
|
-
const
|
|
180
|
-
commandName: "getTaxonomyNode",
|
|
181
|
-
errors: [],
|
|
182
|
-
externalDependencies: [],
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
const result = generateQueryStub(doc);
|
|
173
|
+
const result = renderStub("query", "getTaxonomyNode");
|
|
186
174
|
|
|
187
175
|
expect(result).toContain('import type { ReadonlyDB } from "@tailor-platform/erp-kit/module";');
|
|
188
176
|
expect(result).toContain('import type { DB } from "../generated/kysely-tailordb";');
|
|
@@ -194,9 +182,9 @@ describe("generateQueryStub", () => {
|
|
|
194
182
|
});
|
|
195
183
|
});
|
|
196
184
|
|
|
197
|
-
describe("
|
|
185
|
+
describe("renderStub db", () => {
|
|
198
186
|
it("generates an empty db type definition with TODO", () => {
|
|
199
|
-
const result =
|
|
187
|
+
const result = renderStub("db", "item");
|
|
200
188
|
|
|
201
189
|
expect(result).toContain(
|
|
202
190
|
"import { db, unsafeAllowAllGqlPermission, unsafeAllowAllTypePermission }",
|
|
@@ -210,22 +198,16 @@ describe("generateDbStub", () => {
|
|
|
210
198
|
});
|
|
211
199
|
|
|
212
200
|
it("handles camelCase model names", () => {
|
|
213
|
-
const result =
|
|
201
|
+
const result = renderStub("db", "taxonomyNode");
|
|
214
202
|
|
|
215
203
|
expect(result).toContain("export const taxonomyNode = db");
|
|
216
204
|
expect(result).toContain('.type("TaxonomyNode"');
|
|
217
205
|
});
|
|
218
206
|
});
|
|
219
207
|
|
|
220
|
-
describe("
|
|
208
|
+
describe("renderStub queryTest", () => {
|
|
221
209
|
it("generates a test stub with createMockDb and run import", () => {
|
|
222
|
-
const
|
|
223
|
-
commandName: "getTaxonomyNode",
|
|
224
|
-
errors: [],
|
|
225
|
-
externalDependencies: [],
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
const result = generateQueryTestStub(doc);
|
|
210
|
+
const result = renderStub("queryTest", "getTaxonomyNode");
|
|
229
211
|
|
|
230
212
|
expect(result).toContain('import { describe, expect, it } from "vitest";');
|
|
231
213
|
expect(result).toContain('import { createMockDb } from "../../../testing/index";');
|
|
@@ -238,9 +220,9 @@ describe("generateQueryTestStub", () => {
|
|
|
238
220
|
});
|
|
239
221
|
});
|
|
240
222
|
|
|
241
|
-
describe("
|
|
223
|
+
describe("renderStub resolver", () => {
|
|
242
224
|
it("generates a createResolver stub with SDK imports and transaction boilerplate", () => {
|
|
243
|
-
const result =
|
|
225
|
+
const result = renderStub("resolver", "createItem");
|
|
244
226
|
|
|
245
227
|
expect(result).toContain('import { createResolver, t } from "@tailor-platform/sdk";');
|
|
246
228
|
expect(result).toContain('import { createContext } from "@tailor-platform/erp-kit/app";');
|
|
@@ -252,15 +234,3 @@ describe("generateResolverStub", () => {
|
|
|
252
234
|
expect(result).toContain('.description("CreateItem response")');
|
|
253
235
|
});
|
|
254
236
|
});
|
|
255
|
-
|
|
256
|
-
describe("generateResolverTestStub", () => {
|
|
257
|
-
it("generates a test that imports and verifies the resolver", () => {
|
|
258
|
-
const result = generateResolverTestStub("createItem");
|
|
259
|
-
|
|
260
|
-
expect(result).toContain('import { describe, expect, it } from "vitest";');
|
|
261
|
-
expect(result).toContain('describe("createItem"');
|
|
262
|
-
expect(result).toContain('import("./createItem")');
|
|
263
|
-
expect(result).toContain("expect(resolver.default).toBeDefined()");
|
|
264
|
-
expect(result).toContain('expect(resolver.default.name).toBe("createItem")');
|
|
265
|
-
});
|
|
266
|
-
});
|
|
@@ -4,13 +4,7 @@ import { parseCommandDoc, type ParsedCommandDoc } from "./parse-command-doc";
|
|
|
4
4
|
import { generateErrors } from "./generate-errors";
|
|
5
5
|
import { generatePermissions } from "./generate-permissions";
|
|
6
6
|
import { generateCommandShell, generateQueryShell } from "./generate-shells";
|
|
7
|
-
import {
|
|
8
|
-
generateCommandStub,
|
|
9
|
-
generateTestStub,
|
|
10
|
-
generateQueryStub,
|
|
11
|
-
generateQueryTestStub,
|
|
12
|
-
generateDbStub,
|
|
13
|
-
} from "./generate-stubs";
|
|
7
|
+
import { renderStub } from "./stub-templates";
|
|
14
8
|
import { scaffoldModuleBoilerplate } from "./scaffold";
|
|
15
9
|
|
|
16
10
|
export function runGenerateCode(modulePath: string, moduleName: string): number {
|
|
@@ -81,13 +75,13 @@ export function runGenerateCode(modulePath: string, moduleName: string): number
|
|
|
81
75
|
generated++;
|
|
82
76
|
|
|
83
77
|
if (!fs.existsSync(implFile)) {
|
|
84
|
-
fs.writeFileSync(implFile,
|
|
78
|
+
fs.writeFileSync(implFile, renderStub("command", doc.commandName));
|
|
85
79
|
console.log(` scaffolded ${path.relative(modulePath, implFile)}`);
|
|
86
80
|
}
|
|
87
81
|
|
|
88
82
|
const testFile = path.join(commandDir, `${doc.commandName}.test.ts`);
|
|
89
83
|
if (!fs.existsSync(testFile)) {
|
|
90
|
-
fs.writeFileSync(testFile,
|
|
84
|
+
fs.writeFileSync(testFile, renderStub("commandTest", doc.commandName));
|
|
91
85
|
console.log(` scaffolded ${path.relative(modulePath, testFile)}`);
|
|
92
86
|
}
|
|
93
87
|
}
|
|
@@ -111,13 +105,13 @@ export function runGenerateCode(modulePath: string, moduleName: string): number
|
|
|
111
105
|
|
|
112
106
|
const implFile = path.join(queryDir, `${doc.commandName}.ts`);
|
|
113
107
|
if (!fs.existsSync(implFile)) {
|
|
114
|
-
fs.writeFileSync(implFile,
|
|
108
|
+
fs.writeFileSync(implFile, renderStub("query", doc.commandName));
|
|
115
109
|
console.log(` scaffolded ${path.relative(modulePath, implFile)}`);
|
|
116
110
|
}
|
|
117
111
|
|
|
118
112
|
const testFile = path.join(queryDir, `${doc.commandName}.test.ts`);
|
|
119
113
|
if (!fs.existsSync(testFile)) {
|
|
120
|
-
fs.writeFileSync(testFile,
|
|
114
|
+
fs.writeFileSync(testFile, renderStub("queryTest", doc.commandName));
|
|
121
115
|
console.log(` scaffolded ${path.relative(modulePath, testFile)}`);
|
|
122
116
|
}
|
|
123
117
|
}
|
|
@@ -137,7 +131,7 @@ export function runGenerateCode(modulePath: string, moduleName: string): number
|
|
|
137
131
|
const camelName = modelName.charAt(0).toLowerCase() + modelName.slice(1);
|
|
138
132
|
const dbFile = path.join(dbDir, `${camelName}.ts`);
|
|
139
133
|
if (!fs.existsSync(dbFile)) {
|
|
140
|
-
fs.writeFileSync(dbFile,
|
|
134
|
+
fs.writeFileSync(dbFile, renderStub("db", camelName));
|
|
141
135
|
console.log(` scaffolded ${path.relative(modulePath, dbFile)}`);
|
|
142
136
|
}
|
|
143
137
|
}
|
|
@@ -46,13 +46,6 @@ describe("renderStub", () => {
|
|
|
46
46
|
expect(result).toContain('getDB("main-db")');
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
-
it("resolverTest: generates test that imports resolver", () => {
|
|
50
|
-
const result = renderStub("resolverTest", "createItem");
|
|
51
|
-
expect(result).toContain('describe("createItem"');
|
|
52
|
-
expect(result).toContain('import("./createItem")');
|
|
53
|
-
expect(result).toContain("resolver.default");
|
|
54
|
-
});
|
|
55
|
-
|
|
56
49
|
it("storyTest: generates integration test with graphql client and test cases", () => {
|
|
57
50
|
const result = renderStub("storyTest", "admin--create-item", [
|
|
58
51
|
"creates item successfully",
|
|
@@ -119,20 +119,6 @@ export default createResolver({
|
|
|
119
119
|
})
|
|
120
120
|
.description("${toPascal(name)} response"),
|
|
121
121
|
});
|
|
122
|
-
`;
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
resolverTest: {
|
|
126
|
-
render: (name: string) => {
|
|
127
|
-
return `import { describe, expect, it } from "vitest";
|
|
128
|
-
|
|
129
|
-
describe("${name}", () => {
|
|
130
|
-
it("should be implemented", async () => {
|
|
131
|
-
const resolver = await import("./${name}");
|
|
132
|
-
expect(resolver.default).toBeDefined();
|
|
133
|
-
expect(resolver.default.name).toBe("${name}");
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
122
|
`;
|
|
137
123
|
},
|
|
138
124
|
},
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# README
|
|
2
|
+
|
|
3
|
+
<!-- This section should contain the following subsections in order: -->
|
|
4
|
+
<!-- 1. ## Overview (required) -->
|
|
5
|
+
<!-- 2. ## Key Features (required) -->
|
|
6
|
+
<!-- 3. ## Module Scope (required) -->
|
|
7
|
+
<!-- 4. ## Module Dependencies (required) -->
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
## Key Features
|
|
12
|
+
|
|
13
|
+
<!-- List requirements: -->
|
|
14
|
+
<!-- Minimum 1 unordered lists required -->
|
|
15
|
+
<!-- Minimum 1 items per list -->
|
|
16
|
+
|
|
17
|
+
- TODO: Add list item
|
|
18
|
+
|
|
19
|
+
## Module Scope
|
|
20
|
+
|
|
21
|
+
<!-- This section should contain the following subsections in order: -->
|
|
22
|
+
<!-- 1. ### In Scope (required) -->
|
|
23
|
+
<!-- 2. ### Out of Scope (required) -->
|
|
24
|
+
<!-- 3. ### Scope Decision Rationale (required) -->
|
|
25
|
+
|
|
26
|
+
### In Scope
|
|
27
|
+
|
|
28
|
+
<!-- List requirements: -->
|
|
29
|
+
<!-- Minimum 1 unordered lists required -->
|
|
30
|
+
<!-- Minimum 1 items per list -->
|
|
31
|
+
|
|
32
|
+
- TODO: Add list item
|
|
33
|
+
|
|
34
|
+
### Out of Scope
|
|
35
|
+
|
|
36
|
+
<!-- List requirements: -->
|
|
37
|
+
<!-- Minimum 1 unordered lists required -->
|
|
38
|
+
<!-- Minimum 1 items per list -->
|
|
39
|
+
|
|
40
|
+
- TODO: Add list item
|
|
41
|
+
|
|
42
|
+
### Scope Decision Rationale
|
|
43
|
+
|
|
44
|
+
<!-- Explain why capabilities are in-scope or out-of-scope — domain alignment, separation of concerns, etc. -->
|
|
45
|
+
|
|
46
|
+
## Module Dependencies
|
|
47
|
+
|
|
48
|
+
<!-- List requirements: -->
|
|
49
|
+
<!-- Minimum 1 items per list -->
|
|
50
|
+
|
|
File without changes
|