Coverage for polar/event/system.py: 81%

199 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-12-05 15:52 +0000

1from enum import StrEnum 1a

2from typing import TYPE_CHECKING, Any, Literal, NotRequired, overload 1a

3 

4from sqlalchemy.orm import Mapped 1a

5from sqlalchemy.util.typing import TypedDict 1a

6 

7from polar.kit.address import AddressDict 1a

8from polar.models import Customer, Event, Organization 1a

9from polar.models.benefit import BenefitType 1a

10from polar.models.event import EventSource 1a

11 

12 

13class SystemEvent(StrEnum): 1a

14 meter_credited = "meter.credited" 1a

15 meter_reset = "meter.reset" 1a

16 benefit_granted = "benefit.granted" 1a

17 benefit_cycled = "benefit.cycled" 1a

18 benefit_updated = "benefit.updated" 1a

19 benefit_revoked = "benefit.revoked" 1a

20 subscription_cycled = "subscription.cycled" 1a

21 subscription_revoked = "subscription.revoked" 1a

22 subscription_product_updated = "subscription.product_updated" 1a

23 subscription_seats_updated = "subscription.seats_updated" 1a

24 subscription_billing_period_updated = "subscription.billing_period_updated" 1a

25 order_paid = "order.paid" 1a

26 order_refunded = "order.refunded" 1a

27 customer_created = "customer.created" 1a

28 customer_updated = "customer.updated" 1a

29 customer_deleted = "customer.deleted" 1a

30 

31 

32SYSTEM_EVENT_LABELS: dict[str, str] = { 1a

33 "benefit.granted": "Benefit Granted", 

34 "benefit.cycled": "Benefit Cycled", 

35 "benefit.updated": "Benefit Updated", 

36 "benefit.revoked": "Benefit Revoked", 

37 "subscription.cycled": "Subscription Cycled", 

38 "subscription.revoked": "Subscription Revoked", 

39 "subscription.product_updated": "Subscription Product Updated", 

40 "order.paid": "Order Paid", 

41 "order.refunded": "Order Refunded", 

42 "subscription.seats_updated": "Subscription Seats Updated", 

43 "customer.created": "Customer Created", 

44 "customer.updated": "Customer Updated", 

45 "customer.deleted": "Customer Deleted", 

46 "meter.credited": "Meter Credited", 

47 "meter.reset": "Meter Reset", 

48} 

49 

50 

51class MeterCreditedMetadata(TypedDict): 1a

52 meter_id: str 1a

53 units: int 1a

54 rollover: bool 1a

55 

56 

57class MeterCreditedEvent(Event): 1a

58 if TYPE_CHECKING: 58 ↛ anywhereline 58 didn't jump anywhere: it always raised an exception.1a

59 source: Mapped[Literal[EventSource.system]] 1a

60 name: Mapped[Literal[SystemEvent.meter_credited]] 1a

61 user_metadata: Mapped[MeterCreditedMetadata] # type: ignore[assignment] 1a

62 

63 

64class MeterResetMetadata(TypedDict): 1a

65 meter_id: str 1a

66 

67 

68class MeterResetEvent(Event): 1a

69 if TYPE_CHECKING: 69 ↛ anywhereline 69 didn't jump anywhere: it always raised an exception.1a

70 source: Mapped[Literal[EventSource.system]] 1a

71 name: Mapped[Literal[SystemEvent.meter_reset]] 1a

72 user_metadata: Mapped[MeterResetMetadata] # type: ignore[assignment] 1a

73 

74 

75class BenefitGrantMetadata(TypedDict): 1a

76 benefit_id: str 1a

77 benefit_grant_id: str 1a

78 benefit_type: BenefitType 1a

79 

80 

81class BenefitGrantedEvent(Event): 1a

82 if TYPE_CHECKING: 82 ↛ anywhereline 82 didn't jump anywhere: it always raised an exception.1a

83 source: Mapped[Literal[EventSource.system]] 1a

84 name: Mapped[Literal[SystemEvent.benefit_granted]] 1a

85 user_metadata: Mapped[BenefitGrantMetadata] # type: ignore[assignment] 1a

86 

87 

88class BenefitCycledEvent(Event): 1a

89 if TYPE_CHECKING: 89 ↛ anywhereline 89 didn't jump anywhere: it always raised an exception.1a

90 source: Mapped[Literal[EventSource.system]] 1a

91 name: Mapped[Literal[SystemEvent.benefit_cycled]] 1a

92 user_metadata: Mapped[BenefitGrantMetadata] # type: ignore[assignment] 1a

93 

94 

95class BenefitUpdatedEvent(Event): 1a

96 if TYPE_CHECKING: 96 ↛ anywhereline 96 didn't jump anywhere: it always raised an exception.1a

97 source: Mapped[Literal[EventSource.system]] 1a

98 name: Mapped[Literal[SystemEvent.benefit_updated]] 1a

99 user_metadata: Mapped[BenefitGrantMetadata] # type: ignore[assignment] 1a

100 

101 

102class BenefitRevokedEvent(Event): 1a

103 if TYPE_CHECKING: 103 ↛ anywhereline 103 didn't jump anywhere: it always raised an exception.1a

104 source: Mapped[Literal[EventSource.system]] 1a

105 name: Mapped[Literal[SystemEvent.benefit_revoked]] 1a

106 user_metadata: Mapped[BenefitGrantMetadata] # type: ignore[assignment] 1a

107 

108 

109class CustomerCreatedMetadata(TypedDict): 1a

110 customer_id: str 1a

111 customer_email: str 1a

112 customer_name: str | None 1a

113 customer_external_id: str | None 1a

114 

115 

116class CustomerCreatedEvent(Event): 1a

117 if TYPE_CHECKING: 117 ↛ anywhereline 117 didn't jump anywhere: it always raised an exception.1a

118 source: Mapped[Literal[EventSource.system]] 1a

119 name: Mapped[Literal[SystemEvent.customer_created]] 1a

120 user_metadata: Mapped[CustomerCreatedMetadata] # type: ignore[assignment] 1a

121 

122 

123class CustomerUpdatedFields(TypedDict): 1a

124 name: NotRequired[str | None] 1a

125 email: NotRequired[str | None] 1a

126 billing_address: NotRequired[AddressDict | None] 1a

127 tax_id: NotRequired[str | None] 1a

128 metadata: NotRequired[dict[str, str | int | bool] | None] 1a

129 

130 

131class CustomerUpdatedMetadata(TypedDict): 1a

132 customer_id: str 1a

133 customer_email: str 1a

134 customer_name: str | None 1a

135 customer_external_id: str | None 1a

136 updated_fields: CustomerUpdatedFields 1a

137 

138 

139class CustomerUpdatedEvent(Event): 1a

140 if TYPE_CHECKING: 140 ↛ anywhereline 140 didn't jump anywhere: it always raised an exception.1a

141 source: Mapped[Literal[EventSource.system]] 1a

142 name: Mapped[Literal[SystemEvent.customer_updated]] 1a

143 user_metadata: Mapped[CustomerUpdatedMetadata] # type: ignore[assignment] 1a

144 

145 

146class CustomerDeletedMetadata(TypedDict): 1a

147 customer_id: str 1a

148 customer_email: str 1a

149 customer_name: str | None 1a

150 customer_external_id: str | None 1a

151 

152 

153class CustomerDeletedEvent(Event): 1a

154 if TYPE_CHECKING: 154 ↛ anywhereline 154 didn't jump anywhere: it always raised an exception.1a

155 source: Mapped[Literal[EventSource.system]] 1a

156 name: Mapped[Literal[SystemEvent.customer_deleted]] 1a

157 user_metadata: Mapped[CustomerDeletedMetadata] # type: ignore[assignment] 1a

158 

159 

160class SubscriptionCycledMetadata(TypedDict): 1a

161 subscription_id: str 1a

162 

163 

164class SubscriptionCycledEvent(Event): 1a

165 if TYPE_CHECKING: 165 ↛ anywhereline 165 didn't jump anywhere: it always raised an exception.1a

166 source: Mapped[Literal[EventSource.system]] 1a

167 name: Mapped[Literal[SystemEvent.subscription_cycled]] 1a

168 user_metadata: Mapped[SubscriptionCycledMetadata] # type: ignore[assignment] 1a

169 

170 

171class SubscriptionRevokedMetadata(TypedDict): 1a

172 subscription_id: str 1a

173 

174 

175class SubscriptionRevokedEvent(Event): 1a

176 if TYPE_CHECKING: 176 ↛ anywhereline 176 didn't jump anywhere: it always raised an exception.1a

177 source: Mapped[Literal[EventSource.system]] 1a

178 name: Mapped[Literal[SystemEvent.subscription_revoked]] 1a

179 user_metadata: Mapped[SubscriptionRevokedMetadata] # type: ignore[assignment] 1a

180 

181 

182class SubscriptionProductUpdatedMetadata(TypedDict): 1a

183 subscription_id: str 1a

184 old_product_id: str 1a

185 new_product_id: str 1a

186 

187 

188class SubscriptionProductUpdatedEvent(Event): 1a

189 if TYPE_CHECKING: 189 ↛ anywhereline 189 didn't jump anywhere: it always raised an exception.1a

190 source: Mapped[Literal[EventSource.system]] 1a

191 name: Mapped[Literal[SystemEvent.subscription_product_updated]] 1a

192 user_metadata: Mapped[SubscriptionProductUpdatedMetadata] # type: ignore[assignment] 1a

193 

194 

195class SubscriptionSeatsUpdatedMetadata(TypedDict): 1a

196 subscription_id: str 1a

197 old_seats: int 1a

198 new_seats: int 1a

199 proration_behavior: str 1a

200 

201 

202class SubscriptionSeatsUpdatedEvent(Event): 1a

203 if TYPE_CHECKING: 203 ↛ anywhereline 203 didn't jump anywhere: it always raised an exception.1a

204 source: Mapped[Literal[EventSource.system]] 1a

205 name: Mapped[Literal[SystemEvent.subscription_seats_updated]] 1a

206 user_metadata: Mapped[SubscriptionSeatsUpdatedMetadata] # type: ignore[assignment] 1a

207 

208 

209class SubscriptionBillingPeriodUpdatedMetadata(TypedDict): 1a

210 subscription_id: str 1a

211 old_period_end: str 1a

212 new_period_end: str 1a

213 

214 

215class SubscriptionBillingPeriodUpdatedEvent(Event): 1a

216 if TYPE_CHECKING: 216 ↛ anywhereline 216 didn't jump anywhere: it always raised an exception.1a

217 source: Mapped[Literal[EventSource.system]] 1a

218 name: Mapped[Literal[SystemEvent.subscription_billing_period_updated]] 1a

219 user_metadata: Mapped[SubscriptionBillingPeriodUpdatedMetadata] # type: ignore[assignment] 1a

220 

221 

222class OrderPaidMetadata(TypedDict): 1a

223 order_id: str 1a

224 amount: int 1a

225 currency: str 1a

226 backfilled: NotRequired[bool] 1a

227 

228 

229class OrderPaidEvent(Event): 1a

230 if TYPE_CHECKING: 230 ↛ anywhereline 230 didn't jump anywhere: it always raised an exception.1a

231 source: Mapped[Literal[EventSource.system]] 1a

232 name: Mapped[Literal[SystemEvent.order_paid]] 1a

233 user_metadata: Mapped[OrderPaidMetadata] # type: ignore[assignment] 1a

234 

235 

236class OrderRefundedMetadata(TypedDict): 1a

237 order_id: str 1a

238 refunded_amount: int 1a

239 currency: str 1a

240 backfilled: NotRequired[bool] 1a

241 

242 

243class OrderRefundedEvent(Event): 1a

244 if TYPE_CHECKING: 244 ↛ anywhereline 244 didn't jump anywhere: it always raised an exception.1a

245 source: Mapped[Literal[EventSource.system]] 1a

246 name: Mapped[Literal[SystemEvent.order_refunded]] 1a

247 user_metadata: Mapped[OrderRefundedMetadata] # type: ignore[assignment] 1a

248 

249 

250@overload 1a

251def build_system_event( 251 ↛ exitline 251 didn't return from function 'build_system_event' because 1a

252 name: Literal[SystemEvent.meter_credited], 

253 customer: Customer, 

254 organization: Organization, 

255 metadata: MeterCreditedMetadata, 

256) -> Event: ... 

257 

258 

259@overload 1a

260def build_system_event( 260 ↛ exitline 260 didn't return from function 'build_system_event' because 1a

261 name: Literal[SystemEvent.meter_reset], 

262 customer: Customer, 

263 organization: Organization, 

264 metadata: MeterResetMetadata, 

265) -> Event: ... 

266 

267 

268@overload 1a

269def build_system_event( 269 ↛ exitline 269 didn't return from function 'build_system_event' because 1a

270 name: Literal[SystemEvent.benefit_granted], 

271 customer: Customer, 

272 organization: Organization, 

273 metadata: BenefitGrantMetadata, 

274) -> Event: ... 

275 

276 

277@overload 1a

278def build_system_event( 278 ↛ exitline 278 didn't return from function 'build_system_event' because 1a

279 name: Literal[SystemEvent.benefit_cycled], 

280 customer: Customer, 

281 organization: Organization, 

282 metadata: BenefitGrantMetadata, 

283) -> Event: ... 

284 

285 

286@overload 1a

287def build_system_event( 287 ↛ exitline 287 didn't return from function 'build_system_event' because 1a

288 name: Literal[SystemEvent.benefit_updated], 

289 customer: Customer, 

290 organization: Organization, 

291 metadata: BenefitGrantMetadata, 

292) -> Event: ... 

293 

294 

295@overload 1a

296def build_system_event( 296 ↛ exitline 296 didn't return from function 'build_system_event' because 1a

297 name: Literal[SystemEvent.benefit_revoked], 

298 customer: Customer, 

299 organization: Organization, 

300 metadata: BenefitGrantMetadata, 

301) -> Event: ... 

302 

303 

304@overload 1a

305def build_system_event( 305 ↛ exitline 305 didn't return from function 'build_system_event' because 1a

306 name: Literal[SystemEvent.customer_created], 

307 customer: Customer, 

308 organization: Organization, 

309 metadata: CustomerCreatedMetadata, 

310) -> Event: ... 

311 

312 

313@overload 1a

314def build_system_event( 314 ↛ exitline 314 didn't return from function 'build_system_event' because 1a

315 name: Literal[SystemEvent.customer_updated], 

316 customer: Customer, 

317 organization: Organization, 

318 metadata: CustomerUpdatedMetadata, 

319) -> Event: ... 

320 

321 

322@overload 1a

323def build_system_event( 323 ↛ exitline 323 didn't return from function 'build_system_event' because 1a

324 name: Literal[SystemEvent.customer_deleted], 

325 customer: Customer, 

326 organization: Organization, 

327 metadata: CustomerDeletedMetadata, 

328) -> Event: ... 

329 

330 

331@overload 1a

332def build_system_event( 332 ↛ exitline 332 didn't return from function 'build_system_event' because 1a

333 name: Literal[SystemEvent.subscription_cycled], 

334 customer: Customer, 

335 organization: Organization, 

336 metadata: SubscriptionCycledMetadata, 

337) -> Event: ... 

338 

339 

340@overload 1a

341def build_system_event( 341 ↛ exitline 341 didn't return from function 'build_system_event' because 1a

342 name: Literal[SystemEvent.subscription_revoked], 

343 customer: Customer, 

344 organization: Organization, 

345 metadata: SubscriptionRevokedMetadata, 

346) -> Event: ... 

347 

348 

349@overload 1a

350def build_system_event( 350 ↛ exitline 350 didn't return from function 'build_system_event' because 1a

351 name: Literal[SystemEvent.subscription_product_updated], 

352 customer: Customer, 

353 organization: Organization, 

354 metadata: SubscriptionProductUpdatedMetadata, 

355) -> Event: ... 

356 

357 

358@overload 1a

359def build_system_event( 359 ↛ exitline 359 didn't return from function 'build_system_event' because 1a

360 name: Literal[SystemEvent.subscription_seats_updated], 

361 customer: Customer, 

362 organization: Organization, 

363 metadata: SubscriptionSeatsUpdatedMetadata, 

364) -> Event: ... 

365 

366 

367@overload 1a

368def build_system_event( 368 ↛ exitline 368 didn't return from function 'build_system_event' because 1a

369 name: Literal[SystemEvent.subscription_billing_period_updated], 

370 customer: Customer, 

371 organization: Organization, 

372 metadata: SubscriptionBillingPeriodUpdatedMetadata, 

373) -> Event: ... 

374 

375 

376@overload 1a

377def build_system_event( 377 ↛ exitline 377 didn't return from function 'build_system_event' because 1a

378 name: Literal[SystemEvent.order_paid], 

379 customer: Customer, 

380 organization: Organization, 

381 metadata: OrderPaidMetadata, 

382) -> Event: ... 

383 

384 

385@overload 1a

386def build_system_event( 386 ↛ exitline 386 didn't return from function 'build_system_event' because 1a

387 name: Literal[SystemEvent.order_refunded], 

388 customer: Customer, 

389 organization: Organization, 

390 metadata: OrderRefundedMetadata, 

391) -> Event: ... 

392 

393 

394def build_system_event( 1a

395 name: SystemEvent, 

396 customer: Customer, 

397 organization: Organization, 

398 metadata: Any, 

399) -> Event: 

400 return Event( 

401 name=name, 

402 source=EventSource.system, 

403 customer_id=customer.id, 

404 organization=organization, 

405 user_metadata=metadata, 

406 )