solokit 0.1.1__py3-none-any.whl
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.
- solokit/__init__.py +10 -0
- solokit/__version__.py +3 -0
- solokit/cli.py +374 -0
- solokit/core/__init__.py +1 -0
- solokit/core/cache.py +102 -0
- solokit/core/command_runner.py +278 -0
- solokit/core/config.py +453 -0
- solokit/core/config_validator.py +204 -0
- solokit/core/constants.py +291 -0
- solokit/core/error_formatter.py +279 -0
- solokit/core/error_handlers.py +346 -0
- solokit/core/exceptions.py +1567 -0
- solokit/core/file_ops.py +309 -0
- solokit/core/logging_config.py +166 -0
- solokit/core/output.py +99 -0
- solokit/core/performance.py +57 -0
- solokit/core/protocols.py +141 -0
- solokit/core/types.py +312 -0
- solokit/deployment/__init__.py +1 -0
- solokit/deployment/executor.py +411 -0
- solokit/git/__init__.py +1 -0
- solokit/git/integration.py +619 -0
- solokit/init/__init__.py +41 -0
- solokit/init/claude_commands_installer.py +87 -0
- solokit/init/dependency_installer.py +313 -0
- solokit/init/docs_structure.py +90 -0
- solokit/init/env_generator.py +160 -0
- solokit/init/environment_validator.py +334 -0
- solokit/init/git_hooks_installer.py +71 -0
- solokit/init/git_setup.py +188 -0
- solokit/init/gitignore_updater.py +195 -0
- solokit/init/initial_commit.py +145 -0
- solokit/init/initial_scans.py +109 -0
- solokit/init/orchestrator.py +246 -0
- solokit/init/readme_generator.py +207 -0
- solokit/init/session_structure.py +239 -0
- solokit/init/template_installer.py +424 -0
- solokit/learning/__init__.py +1 -0
- solokit/learning/archiver.py +115 -0
- solokit/learning/categorizer.py +126 -0
- solokit/learning/curator.py +428 -0
- solokit/learning/extractor.py +352 -0
- solokit/learning/reporter.py +351 -0
- solokit/learning/repository.py +254 -0
- solokit/learning/similarity.py +342 -0
- solokit/learning/validator.py +144 -0
- solokit/project/__init__.py +1 -0
- solokit/project/init.py +1162 -0
- solokit/project/stack.py +436 -0
- solokit/project/sync_plugin.py +438 -0
- solokit/project/tree.py +375 -0
- solokit/quality/__init__.py +1 -0
- solokit/quality/api_validator.py +424 -0
- solokit/quality/checkers/__init__.py +25 -0
- solokit/quality/checkers/base.py +114 -0
- solokit/quality/checkers/context7.py +221 -0
- solokit/quality/checkers/custom.py +162 -0
- solokit/quality/checkers/deployment.py +323 -0
- solokit/quality/checkers/documentation.py +179 -0
- solokit/quality/checkers/formatting.py +161 -0
- solokit/quality/checkers/integration.py +394 -0
- solokit/quality/checkers/linting.py +159 -0
- solokit/quality/checkers/security.py +261 -0
- solokit/quality/checkers/spec_completeness.py +127 -0
- solokit/quality/checkers/tests.py +184 -0
- solokit/quality/env_validator.py +306 -0
- solokit/quality/gates.py +655 -0
- solokit/quality/reporters/__init__.py +10 -0
- solokit/quality/reporters/base.py +25 -0
- solokit/quality/reporters/console.py +98 -0
- solokit/quality/reporters/json_reporter.py +34 -0
- solokit/quality/results.py +98 -0
- solokit/session/__init__.py +1 -0
- solokit/session/briefing/__init__.py +245 -0
- solokit/session/briefing/documentation_loader.py +53 -0
- solokit/session/briefing/formatter.py +476 -0
- solokit/session/briefing/git_context.py +282 -0
- solokit/session/briefing/learning_loader.py +212 -0
- solokit/session/briefing/milestone_builder.py +78 -0
- solokit/session/briefing/orchestrator.py +137 -0
- solokit/session/briefing/stack_detector.py +51 -0
- solokit/session/briefing/tree_generator.py +52 -0
- solokit/session/briefing/work_item_loader.py +209 -0
- solokit/session/briefing.py +353 -0
- solokit/session/complete.py +1188 -0
- solokit/session/status.py +246 -0
- solokit/session/validate.py +452 -0
- solokit/templates/.claude/commands/end.md +109 -0
- solokit/templates/.claude/commands/init.md +159 -0
- solokit/templates/.claude/commands/learn-curate.md +88 -0
- solokit/templates/.claude/commands/learn-search.md +62 -0
- solokit/templates/.claude/commands/learn-show.md +69 -0
- solokit/templates/.claude/commands/learn.md +136 -0
- solokit/templates/.claude/commands/start.md +114 -0
- solokit/templates/.claude/commands/status.md +22 -0
- solokit/templates/.claude/commands/validate.md +27 -0
- solokit/templates/.claude/commands/work-delete.md +119 -0
- solokit/templates/.claude/commands/work-graph.md +139 -0
- solokit/templates/.claude/commands/work-list.md +26 -0
- solokit/templates/.claude/commands/work-new.md +114 -0
- solokit/templates/.claude/commands/work-next.md +25 -0
- solokit/templates/.claude/commands/work-show.md +24 -0
- solokit/templates/.claude/commands/work-update.md +141 -0
- solokit/templates/CHANGELOG.md +17 -0
- solokit/templates/WORK_ITEM_TYPES.md +141 -0
- solokit/templates/__init__.py +1 -0
- solokit/templates/bug_spec.md +217 -0
- solokit/templates/config.schema.json +150 -0
- solokit/templates/dashboard_refine/base/.gitignore +36 -0
- solokit/templates/dashboard_refine/base/app/(dashboard)/layout.tsx +22 -0
- solokit/templates/dashboard_refine/base/app/(dashboard)/page.tsx +68 -0
- solokit/templates/dashboard_refine/base/app/(dashboard)/users/page.tsx +77 -0
- solokit/templates/dashboard_refine/base/app/globals.css +60 -0
- solokit/templates/dashboard_refine/base/app/layout.tsx +23 -0
- solokit/templates/dashboard_refine/base/app/page.tsx +9 -0
- solokit/templates/dashboard_refine/base/components/client-refine-wrapper.tsx +21 -0
- solokit/templates/dashboard_refine/base/components/layout/header.tsx +44 -0
- solokit/templates/dashboard_refine/base/components/layout/sidebar.tsx +82 -0
- solokit/templates/dashboard_refine/base/components/ui/button.tsx +53 -0
- solokit/templates/dashboard_refine/base/components/ui/card.tsx +78 -0
- solokit/templates/dashboard_refine/base/components/ui/table.tsx +116 -0
- solokit/templates/dashboard_refine/base/components.json +16 -0
- solokit/templates/dashboard_refine/base/lib/refine.tsx +65 -0
- solokit/templates/dashboard_refine/base/lib/utils.ts +13 -0
- solokit/templates/dashboard_refine/base/next.config.ts +10 -0
- solokit/templates/dashboard_refine/base/package.json.template +40 -0
- solokit/templates/dashboard_refine/base/postcss.config.mjs +8 -0
- solokit/templates/dashboard_refine/base/providers/refine-provider.tsx +26 -0
- solokit/templates/dashboard_refine/base/tailwind.config.ts +57 -0
- solokit/templates/dashboard_refine/base/tsconfig.json +27 -0
- solokit/templates/dashboard_refine/docker/Dockerfile +57 -0
- solokit/templates/dashboard_refine/docker/docker-compose.prod.yml +31 -0
- solokit/templates/dashboard_refine/docker/docker-compose.yml +21 -0
- solokit/templates/dashboard_refine/tier-1-essential/.eslintrc.json +7 -0
- solokit/templates/dashboard_refine/tier-1-essential/jest.config.ts +17 -0
- solokit/templates/dashboard_refine/tier-1-essential/jest.setup.ts +1 -0
- solokit/templates/dashboard_refine/tier-1-essential/package.json.tier1.template +57 -0
- solokit/templates/dashboard_refine/tier-1-essential/tests/setup.ts +26 -0
- solokit/templates/dashboard_refine/tier-1-essential/tests/unit/example.test.tsx +73 -0
- solokit/templates/dashboard_refine/tier-2-standard/package.json.tier2.template +62 -0
- solokit/templates/dashboard_refine/tier-3-comprehensive/eslint.config.mjs +22 -0
- solokit/templates/dashboard_refine/tier-3-comprehensive/package.json.tier3.template +79 -0
- solokit/templates/dashboard_refine/tier-3-comprehensive/playwright.config.ts +66 -0
- solokit/templates/dashboard_refine/tier-3-comprehensive/stryker.conf.json +38 -0
- solokit/templates/dashboard_refine/tier-3-comprehensive/tests/e2e/dashboard.spec.ts +88 -0
- solokit/templates/dashboard_refine/tier-3-comprehensive/tests/e2e/user-management.spec.ts +102 -0
- solokit/templates/dashboard_refine/tier-3-comprehensive/tests/integration/dashboard.test.tsx +90 -0
- solokit/templates/dashboard_refine/tier-3-comprehensive/type-coverage.json +16 -0
- solokit/templates/dashboard_refine/tier-4-production/instrumentation.ts +9 -0
- solokit/templates/dashboard_refine/tier-4-production/k6/dashboard-load-test.js +70 -0
- solokit/templates/dashboard_refine/tier-4-production/next.config.ts +46 -0
- solokit/templates/dashboard_refine/tier-4-production/package.json.tier4.template +89 -0
- solokit/templates/dashboard_refine/tier-4-production/sentry.client.config.ts +26 -0
- solokit/templates/dashboard_refine/tier-4-production/sentry.edge.config.ts +11 -0
- solokit/templates/dashboard_refine/tier-4-production/sentry.server.config.ts +11 -0
- solokit/templates/deployment_spec.md +500 -0
- solokit/templates/feature_spec.md +248 -0
- solokit/templates/fullstack_nextjs/base/.gitignore +36 -0
- solokit/templates/fullstack_nextjs/base/app/api/example/route.ts +65 -0
- solokit/templates/fullstack_nextjs/base/app/globals.css +27 -0
- solokit/templates/fullstack_nextjs/base/app/layout.tsx +20 -0
- solokit/templates/fullstack_nextjs/base/app/page.tsx +32 -0
- solokit/templates/fullstack_nextjs/base/components/example-component.tsx +20 -0
- solokit/templates/fullstack_nextjs/base/lib/prisma.ts +17 -0
- solokit/templates/fullstack_nextjs/base/lib/utils.ts +13 -0
- solokit/templates/fullstack_nextjs/base/lib/validations.ts +20 -0
- solokit/templates/fullstack_nextjs/base/next.config.ts +7 -0
- solokit/templates/fullstack_nextjs/base/package.json.template +32 -0
- solokit/templates/fullstack_nextjs/base/postcss.config.mjs +8 -0
- solokit/templates/fullstack_nextjs/base/prisma/schema.prisma +21 -0
- solokit/templates/fullstack_nextjs/base/tailwind.config.ts +19 -0
- solokit/templates/fullstack_nextjs/base/tsconfig.json +27 -0
- solokit/templates/fullstack_nextjs/docker/Dockerfile +60 -0
- solokit/templates/fullstack_nextjs/docker/docker-compose.prod.yml +57 -0
- solokit/templates/fullstack_nextjs/docker/docker-compose.yml +47 -0
- solokit/templates/fullstack_nextjs/tier-1-essential/.eslintrc.json +7 -0
- solokit/templates/fullstack_nextjs/tier-1-essential/jest.config.ts +17 -0
- solokit/templates/fullstack_nextjs/tier-1-essential/jest.setup.ts +1 -0
- solokit/templates/fullstack_nextjs/tier-1-essential/package.json.tier1.template +48 -0
- solokit/templates/fullstack_nextjs/tier-1-essential/tests/api/example.test.ts +88 -0
- solokit/templates/fullstack_nextjs/tier-1-essential/tests/setup.ts +22 -0
- solokit/templates/fullstack_nextjs/tier-1-essential/tests/unit/example.test.tsx +22 -0
- solokit/templates/fullstack_nextjs/tier-2-standard/package.json.tier2.template +52 -0
- solokit/templates/fullstack_nextjs/tier-3-comprehensive/eslint.config.mjs +39 -0
- solokit/templates/fullstack_nextjs/tier-3-comprehensive/package.json.tier3.template +68 -0
- solokit/templates/fullstack_nextjs/tier-3-comprehensive/playwright.config.ts +66 -0
- solokit/templates/fullstack_nextjs/tier-3-comprehensive/stryker.conf.json +33 -0
- solokit/templates/fullstack_nextjs/tier-3-comprehensive/tests/e2e/flow.spec.ts +59 -0
- solokit/templates/fullstack_nextjs/tier-3-comprehensive/tests/integration/api.test.ts +165 -0
- solokit/templates/fullstack_nextjs/tier-3-comprehensive/type-coverage.json +12 -0
- solokit/templates/fullstack_nextjs/tier-4-production/instrumentation.ts +9 -0
- solokit/templates/fullstack_nextjs/tier-4-production/k6/load-test.js +45 -0
- solokit/templates/fullstack_nextjs/tier-4-production/next.config.ts +46 -0
- solokit/templates/fullstack_nextjs/tier-4-production/package.json.tier4.template +77 -0
- solokit/templates/fullstack_nextjs/tier-4-production/sentry.client.config.ts +26 -0
- solokit/templates/fullstack_nextjs/tier-4-production/sentry.edge.config.ts +11 -0
- solokit/templates/fullstack_nextjs/tier-4-production/sentry.server.config.ts +11 -0
- solokit/templates/git-hooks/prepare-commit-msg +24 -0
- solokit/templates/integration_test_spec.md +363 -0
- solokit/templates/learnings.json +15 -0
- solokit/templates/ml_ai_fastapi/base/.gitignore +104 -0
- solokit/templates/ml_ai_fastapi/base/alembic/env.py +96 -0
- solokit/templates/ml_ai_fastapi/base/alembic.ini +114 -0
- solokit/templates/ml_ai_fastapi/base/pyproject.toml.template +91 -0
- solokit/templates/ml_ai_fastapi/base/requirements.txt.template +28 -0
- solokit/templates/ml_ai_fastapi/base/src/__init__.py +5 -0
- solokit/templates/ml_ai_fastapi/base/src/api/__init__.py +3 -0
- solokit/templates/ml_ai_fastapi/base/src/api/dependencies.py +20 -0
- solokit/templates/ml_ai_fastapi/base/src/api/routes/__init__.py +3 -0
- solokit/templates/ml_ai_fastapi/base/src/api/routes/example.py +134 -0
- solokit/templates/ml_ai_fastapi/base/src/api/routes/health.py +66 -0
- solokit/templates/ml_ai_fastapi/base/src/core/__init__.py +3 -0
- solokit/templates/ml_ai_fastapi/base/src/core/config.py +64 -0
- solokit/templates/ml_ai_fastapi/base/src/core/database.py +50 -0
- solokit/templates/ml_ai_fastapi/base/src/main.py +64 -0
- solokit/templates/ml_ai_fastapi/base/src/models/__init__.py +7 -0
- solokit/templates/ml_ai_fastapi/base/src/models/example.py +61 -0
- solokit/templates/ml_ai_fastapi/base/src/services/__init__.py +3 -0
- solokit/templates/ml_ai_fastapi/base/src/services/example.py +115 -0
- solokit/templates/ml_ai_fastapi/docker/Dockerfile +59 -0
- solokit/templates/ml_ai_fastapi/docker/docker-compose.prod.yml +112 -0
- solokit/templates/ml_ai_fastapi/docker/docker-compose.yml +77 -0
- solokit/templates/ml_ai_fastapi/tier-1-essential/pyproject.toml.tier1.template +112 -0
- solokit/templates/ml_ai_fastapi/tier-1-essential/pyrightconfig.json +41 -0
- solokit/templates/ml_ai_fastapi/tier-1-essential/pytest.ini +69 -0
- solokit/templates/ml_ai_fastapi/tier-1-essential/requirements-dev.txt +17 -0
- solokit/templates/ml_ai_fastapi/tier-1-essential/ruff.toml +81 -0
- solokit/templates/ml_ai_fastapi/tier-1-essential/tests/__init__.py +3 -0
- solokit/templates/ml_ai_fastapi/tier-1-essential/tests/conftest.py +72 -0
- solokit/templates/ml_ai_fastapi/tier-1-essential/tests/test_main.py +49 -0
- solokit/templates/ml_ai_fastapi/tier-1-essential/tests/unit/__init__.py +3 -0
- solokit/templates/ml_ai_fastapi/tier-1-essential/tests/unit/test_example.py +113 -0
- solokit/templates/ml_ai_fastapi/tier-2-standard/pyproject.toml.tier2.template +130 -0
- solokit/templates/ml_ai_fastapi/tier-3-comprehensive/locustfile.py +99 -0
- solokit/templates/ml_ai_fastapi/tier-3-comprehensive/mutmut_config.py +53 -0
- solokit/templates/ml_ai_fastapi/tier-3-comprehensive/pyproject.toml.tier3.template +150 -0
- solokit/templates/ml_ai_fastapi/tier-3-comprehensive/tests/integration/__init__.py +3 -0
- solokit/templates/ml_ai_fastapi/tier-3-comprehensive/tests/integration/conftest.py +74 -0
- solokit/templates/ml_ai_fastapi/tier-3-comprehensive/tests/integration/test_api.py +131 -0
- solokit/templates/ml_ai_fastapi/tier-4-production/pyproject.toml.tier4.template +162 -0
- solokit/templates/ml_ai_fastapi/tier-4-production/requirements-prod.txt +25 -0
- solokit/templates/ml_ai_fastapi/tier-4-production/src/api/routes/metrics.py +19 -0
- solokit/templates/ml_ai_fastapi/tier-4-production/src/core/logging.py +74 -0
- solokit/templates/ml_ai_fastapi/tier-4-production/src/core/monitoring.py +68 -0
- solokit/templates/ml_ai_fastapi/tier-4-production/src/core/sentry.py +66 -0
- solokit/templates/ml_ai_fastapi/tier-4-production/src/middleware/__init__.py +3 -0
- solokit/templates/ml_ai_fastapi/tier-4-production/src/middleware/logging.py +79 -0
- solokit/templates/ml_ai_fastapi/tier-4-production/src/middleware/tracing.py +60 -0
- solokit/templates/refactor_spec.md +287 -0
- solokit/templates/saas_t3/base/.gitignore +36 -0
- solokit/templates/saas_t3/base/app/api/trpc/[trpc]/route.ts +33 -0
- solokit/templates/saas_t3/base/app/globals.css +27 -0
- solokit/templates/saas_t3/base/app/layout.tsx +23 -0
- solokit/templates/saas_t3/base/app/page.tsx +31 -0
- solokit/templates/saas_t3/base/lib/api.tsx +77 -0
- solokit/templates/saas_t3/base/lib/utils.ts +13 -0
- solokit/templates/saas_t3/base/next.config.ts +7 -0
- solokit/templates/saas_t3/base/package.json.template +38 -0
- solokit/templates/saas_t3/base/postcss.config.mjs +8 -0
- solokit/templates/saas_t3/base/prisma/schema.prisma +20 -0
- solokit/templates/saas_t3/base/server/api/root.ts +19 -0
- solokit/templates/saas_t3/base/server/api/routers/example.ts +28 -0
- solokit/templates/saas_t3/base/server/api/trpc.ts +52 -0
- solokit/templates/saas_t3/base/server/db.ts +17 -0
- solokit/templates/saas_t3/base/tailwind.config.ts +19 -0
- solokit/templates/saas_t3/base/tsconfig.json +27 -0
- solokit/templates/saas_t3/docker/Dockerfile +60 -0
- solokit/templates/saas_t3/docker/docker-compose.prod.yml +59 -0
- solokit/templates/saas_t3/docker/docker-compose.yml +49 -0
- solokit/templates/saas_t3/tier-1-essential/.eslintrc.json +7 -0
- solokit/templates/saas_t3/tier-1-essential/jest.config.ts +17 -0
- solokit/templates/saas_t3/tier-1-essential/jest.setup.ts +1 -0
- solokit/templates/saas_t3/tier-1-essential/package.json.tier1.template +54 -0
- solokit/templates/saas_t3/tier-1-essential/tests/setup.ts +22 -0
- solokit/templates/saas_t3/tier-1-essential/tests/unit/example.test.tsx +24 -0
- solokit/templates/saas_t3/tier-2-standard/package.json.tier2.template +58 -0
- solokit/templates/saas_t3/tier-3-comprehensive/eslint.config.mjs +39 -0
- solokit/templates/saas_t3/tier-3-comprehensive/package.json.tier3.template +74 -0
- solokit/templates/saas_t3/tier-3-comprehensive/playwright.config.ts +66 -0
- solokit/templates/saas_t3/tier-3-comprehensive/stryker.conf.json +34 -0
- solokit/templates/saas_t3/tier-3-comprehensive/tests/e2e/home.spec.ts +41 -0
- solokit/templates/saas_t3/tier-3-comprehensive/tests/integration/api.test.ts +44 -0
- solokit/templates/saas_t3/tier-3-comprehensive/type-coverage.json +12 -0
- solokit/templates/saas_t3/tier-4-production/instrumentation.ts +9 -0
- solokit/templates/saas_t3/tier-4-production/k6/load-test.js +51 -0
- solokit/templates/saas_t3/tier-4-production/next.config.ts +46 -0
- solokit/templates/saas_t3/tier-4-production/package.json.tier4.template +83 -0
- solokit/templates/saas_t3/tier-4-production/sentry.client.config.ts +26 -0
- solokit/templates/saas_t3/tier-4-production/sentry.edge.config.ts +11 -0
- solokit/templates/saas_t3/tier-4-production/sentry.server.config.ts +11 -0
- solokit/templates/saas_t3/tier-4-production/vercel.json +37 -0
- solokit/templates/security_spec.md +287 -0
- solokit/templates/stack-versions.yaml +617 -0
- solokit/templates/status_update.json +6 -0
- solokit/templates/template-registry.json +257 -0
- solokit/templates/work_items.json +11 -0
- solokit/testing/__init__.py +1 -0
- solokit/testing/integration_runner.py +550 -0
- solokit/testing/performance.py +637 -0
- solokit/visualization/__init__.py +1 -0
- solokit/visualization/dependency_graph.py +788 -0
- solokit/work_items/__init__.py +1 -0
- solokit/work_items/creator.py +217 -0
- solokit/work_items/delete.py +264 -0
- solokit/work_items/get_dependencies.py +185 -0
- solokit/work_items/get_dependents.py +113 -0
- solokit/work_items/get_metadata.py +121 -0
- solokit/work_items/get_next_recommendations.py +133 -0
- solokit/work_items/manager.py +235 -0
- solokit/work_items/milestones.py +137 -0
- solokit/work_items/query.py +376 -0
- solokit/work_items/repository.py +267 -0
- solokit/work_items/scheduler.py +184 -0
- solokit/work_items/spec_parser.py +838 -0
- solokit/work_items/spec_validator.py +493 -0
- solokit/work_items/updater.py +157 -0
- solokit/work_items/validator.py +205 -0
- solokit-0.1.1.dist-info/METADATA +640 -0
- solokit-0.1.1.dist-info/RECORD +323 -0
- solokit-0.1.1.dist-info/WHEEL +5 -0
- solokit-0.1.1.dist-info/entry_points.txt +2 -0
- solokit-0.1.1.dist-info/licenses/LICENSE +21 -0
- solokit-0.1.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
# Integration Test: [Name]
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
TEMPLATE INSTRUCTIONS:
|
|
5
|
+
- Replace [Name] with a descriptive name for the integration test
|
|
6
|
+
- Define all components and their integration points
|
|
7
|
+
- Include sequence diagrams using mermaid for complex flows
|
|
8
|
+
- Specify performance benchmarks and acceptance criteria
|
|
9
|
+
- Document all test scenarios with setup, actions, and expected results
|
|
10
|
+
- Remove these instructions before finalizing the spec
|
|
11
|
+
-->
|
|
12
|
+
|
|
13
|
+
## Scope
|
|
14
|
+
|
|
15
|
+
<!-- Define which components are being integrated and tested -->
|
|
16
|
+
|
|
17
|
+
Define which components are being integrated and tested.
|
|
18
|
+
|
|
19
|
+
**Example:**
|
|
20
|
+
> This integration test validates the end-to-end order processing flow, including the Order API, Payment Service, Inventory Service, and Notification Service. It tests the happy path, error scenarios, and ensures data consistency across all services.
|
|
21
|
+
|
|
22
|
+
**Components:**
|
|
23
|
+
- Order API: `v2.3.0` (receives order requests, orchestrates workflow)
|
|
24
|
+
- Payment Service: `v1.8.2` (processes payments via Stripe)
|
|
25
|
+
- Inventory Service: `v2.1.0` (checks and reserves inventory)
|
|
26
|
+
- Notification Service: `v1.5.0` (sends email confirmations)
|
|
27
|
+
- Database: PostgreSQL `14.2` (order and inventory data)
|
|
28
|
+
- Message Queue: RabbitMQ `3.11` (async communication)
|
|
29
|
+
|
|
30
|
+
**Integration Points:**
|
|
31
|
+
- REST API: Order API → Payment Service (`POST /api/payments`)
|
|
32
|
+
- REST API: Order API → Inventory Service (`POST /api/inventory/reserve`)
|
|
33
|
+
- Message Queue: Order API → Notification Service (queue: `order.completed`)
|
|
34
|
+
- Database: All services → PostgreSQL (shared database)
|
|
35
|
+
- External API: Payment Service → Stripe API
|
|
36
|
+
|
|
37
|
+
## Test Scenarios
|
|
38
|
+
|
|
39
|
+
<!-- Document all test scenarios with sequence diagrams, setup, actions, and expected results -->
|
|
40
|
+
|
|
41
|
+
### Scenario 1: Successful Order Processing (Happy Path)
|
|
42
|
+
|
|
43
|
+
**Description:**
|
|
44
|
+
> Customer places an order for an in-stock item. Payment is processed successfully, inventory is reserved, and confirmation email is sent.
|
|
45
|
+
|
|
46
|
+
**Sequence Diagram:**
|
|
47
|
+
```mermaid
|
|
48
|
+
sequenceDiagram
|
|
49
|
+
participant Client
|
|
50
|
+
participant OrderAPI
|
|
51
|
+
participant PaymentService
|
|
52
|
+
participant InventoryService
|
|
53
|
+
participant NotificationQueue
|
|
54
|
+
participant Database
|
|
55
|
+
|
|
56
|
+
Client->>OrderAPI: POST /api/orders (order data)
|
|
57
|
+
OrderAPI->>Database: Create order record (status: pending)
|
|
58
|
+
OrderAPI->>InventoryService: POST /api/inventory/reserve
|
|
59
|
+
InventoryService->>Database: Check stock availability
|
|
60
|
+
Database-->>InventoryService: Stock available
|
|
61
|
+
InventoryService->>Database: Reserve inventory
|
|
62
|
+
InventoryService-->>OrderAPI: 200 OK (reservation_id)
|
|
63
|
+
OrderAPI->>PaymentService: POST /api/payments
|
|
64
|
+
PaymentService->>Stripe: Process payment
|
|
65
|
+
Stripe-->>PaymentService: Payment successful
|
|
66
|
+
PaymentService->>Database: Record payment
|
|
67
|
+
PaymentService-->>OrderAPI: 200 OK (payment_id)
|
|
68
|
+
OrderAPI->>Database: Update order (status: completed)
|
|
69
|
+
OrderAPI->>NotificationQueue: Publish order.completed event
|
|
70
|
+
OrderAPI-->>Client: 201 Created (order_id, status)
|
|
71
|
+
NotificationQueue->>NotificationService: Consume event
|
|
72
|
+
NotificationService->>SMTP: Send confirmation email
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Setup:**
|
|
76
|
+
- All services running (Order API on 8001, Payment on 8002, Inventory on 8003, Notification on 8004)
|
|
77
|
+
- PostgreSQL database seeded with test data:
|
|
78
|
+
- Product ID `prod_123` with stock quantity 50
|
|
79
|
+
- Customer ID `cust_456` with valid email
|
|
80
|
+
- RabbitMQ running on port 5672
|
|
81
|
+
- Stripe test mode enabled with test API key
|
|
82
|
+
- Mock SMTP server running
|
|
83
|
+
|
|
84
|
+
**Actions:**
|
|
85
|
+
1. Send POST request to `/api/orders` with payload:
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"customer_id": "cust_456",
|
|
89
|
+
"items": [{"product_id": "prod_123", "quantity": 2}],
|
|
90
|
+
"payment_method": "card",
|
|
91
|
+
"card_token": "tok_visa_test"
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
2. Wait for order processing (max 5 seconds)
|
|
95
|
+
3. Check order status via `GET /api/orders/{order_id}`
|
|
96
|
+
4. Verify email sent via SMTP mock
|
|
97
|
+
|
|
98
|
+
**Expected Results:**
|
|
99
|
+
- HTTP 201 response with order details:
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"order_id": "ord_789",
|
|
103
|
+
"status": "completed",
|
|
104
|
+
"total": 49.98,
|
|
105
|
+
"payment_id": "pay_123",
|
|
106
|
+
"reservation_id": "res_456"
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
- Database state:
|
|
110
|
+
- Order record created with status `completed`
|
|
111
|
+
- Payment record created
|
|
112
|
+
- Inventory reduced by 2 (from 50 to 48)
|
|
113
|
+
- Notification sent:
|
|
114
|
+
- Email queued in RabbitMQ
|
|
115
|
+
- Email delivered via SMTP mock
|
|
116
|
+
- Email contains order ID and confirmation details
|
|
117
|
+
- Logs show successful processing in all services
|
|
118
|
+
- Response time < 2000ms (p95)
|
|
119
|
+
|
|
120
|
+
### Scenario 2: Insufficient Inventory (Error Handling)
|
|
121
|
+
|
|
122
|
+
**Description:**
|
|
123
|
+
> Customer attempts to order more items than available in stock. Order should fail gracefully without charging payment or corrupting data.
|
|
124
|
+
|
|
125
|
+
**Sequence Diagram:**
|
|
126
|
+
```mermaid
|
|
127
|
+
sequenceDiagram
|
|
128
|
+
participant Client
|
|
129
|
+
participant OrderAPI
|
|
130
|
+
participant InventoryService
|
|
131
|
+
participant Database
|
|
132
|
+
|
|
133
|
+
Client->>OrderAPI: POST /api/orders (quantity > stock)
|
|
134
|
+
OrderAPI->>Database: Create order record (status: pending)
|
|
135
|
+
OrderAPI->>InventoryService: POST /api/inventory/reserve
|
|
136
|
+
InventoryService->>Database: Check stock availability
|
|
137
|
+
Database-->>InventoryService: Insufficient stock
|
|
138
|
+
InventoryService-->>OrderAPI: 409 Conflict (insufficient_stock)
|
|
139
|
+
OrderAPI->>Database: Update order (status: failed)
|
|
140
|
+
OrderAPI-->>Client: 409 Conflict (error details)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Setup:**
|
|
144
|
+
- Product ID `prod_789` with stock quantity 5
|
|
145
|
+
- Customer requests quantity 10
|
|
146
|
+
|
|
147
|
+
**Actions:**
|
|
148
|
+
1. Send POST request with `quantity: 10` for product with stock 5
|
|
149
|
+
2. Observe order creation and inventory check
|
|
150
|
+
|
|
151
|
+
**Expected Results:**
|
|
152
|
+
- HTTP 409 Conflict response:
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"error": "insufficient_stock",
|
|
156
|
+
"message": "Requested quantity (10) exceeds available stock (5)",
|
|
157
|
+
"product_id": "prod_789",
|
|
158
|
+
"available": 5,
|
|
159
|
+
"requested": 10
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
- Database state:
|
|
163
|
+
- Order record created with status `failed`
|
|
164
|
+
- Inventory unchanged (still 5)
|
|
165
|
+
- No payment record created
|
|
166
|
+
- No email sent
|
|
167
|
+
- Logs contain error with context
|
|
168
|
+
|
|
169
|
+
## Performance Benchmarks
|
|
170
|
+
|
|
171
|
+
<!-- Define quantitative performance requirements for the integration -->
|
|
172
|
+
|
|
173
|
+
**Response Time Requirements:**
|
|
174
|
+
- p50 (median): < 500ms
|
|
175
|
+
- p95: < 2000ms
|
|
176
|
+
- p99: < 5000ms
|
|
177
|
+
- p99.9: < 10000ms
|
|
178
|
+
|
|
179
|
+
**Example:** Order processing should complete within 2 seconds for 95% of requests under normal load.
|
|
180
|
+
|
|
181
|
+
**Throughput Requirements:**
|
|
182
|
+
- Minimum: 50 orders/minute (baseline for production)
|
|
183
|
+
- Target: 200 orders/minute (target for peak traffic)
|
|
184
|
+
- Maximum tested: 500 orders/minute (stress test)
|
|
185
|
+
|
|
186
|
+
**Resource Limits:**
|
|
187
|
+
- CPU: < 70% utilization per service (average under load)
|
|
188
|
+
- Memory: < 1GB per service (Order API, Payment, Inventory, Notification)
|
|
189
|
+
- Database connections: < 50 active connections
|
|
190
|
+
- Message queue depth: < 1000 messages
|
|
191
|
+
- Disk I/O: < 50MB/s
|
|
192
|
+
|
|
193
|
+
**Load Test Configuration:**
|
|
194
|
+
```yaml
|
|
195
|
+
load_test:
|
|
196
|
+
ramp_up: 5 minutes # Gradually increase load
|
|
197
|
+
sustained: 15 minutes # Maintain peak load
|
|
198
|
+
ramp_down: 5 minutes # Gradually decrease load
|
|
199
|
+
scenarios:
|
|
200
|
+
- name: "happy_path"
|
|
201
|
+
weight: 80% # 80% of requests are successful orders
|
|
202
|
+
- name: "insufficient_stock"
|
|
203
|
+
weight: 15% # 15% fail due to stock issues
|
|
204
|
+
- name: "payment_failure"
|
|
205
|
+
weight: 5% # 5% fail due to payment issues
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Acceptance Criteria:**
|
|
209
|
+
- [ ] p95 response time < 2000ms under 200 orders/minute
|
|
210
|
+
- [ ] No errors under sustained load for 15 minutes
|
|
211
|
+
- [ ] All services recover gracefully after spike (500 orders/minute for 1 minute)
|
|
212
|
+
- [ ] No memory leaks detected (memory stable over 15 minute test)
|
|
213
|
+
- [ ] Database connection pool doesn't exhaust
|
|
214
|
+
|
|
215
|
+
## API Contracts
|
|
216
|
+
|
|
217
|
+
<!-- Document all API contracts between services to ensure compatibility -->
|
|
218
|
+
|
|
219
|
+
**Order API → Payment Service:**
|
|
220
|
+
- Contract file: `contracts/order-to-payment.yaml`
|
|
221
|
+
- Version: 2.1.0
|
|
222
|
+
- Breaking changes: None allowed without major version bump
|
|
223
|
+
- Example request:
|
|
224
|
+
```json
|
|
225
|
+
POST /api/payments
|
|
226
|
+
{
|
|
227
|
+
"order_id": "ord_789",
|
|
228
|
+
"amount": 49.98,
|
|
229
|
+
"currency": "USD",
|
|
230
|
+
"payment_method": "card",
|
|
231
|
+
"card_token": "tok_visa_test"
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
- Example response:
|
|
235
|
+
```json
|
|
236
|
+
{
|
|
237
|
+
"payment_id": "pay_123",
|
|
238
|
+
"status": "succeeded",
|
|
239
|
+
"amount_captured": 49.98
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**Order API → Inventory Service:**
|
|
244
|
+
- Contract file: `contracts/order-to-inventory.yaml`
|
|
245
|
+
- Version: 1.8.0
|
|
246
|
+
- Example request:
|
|
247
|
+
```json
|
|
248
|
+
POST /api/inventory/reserve
|
|
249
|
+
{
|
|
250
|
+
"product_id": "prod_123",
|
|
251
|
+
"quantity": 2,
|
|
252
|
+
"order_id": "ord_789"
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Database Schema:**
|
|
257
|
+
- Schema file: `schemas/integration_test_schema.sql`
|
|
258
|
+
- Tables: `orders`, `payments`, `inventory_reservations`, `notifications`
|
|
259
|
+
- Migrations: `migrations/014_add_order_processing.sql`
|
|
260
|
+
|
|
261
|
+
## Environment Requirements
|
|
262
|
+
|
|
263
|
+
<!-- List all services, configuration, and infrastructure needed to run the integration tests -->
|
|
264
|
+
|
|
265
|
+
**Services Required:**
|
|
266
|
+
- order-api:2.3.0 (port 8001)
|
|
267
|
+
- payment-service:1.8.2 (port 8002)
|
|
268
|
+
- inventory-service:2.1.0 (port 8003)
|
|
269
|
+
- notification-service:1.5.0 (port 8004)
|
|
270
|
+
- postgres:14.2 (port 5432)
|
|
271
|
+
- rabbitmq:3.11 (ports 5672, 15672)
|
|
272
|
+
- smtp-mock:latest (port 1025) - for email testing
|
|
273
|
+
|
|
274
|
+
**Configuration:**
|
|
275
|
+
- Environment: `integration-test`
|
|
276
|
+
- Config files: `config/integration-test/*.yaml`
|
|
277
|
+
- Environment variables loaded from `.env.integration-test`:
|
|
278
|
+
```bash
|
|
279
|
+
DATABASE_URL=postgresql://test:test@localhost:5432/integration_test
|
|
280
|
+
RABBITMQ_URL=amqp://guest:guest@localhost:5672
|
|
281
|
+
STRIPE_API_KEY=sk_test_xxxxx
|
|
282
|
+
SMTP_HOST=localhost
|
|
283
|
+
SMTP_PORT=1025
|
|
284
|
+
LOG_LEVEL=debug
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**Infrastructure:**
|
|
288
|
+
- Docker Compose file: `docker-compose.integration-test.yml`
|
|
289
|
+
```yaml
|
|
290
|
+
version: '3.8'
|
|
291
|
+
services:
|
|
292
|
+
postgres:
|
|
293
|
+
image: postgres:14.2
|
|
294
|
+
environment:
|
|
295
|
+
POSTGRES_DB: integration_test
|
|
296
|
+
POSTGRES_USER: test
|
|
297
|
+
POSTGRES_PASSWORD: test
|
|
298
|
+
ports:
|
|
299
|
+
- "5432:5432"
|
|
300
|
+
|
|
301
|
+
rabbitmq:
|
|
302
|
+
image: rabbitmq:3.11-management
|
|
303
|
+
ports:
|
|
304
|
+
- "5672:5672"
|
|
305
|
+
- "15672:15672"
|
|
306
|
+
|
|
307
|
+
# ... other services
|
|
308
|
+
```
|
|
309
|
+
- Network: `integration-test-network`
|
|
310
|
+
- Volumes: `postgres-data`, `rabbitmq-data`
|
|
311
|
+
|
|
312
|
+
**Test Data Fixtures:**
|
|
313
|
+
- Location: `tests/fixtures/integration_test_data.sql`
|
|
314
|
+
- Includes: 10 test products, 5 test customers, sample inventory levels
|
|
315
|
+
|
|
316
|
+
## Dependencies
|
|
317
|
+
|
|
318
|
+
**Work Item Dependencies:**
|
|
319
|
+
- [ ] Component A implementation complete
|
|
320
|
+
- [ ] Component B implementation complete
|
|
321
|
+
- [ ] Integration test infrastructure ready
|
|
322
|
+
- [ ] Test data fixtures created
|
|
323
|
+
|
|
324
|
+
**Service Dependencies:**
|
|
325
|
+
- Component A depends on Component B API
|
|
326
|
+
- Component B depends on PostgreSQL database
|
|
327
|
+
- Both components depend on Redis cache
|
|
328
|
+
|
|
329
|
+
## Acceptance Criteria
|
|
330
|
+
|
|
331
|
+
<!-- Specific, measurable criteria that must be met for this integration test to pass -->
|
|
332
|
+
|
|
333
|
+
**Functional:**
|
|
334
|
+
- [ ] All integration test scenarios passing (100% success rate)
|
|
335
|
+
- [ ] Happy path (Scenario 1) completes successfully in <span>< 2000ms (p95)</span>
|
|
336
|
+
- [ ] Error handling scenarios validated (Scenario 2: insufficient stock handled correctly)
|
|
337
|
+
- [ ] Data consistency verified across all services (order status matches payment and inventory state)
|
|
338
|
+
- [ ] End-to-end flows complete successfully without manual intervention
|
|
339
|
+
- [ ] All services handle errors gracefully (no crashes, proper error responses)
|
|
340
|
+
- [ ] Message queue processing works reliably (notifications delivered)
|
|
341
|
+
|
|
342
|
+
**Performance:**
|
|
343
|
+
- [ ] All performance benchmarks met (p95 < 2000ms under 200 orders/minute)
|
|
344
|
+
- [ ] No performance regression from baseline (<10% slower than previous version)
|
|
345
|
+
- [ ] Resource utilization within limits (CPU < 70%, Memory < 1GB per service)
|
|
346
|
+
- [ ] Load tests passing for 15 minutes sustained load
|
|
347
|
+
- [ ] Services recover gracefully after traffic spike
|
|
348
|
+
- [ ] No memory leaks detected (heap size stable)
|
|
349
|
+
- [ ] Database connection pool doesn't exhaust
|
|
350
|
+
|
|
351
|
+
**Contracts:**
|
|
352
|
+
- [ ] API contracts validated (no breaking changes detected)
|
|
353
|
+
- [ ] Database schema matches expected version (migration 014 applied)
|
|
354
|
+
- [ ] Contract tests passing for all integration points (Order→Payment, Order→Inventory)
|
|
355
|
+
- [ ] Message queue contracts verified (order.completed event structure correct)
|
|
356
|
+
- [ ] External API contracts verified (Stripe API integration works)
|
|
357
|
+
|
|
358
|
+
**Documentation:**
|
|
359
|
+
- [ ] Integration architecture diagram created (shows all services and connections)
|
|
360
|
+
- [ ] Sequence diagrams for all scenarios (mermaid diagrams in spec)
|
|
361
|
+
- [ ] API contract documentation updated (YAML files current)
|
|
362
|
+
- [ ] Performance baseline documented (benchmark results recorded)
|
|
363
|
+
- [ ] Runbook created for troubleshooting integration failures
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"metadata": {
|
|
3
|
+
"total_learnings": 0,
|
|
4
|
+
"last_curated": null
|
|
5
|
+
},
|
|
6
|
+
"categories": {
|
|
7
|
+
"architecture_patterns": [],
|
|
8
|
+
"gotchas": [],
|
|
9
|
+
"best_practices": [],
|
|
10
|
+
"technical_debt": [],
|
|
11
|
+
"performance": [],
|
|
12
|
+
"security": []
|
|
13
|
+
},
|
|
14
|
+
"learnings": []
|
|
15
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
|
|
8
|
+
# Virtual Environments
|
|
9
|
+
venv/
|
|
10
|
+
env/
|
|
11
|
+
ENV/
|
|
12
|
+
.venv/
|
|
13
|
+
|
|
14
|
+
# Distribution / packaging
|
|
15
|
+
build/
|
|
16
|
+
develop-eggs/
|
|
17
|
+
dist/
|
|
18
|
+
downloads/
|
|
19
|
+
eggs/
|
|
20
|
+
.eggs/
|
|
21
|
+
lib/
|
|
22
|
+
lib64/
|
|
23
|
+
parts/
|
|
24
|
+
sdist/
|
|
25
|
+
var/
|
|
26
|
+
wheels/
|
|
27
|
+
*.egg-info/
|
|
28
|
+
.installed.cfg
|
|
29
|
+
*.egg
|
|
30
|
+
|
|
31
|
+
# PyInstaller
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Testing
|
|
36
|
+
.pytest_cache/
|
|
37
|
+
.coverage
|
|
38
|
+
.coverage.*
|
|
39
|
+
htmlcov/
|
|
40
|
+
.tox/
|
|
41
|
+
.nox/
|
|
42
|
+
coverage.xml
|
|
43
|
+
*.cover
|
|
44
|
+
.hypothesis/
|
|
45
|
+
.mutmut-cache/
|
|
46
|
+
|
|
47
|
+
# MyPy / Pyright
|
|
48
|
+
.mypy_cache/
|
|
49
|
+
.dmypy.json
|
|
50
|
+
dmypy.json
|
|
51
|
+
.pytype/
|
|
52
|
+
pyrightconfig.json.user
|
|
53
|
+
|
|
54
|
+
# Ruff
|
|
55
|
+
.ruff_cache/
|
|
56
|
+
|
|
57
|
+
# IDEs
|
|
58
|
+
.vscode/
|
|
59
|
+
.idea/
|
|
60
|
+
*.swp
|
|
61
|
+
*.swo
|
|
62
|
+
*~
|
|
63
|
+
.DS_Store
|
|
64
|
+
|
|
65
|
+
# Environment variables
|
|
66
|
+
.env
|
|
67
|
+
.env.local
|
|
68
|
+
.env.*.local
|
|
69
|
+
|
|
70
|
+
# Database
|
|
71
|
+
*.db
|
|
72
|
+
*.sqlite
|
|
73
|
+
*.sqlite3
|
|
74
|
+
|
|
75
|
+
# Alembic
|
|
76
|
+
alembic/versions/*.py
|
|
77
|
+
!alembic/versions/.gitkeep
|
|
78
|
+
|
|
79
|
+
# Logs
|
|
80
|
+
logs/
|
|
81
|
+
*.log
|
|
82
|
+
|
|
83
|
+
# Jupyter Notebook
|
|
84
|
+
.ipynb_checkpoints
|
|
85
|
+
|
|
86
|
+
# pyenv
|
|
87
|
+
.python-version.local
|
|
88
|
+
|
|
89
|
+
# Celery
|
|
90
|
+
celerybeat-schedule
|
|
91
|
+
celerybeat.pid
|
|
92
|
+
|
|
93
|
+
# SageMath parsed files
|
|
94
|
+
*.sage.py
|
|
95
|
+
|
|
96
|
+
# Profiling
|
|
97
|
+
.prof
|
|
98
|
+
|
|
99
|
+
# Security
|
|
100
|
+
.secrets.baseline
|
|
101
|
+
|
|
102
|
+
# Local development
|
|
103
|
+
.DS_Store
|
|
104
|
+
Thumbs.db
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Alembic environment configuration for SQLModel
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
from logging.config import fileConfig
|
|
7
|
+
|
|
8
|
+
from alembic import context
|
|
9
|
+
from sqlalchemy import pool
|
|
10
|
+
from sqlalchemy.engine import Connection
|
|
11
|
+
from sqlalchemy.ext.asyncio import async_engine_from_config
|
|
12
|
+
from sqlmodel import SQLModel
|
|
13
|
+
from src.core.config import settings
|
|
14
|
+
|
|
15
|
+
# Import your models here to ensure they're registered
|
|
16
|
+
from src.models import Item # noqa: F401
|
|
17
|
+
|
|
18
|
+
# this is the Alembic Config object, which provides
|
|
19
|
+
# access to the values within the .ini file in use.
|
|
20
|
+
config = context.config
|
|
21
|
+
|
|
22
|
+
# Interpret the config file for Python logging.
|
|
23
|
+
# This line sets up loggers basically.
|
|
24
|
+
if config.config_file_name is not None:
|
|
25
|
+
fileConfig(config.config_file_name)
|
|
26
|
+
|
|
27
|
+
# Set the SQLAlchemy URL from settings
|
|
28
|
+
config.set_main_option(
|
|
29
|
+
"sqlalchemy.url", settings.DATABASE_URL.replace("postgresql://", "postgresql+asyncpg://")
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# add your model's MetaData object here
|
|
33
|
+
# for 'autogenerate' support
|
|
34
|
+
target_metadata = SQLModel.metadata
|
|
35
|
+
|
|
36
|
+
# other values from the config, defined by the needs of env.py,
|
|
37
|
+
# can be acquired:
|
|
38
|
+
# my_important_option = config.get_main_option("my_important_option")
|
|
39
|
+
# ... etc.
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def run_migrations_offline() -> None:
|
|
43
|
+
"""Run migrations in 'offline' mode.
|
|
44
|
+
|
|
45
|
+
This configures the context with just a URL
|
|
46
|
+
and not an Engine, though an Engine is acceptable
|
|
47
|
+
here as well. By skipping the Engine creation
|
|
48
|
+
we don't even need a DBAPI to be available.
|
|
49
|
+
|
|
50
|
+
Calls to context.execute() here emit the given string to the
|
|
51
|
+
script output.
|
|
52
|
+
|
|
53
|
+
"""
|
|
54
|
+
url = config.get_main_option("sqlalchemy.url")
|
|
55
|
+
context.configure(
|
|
56
|
+
url=url,
|
|
57
|
+
target_metadata=target_metadata,
|
|
58
|
+
literal_binds=True,
|
|
59
|
+
dialect_opts={"paramstyle": "named"},
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
with context.begin_transaction():
|
|
63
|
+
context.run_migrations()
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def do_run_migrations(connection: Connection) -> None:
|
|
67
|
+
"""Run migrations with the given connection."""
|
|
68
|
+
context.configure(connection=connection, target_metadata=target_metadata)
|
|
69
|
+
|
|
70
|
+
with context.begin_transaction():
|
|
71
|
+
context.run_migrations()
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
async def run_async_migrations() -> None:
|
|
75
|
+
"""Run migrations in async mode."""
|
|
76
|
+
connectable = async_engine_from_config(
|
|
77
|
+
config.get_section(config.config_ini_section, {}),
|
|
78
|
+
prefix="sqlalchemy.",
|
|
79
|
+
poolclass=pool.NullPool,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
async with connectable.connect() as connection:
|
|
83
|
+
await connection.run_sync(do_run_migrations)
|
|
84
|
+
|
|
85
|
+
await connectable.dispose()
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def run_migrations_online() -> None:
|
|
89
|
+
"""Run migrations in 'online' mode."""
|
|
90
|
+
asyncio.run(run_async_migrations())
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
if context.is_offline_mode():
|
|
94
|
+
run_migrations_offline()
|
|
95
|
+
else:
|
|
96
|
+
run_migrations_online()
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# A generic, single database configuration.
|
|
2
|
+
|
|
3
|
+
[alembic]
|
|
4
|
+
# path to migration scripts
|
|
5
|
+
script_location = alembic
|
|
6
|
+
|
|
7
|
+
# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s
|
|
8
|
+
# Uncomment the line below if you want the files to be prepended with date and time
|
|
9
|
+
# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s
|
|
10
|
+
|
|
11
|
+
# sys.path path, will be prepended to sys.path if present.
|
|
12
|
+
# defaults to the current working directory.
|
|
13
|
+
prepend_sys_path = .
|
|
14
|
+
|
|
15
|
+
# timezone to use when rendering the date within the migration file
|
|
16
|
+
# as well as the filename.
|
|
17
|
+
# If specified, requires the python-dateutil library that can be
|
|
18
|
+
# installed by adding `alembic[tz]` to the pip requirements
|
|
19
|
+
# string value is passed to dateutil.tz.gettz()
|
|
20
|
+
# leave blank for localtime
|
|
21
|
+
# timezone =
|
|
22
|
+
|
|
23
|
+
# max length of characters to apply to the
|
|
24
|
+
# "slug" field
|
|
25
|
+
# truncate_slug_length = 40
|
|
26
|
+
|
|
27
|
+
# set to 'true' to run the environment during
|
|
28
|
+
# the 'revision' command, regardless of autogenerate
|
|
29
|
+
# revision_environment = false
|
|
30
|
+
|
|
31
|
+
# set to 'true' to allow .pyc and .pyo files without
|
|
32
|
+
# a source .py file to be detected as revisions in the
|
|
33
|
+
# versions/ directory
|
|
34
|
+
# sourceless = false
|
|
35
|
+
|
|
36
|
+
# version location specification; This defaults
|
|
37
|
+
# to alembic/versions. When using multiple version
|
|
38
|
+
# directories, initial revisions must be specified with --version-path.
|
|
39
|
+
# The path separator used here should be the separator specified by "version_path_separator" below.
|
|
40
|
+
# version_locations = %(here)s/bar:%(here)s/bat:alembic/versions
|
|
41
|
+
|
|
42
|
+
# version path separator; As mentioned above, this is the character used to split
|
|
43
|
+
# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep.
|
|
44
|
+
# If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas.
|
|
45
|
+
# Valid values for version_path_separator are:
|
|
46
|
+
#
|
|
47
|
+
# version_path_separator = :
|
|
48
|
+
# version_path_separator = ;
|
|
49
|
+
# version_path_separator = space
|
|
50
|
+
version_path_separator = os # Use os.pathsep. Default configuration used for new projects.
|
|
51
|
+
|
|
52
|
+
# set to 'true' to search source files recursively
|
|
53
|
+
# in each "version_locations" directory
|
|
54
|
+
# new in Alembic version 1.10
|
|
55
|
+
# recursive_version_locations = false
|
|
56
|
+
|
|
57
|
+
# the output encoding used when revision files
|
|
58
|
+
# are written from script.py.mako
|
|
59
|
+
# output_encoding = utf-8
|
|
60
|
+
|
|
61
|
+
sqlalchemy.url = driver://user:pass@localhost/dbname
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
[post_write_hooks]
|
|
65
|
+
# post_write_hooks defines scripts or Python functions that are run
|
|
66
|
+
# on newly generated revision scripts. See the documentation for further
|
|
67
|
+
# detail and examples
|
|
68
|
+
|
|
69
|
+
# format using "black" - use the console_scripts runner, against the "black" entrypoint
|
|
70
|
+
# hooks = black
|
|
71
|
+
# black.type = console_scripts
|
|
72
|
+
# black.entrypoint = black
|
|
73
|
+
# black.options = -l 79 REVISION_SCRIPT_FILENAME
|
|
74
|
+
|
|
75
|
+
# lint with attempts to fix using "ruff" - use the exec runner, execute a binary
|
|
76
|
+
# hooks = ruff
|
|
77
|
+
# ruff.type = exec
|
|
78
|
+
# ruff.executable = ruff
|
|
79
|
+
# ruff.options = --fix REVISION_SCRIPT_FILENAME
|
|
80
|
+
|
|
81
|
+
# Logging configuration
|
|
82
|
+
[loggers]
|
|
83
|
+
keys = root,sqlalchemy,alembic
|
|
84
|
+
|
|
85
|
+
[handlers]
|
|
86
|
+
keys = console
|
|
87
|
+
|
|
88
|
+
[formatters]
|
|
89
|
+
keys = generic
|
|
90
|
+
|
|
91
|
+
[logger_root]
|
|
92
|
+
level = WARN
|
|
93
|
+
handlers = console
|
|
94
|
+
qualname =
|
|
95
|
+
|
|
96
|
+
[logger_sqlalchemy]
|
|
97
|
+
level = WARN
|
|
98
|
+
handlers =
|
|
99
|
+
qualname = sqlalchemy.engine
|
|
100
|
+
|
|
101
|
+
[logger_alembic]
|
|
102
|
+
level = INFO
|
|
103
|
+
handlers =
|
|
104
|
+
qualname = alembic
|
|
105
|
+
|
|
106
|
+
[handler_console]
|
|
107
|
+
class = StreamHandler
|
|
108
|
+
args = (sys.stderr,)
|
|
109
|
+
level = NOTSET
|
|
110
|
+
formatter = generic
|
|
111
|
+
|
|
112
|
+
[formatter_generic]
|
|
113
|
+
format = %(levelname)-5.5s [%(name)s] %(message)s
|
|
114
|
+
datefmt = %H:%M:%S
|