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
@@ -3,18 +3,23 @@ from __future__ import annotations
3
3
  from datetime import datetime
4
4
  from typing import Optional
5
5
 
6
- from sqlalchemy import JSON, Boolean, DateTime, Index, Numeric, String, text
6
+ from sqlalchemy import JSON, Boolean, DateTime, Index, Numeric, String, UniqueConstraint, text
7
7
  from sqlalchemy.orm import Mapped, mapped_column
8
8
 
9
9
  from svc_infra.db.sql.authref import user_fk_constraint, user_id_type
10
10
  from svc_infra.db.sql.base import ModelBase
11
11
 
12
+ TENANT_ID_LEN = 64
13
+
12
14
 
13
15
  class PayCustomer(ModelBase):
14
16
  __tablename__ = "pay_customers"
15
17
 
16
18
  id: Mapped[str] = mapped_column(String(64), primary_key=True)
17
19
 
20
+ # Tenant scoping
21
+ tenant_id: Mapped[str] = mapped_column(String(TENANT_ID_LEN), index=True, nullable=False)
22
+
18
23
  # Always typed to match the actual auth PK; FK is enforced at table level
19
24
  user_id: Mapped[Optional[str]] = mapped_column(user_id_type(), index=True, nullable=True)
20
25
 
@@ -30,6 +35,7 @@ class PayCustomer(ModelBase):
30
35
  __table_args__ = (
31
36
  user_fk_constraint("user_id", ondelete="SET NULL"),
32
37
  Index("ix_pay_customers_user_provider", "user_id", "provider"),
38
+ Index("ix_pay_customers_tenant_provider", "tenant_id", "provider"),
33
39
  )
34
40
 
35
41
 
@@ -38,6 +44,8 @@ class PayIntent(ModelBase):
38
44
 
39
45
  id: Mapped[str] = mapped_column(String(64), primary_key=True)
40
46
 
47
+ tenant_id: Mapped[str] = mapped_column(String(TENANT_ID_LEN), index=True, nullable=False)
48
+
41
49
  user_id: Mapped[Optional[str]] = mapped_column(user_id_type(), index=True, nullable=True)
42
50
 
43
51
  provider: Mapped[str] = mapped_column(String(32), index=True, nullable=False)
@@ -57,6 +65,7 @@ class PayIntent(ModelBase):
57
65
  __table_args__ = (
58
66
  user_fk_constraint("user_id", ondelete="SET NULL"),
59
67
  Index("ix_pay_intents_user_provider", "user_id", "provider"),
68
+ Index("ix_pay_intents_tenant_provider", "tenant_id", "provider"),
60
69
  )
61
70
 
62
71
 
@@ -65,6 +74,8 @@ class PayEvent(ModelBase):
65
74
 
66
75
  id: Mapped[str] = mapped_column(String(64), primary_key=True)
67
76
 
77
+ tenant_id: Mapped[str] = mapped_column(String(TENANT_ID_LEN), index=True, nullable=False)
78
+
68
79
  provider: Mapped[str] = mapped_column(String(32), index=True, nullable=False)
69
80
  provider_event_id: Mapped[str] = mapped_column(
70
81
  String(128), unique=True, index=True, nullable=False
@@ -81,6 +92,8 @@ class LedgerEntry(ModelBase):
81
92
 
82
93
  id: Mapped[str] = mapped_column(String(64), primary_key=True)
83
94
 
95
+ tenant_id: Mapped[str] = mapped_column(String(TENANT_ID_LEN), index=True, nullable=False)
96
+
84
97
  ts: Mapped[datetime] = mapped_column(
85
98
  DateTime(timezone=True),
86
99
  server_default=text("CURRENT_TIMESTAMP"),
@@ -99,12 +112,24 @@ class LedgerEntry(ModelBase):
99
112
  __table_args__ = (
100
113
  user_fk_constraint("user_id", ondelete="SET NULL"),
101
114
  Index("ix_ledger_user_ts", "user_id", "ts"),
115
+ Index("ix_ledger_tenant_provider", "tenant_id", "provider"),
116
+ UniqueConstraint(
117
+ "tenant_id",
118
+ "provider",
119
+ "provider_ref",
120
+ "kind",
121
+ name="uq_ledger_tenant_provider_ref_kind",
122
+ ),
102
123
  )
103
124
 
104
125
 
105
126
  class PayPaymentMethod(ModelBase):
106
127
  __tablename__ = "pay_methods"
128
+
107
129
  id: Mapped[str] = mapped_column(String(64), primary_key=True)
130
+
131
+ tenant_id: Mapped[str] = mapped_column(String(TENANT_ID_LEN), index=True, nullable=False)
132
+
108
133
  user_id: Mapped[Optional[str]] = mapped_column(user_id_type(), index=True, nullable=True)
109
134
  provider: Mapped[str] = mapped_column(String(32), index=True, nullable=False)
110
135
  provider_customer_id: Mapped[str] = mapped_column(String(128), index=True, nullable=False)
@@ -120,12 +145,24 @@ class PayPaymentMethod(ModelBase):
120
145
  DateTime(timezone=True), server_default=text("CURRENT_TIMESTAMP"), nullable=False
121
146
  )
122
147
 
123
- __table_args__ = (user_fk_constraint("user_id", ondelete="SET NULL"),)
148
+ __table_args__ = (
149
+ user_fk_constraint("user_id", ondelete="SET NULL"),
150
+ Index(
151
+ "ix_pay_methods_tenant_provider_customer",
152
+ "tenant_id",
153
+ "provider",
154
+ "provider_customer_id",
155
+ ),
156
+ )
124
157
 
125
158
 
126
159
  class PayProduct(ModelBase):
127
160
  __tablename__ = "pay_products"
161
+
128
162
  id: Mapped[str] = mapped_column(String(64), primary_key=True)
163
+
164
+ tenant_id: Mapped[str] = mapped_column(String(TENANT_ID_LEN), index=True, nullable=False)
165
+
129
166
  provider: Mapped[str] = mapped_column(String(32), index=True, nullable=False)
130
167
  provider_product_id: Mapped[str] = mapped_column(
131
168
  String(128), unique=True, index=True, nullable=False
@@ -139,7 +176,11 @@ class PayProduct(ModelBase):
139
176
 
140
177
  class PayPrice(ModelBase):
141
178
  __tablename__ = "pay_prices"
179
+
142
180
  id: Mapped[str] = mapped_column(String(64), primary_key=True)
181
+
182
+ tenant_id: Mapped[str] = mapped_column(String(TENANT_ID_LEN), index=True, nullable=False)
183
+
143
184
  provider: Mapped[str] = mapped_column(String(32), index=True, nullable=False)
144
185
  provider_price_id: Mapped[str] = mapped_column(
145
186
  String(128), unique=True, index=True, nullable=False
@@ -157,7 +198,11 @@ class PayPrice(ModelBase):
157
198
 
158
199
  class PaySubscription(ModelBase):
159
200
  __tablename__ = "pay_subscriptions"
201
+
160
202
  id: Mapped[str] = mapped_column(String(64), primary_key=True)
203
+
204
+ tenant_id: Mapped[str] = mapped_column(String(TENANT_ID_LEN), index=True, nullable=False)
205
+
161
206
  user_id: Mapped[Optional[str]] = mapped_column(user_id_type(), index=True, nullable=True)
162
207
  provider: Mapped[str] = mapped_column(String(32), index=True, nullable=False)
163
208
  provider_customer_id: Mapped[str] = mapped_column(String(128), index=True, nullable=False)
@@ -175,12 +220,24 @@ class PaySubscription(ModelBase):
175
220
  DateTime(timezone=True), server_default=text("CURRENT_TIMESTAMP"), nullable=False
176
221
  )
177
222
 
178
- __table_args__ = (user_fk_constraint("user_id", ondelete="SET NULL"),)
223
+ __table_args__ = (
224
+ user_fk_constraint("user_id", ondelete="SET NULL"),
225
+ Index(
226
+ "ix_pay_subscriptions_tenant_provider_customer",
227
+ "tenant_id",
228
+ "provider",
229
+ "provider_customer_id",
230
+ ),
231
+ )
179
232
 
180
233
 
181
234
  class PayInvoice(ModelBase):
182
235
  __tablename__ = "pay_invoices"
236
+
183
237
  id: Mapped[str] = mapped_column(String(64), primary_key=True)
238
+
239
+ tenant_id: Mapped[str] = mapped_column(String(TENANT_ID_LEN), index=True, nullable=False)
240
+
184
241
  user_id: Mapped[Optional[str]] = mapped_column(user_id_type(), index=True, nullable=True)
185
242
  provider: Mapped[str] = mapped_column(String(32), index=True, nullable=False)
186
243
  provider_invoice_id: Mapped[str] = mapped_column(
@@ -198,4 +255,85 @@ class PayInvoice(ModelBase):
198
255
  DateTime(timezone=True), server_default=text("CURRENT_TIMESTAMP"), nullable=False
199
256
  )
200
257
 
201
- __table_args__ = (user_fk_constraint("user_id", ondelete="SET NULL"),)
258
+ __table_args__ = (
259
+ user_fk_constraint("user_id", ondelete="SET NULL"),
260
+ Index(
261
+ "ix_pay_invoices_tenant_provider_customer",
262
+ "tenant_id",
263
+ "provider",
264
+ "provider_customer_id",
265
+ ),
266
+ )
267
+
268
+
269
+ class PaySetupIntent(ModelBase):
270
+ __tablename__ = "pay_setup_intents"
271
+
272
+ id: Mapped[str] = mapped_column(String(64), primary_key=True)
273
+
274
+ tenant_id: Mapped[str] = mapped_column(String(TENANT_ID_LEN), index=True, nullable=False)
275
+
276
+ user_id: Mapped[Optional[str]] = mapped_column(user_id_type(), index=True, nullable=True)
277
+ provider: Mapped[str] = mapped_column(String(32), index=True, nullable=False)
278
+ provider_setup_intent_id: Mapped[str] = mapped_column(
279
+ String(128), unique=True, index=True, nullable=False
280
+ )
281
+ status: Mapped[str] = mapped_column(
282
+ String(32), index=True, nullable=False
283
+ ) # requires_action|succeeded|canceled|processing
284
+ client_secret: Mapped[Optional[str]] = mapped_column(String(255))
285
+ created_at: Mapped[datetime] = mapped_column(
286
+ DateTime(timezone=True), server_default=text("CURRENT_TIMESTAMP"), nullable=False
287
+ )
288
+
289
+ __table_args__ = (
290
+ user_fk_constraint("user_id", ondelete="SET NULL"),
291
+ Index("ix_pay_setup_intents_tenant_provider", "tenant_id", "provider"),
292
+ )
293
+
294
+
295
+ class PayDispute(ModelBase):
296
+ __tablename__ = "pay_disputes"
297
+
298
+ id: Mapped[str] = mapped_column(String(64), primary_key=True)
299
+
300
+ tenant_id: Mapped[str] = mapped_column(String(TENANT_ID_LEN), index=True, nullable=False)
301
+
302
+ provider: Mapped[str] = mapped_column(String(32), index=True, nullable=False)
303
+ provider_dispute_id: Mapped[str] = mapped_column(
304
+ String(128), unique=True, index=True, nullable=False
305
+ )
306
+ provider_charge_id: Mapped[Optional[str]] = mapped_column(String(128), index=True)
307
+ amount: Mapped[int] = mapped_column(Numeric(18, 0), nullable=False)
308
+ currency: Mapped[str] = mapped_column(String(8), nullable=False)
309
+ reason: Mapped[Optional[str]] = mapped_column(String(64))
310
+ status: Mapped[str] = mapped_column(
311
+ String(32), index=True, nullable=False
312
+ ) # needs_response|under_review|won|lost|warning_closed
313
+ evidence_due_by: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True))
314
+ created_at: Mapped[datetime] = mapped_column(
315
+ DateTime(timezone=True), server_default=text("CURRENT_TIMESTAMP"), nullable=False
316
+ )
317
+
318
+
319
+ class PayPayout(ModelBase):
320
+ __tablename__ = "pay_payouts"
321
+
322
+ id: Mapped[str] = mapped_column(String(64), primary_key=True)
323
+
324
+ tenant_id: Mapped[str] = mapped_column(String(TENANT_ID_LEN), index=True, nullable=False)
325
+
326
+ provider: Mapped[str] = mapped_column(String(32), index=True, nullable=False)
327
+ provider_payout_id: Mapped[str] = mapped_column(
328
+ String(128), unique=True, index=True, nullable=False
329
+ )
330
+ amount: Mapped[int] = mapped_column(Numeric(18, 0), nullable=False)
331
+ currency: Mapped[str] = mapped_column(String(8), nullable=False)
332
+ status: Mapped[str] = mapped_column(
333
+ String(32), index=True, nullable=False
334
+ ) # pending|in_transit|paid|canceled|failed
335
+ arrival_date: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True))
336
+ type: Mapped[Optional[str]] = mapped_column(String(32)) # bank_account|card|...
337
+ created_at: Mapped[datetime] = mapped_column(
338
+ DateTime(timezone=True), server_default=text("CURRENT_TIMESTAMP"), nullable=False
339
+ )
@@ -0,0 +1,4 @@
1
+ from .aiydan import AiydanAdapter # noqa: F401
2
+ from .stripe import StripeAdapter # noqa: F401
3
+
4
+ __all__ = ["AiydanAdapter", "StripeAdapter"]