svc-infra 0.1.562__py3-none-any.whl → 0.1.654__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.
Files changed (175) hide show
  1. svc_infra/apf_payments/README.md +732 -0
  2. svc_infra/apf_payments/models.py +142 -4
  3. svc_infra/apf_payments/provider/__init__.py +4 -0
  4. svc_infra/apf_payments/provider/aiydan.py +797 -0
  5. svc_infra/apf_payments/provider/base.py +178 -12
  6. svc_infra/apf_payments/provider/stripe.py +757 -48
  7. svc_infra/apf_payments/schemas.py +163 -1
  8. svc_infra/apf_payments/service.py +582 -42
  9. svc_infra/apf_payments/settings.py +22 -2
  10. svc_infra/api/fastapi/admin/__init__.py +3 -0
  11. svc_infra/api/fastapi/admin/add.py +231 -0
  12. svc_infra/api/fastapi/apf_payments/router.py +792 -73
  13. svc_infra/api/fastapi/apf_payments/setup.py +13 -4
  14. svc_infra/api/fastapi/auth/add.py +10 -4
  15. svc_infra/api/fastapi/auth/gaurd.py +67 -5
  16. svc_infra/api/fastapi/auth/routers/oauth_router.py +74 -34
  17. svc_infra/api/fastapi/auth/routers/session_router.py +63 -0
  18. svc_infra/api/fastapi/auth/settings.py +2 -0
  19. svc_infra/api/fastapi/billing/router.py +64 -0
  20. svc_infra/api/fastapi/billing/setup.py +19 -0
  21. svc_infra/api/fastapi/cache/add.py +9 -5
  22. svc_infra/api/fastapi/db/nosql/mongo/add.py +33 -27
  23. svc_infra/api/fastapi/db/sql/add.py +40 -18
  24. svc_infra/api/fastapi/db/sql/crud_router.py +176 -14
  25. svc_infra/api/fastapi/db/sql/session.py +16 -0
  26. svc_infra/api/fastapi/db/sql/users.py +13 -1
  27. svc_infra/api/fastapi/dependencies/ratelimit.py +116 -0
  28. svc_infra/api/fastapi/docs/add.py +160 -0
  29. svc_infra/api/fastapi/docs/landing.py +1 -1
  30. svc_infra/api/fastapi/docs/scoped.py +41 -6
  31. svc_infra/api/fastapi/middleware/errors/handlers.py +45 -7
  32. svc_infra/api/fastapi/middleware/graceful_shutdown.py +87 -0
  33. svc_infra/api/fastapi/middleware/idempotency.py +82 -42
  34. svc_infra/api/fastapi/middleware/idempotency_store.py +187 -0
  35. svc_infra/api/fastapi/middleware/optimistic_lock.py +37 -0
  36. svc_infra/api/fastapi/middleware/ratelimit.py +84 -11
  37. svc_infra/api/fastapi/middleware/ratelimit_store.py +84 -0
  38. svc_infra/api/fastapi/middleware/request_size_limit.py +36 -0
  39. svc_infra/api/fastapi/middleware/timeout.py +148 -0
  40. svc_infra/api/fastapi/openapi/mutators.py +244 -38
  41. svc_infra/api/fastapi/ops/add.py +73 -0
  42. svc_infra/api/fastapi/pagination.py +133 -32
  43. svc_infra/api/fastapi/routers/ping.py +1 -0
  44. svc_infra/api/fastapi/setup.py +23 -14
  45. svc_infra/api/fastapi/tenancy/add.py +19 -0
  46. svc_infra/api/fastapi/tenancy/context.py +112 -0
  47. svc_infra/api/fastapi/versioned.py +101 -0
  48. svc_infra/app/README.md +5 -5
  49. svc_infra/billing/__init__.py +23 -0
  50. svc_infra/billing/async_service.py +147 -0
  51. svc_infra/billing/jobs.py +230 -0
  52. svc_infra/billing/models.py +131 -0
  53. svc_infra/billing/quotas.py +101 -0
  54. svc_infra/billing/schemas.py +33 -0
  55. svc_infra/billing/service.py +115 -0
  56. svc_infra/bundled_docs/README.md +5 -0
  57. svc_infra/bundled_docs/__init__.py +1 -0
  58. svc_infra/bundled_docs/getting-started.md +6 -0
  59. svc_infra/cache/__init__.py +4 -0
  60. svc_infra/cache/add.py +158 -0
  61. svc_infra/cache/backend.py +5 -2
  62. svc_infra/cache/decorators.py +19 -1
  63. svc_infra/cache/keys.py +24 -4
  64. svc_infra/cli/__init__.py +32 -8
  65. svc_infra/cli/__main__.py +4 -0
  66. svc_infra/cli/cmds/__init__.py +10 -0
  67. svc_infra/cli/cmds/db/nosql/mongo/mongo_cmds.py +4 -3
  68. svc_infra/cli/cmds/db/nosql/mongo/mongo_scaffold_cmds.py +4 -4
  69. svc_infra/cli/cmds/db/sql/alembic_cmds.py +80 -11
  70. svc_infra/cli/cmds/db/sql/sql_export_cmds.py +80 -0
  71. svc_infra/cli/cmds/db/sql/sql_scaffold_cmds.py +3 -3
  72. svc_infra/cli/cmds/docs/docs_cmds.py +140 -0
  73. svc_infra/cli/cmds/dx/__init__.py +12 -0
  74. svc_infra/cli/cmds/dx/dx_cmds.py +99 -0
  75. svc_infra/cli/cmds/help.py +4 -0
  76. svc_infra/cli/cmds/jobs/__init__.py +1 -0
  77. svc_infra/cli/cmds/jobs/jobs_cmds.py +43 -0
  78. svc_infra/cli/cmds/obs/obs_cmds.py +4 -3
  79. svc_infra/cli/cmds/sdk/__init__.py +0 -0
  80. svc_infra/cli/cmds/sdk/sdk_cmds.py +102 -0
  81. svc_infra/data/add.py +61 -0
  82. svc_infra/data/backup.py +53 -0
  83. svc_infra/data/erasure.py +45 -0
  84. svc_infra/data/fixtures.py +40 -0
  85. svc_infra/data/retention.py +55 -0
  86. svc_infra/db/inbox.py +67 -0
  87. svc_infra/db/nosql/mongo/README.md +13 -13
  88. svc_infra/db/outbox.py +104 -0
  89. svc_infra/db/sql/repository.py +52 -12
  90. svc_infra/db/sql/resource.py +5 -0
  91. svc_infra/db/sql/templates/models_schemas/auth/schemas.py.tmpl +1 -1
  92. svc_infra/db/sql/templates/setup/env_async.py.tmpl +13 -8
  93. svc_infra/db/sql/templates/setup/env_sync.py.tmpl +9 -5
  94. svc_infra/db/sql/tenant.py +79 -0
  95. svc_infra/db/sql/utils.py +18 -4
  96. svc_infra/db/sql/versioning.py +14 -0
  97. svc_infra/docs/acceptance-matrix.md +71 -0
  98. svc_infra/docs/acceptance.md +44 -0
  99. svc_infra/docs/admin.md +425 -0
  100. svc_infra/docs/adr/0002-background-jobs-and-scheduling.md +40 -0
  101. svc_infra/docs/adr/0003-webhooks-framework.md +24 -0
  102. svc_infra/docs/adr/0004-tenancy-model.md +42 -0
  103. svc_infra/docs/adr/0005-data-lifecycle.md +86 -0
  104. svc_infra/docs/adr/0006-ops-slos-and-metrics.md +47 -0
  105. svc_infra/docs/adr/0007-docs-and-sdks.md +83 -0
  106. svc_infra/docs/adr/0008-billing-primitives.md +143 -0
  107. svc_infra/docs/adr/0009-acceptance-harness.md +40 -0
  108. svc_infra/docs/adr/0010-timeouts-and-resource-limits.md +54 -0
  109. svc_infra/docs/adr/0011-admin-scope-and-impersonation.md +73 -0
  110. svc_infra/docs/api.md +59 -0
  111. svc_infra/docs/auth.md +11 -0
  112. svc_infra/docs/billing.md +190 -0
  113. svc_infra/docs/cache.md +76 -0
  114. svc_infra/docs/cli.md +74 -0
  115. svc_infra/docs/contributing.md +34 -0
  116. svc_infra/docs/data-lifecycle.md +52 -0
  117. svc_infra/docs/database.md +14 -0
  118. svc_infra/docs/docs-and-sdks.md +62 -0
  119. svc_infra/docs/environment.md +114 -0
  120. svc_infra/docs/getting-started.md +63 -0
  121. svc_infra/docs/idempotency.md +111 -0
  122. svc_infra/docs/jobs.md +67 -0
  123. svc_infra/docs/observability.md +16 -0
  124. svc_infra/docs/ops.md +37 -0
  125. svc_infra/docs/rate-limiting.md +125 -0
  126. svc_infra/docs/repo-review.md +48 -0
  127. svc_infra/docs/security.md +176 -0
  128. svc_infra/docs/tenancy.md +35 -0
  129. svc_infra/docs/timeouts-and-resource-limits.md +147 -0
  130. svc_infra/docs/versioned-integrations.md +146 -0
  131. svc_infra/docs/webhooks.md +112 -0
  132. svc_infra/dx/add.py +63 -0
  133. svc_infra/dx/changelog.py +74 -0
  134. svc_infra/dx/checks.py +67 -0
  135. svc_infra/http/__init__.py +13 -0
  136. svc_infra/http/client.py +72 -0
  137. svc_infra/jobs/builtins/outbox_processor.py +38 -0
  138. svc_infra/jobs/builtins/webhook_delivery.py +90 -0
  139. svc_infra/jobs/easy.py +32 -0
  140. svc_infra/jobs/loader.py +45 -0
  141. svc_infra/jobs/queue.py +81 -0
  142. svc_infra/jobs/redis_queue.py +191 -0
  143. svc_infra/jobs/runner.py +75 -0
  144. svc_infra/jobs/scheduler.py +41 -0
  145. svc_infra/jobs/worker.py +40 -0
  146. svc_infra/mcp/svc_infra_mcp.py +85 -28
  147. svc_infra/obs/README.md +2 -0
  148. svc_infra/obs/add.py +54 -7
  149. svc_infra/obs/grafana/dashboards/http-overview.json +45 -0
  150. svc_infra/obs/metrics/__init__.py +53 -0
  151. svc_infra/obs/metrics.py +52 -0
  152. svc_infra/security/add.py +201 -0
  153. svc_infra/security/audit.py +130 -0
  154. svc_infra/security/audit_service.py +73 -0
  155. svc_infra/security/headers.py +52 -0
  156. svc_infra/security/hibp.py +95 -0
  157. svc_infra/security/jwt_rotation.py +53 -0
  158. svc_infra/security/lockout.py +96 -0
  159. svc_infra/security/models.py +255 -0
  160. svc_infra/security/org_invites.py +128 -0
  161. svc_infra/security/passwords.py +77 -0
  162. svc_infra/security/permissions.py +149 -0
  163. svc_infra/security/session.py +98 -0
  164. svc_infra/security/signed_cookies.py +80 -0
  165. svc_infra/webhooks/__init__.py +16 -0
  166. svc_infra/webhooks/add.py +322 -0
  167. svc_infra/webhooks/fastapi.py +37 -0
  168. svc_infra/webhooks/router.py +55 -0
  169. svc_infra/webhooks/service.py +67 -0
  170. svc_infra/webhooks/signing.py +30 -0
  171. svc_infra-0.1.654.dist-info/METADATA +154 -0
  172. {svc_infra-0.1.562.dist-info → svc_infra-0.1.654.dist-info}/RECORD +174 -56
  173. svc_infra-0.1.562.dist-info/METADATA +0 -79
  174. {svc_infra-0.1.562.dist-info → svc_infra-0.1.654.dist-info}/WHEEL +0 -0
  175. {svc_infra-0.1.562.dist-info → svc_infra-0.1.654.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,30 @@
1
+ from __future__ import annotations
2
+
3
+ import hashlib
4
+ import hmac
5
+ import json
6
+ from typing import Dict, Iterable
7
+
8
+
9
+ def canonical_body(payload: Dict) -> bytes:
10
+ return json.dumps(payload, separators=(",", ":"), sort_keys=True).encode()
11
+
12
+
13
+ def sign(secret: str, payload: Dict) -> str:
14
+ body = canonical_body(payload)
15
+ return hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
16
+
17
+
18
+ def verify(secret: str, payload: Dict, signature: str) -> bool:
19
+ expected = sign(secret, payload)
20
+ try:
21
+ return hmac.compare_digest(expected, signature)
22
+ except Exception:
23
+ return False
24
+
25
+
26
+ def verify_any(secrets: Iterable[str], payload: Dict, signature: str) -> bool:
27
+ for s in secrets:
28
+ if verify(s, payload, signature):
29
+ return True
30
+ return False
@@ -0,0 +1,154 @@
1
+ Metadata-Version: 2.3
2
+ Name: svc-infra
3
+ Version: 0.1.654
4
+ Summary: Infrastructure for building and deploying prod-ready services
5
+ License: MIT
6
+ Keywords: fastapi,sqlalchemy,alembic,auth,infra,async,pydantic
7
+ Author: Ali Khatami
8
+ Author-email: aliikhatami94@gmail.com
9
+ Requires-Python: >=3.11,<4.0
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Framework :: FastAPI
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3 :: Only
19
+ Classifier: Typing :: Typed
20
+ Provides-Extra: duckdb
21
+ Provides-Extra: metrics
22
+ Provides-Extra: mssql
23
+ Provides-Extra: mysql
24
+ Provides-Extra: pg
25
+ Provides-Extra: pg2
26
+ Provides-Extra: redshift
27
+ Provides-Extra: snowflake
28
+ Provides-Extra: sqlite
29
+ Requires-Dist: adyen (>=13.4.0,<14.0.0)
30
+ Requires-Dist: ai-infra (>=0.1.63,<0.2.0)
31
+ Requires-Dist: aiosqlite (>=0.20.0,<0.21.0) ; extra == "sqlite"
32
+ Requires-Dist: alembic (>=1.13.2,<2.0.0)
33
+ Requires-Dist: asyncpg (>=0.30.0,<0.31.0) ; extra == "pg"
34
+ Requires-Dist: authlib (>=1.6.2,<2.0.0)
35
+ Requires-Dist: cashews[redis] (>=7.4.1,<8.0.0)
36
+ Requires-Dist: duckdb (>=1.1.3,<2.0.0) ; extra == "duckdb"
37
+ Requires-Dist: email-validator (>=2.2.0,<3.0.0)
38
+ Requires-Dist: fastapi (>=0.116.1,<0.117.0)
39
+ Requires-Dist: fastapi-users-db-sqlalchemy (>=7.0.0,<8.0.0)
40
+ Requires-Dist: fastapi-users[oauth] (>=14.0.1,<15.0.0)
41
+ Requires-Dist: greenlet (>=3,<4)
42
+ Requires-Dist: httpx (>=0.28.1,<0.29.0)
43
+ Requires-Dist: httpx-oauth (>=0.16.1,<0.17.0)
44
+ Requires-Dist: itsdangerous (>=2.2.0,<3.0.0)
45
+ Requires-Dist: mcp (>=1.13.0,<2.0.0)
46
+ Requires-Dist: motor (>=3.7.1,<4.0.0)
47
+ Requires-Dist: mysqlclient (>=2.2.4,<3.0.0) ; extra == "mysql"
48
+ Requires-Dist: opentelemetry-exporter-otlp (>=1.36.0,<2.0.0)
49
+ Requires-Dist: opentelemetry-instrumentation-fastapi (>=0.57b0,<0.58)
50
+ Requires-Dist: opentelemetry-instrumentation-httpx (>=0.57b0,<0.58)
51
+ Requires-Dist: opentelemetry-instrumentation-requests (>=0.57b0,<0.58)
52
+ Requires-Dist: opentelemetry-instrumentation-sqlalchemy (>=0.57b0,<0.58)
53
+ Requires-Dist: opentelemetry-propagator-b3 (>=1.36.0,<2.0.0)
54
+ Requires-Dist: opentelemetry-sdk (>=1.36.0,<2.0.0)
55
+ Requires-Dist: passlib[bcrypt] (>=1.7.4,<2.0.0)
56
+ Requires-Dist: pre-commit (>=4.3.0,<5.0.0)
57
+ Requires-Dist: prometheus-client (>=0.22.1,<0.23.0) ; extra == "metrics"
58
+ Requires-Dist: psycopg2-binary (>=2.9.10,<3.0.0) ; extra == "pg2"
59
+ Requires-Dist: psycopg[binary] (>=3.2.10,<4.0.0) ; extra == "pg"
60
+ Requires-Dist: pydantic-settings (>=2.10.1,<3.0.0)
61
+ Requires-Dist: pymysql (>=1.1.1,<2.0.0) ; extra == "mysql"
62
+ Requires-Dist: pyodbc (>=5.1.0,<6.0.0) ; extra == "mssql"
63
+ Requires-Dist: pyotp (>=2.9.0,<3.0.0)
64
+ Requires-Dist: python-dotenv (>=1.1.1,<2.0.0)
65
+ Requires-Dist: redis (>=6.4.0,<7.0.0)
66
+ Requires-Dist: redshift-connector (>=2.0.918,<3.0.0) ; extra == "redshift"
67
+ Requires-Dist: snowflake-connector-python (>=3.12.0,<4.0.0) ; extra == "snowflake"
68
+ Requires-Dist: sqlalchemy[asyncio] (>=2.0.43,<3.0.0)
69
+ Requires-Dist: stripe (>=13.0.1,<14.0.0)
70
+ Requires-Dist: typer (>=0.16.1,<0.17.0)
71
+ Project-URL: Documentation, https://github.com/your-org/svc-infra#readme
72
+ Project-URL: Homepage, https://github.com/your-org/svc-infra
73
+ Project-URL: Issues, https://github.com/your-org/svc-infra/issues
74
+ Project-URL: Repository, https://github.com/your-org/svc-infra
75
+ Description-Content-Type: text/markdown
76
+
77
+ # svc-infra
78
+
79
+ [![PyPI](https://img.shields.io/pypi/v/svc-infra.svg)](https://pypi.org/project/svc-infra/)
80
+ [![Docs](https://img.shields.io/badge/docs-reference-blue)](.)
81
+
82
+ svc-infra packages the shared building blocks we use to ship production FastAPI services fast—HTTP APIs with secure auth, durable persistence, background execution, cache, observability, and webhook plumbing that all share the same batteries-included defaults.
83
+
84
+ ## Helper index
85
+
86
+ | Area | What it covers | Guide |
87
+ | --- | --- | --- |
88
+ | Getting Started | Overview and entry points | [This page](src/svc_infra/docs/getting-started.md) |
89
+ | Environment | Feature switches and env vars | [Environment](src/svc_infra/docs/environment.md) |
90
+ | API | FastAPI bootstrap, middleware, docs wiring | [API guide](src/svc_infra/docs/api.md) |
91
+ | Auth | Sessions, OAuth/OIDC, MFA, SMTP delivery | [Auth](src/svc_infra/docs/auth.md) |
92
+ | Security | Password policy, lockout, signed cookies, headers | [Security](ssrc/svc_infra/docs/ecurity.md) |
93
+ | Database | SQL + Mongo wiring, Alembic helpers, inbox/outbox patterns | [Database](src/svc_infra/docs/database.md) |
94
+ | Tenancy | Multi-tenant boundaries and helpers | [Tenancy](src/svc_infra/docs/tenancy.md) |
95
+ | Idempotency | Idempotent endpoints and middleware | [Idempotency](src/svc_infra/docs/idempotency.md) |
96
+ | Rate Limiting | Middleware, dependency limiter, headers | [Rate limiting](rsrc/svc_infra/docs/ate-limiting.md) |
97
+ | Cache | cashews decorators, namespace management, TTL helpers | [Cache](src/svc_infra/docs/cache.md) |
98
+ | Jobs | JobQueue, scheduler, CLI worker | [Jobs](src/svc_infra/docs/jobs.md) |
99
+ | Observability | Prometheus, Grafana, OpenTelemetry | [Observability](src/svc_infra/docs/observability.md) |
100
+ | Ops | Probes, breakers, SLOs & dashboards | [Ops](src/svc_infra/docs/ops.md) |
101
+ | Webhooks | Subscription store, signing, retry worker | [Webhooks](src/svc_infra/docs/webhooks.md) |
102
+ | CLI | Command groups for sql/mongo/obs/docs/dx/sdk/jobs | [CLI](src/svc_infra/docs/cli.md) |
103
+ | Docs & SDKs | Publishing docs, generating SDKs | [Docs & SDKs](src/svc_infra/docs/docs-and-sdks.md) |
104
+ | Acceptance | Acceptance harness and flows | [Acceptance](src/svc_infra/docs/acceptance.md), [Matrix](src/svc_infra/docs/acceptance-matrix.md) |
105
+ | Contributing | Dev setup and quality gates | [Contributing](src/svc_infra/docs/contributing.md) |
106
+ | Repo Review | Checklist for releasing/PRs | [Repo review](src/svc_infra/docs/repo-review.md) |
107
+ | Data Lifecycle | Fixtures, retention, erasure, backups | [Data lifecycle](src/svc_infra/docs/data-lifecycle.md) |
108
+
109
+ ## Quick Start with Template Example
110
+
111
+ See **ALL** svc-infra features working together in a complete example:
112
+
113
+ ```bash
114
+ # One-time setup (from repo root)
115
+ make setup-template # Scaffolds models, runs migrations
116
+
117
+ # Run the example server
118
+ make run-template # Starts at http://localhost:8001
119
+ ```
120
+
121
+ See [`examples/README.md`](examples/README.md) for full documentation and manual setup options.
122
+
123
+ ## Minimal FastAPI bootstrap
124
+
125
+ ```python
126
+ from fastapi import Depends
127
+ from svc_infra.api.fastapi.ease import easy_service_app
128
+ from svc_infra.api.fastapi.db.sql.add import add_sql_db
129
+ from svc_infra.cache import init_cache
130
+ from svc_infra.jobs.easy import easy_jobs
131
+ from svc_infra.webhooks.fastapi import require_signature
132
+
133
+ app = easy_service_app(name="Billing", release="1.2.3")
134
+ add_sql_db(app) # reads SQL_URL / DB_* envs
135
+ init_cache() # honors CACHE_PREFIX / CACHE_VERSION
136
+ queue, scheduler = easy_jobs() # switches via JOBS_DRIVER / REDIS_URL
137
+
138
+ @app.post("/webhooks/billing")
139
+ async def handle_webhook(payload = Depends(require_signature(lambda: ["current", "next"]))):
140
+ queue.enqueue("process-billing-webhook", payload)
141
+ return {"status": "queued"}
142
+ ```
143
+
144
+ ## Environment switches
145
+
146
+ - **API** – toggle logging/observability and docs exposure with `ENABLE_LOGGING`, `LOG_LEVEL`, `LOG_FORMAT`, `ENABLE_OBS`, `METRICS_PATH`, `OBS_SKIP_PATHS`, and `CORS_ALLOW_ORIGINS`. 【F:src/svc_infra/api/fastapi/ease.py†L67-L111】【F:src/svc_infra/api/fastapi/setup.py†L47-L88】
147
+ - **Auth** – configure JWT secrets, SMTP, cookies, and policy using the `AUTH_…` settings family (e.g., `AUTH_JWT__SECRET`, `AUTH_SMTP_HOST`, `AUTH_SESSION_COOKIE_SECURE`). 【F:src/svc_infra/api/fastapi/auth/settings.py†L23-L91】
148
+ - **Database** – set connection URLs or components via `SQL_URL`/`SQL_URL_FILE`, `DB_DIALECT`, `DB_HOST`, `DB_USER`, `DB_PASSWORD`, plus Mongo knobs like `MONGO_URL`, `MONGO_DB`, and `MONGO_URL_FILE`. 【F:src/svc_infra/api/fastapi/db/sql/add.py†L55-L114】【F:src/svc_infra/db/sql/utils.py†L85-L206】【F:src/svc_infra/db/nosql/mongo/settings.py†L9-L13】【F:src/svc_infra/db/nosql/utils.py†L56-L113】
149
+ - **Jobs** – choose the queue backend with `JOBS_DRIVER` and provide Redis via `REDIS_URL`; interval schedules can be declared with `JOBS_SCHEDULE_JSON`. 【F:src/svc_infra/jobs/easy.py†L11-L27】【F:src/svc_infra/docs/jobs.md†L11-L48】
150
+ - **Cache** – namespace keys and lifetimes through `CACHE_PREFIX`, `CACHE_VERSION`, and TTL overrides `CACHE_TTL_DEFAULT`, `CACHE_TTL_SHORT`, `CACHE_TTL_LONG`. 【F:src/svc_infra/cache/README.md†L20-L173】【F:src/svc_infra/cache/ttl.py†L26-L55】
151
+ - **Observability** – turn metrics on/off or adjust scrape paths with `ENABLE_OBS`, `METRICS_PATH`, `OBS_SKIP_PATHS`, and Prometheus/Grafana flags like `SVC_INFRA_DISABLE_PROMETHEUS`, `SVC_INFRA_RATE_WINDOW`, `SVC_INFRA_DASHBOARD_REFRESH`, `SVC_INFRA_DASHBOARD_RANGE`. 【F:src/svc_infra/api/fastapi/ease.py†L67-L111】【F:src/svc_infra/obs/metrics/asgi.py†L49-L206】【F:src/svc_infra/obs/cloud_dash.py†L85-L108】
152
+ - **Webhooks** – reuse the jobs envs (`JOBS_DRIVER`, `REDIS_URL`) for the delivery worker and queue configuration. 【F:src/svc_infra/docs/webhooks.md†L32-L53】
153
+ - **Security** – enforce password policy, MFA, and rotation with auth prefixes such as `AUTH_PASSWORD_MIN_LENGTH`, `AUTH_PASSWORD_REQUIRE_SYMBOL`, `AUTH_JWT__SECRET`, and `AUTH_JWT__OLD_SECRETS`. 【F:src/svc_infra/docs/security.md†L24-L70】
154
+
@@ -1,23 +1,27 @@
1
1
  svc_infra/__init__.py,sha256=8maroJlM18MasrrLLcSbleK9pc0Q26Ek_sLvfafEG1c,49
2
+ svc_infra/apf_payments/README.md,sha256=wqJrJcCkWIFMS0d1pUhYGt6NmgnxmYJcHFnUnm8Bf1Y,23321
2
3
  svc_infra/apf_payments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
4
  svc_infra/apf_payments/alembic.py,sha256=XJIcCDOoaO1EeJbSx_qK9o4cBi430qyo5gECtjHIojw,299
4
- svc_infra/apf_payments/models.py,sha256=21uJfAxB95Dh01_W9ST6bc-l2WyBjJdnGvYm0rt5K1I,9173
5
- svc_infra/apf_payments/provider/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- svc_infra/apf_payments/provider/base.py,sha256=QyDXkUwpJfnWyjQq7Cp7XEGPI3zyQmaKotNIZoFZaZo,2745
5
+ svc_infra/apf_payments/models.py,sha256=u4U5oszha5uulCIrNoajaFDIc5YmTlh2mtm-yJUvr9I,14251
6
+ svc_infra/apf_payments/provider/__init__.py,sha256=zBh26eY7kcWHD4RXqAKfqaspY0_VE9thfts7aE8zbHg,142
7
+ svc_infra/apf_payments/provider/aiydan.py,sha256=vraxdcPvaLyqF2O-lolKdhKNTWF7upuLpLvv3POt2Zs,31991
8
+ svc_infra/apf_payments/provider/base.py,sha256=1t5znglpGFhjt4zdbuzE5VlHvGarFwzH2oscK8yyKNY,7678
7
9
  svc_infra/apf_payments/provider/registry.py,sha256=NZ4pUkFcbXNtqWEpFeI3NwoKRYGWe9fVQakmlrVLTKE,878
8
- svc_infra/apf_payments/provider/stripe.py,sha256=gSeoaDUwByFtLLswuvs1XYYXy8-n3Qsm3MQ5g34zg8Y,6244
9
- svc_infra/apf_payments/schemas.py,sha256=KD_LopvtoiKGxCz_XfsiWtBCvOU2EwNXHdNZMtIFB4g,4111
10
- svc_infra/apf_payments/service.py,sha256=7YXmxoYjQHodd93as3ENOhgeJENFYqP08Y8--W-QRjc,13067
11
- svc_infra/apf_payments/settings.py,sha256=VnNQbajbv843buUisqa82xOQ-f5JA8JzHD8o01-yhPQ,1239
10
+ svc_infra/apf_payments/provider/stripe.py,sha256=Xb_UjdobbBzK-an9cO1jRWiP6OHvki5MDp6JnS6a1-I,34392
11
+ svc_infra/apf_payments/schemas.py,sha256=1fdGnrXrm8Rmk9nwDsbcvrVIyPL2o8HwbZ7-KY9-yZo,8561
12
+ svc_infra/apf_payments/service.py,sha256=Y5wtT9qnL57b_A3AAIL8fruliAitxeVyMPaYLZsv7ew,34851
13
+ svc_infra/apf_payments/settings.py,sha256=vVWsvz_ajtVlRPH4N8ijSI4V7hUfjZFZT3h4wHRNa-s,2032
12
14
  svc_infra/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
15
  svc_infra/api/fastapi/__init__.py,sha256=VVdQjak74_wTDqmvL05_C97vIFugQxPVU-3JQEFBgR8,747
16
+ svc_infra/api/fastapi/admin/__init__.py,sha256=AmuCHI5EQRCqwM40Gs1245z7MTcYZkg5xuoaplCExko,82
17
+ svc_infra/api/fastapi/admin/add.py,sha256=9mCfvKvwBf_sr-SkpCbF1YMNvg-KRovrM_WV3hHs8m8,8649
14
18
  svc_infra/api/fastapi/apf_payments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- svc_infra/api/fastapi/apf_payments/router.py,sha256=sZheKngTWPQCzaQ1UzQzbbgJuf9zDU9B-xk9OojD5hc,12688
16
- svc_infra/api/fastapi/apf_payments/setup.py,sha256=PX-LHDiyu2eDuaw2m98VPUkF6EmXXRkbjRqh_gL8Kls,2263
19
+ svc_infra/api/fastapi/apf_payments/router.py,sha256=JIMCAZ1_Vie_EfvOS999iYSDH9ZBx1Nfizud-F_b5T0,36788
20
+ svc_infra/api/fastapi/apf_payments/setup.py,sha256=qFxImRUiaBg6YZaCcKIIsr7JTyMr_UTo9dP0MbuqpPg,2553
17
21
  svc_infra/api/fastapi/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
22
  svc_infra/api/fastapi/auth/_cookies.py,sha256=U4heUmMnLezHx8U6ksuUEpSZ6sNMJcIO0gdLpmZ5FXw,1367
19
- svc_infra/api/fastapi/auth/add.py,sha256=HSVP3Y01_gXPnRiJG0tEA9OS-cBd-zmqsiDbLMFGWu4,9528
20
- svc_infra/api/fastapi/auth/gaurd.py,sha256=CMqambXyrLYnpIsfmy1yll8t_74U4KO-yyaIatmIgAI,6414
23
+ svc_infra/api/fastapi/auth/add.py,sha256=nQX1pdhJHMP7kn0D7LLZBrB5nRmkhd6R8b8C_yntL58,9846
24
+ svc_infra/api/fastapi/auth/gaurd.py,sha256=CXT5oMjxy_uQNyDRxQCxY2C4JFpMJqTTAz2j8pY5jOQ,8743
21
25
  svc_infra/api/fastapi/auth/mfa/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
26
  svc_infra/api/fastapi/auth/mfa/models.py,sha256=Te1cpGEBguUgul2NS50W_tHgybuu-TOIMPEBy53y9xc,1232
23
27
  svc_infra/api/fastapi/auth/mfa/pre_auth.py,sha256=ZsXIUNnObF8wx9-sz7PXGHrSSpaY2G0Ed5wwvu8TBzA,1379
@@ -30,30 +34,35 @@ svc_infra/api/fastapi/auth/providers.py,sha256=q-ftVn04dqYxx0rnc28uFKieQqMpc_Jnf
30
34
  svc_infra/api/fastapi/auth/routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
35
  svc_infra/api/fastapi/auth/routers/account.py,sha256=IzLCk9e6ST8oorI8GWTuU0bfPyGvONqAjxadoE6L6Fg,1614
32
36
  svc_infra/api/fastapi/auth/routers/apikey_router.py,sha256=EoX-u1uZ0_r1dZ1hDO_PmG2sfSYZPa7uzj-4c520h8Y,5314
33
- svc_infra/api/fastapi/auth/routers/oauth_router.py,sha256=5NGjGzY5Bz5W-J7FC8LPXZ5LWVe0iBoVbNBmQ_vH3Cs,25069
37
+ svc_infra/api/fastapi/auth/routers/oauth_router.py,sha256=vrqrIJSCnsWJLtA6OdE4xdWMIXQp35flf_EulXzeM2Y,26361
38
+ svc_infra/api/fastapi/auth/routers/session_router.py,sha256=CVCum8Tczdj6ailRm1oRxys_EcNrOgBMYJT25yV4u3c,2359
34
39
  svc_infra/api/fastapi/auth/security.py,sha256=FU_XlaXHO1jocUbxeMOX3w2GWkR5ZXAcWbIUKTmOYvw,6482
35
40
  svc_infra/api/fastapi/auth/sender.py,sha256=7a47HXuP0JLR4NlFQVb3TpoQHOPYybKPJ06C2fMJaec,1811
36
- svc_infra/api/fastapi/auth/settings.py,sha256=KDqa74sHgu82kIXnzjo-2MOmaZHGWupove5ypljI8ak,3329
41
+ svc_infra/api/fastapi/auth/settings.py,sha256=H6jF9EOZOBbRJX0JugvirLMylJw64KK_32osGkJYRB8,3470
37
42
  svc_infra/api/fastapi/auth/state.py,sha256=_FAGOG36EPFAl2VbB6fdsFX0W9JNIdWN9X1_OVMz4Q8,1070
43
+ svc_infra/api/fastapi/billing/router.py,sha256=vy9Zsf49f3c5Ni9xnBxUVmfgWhNBbkCWiZDLNxl8uOg,2132
44
+ svc_infra/api/fastapi/billing/setup.py,sha256=N4_yvNdvCt2l2OUmREUdUAClGwLUvCwqN1IHgY99ZMI,621
38
45
  svc_infra/api/fastapi/cache/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- svc_infra/api/fastapi/cache/add.py,sha256=CX4TWsxrZ2EnN_TjVDOhQf382k8aUj2CXTG1GaZ5jU0,338
46
+ svc_infra/api/fastapi/cache/add.py,sha256=eIgv8zP1Zp5Bg0i1ZeDIJlP9wtnOePx7x0e0LaEtpCM,429
40
47
  svc_infra/api/fastapi/db/__init__.py,sha256=ixNtgx8afhMDnLMEFis672r3t5yVC-Bt8VkTX15S95A,355
41
48
  svc_infra/api/fastapi/db/http.py,sha256=tD1Tj0S1G1hYBFSHdu0KfPURs0QoEmOx4zNQdKkZhN8,2280
42
49
  svc_infra/api/fastapi/db/nosql/__init__.py,sha256=Z23rgAMrWCotsUMZVr-5Z78m5w6DIzsstuwxSvqaKR8,175
43
50
  svc_infra/api/fastapi/db/nosql/mongo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
- svc_infra/api/fastapi/db/nosql/mongo/add.py,sha256=CGk0fWLgg4xzsRvBtob4nwYOCOv0_mH6gEi4cTwtWKU,4183
51
+ svc_infra/api/fastapi/db/nosql/mongo/add.py,sha256=LkFxqyjEetfH64uaOv1XZJP2ArdPX3MEaiBMpGVXgQo,4468
45
52
  svc_infra/api/fastapi/db/nosql/mongo/crud_router.py,sha256=9z_H-3SFCFurHv_NajtljnBfF6qH6j4GsJvj_jlfsvs,4223
46
53
  svc_infra/api/fastapi/db/nosql/mongo/health.py,sha256=OM4_Pig3IRSrBhz2yHweIhGlSBrW1bubY_mDt5uyORA,507
47
54
  svc_infra/api/fastapi/db/sql/README.md,sha256=uF_k4wbNSeWR6JF_8evWkeSFidBEXMXcIiYyR6sEv48,3082
48
55
  svc_infra/api/fastapi/db/sql/__init__.py,sha256=R9P1Vy2Uqf9gFISxChMhO9tOGciIjEymVPhpXmsY3zc,255
49
- svc_infra/api/fastapi/db/sql/add.py,sha256=zrt6z4iVPEdq_f8dtBOJW_TRl-WlLBpW35KdTXpUWHQ,4003
50
- svc_infra/api/fastapi/db/sql/crud_router.py,sha256=GCNhGLZ2jfksBfgzqN20eStwpN9oUc9KPd0F0ztk4Bw,5030
56
+ svc_infra/api/fastapi/db/sql/add.py,sha256=9Pg45gwdvfGaKu_c1NxEC2lJYozz_uS6LyzPt5VtfxU,4833
57
+ svc_infra/api/fastapi/db/sql/crud_router.py,sha256=-K6UyP_wOGZu7tXnb1CVqbySNu7wZQ9KvWJfVvi7vPs,11573
51
58
  svc_infra/api/fastapi/db/sql/health.py,sha256=ELLgQerooHHnvZRhGueSAc4QJsb3C4RojUGIu_U-hA4,792
52
- svc_infra/api/fastapi/db/sql/session.py,sha256=DUBqKTRJAX4fqRz9B-w9eD9SpzZ8EUS862-GsjCL3ts,1869
53
- svc_infra/api/fastapi/db/sql/users.py,sha256=g7XI8GWm1h7i_xkDcGBOEy1aZw2XvXB-03Nxgh2Rm_g,4838
59
+ svc_infra/api/fastapi/db/sql/session.py,sha256=5MpwHignl2OmlgWY-SOU7TQ7phJ58enOf2u1nBMZH5w,2567
60
+ svc_infra/api/fastapi/db/sql/users.py,sha256=68HGJgYVTEjKJm4-DPPC8-6nwXJoCukmgrYIIOHEUjs,5346
61
+ svc_infra/api/fastapi/dependencies/ratelimit.py,sha256=DiOC-MJfqTtSydM6RAaeAsiXXL_6oZQoBLvRSpdWzs4,3794
54
62
  svc_infra/api/fastapi/docs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
- svc_infra/api/fastapi/docs/landing.py,sha256=5JqJYCxQDCWy-BeDLfkv7OBlzWQKSGWUCYXQ51hojG8,4627
56
- svc_infra/api/fastapi/docs/scoped.py,sha256=AuN35Op-9fUvHQCLOBtRjd5eWSpB5C9EAW_7-Boxmfo,7540
63
+ svc_infra/api/fastapi/docs/add.py,sha256=41asodVG_0Iokl9dpcGGmFO8z5ak3gNRmsmx6rNHnaM,5689
64
+ svc_infra/api/fastapi/docs/landing.py,sha256=GYFF-2gcYALZOlhJJ5JCrfOpv9j_q_6cfVjY0UGCLFM,4620
65
+ svc_infra/api/fastapi/docs/scoped.py,sha256=3zFGPTrGQtwoNSa0gUXIKzv4ZL6SQStwcmyQ0qGFcxY,9003
57
66
  svc_infra/api/fastapi/dual/__init__.py,sha256=scHLcNFkGbgX_R21V702xnAv6GMCkQ4n7yUtNDNgliM,552
58
67
  svc_infra/api/fastapi/dual/dualize.py,sha256=OkWmuscJlBUlwt3S_P8CssXFsyf5c7F0fCA6bdSl_LU,3829
59
68
  svc_infra/api/fastapi/dual/protected.py,sha256=6e3ojMKJmgrNOEHwfCNo5UNXaqsHbp10Wzt0cCJneJI,3189
@@ -71,28 +80,38 @@ svc_infra/api/fastapi/middleware/debug.py,sha256=H3jBKvdPkr2KHUEMGnqWBPZ0tG6Fgw-
71
80
  svc_infra/api/fastapi/middleware/errors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
81
  svc_infra/api/fastapi/middleware/errors/catchall.py,sha256=TG0W71UCDbfgLNdIaIv6mBSwZA_etMp5GquwKcAwYbI,1842
73
82
  svc_infra/api/fastapi/middleware/errors/exceptions.py,sha256=857_bdMgQugf8rb7U6ZaTZV3aiFTfBzFaUg80YUfAYE,475
74
- svc_infra/api/fastapi/middleware/errors/handlers.py,sha256=9Em_Z6PXTm9gM9ulEYwY02DqRuNxz6LLh8z5CMheruY,7128
75
- svc_infra/api/fastapi/middleware/idempotency.py,sha256=dISECaVpo4Zv9rkdjAp4SI5JECbVxTvS9nQVydPmmY0,2938
76
- svc_infra/api/fastapi/middleware/ratelimit.py,sha256=xcrgOq7IEtMXg9Tzd2u45xhdkPSEc1Zd55OFzLoacmw,1718
83
+ svc_infra/api/fastapi/middleware/errors/handlers.py,sha256=mxPaYMoK5JaF3w4t8gE0X8jqt9wzyxVxpDYgXMp8H9U,8606
84
+ svc_infra/api/fastapi/middleware/graceful_shutdown.py,sha256=U0s0IQHSyjOcxzdLSB_as1pAHobjFA68zbNciejI6GU,2883
85
+ svc_infra/api/fastapi/middleware/idempotency.py,sha256=vnBQgMWzJVaF8oWgfw2ATjEKCyQifDeGPUc9z1N7ebE,5051
86
+ svc_infra/api/fastapi/middleware/idempotency_store.py,sha256=BQN_Cq_jf_cuZRhze4EF5v0lOMQXpUWoRo7CsSTprug,5528
87
+ svc_infra/api/fastapi/middleware/optimistic_lock.py,sha256=9lOMBI4VNIVndXnrMmgSq4qeR7xPjNR1H9d1F71M5S8,1271
88
+ svc_infra/api/fastapi/middleware/ratelimit.py,sha256=Zw55_vlSVz4aqwr7gZ1P53HHZMO6fYUUQ7TXBzjEbw8,5014
89
+ svc_infra/api/fastapi/middleware/ratelimit_store.py,sha256=qJqkDi_iPrWIUZJzkhaYFcgyD1fCNDKFMa_wN53UPSQ,2796
77
90
  svc_infra/api/fastapi/middleware/request_id.py,sha256=Iru7ypTdK_n76lwziEGDWoVF4FKS0Ps1PMASYmzK8ek,768
91
+ svc_infra/api/fastapi/middleware/request_size_limit.py,sha256=AcGqaB-F7Tbhg-at7ViT4Bpifst34jFneDBlUBjgo5I,1248
92
+ svc_infra/api/fastapi/middleware/timeout.py,sha256=VbbJGbJqb7LD6ZGtBrbBu_5ZlZjqkgqKuQg9NC7UrlM,5448
78
93
  svc_infra/api/fastapi/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
94
  svc_infra/api/fastapi/openapi/apply.py,sha256=VAwRfcYSLCSKIpO1dp9okG1MXvkZuciU41jrSSuvUpI,1697
80
95
  svc_infra/api/fastapi/openapi/conventions.py,sha256=e6gUsFyfEGvz3KkUimjAWMfF7_fonMJ3IoGvQZjpvfs,7171
81
96
  svc_infra/api/fastapi/openapi/models.py,sha256=MmXMpPZQjZygajfIHaL4_3q0zluPtpRevsSyOIiE83Y,2562
82
- svc_infra/api/fastapi/openapi/mutators.py,sha256=pghUuNloaIu3M2jvIli6HRjqWGtQDkrkDfEPsJA2YXU,47569
97
+ svc_infra/api/fastapi/openapi/mutators.py,sha256=gzd7WbS_t6zrmFBJ_m1sxpzRNK6g_foHS5TqOED79Qw,55414
83
98
  svc_infra/api/fastapi/openapi/pipeline.py,sha256=GAf-qzwmWlYbrAlPirr8w89fEO4-kFrhCoeMj-7mE44,646
84
99
  svc_infra/api/fastapi/openapi/responses.py,sha256=pBUoJd0lltBkQBJACS1Zd1wd975gbw6dYyMEqyueRuw,1093
85
100
  svc_infra/api/fastapi/openapi/security.py,sha256=U78KMwgc7FilFPLbIE2f6xrp74hq6TDFXpUMGRyK_bg,1248
86
- svc_infra/api/fastapi/pagination.py,sha256=Pb_ZLYgRyi40HhywfnGBAER8p0ZFfggUlYbM3lX0Zac,7854
101
+ svc_infra/api/fastapi/ops/add.py,sha256=ILMzFhYhfAaHEk6iqZQ15a2xgKAiZ0IKNuqWX-T8F04,2560
102
+ svc_infra/api/fastapi/pagination.py,sha256=gQobCBb1dmyRjm62xYfkz-rBq_0hNyD0qEigYaLUky8,10972
87
103
  svc_infra/api/fastapi/paths/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
88
104
  svc_infra/api/fastapi/paths/auth.py,sha256=hy9N0QFQnpv7dBOuHStui5eP9oIGHrawa0sADIVVD64,553
89
105
  svc_infra/api/fastapi/paths/generic.py,sha256=z2hAYoanpxXCksHLJyo5_GsnmmQEgslM5CaG3kVsy0E,38
90
106
  svc_infra/api/fastapi/paths/prefix.py,sha256=I1xEt1lKDlOPn2Oa-y_1B-Q8JCwAPpu3_F_1YUHu_Sc,45
91
107
  svc_infra/api/fastapi/paths/user.py,sha256=z8xv_A3dPhG366ezJU1c839oHbU3tEg06rbx3HUUuL0,323
92
108
  svc_infra/api/fastapi/routers/__init__.py,sha256=pbyrfVZzrMFgX11K47TvTS94yN0q-t-BdrVrGG9QyDk,9163
93
- svc_infra/api/fastapi/routers/ping.py,sha256=4M1xJ5nPu_CSvHHSD2DQJKzS7Mf5m8J-Ok9bXSEwudA,540
94
- svc_infra/api/fastapi/setup.py,sha256=_gXq1oiRavlpTuDHpN640oJhku0HwlGn3s5-So4vg9I,9507
95
- svc_infra/app/README.md,sha256=jWbgyvP90NobTgxlkwyzCZpFOS-zDSkKw0JoRNauCrs,5074
109
+ svc_infra/api/fastapi/routers/ping.py,sha256=71DGaklMAkCL8g_NHdQk9LXG7C_cVem1p8qtapGtnBk,576
110
+ svc_infra/api/fastapi/setup.py,sha256=p2nTdmhsZw9kDTgtOPiQNdez8cRiv_Z4YHO2ztyzfu4,9989
111
+ svc_infra/api/fastapi/tenancy/add.py,sha256=47lhWoHjuqbgSckJBTNGz-Mo5R6W7SQ0hQDiOGC0HU0,509
112
+ svc_infra/api/fastapi/tenancy/context.py,sha256=nYnUKKP88Xy5mZCY7B7ob9PTDAnaKIhrj7pN6s-lBqg,3308
113
+ svc_infra/api/fastapi/versioned.py,sha256=O7FlSyHssvLy4Qo-pagu1zX7Y2m-40WaR1WaDe-VOHk,3238
114
+ svc_infra/app/README.md,sha256=MqnKTVjE9txaqlcl41wAv34hWhNfc_fJXCqCTsEWNdk,5070
96
115
  svc_infra/app/__init__.py,sha256=za20ALo_kvJMgf7R_kF98DWk3h9acmvhYrCMhThcSmU,209
97
116
  svc_infra/app/env.py,sha256=AOs4ksLZDXoAWrXeSnkYZ2yyS4UP68QUYfaWDcQ1QfA,4426
98
117
  svc_infra/app/logging/__init__.py,sha256=Nbu2wWySPztxvjW73yIdIi5NEnVNOrOH1PlaUWYIxIM,116
@@ -100,43 +119,69 @@ svc_infra/app/logging/add.py,sha256=D5wYNYqnhzsh3MVWXzN6ORY5I0cGw5ZdRbEH3ljpi50,
100
119
  svc_infra/app/logging/filter.py,sha256=lPHUoCFoTP5AfwORCvwVe5z2Kltb0MwAXANwrcBAIdE,1992
101
120
  svc_infra/app/logging/formats.py,sha256=65eHUMWj7aD1RG7lCYIBSkFa_B748TutrZsta0OS_-8,4657
102
121
  svc_infra/app/root.py,sha256=344EWBMJCduwzJ1BBo0yGAu15TkryuvOW4qBZ6Gk-8w,1635
122
+ svc_infra/billing/__init__.py,sha256=AdVxgBWibsz0xWk-Z91B7HecA-EhPMSRrXWIYPBgtMA,365
123
+ svc_infra/billing/async_service.py,sha256=afJR3vqkKFm3pIrYURR0E3xUmnRcxIx2TWfeDlLV2js,4680
124
+ svc_infra/billing/jobs.py,sha256=pS6f8pDIarR935rUzXJs6lWoPN5yElbiB_2R46BwX7U,8469
125
+ svc_infra/billing/models.py,sha256=bnCGPKfnK__6x0f0bwKYQsG2GwXjJFi3YRXnq5JYs7c,6083
126
+ svc_infra/billing/quotas.py,sha256=hreWT1ZI4f7uckAA19wlIC6JqgwBWJYrmaGsp0uqa1M,3469
127
+ svc_infra/billing/schemas.py,sha256=fjONpVnI4s4lwlcY8EBr6qHCA5GQ7vRVrxObkoECQJ8,898
128
+ svc_infra/billing/service.py,sha256=3SDpPA3NF2lMYiOP4U99sgXpZAXaauexBfZQmYE2kvU,3727
129
+ svc_infra/bundled_docs/README.md,sha256=FqTieL4ADODxTnig8yehV2KdHX9bASDega52bjp5n70,338
130
+ svc_infra/bundled_docs/__init__.py,sha256=8_jF4fM-3Wf6j_mE4000_9AHcJ3tYZXO9hJY-pBEepM,63
131
+ svc_infra/bundled_docs/getting-started.md,sha256=JaMOgRUK_ajaX4SCtiE3GrhQ81wMwng6y46t0032ftU,210
103
132
  svc_infra/cache/README.md,sha256=ZgIpmE0UVlGktp2nXUYv6FKJATCdkR_01v-GGxHN6Ao,10795
104
- svc_infra/cache/__init__.py,sha256=Fz3NS81jrY5sLikRhITCeHDT4MlOLcbMed5EjVecSAg,956
105
- svc_infra/cache/backend.py,sha256=Vrza_8oi1AYUG1KdFmxg8S11WB4rKpKI246fZn4pdWs,4233
106
- svc_infra/cache/decorators.py,sha256=1lsQyEEGC3etwqKdh-GxUHmudfoZnVy3UjNTZjDOusA,7606
133
+ svc_infra/cache/__init__.py,sha256=5hlTZNdV3DA4SUecAmTy2waAG5eTuNWhc9XCdPT85M4,1031
134
+ svc_infra/cache/add.py,sha256=8JHkcXKj6CP8ioxb6RyR1gkM1hvHLbxjmpW-Kb1SO9k,5848
135
+ svc_infra/cache/backend.py,sha256=-dbZ2qkhebzbKosQqgvBNb01A-2_jGt6_0WmJhPoHy8,4418
136
+ svc_infra/cache/decorators.py,sha256=hsXTcdGo-Q1RKMrqQB0ROmFuce9A1JTt9sJAcWaHvMc,8330
107
137
  svc_infra/cache/demo.py,sha256=MX8LK-4Ju1xAxZtBh-p_Weh8yPNWmmPnDkOW5wAiGKI,2507
108
- svc_infra/cache/keys.py,sha256=6wczoSu4OFBAx4XZdNS94_mParNMox2WTrZRZHgUTpI,3146
138
+ svc_infra/cache/keys.py,sha256=8A122Te4VI40-CpLazEPOBgibX62cyjwClM5SIFeYac,3978
109
139
  svc_infra/cache/recache.py,sha256=adS9OK_dZNGaJKcG0caQlIm449GJ53zd3BkaB_dUF2c,8572
110
140
  svc_infra/cache/resources.py,sha256=BhvPAZvCQ-fitUdniGEOOE4g1ZvljdCA_R5pR8WfJz4,7421
111
141
  svc_infra/cache/tags.py,sha256=9URw4BRlnb4QFAYpDI36fMms6642xq4TeV9jqsEjzE8,2625
112
142
  svc_infra/cache/ttl.py,sha256=_lWvNx1CTE4RcFEOUYkADd7_k4I13SLmtK0AMRUq2OM,1945
113
143
  svc_infra/cache/utils.py,sha256=-LWr5IiJCNm3pwaoeCVlxNknnO2ChNKFcAGlFU98kjg,4856
114
- svc_infra/cli/__init__.py,sha256=0pamzH-j-ePUgnqxfI6NiAiVn9NzptQbNbtNtK4O4oc,624
115
- svc_infra/cli/cmds/__init__.py,sha256=u-plcPPdmz1J4724M0sEdlt3wW7834QgzBLmKBy47hA,613
144
+ svc_infra/cli/__init__.py,sha256=3H3RePgCv_fCw9mFzYkbdn1VEeiZ1T88_BdloqrlEPY,1321
145
+ svc_infra/cli/__main__.py,sha256=5BjNuyet8AY-POwoF5rGt722rHQ7tJ0Vf0UFUfzzi-I,58
146
+ svc_infra/cli/cmds/__init__.py,sha256=xKVXpMP_fD7jfmYonxWxh5LKHUQiuIFaJgkpqtkPt-M,1051
116
147
  svc_infra/cli/cmds/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
117
148
  svc_infra/cli/cmds/db/nosql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
118
149
  svc_infra/cli/cmds/db/nosql/mongo/README.md,sha256=0u3XLeoBd0XQzXwwfEiFISMIij11TJ9iOGzrysBvsFk,1788
119
150
  svc_infra/cli/cmds/db/nosql/mongo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
120
- svc_infra/cli/cmds/db/nosql/mongo/mongo_cmds.py,sha256=83_I0-63aRyR2uRLhpG1DKavH8BJ6fwdL3qpCpksyBU,6109
121
- svc_infra/cli/cmds/db/nosql/mongo/mongo_scaffold_cmds.py,sha256=gsv7V3eGxyhQQm4J8IPYV9xQkdv0DoX7txcPLgbiejk,4277
151
+ svc_infra/cli/cmds/db/nosql/mongo/mongo_cmds.py,sha256=s5oAlZ9bYndiRhtmi9gSbcJPvR82bwCGRbxAF_ziBx4,6125
152
+ svc_infra/cli/cmds/db/nosql/mongo/mongo_scaffold_cmds.py,sha256=AR2sNt8Faxa6vAJ3MxGSWqLU54DMOL_r72hDtnEk4Pg,4253
122
153
  svc_infra/cli/cmds/db/sql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
123
- svc_infra/cli/cmds/db/sql/alembic_cmds.py,sha256=KjumtKSOZR1UxbpZUuqllpknerDLNcY-0kqqqxiOnL4,7664
124
- svc_infra/cli/cmds/db/sql/sql_scaffold_cmds.py,sha256=eNTCqHXOxgl9H3WTbGVn9BHXYwCpjIEJsDqhEFdrYMM,4613
125
- svc_infra/cli/cmds/help.py,sha256=wGfZFMYaR2ZPwW2JwKDU7M3m4AtdCd8GRQ412AmEBUM,758
154
+ svc_infra/cli/cmds/db/sql/alembic_cmds.py,sha256=C0TEZuwGmdb1WaaSbtjHf2RHAlxfuuacjLHfCi7ezxA,10237
155
+ svc_infra/cli/cmds/db/sql/sql_export_cmds.py,sha256=YpkguUJFeFApMphVkhOJllTi25ejlsQaJarMe6vJD54,2685
156
+ svc_infra/cli/cmds/db/sql/sql_scaffold_cmds.py,sha256=MKc_T_tY1Y_wQl7XTlq8GhYWMMI1q1_vcFZVPOEcNUg,4601
157
+ svc_infra/cli/cmds/docs/docs_cmds.py,sha256=kvrBLeAvkv1lx_6TzvY_ciC9NJNBMNbmH0-wzA9LeHo,4501
158
+ svc_infra/cli/cmds/dx/__init__.py,sha256=wQtl3-kOgoESlpVkjl3YFtqkOnQSIvVsOdutiaZFejM,197
159
+ svc_infra/cli/cmds/dx/dx_cmds.py,sha256=XTKUJzS3UIYn6h3CHzDEWKYJaWn0TzGiUCq3OeW27E0,3326
160
+ svc_infra/cli/cmds/help.py,sha256=a_U0MbzBTAs4WHO0e8GcdFwLUA8O5mzVXTxpyelhtiU,906
161
+ svc_infra/cli/cmds/jobs/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
162
+ svc_infra/cli/cmds/jobs/jobs_cmds.py,sha256=l-w5GuR82GWR_F1CA7WPYAM895XBD8TQj_hZ6retBv0,1252
126
163
  svc_infra/cli/cmds/obs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
127
- svc_infra/cli/cmds/obs/obs_cmds.py,sha256=fltUZu5fcnZdl0_JPJBIxIaA1Xqpw1BXE-SWBP-PRuY,6485
164
+ svc_infra/cli/cmds/obs/obs_cmds.py,sha256=cAFzkO6j6FCZZxn5ch93Gq4TflV5Bx-6l3gyhKemxqM,6505
165
+ svc_infra/cli/cmds/sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
166
+ svc_infra/cli/cmds/sdk/sdk_cmds.py,sha256=xzEbhA-L5bXMxf-DFzYXkdITfC4ua1Lt8I9x6PoEax0,2886
128
167
  svc_infra/cli/foundation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
129
168
  svc_infra/cli/foundation/runner.py,sha256=RbfjKwb3aHk1Y0MYU8xMpKRpIqRVMVr8GuL2EDZ6n38,1862
130
169
  svc_infra/cli/foundation/typer_bootstrap.py,sha256=KapgH1R-qON9FuYH1KYlVx_5sJvjmAGl25pB61XCpm4,985
170
+ svc_infra/data/add.py,sha256=IG_1kMthOcYwpBYfZEGr90XE5Z96z2TEnl1hs5w0jAs,2222
171
+ svc_infra/data/backup.py,sha256=LZcfw7aQGge0I0PG8P1dQWkgFHTTPKc5iXnsvf9oAUA,1619
172
+ svc_infra/data/erasure.py,sha256=VG4XKCE9XMc63qHW7jd-mivwzeITOJe-Ru2X1-7bE_I,1155
173
+ svc_infra/data/fixtures.py,sha256=2WKU6-HCKfA_uiwjI0cB_79F-aCbqoo3Ro05ksGbH3Y,1278
174
+ svc_infra/data/retention.py,sha256=8K_lG4vVLl5BaLVw3S2bm2Vu88oTZOpUL9_ifGtes6I,2062
131
175
  svc_infra/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
132
176
  svc_infra/db/crud_schema.py,sha256=-fv-Om1lHVt6lcNbie6A2kRcPex4SDByUPfks6SpmUc,2521
177
+ svc_infra/db/inbox.py,sha256=drxLRLHaMRrCDgo_8wj12do80wDh5ssHV6LGkaM98no,1996
133
178
  svc_infra/db/nosql/__init__.py,sha256=5ETPHk-KYUtc-efuGzDFQmWkT0xFtYy8YWOHobMZhvM,154
134
179
  svc_infra/db/nosql/base.py,sha256=p47VVpwWvGNkyWe5RDSmGaUFyZovcyNqirMqoHFQ4QU,230
135
180
  svc_infra/db/nosql/constants.py,sha256=Z9bJImxwb8D7vovASFegv8XMwaWcM28tsKJV2SjywXE,416
136
181
  svc_infra/db/nosql/core.py,sha256=hWda-OsiutD_7wVLI_S6QkkH6gHK8oHbVzRPjNfIBxY,4634
137
182
  svc_infra/db/nosql/indexes.py,sha256=XCVeSM73x3iF1bWITlyvYOr89dkcgliRcXUMTPg8Tmo,2302
138
183
  svc_infra/db/nosql/management.py,sha256=YreJXcNpPBAQTRGvyXjDK4pJhNL87hljT_2-i7CAlvg,3468
139
- svc_infra/db/nosql/mongo/README.md,sha256=Trygd6gkfMImErrBsR1_DMaxeeUGnmwOFL-9IYX316s,11681
184
+ svc_infra/db/nosql/mongo/README.md,sha256=rFGck7VMGOMh9PZ8KkgDbxzZfbsWAoTJg5UWGlvK4oM,11687
140
185
  svc_infra/db/nosql/mongo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
141
186
  svc_infra/db/nosql/mongo/client.py,sha256=dAhbi6cnhrTz6AgHW48hrXt-ptVl3X8_b75yAyjoOa0,1325
142
187
  svc_infra/db/nosql/mongo/settings.py,sha256=uat8k2FlgBmcEpcKXgzYvIK-_Zi4n-lnFEjlMqr23q8,522
@@ -151,6 +196,7 @@ svc_infra/db/nosql/service.py,sha256=CtltFp1Bwm4wCQnFLDtH5-P5NmUEzkWSAf3htoiTBCQ
151
196
  svc_infra/db/nosql/service_with_hooks.py,sha256=rNH6renb-ppc8Y07jX5eSQnkkhJct2IZCq7mM9aBb48,747
152
197
  svc_infra/db/nosql/types.py,sha256=lcyuoZvBHRlGD24WL2HCEG5YmCpwo7qB4VYAckcY-WE,814
153
198
  svc_infra/db/nosql/utils.py,sha256=3u7X8WEPO1Cwy1SmZHmFMMbDfu1HhapJUAFbSMe3J9g,3524
199
+ svc_infra/db/outbox.py,sha256=1ZIXaYMgQ2wLZX40iR8MKrRL5QNgoMP_jjSr-gSLAjY,3363
154
200
  svc_infra/db/sql/README.md,sha256=OI1T7SiY4_f0eTWQGtIeUsgkFqzvloh1vctOm6nvIvU,8581
155
201
  svc_infra/db/sql/__init__.py,sha256=PkDutfhzofY0jbE83ZuxbrvXhogvP1tmk5MniyfwQws,159
156
202
  svc_infra/db/sql/apikey.py,sha256=27-4GAieD8NxoVKHw_WF2cj8A4UXbcnvtUUTztbo_yw,5019
@@ -159,38 +205,91 @@ svc_infra/db/sql/base.py,sha256=yeOM4Xo2CtTzsfx0hN8KLFTgOPZp6BrbV7Omz_bZUMg,317
159
205
  svc_infra/db/sql/constants.py,sha256=FqtoBWqP13gW8avIWpr8E41PDW5aQ88tjGmnokCV9Lk,1656
160
206
  svc_infra/db/sql/core.py,sha256=2W7o1uyEZBDbqX1ptArP5Fa5obaVpZqHpczJCdf1NZk,10855
161
207
  svc_infra/db/sql/management.py,sha256=bVpzj8BapwcghxAwmBsTnntWf3kaNf7CYETndppaiUM,3620
162
- svc_infra/db/sql/repository.py,sha256=_LT65NLvehGNuD2gq-3oQBATo7W_5-RKC87jA_sYyMU,5838
163
- svc_infra/db/sql/resource.py,sha256=RfbFGo1u4NOZ8AZpBwd7PfK42871eItvFDoCv5COuTo,1058
208
+ svc_infra/db/sql/repository.py,sha256=E3-tTKUfwTzWnJszcJNhC1CZrE7e9QlhE8JrMAqn6GQ,7201
209
+ svc_infra/db/sql/resource.py,sha256=CfBmRvMq_1-cgYBS9uc_G4i1W5e6wk6zo4MGdKTPT9I,1194
164
210
  svc_infra/db/sql/scaffold.py,sha256=aRC572W9Jqs1nLprR_zmmgERthMlJwoUjQ_xbRh53RU,9107
165
211
  svc_infra/db/sql/service.py,sha256=Jtb89FQgXWNRrh_bPLCvNyM7Up0_rn_wx1_CGWfiqNs,2790
166
212
  svc_infra/db/sql/service_with_hooks.py,sha256=E2VHC-nqDp3AAop37WIM9nWyfTOsxzsa7W6jCFWxl9Q,721
167
213
  svc_infra/db/sql/templates/__init__.py,sha256=atHi2TYS0oe8ZzUv2JIMSYdPduuyvu8RcOQASo7SqwM,48
168
214
  svc_infra/db/sql/templates/models_schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
169
215
  svc_infra/db/sql/templates/models_schemas/auth/models.py.tmpl,sha256=9ji7yIAh2Cy942B8f67LBZpuWjtcEclplD0bCvoQd68,9453
170
- svc_infra/db/sql/templates/models_schemas/auth/schemas.py.tmpl,sha256=zLkYVJb-QFiKmjoDCHgSV_7pGvUtc9RC_TUZ37t16-k,2849
216
+ svc_infra/db/sql/templates/models_schemas/auth/schemas.py.tmpl,sha256=EVLGBBtQIlYXz0MN4yqAgbYLw0BdYawpZSFlPiw879g,2872
171
217
  svc_infra/db/sql/templates/models_schemas/entity/models.py.tmpl,sha256=cSUAfYgATv2SI0NQoHkn9Bzvt7RbOZ3_V8_p_VQsNMk,4349
172
218
  svc_infra/db/sql/templates/models_schemas/entity/schemas.py.tmpl,sha256=xHTXk8u2uiqmQe8XpXjGAPg8pDpdr0rLtsSOC_fo9vo,1032
173
219
  svc_infra/db/sql/templates/setup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
174
220
  svc_infra/db/sql/templates/setup/alembic.ini.tmpl,sha256=7SHSOyUq9S7XqVdKpWLJW7gIWadv58t4AIooa306gDo,771
175
- svc_infra/db/sql/templates/setup/env_async.py.tmpl,sha256=inKnexIhdnvwQ9gy-ODBgK1mdSKpzw2Q3pdTS_9AN0A,12781
176
- svc_infra/db/sql/templates/setup/env_sync.py.tmpl,sha256=SP6OocHQIfkZl9g9iV0qVgkKOgQyViURQmTVqIIicPw,14195
221
+ svc_infra/db/sql/templates/setup/env_async.py.tmpl,sha256=h9d-1WBV9033GYT4MVgZQ46qWQZGzOZ2p-cXh7ZUnr0,13186
222
+ svc_infra/db/sql/templates/setup/env_sync.py.tmpl,sha256=GC6uaJ1KZF7ViaNnz3xiZEa_fC-bXI1iwF6Q5g6pdsk,14483
177
223
  svc_infra/db/sql/templates/setup/script.py.mako.tmpl,sha256=RiEMqF6dTN0S_lSRr90w5K2VtyK0_C81kBPZ02qQDZU,588
224
+ svc_infra/db/sql/tenant.py,sha256=erCB_TjZ62NXXIiOjsTOV_u3mM8kj0-R7gy4RFc-NrE,2779
178
225
  svc_infra/db/sql/types.py,sha256=aDcYS-lEb3Aw9nlc8D67wyS5rmE9ZOkblxPjPFbMM_0,863
179
226
  svc_infra/db/sql/uniq.py,sha256=IxW7SpgOTcHEAMe2oaDnuYFvj7YOfyjCpZRXdR45yP8,2530
180
227
  svc_infra/db/sql/uniq_hooks.py,sha256=6gCnO0_Y-rhB0p-VuY0mZ9m1u3haiLWI3Ns_iUTqF_8,4294
181
- svc_infra/db/sql/utils.py,sha256=nzuDcDhnVNehx5Y9BZLgxw8fvpfYbxTfXQsgnznVf4w,32862
228
+ svc_infra/db/sql/utils.py,sha256=fm6wihJ90MUNqP8WBG4hScOndUoNiwkBFzSvOg2AzI4,33574
229
+ svc_infra/db/sql/versioning.py,sha256=okZu2ad5RAFXNLXJgGpcQvZ5bc6gPjRWzwiBT0rEJJw,400
182
230
  svc_infra/db/utils.py,sha256=aTD49VJSEu319kIWJ1uijUoP51co4lNJ3S0_tvuyGio,802
231
+ svc_infra/docs/acceptance-matrix.md,sha256=1J0722pdxNGVtjI5tAZA2wzzr1UiagjvPgzB8zo0Ks8,2383
232
+ svc_infra/docs/acceptance.md,sha256=1e9Ym4YOwnKHLfCTjx9garKlSKEnxzIYunx4cqoWhZ8,2327
233
+ svc_infra/docs/admin.md,sha256=_KCrfNbpfEJhAcl1kuMQrSkRLXt2VIivRalvakgn4r8,12124
234
+ svc_infra/docs/adr/0002-background-jobs-and-scheduling.md,sha256=iscWFmDmMFcaON3W1FePZT9aHvlBLWCoB4QE7iA5BBI,2418
235
+ svc_infra/docs/adr/0003-webhooks-framework.md,sha256=CFFd4RrmbTbKPr_RRuEe4zdpbpU8C6vD_DimCd702zE,1405
236
+ svc_infra/docs/adr/0004-tenancy-model.md,sha256=ZaJesiWqVggrRLbTXCIyyaVNiDDjl0NWPt7dSrj5SIQ,2732
237
+ svc_infra/docs/adr/0005-data-lifecycle.md,sha256=XLFu2I0d_6Oc7e-MOy9UE_UuCkVHCvhWy8rUlVBeAcE,4897
238
+ svc_infra/docs/adr/0006-ops-slos-and-metrics.md,sha256=Qd17l0RKGXczLs2AKJewCAxr2g0SP7BpcLLViGknJnE,2453
239
+ svc_infra/docs/adr/0007-docs-and-sdks.md,sha256=uQ-q-5omaOXPL5tW5q0_1FE9P_OmO9aDHXqWSGme3eg,4481
240
+ svc_infra/docs/adr/0008-billing-primitives.md,sha256=6em0RYeDAQScN7oSZfD_XslzrzIZZ-qykROJixCcEQs,8479
241
+ svc_infra/docs/adr/0009-acceptance-harness.md,sha256=jDmoWn2uJTeK28YZo75YR1ym6NdgcmPOlMfupZlCCBs,2146
242
+ svc_infra/docs/adr/0010-timeouts-and-resource-limits.md,sha256=tpOTjncKJAjTsDN8jSUOTNqEKHfhVcfooxfW0nnbnro,2815
243
+ svc_infra/docs/adr/0011-admin-scope-and-impersonation.md,sha256=tHg0vXzyefr6qEQOes2OyQByZsK-ogDe1VQ1dQn2Ibc,4850
244
+ svc_infra/docs/api.md,sha256=AlPL9kBS6_dM0NrOteDQ9WqalSfKf_p9_zdy1CtGJdU,2384
245
+ svc_infra/docs/auth.md,sha256=PRl9G4UW78cT_7c4koVh5NDlheNAr02CpJT2YFbEXto,1333
246
+ svc_infra/docs/billing.md,sha256=MArKbKhzFwMLaOMABNDRtT_2D0zGgyFZ2r54o-99v68,7884
247
+ svc_infra/docs/cache.md,sha256=mwObz4F_9KwGO2ftcYSvWfieYekJs1dva3UzaIHFI64,2454
248
+ svc_infra/docs/cli.md,sha256=w5og4SWrLyizlJAJiFgcWu2jDSc1Wj3NCYqzbbvg8VE,1702
249
+ svc_infra/docs/contributing.md,sha256=a0PhmzCLFw8S3odxFbI3p5_FOiPMZLrxk15Ujrk7ao4,1175
250
+ svc_infra/docs/data-lifecycle.md,sha256=_XFZCj9qiYgEiN9jO_lq7RcpVIeLVN7REaFziiNCnEI,2684
251
+ svc_infra/docs/database.md,sha256=p_t-4ApQqa7ImhiV6wv0oklDTEZPn-snO1K1FoNtZpI,1129
252
+ svc_infra/docs/docs-and-sdks.md,sha256=v5Uz-CVNswiZ-ITiqo6tiOX5xGJSnftfbA7b3hrqHqI,2330
253
+ svc_infra/docs/environment.md,sha256=w84-1hL3zog6fYYgDLiQRQiAlS2CadjmZmu87Frzxy8,9700
254
+ svc_infra/docs/getting-started.md,sha256=B1ns6Zm_LOGtncuBafxVb2yGHSqRkUsncytJw6RxSbU,5262
255
+ svc_infra/docs/idempotency.md,sha256=jvemdVY4g6xoHW38OAZIS5JxA3SdK8a0iAayx18kIbk,3890
256
+ svc_infra/docs/jobs.md,sha256=iyDPo6oo7fJdBZ9e6Qt9x_kX4sX7_TUUdY89CFiZ61I,1586
257
+ svc_infra/docs/observability.md,sha256=qzu44CSmGwjdLkBj0TQ1LBMmXd7BO2hmJSdByZlBXck,1021
258
+ svc_infra/docs/ops.md,sha256=Tvqg5qvJ2RqLWbHAUlH3JPgK8yn-lNpyHb-lIpYUakg,1508
259
+ svc_infra/docs/rate-limiting.md,sha256=j1df-D9t5sJtv6HVaATfSxQrv5S8zLTo2N9S_3HHzkM,4156
260
+ svc_infra/docs/repo-review.md,sha256=REz2zT1LXURQUB9yZiBn9ICXHkpdpBSJCRTp-AKH190,8153
261
+ svc_infra/docs/security.md,sha256=DMOg58ZvFrmRyGDmuAYdJtF_q22DnhK4d3_q6ijdry0,7081
262
+ svc_infra/docs/tenancy.md,sha256=k7mOvIQWZF1b3-CETyE8UsIPdhGjNNa9Q4j5AXAqQrQ,2023
263
+ svc_infra/docs/timeouts-and-resource-limits.md,sha256=M3AoKQlCmMvgXAGOoBWeVQ-0Fwm0t5Zz0dYUCf54Mbo,6559
264
+ svc_infra/docs/versioned-integrations.md,sha256=bpEAOexrBqHiajTCBn6mQMp83jr2HUGtdatk1zmpwcA,4681
265
+ svc_infra/docs/webhooks.md,sha256=b0F2vnkxOWdYWwCBAo9i39xdi11nbgEtl05JE3e0lrE,3671
266
+ svc_infra/dx/add.py,sha256=FAnLGP0BPm_q_VCEcpUwfj-b0mEse988chh9DHeS7GU,1474
267
+ svc_infra/dx/changelog.py,sha256=9SD29ZzKzbGTA6kHQXiPLtb7uueL1wrRiiLE2qMzz8o,1941
268
+ svc_infra/dx/checks.py,sha256=R6YqRvpKPr9zQgif4QVx2_Zl4s9YjehSkAvwlxK46lI,2267
269
+ svc_infra/http/__init__.py,sha256=K79-aGyq_JdsxhyxispQlnygvf9LhU0_NJQcFYlWB9I,249
270
+ svc_infra/http/client.py,sha256=p83CLFuIKvmuV9fldNGiOk9w4OyukLIbdHIlwRZZXiU,2351
271
+ svc_infra/jobs/builtins/outbox_processor.py,sha256=VZoehNyjdaV_MmV74WMcbZR6z9E3VFMtZC-pxEwK0x0,1247
272
+ svc_infra/jobs/builtins/webhook_delivery.py,sha256=ID0V1r0OgNRlvh8zU_DQaXeZtAMQGaaTTUvqUzZG5JQ,3547
273
+ svc_infra/jobs/easy.py,sha256=eix-OxWeE3vdkY3GGNoYM0GAyOxc928SpiSzMkr9k0A,977
274
+ svc_infra/jobs/loader.py,sha256=LFO6gOacj6rT698vkDg0YfcHDRTue4zus3Nl9QrS5R0,1164
275
+ svc_infra/jobs/queue.py,sha256=KNpYU_za8B7mmmWY6eWDohSRYy7VIKHyWAGD1qkXUOw,2816
276
+ svc_infra/jobs/redis_queue.py,sha256=wgmWKslF1dkYscJe49UgUX7gwEuGyOUWEb0-pn82I3g,7543
277
+ svc_infra/jobs/runner.py,sha256=Cxs1pvcGxK2GCY5r7V6DGRgxadKrIX2tXPGIK6tEx98,2746
278
+ svc_infra/jobs/scheduler.py,sha256=dTUEEyEuTVHNmJT8wPdMu4YjnTN7R_YW67gtCKpqC7M,1180
279
+ svc_infra/jobs/worker.py,sha256=_Xfnhot3WOpDJNtCO5mSds-10sN1Ye2ltDBo_WZ2VpY,1099
183
280
  svc_infra/mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
184
- svc_infra/mcp/svc_infra_mcp.py,sha256=NmBY7AM3_pnHAumE-eM5Njr8kpb7Gh1-fjcZAEammiI,1927
185
- svc_infra/obs/README.md,sha256=wOABJUOhuj0ftGt24ZfuChlFNJTYvYq4KM_rcRIdWRU,7884
281
+ svc_infra/mcp/svc_infra_mcp.py,sha256=ELX4jUOrHa55asCu7q4jhDvfB9EFPNwogqX3fnSa-z0,3489
282
+ svc_infra/obs/README.md,sha256=pmd6AyFZW3GCCi0sr3uTHrPj5KgAI8rrXw8QPkrf1R8,8021
186
283
  svc_infra/obs/__init__.py,sha256=t5DgkiuuhHnfAHChzYqCI1-Fpr68iQ0A1nHOLFIlAuM,75
187
- svc_infra/obs/add.py,sha256=j8Nsv6k7mGM7tGFIoCxgSpFNV93G_WmtSbCIBohHRT4,2026
284
+ svc_infra/obs/add.py,sha256=Qa8pswZDxspIn3oniqe8NYeHmVhFwiYOYxF9xNAyCOs,4016
188
285
  svc_infra/obs/cloud_dash.py,sha256=1rg6NO9kjhN3zCugfBqDxkTN5nQqjQRC5ye2gFxb6g4,4329
189
- svc_infra/obs/metrics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
286
+ svc_infra/obs/grafana/dashboards/http-overview.json,sha256=WVwkMazdfRAAUdLwGItfzePL9sXuDdhlLVbOLtk1Vic,1042
287
+ svc_infra/obs/metrics/__init__.py,sha256=fSqtl2CNV24j13tihK-bsflt0wSSGK8qjxFKvKWBSfk,1421
190
288
  svc_infra/obs/metrics/asgi.py,sha256=d9qvOdwJmkIHeB_YV_QcqflXYXYWiriffuqBaaLRbCg,8873
191
289
  svc_infra/obs/metrics/base.py,sha256=IHpNJk12whfBEerW9Qkj2fV5Iiw_H-Od4gqPcdOVWNs,2649
192
290
  svc_infra/obs/metrics/http.py,sha256=n-AuzOETxxLPpo0h-kTGHyn9-F19od_Eh1pM3C0oVCs,3003
193
291
  svc_infra/obs/metrics/sqlalchemy.py,sha256=pLvp2hdV_4Wa4Bsottd1Kh8Hlru3PXUtUugJMtCdFNM,2353
292
+ svc_infra/obs/metrics.py,sha256=hvvgY3oO1ssqB-IDAeRXf-l4AjrfU-mqKYEsLG0-WF4,1475
194
293
  svc_infra/obs/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
195
294
  svc_infra/obs/providers/compose_cloud/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
196
295
  svc_infra/obs/providers/compose_cloud/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -227,8 +326,27 @@ svc_infra/obs/templates/sidecars/railway/README.md,sha256=3tFBJPKvmxjg3FjtfGYLwB
227
326
  svc_infra/obs/templates/sidecars/railway/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
228
327
  svc_infra/obs/templates/sidecars/railway/agent.yaml,sha256=hYv35yG92XEP_4joMFmMcVTD-4fG_zHitmChjreUJh4,516
229
328
  svc_infra/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
329
+ svc_infra/security/add.py,sha256=VrGPDUSXnGX3caNXi4BbqNllSQ5YGsZzBtKESWXDJzA,6114
330
+ svc_infra/security/audit.py,sha256=r_OrXAz5uIa2o5nVD-8lsWqzggRGDKfp2sWd8URlz-E,4355
331
+ svc_infra/security/audit_service.py,sha256=Xd5V7Iz6PS4YpxmLyJypnaqr8poaaleKwAI2uFF7y1A,2351
332
+ svc_infra/security/headers.py,sha256=CcdNC1j14oj6LS8-TMW2K-l7LIfXYlL12mw8R32b2R0,2074
333
+ svc_infra/security/hibp.py,sha256=dTJXEdUNxLpxS5Eq8vUuWUdzDXh_b3_OjmvlR5jPHvQ,2894
334
+ svc_infra/security/jwt_rotation.py,sha256=VXPRQeSCoJEl2kQnIJZELWIS0-rGUZrxCdH4Fr47vig,1767
335
+ svc_infra/security/lockout.py,sha256=KdKN9FWejuzHRKS9jXzi_f3-lNF6QZyiEDBXCej0LSY,2804
336
+ svc_infra/security/models.py,sha256=yl62mJKTIoTahJASyRJhTxt4jn65dKRQGbR5im45VHU,9618
337
+ svc_infra/security/org_invites.py,sha256=TuXEstZp5GfRQflz8OR2q6m7GpSOonSxm0QU7ojkbH0,3876
338
+ svc_infra/security/passwords.py,sha256=zUiduHFOWYT7USzMkBntI3-LNEyVMn2A78CvaKpB7MY,2459
339
+ svc_infra/security/permissions.py,sha256=gQijNud6jh0yY2JIuZazAVE8i9zYhbwAR6tSjbncv5o,4556
340
+ svc_infra/security/session.py,sha256=JkClqoZ-Moo9yqHzCREXMVSpzyjbn2Zh6zCjtWO93Ik,2848
341
+ svc_infra/security/signed_cookies.py,sha256=2t61BgjsBaTzU46bt7IUJo7lwDRE9_eS4vmAQXJ8mlY,2219
230
342
  svc_infra/utils.py,sha256=VX1yjTx61-YvAymyRhGy18DhybiVdPddiYD_FlKTbJU,952
231
- svc_infra-0.1.562.dist-info/METADATA,sha256=MMwZZII8Aq8nzl_mKvbnLO--64rr0ZSxQB-eXwLyT7E,3487
232
- svc_infra-0.1.562.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
233
- svc_infra-0.1.562.dist-info/entry_points.txt,sha256=6x_nZOsjvn6hRZsMgZLgTasaCSKCgAjsGhACe_CiP0U,48
234
- svc_infra-0.1.562.dist-info/RECORD,,
343
+ svc_infra/webhooks/__init__.py,sha256=fvPhbFoS6whoT67DWp43pL3m1o-et104vwqxunCUAPA,398
344
+ svc_infra/webhooks/add.py,sha256=u9Spfwg0ztQmXg7uXP1sZ9-_qwnagnW4UnV9HvQtPwc,12191
345
+ svc_infra/webhooks/fastapi.py,sha256=BCNvGNxukf6dC2a4i-6en-PrjBGV19YvCWOot5lXWsA,1101
346
+ svc_infra/webhooks/router.py,sha256=6JvAVPMEth_xxHX-IsIOcyMgHX7g1H0OVxVXKLuMp9w,1596
347
+ svc_infra/webhooks/service.py,sha256=hh-rw0otc00vipZ998XaV5mHsk0IDGYqon0FnhaGr60,2229
348
+ svc_infra/webhooks/signing.py,sha256=NCwdZzmravUe7HVIK_uXK0qqf12FG-_MVsgPvOw6lsM,784
349
+ svc_infra-0.1.654.dist-info/METADATA,sha256=9wpBksBDr3J7dq1G601NMdKoc7jhiwgF-YuUbKflyu8,9543
350
+ svc_infra-0.1.654.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
351
+ svc_infra-0.1.654.dist-info/entry_points.txt,sha256=6x_nZOsjvn6hRZsMgZLgTasaCSKCgAjsGhACe_CiP0U,48
352
+ svc_infra-0.1.654.dist-info/RECORD,,