Skip to main content

alibi_schema_registry/
lib.rs

1//! Authoritative field registry for Alibi entity schemas.
2//!
3//! Shared by the `AuthEntity` proc macro (for compile-time validation)
4//! and the CLI (for code generation). This is the single source of truth
5//! for which fields belong to core vs which are plugin-provided.
6
7#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8pub enum EntityRole {
9    User,
10    Session,
11    Account,
12    Verification,
13}
14
15#[derive(Clone, Copy, Debug)]
16pub struct FieldDef {
17    pub name: &'static str,
18    /// Rust type as it appears in a `SeaORM` `Model` struct,
19    /// e.g. `"Option<String>"`, `"bool"`, `"DateTimeUtc"`, `"Json"`.
20    pub ty: &'static str,
21    pub is_primary_key: bool,
22    pub column_name: Option<&'static str>,
23    /// Database string default, rendered as a literal by each backend.
24    pub default_value: Option<&'static str>,
25}
26
27#[derive(Clone, Copy, Debug)]
28pub struct PluginSchema {
29    pub name: &'static str,
30    pub user_fields: &'static [FieldDef],
31    pub session_fields: &'static [FieldDef],
32    pub extra_entities: &'static [ExtraEntitySchema],
33}
34
35#[derive(Clone, Copy, Debug)]
36pub struct ExtraEntitySchema {
37    pub mod_name: &'static str,
38    pub table_name: &'static str,
39    pub role: Option<EntityRole>,
40    pub fields: &'static [FieldDef],
41}
42
43macro_rules! f {
44    ($name:expr, $ty:expr, $default:expr) => {
45        FieldDef {
46            default_value: Some($default),
47            ..f!($name, $ty)
48        }
49    };
50    ($name:expr, $ty:expr) => {
51        FieldDef {
52            name: $name,
53            ty: $ty,
54            is_primary_key: false,
55            column_name: None,
56            default_value: None,
57        }
58    };
59}
60
61macro_rules! pk {
62    ($name:expr, $ty:expr) => {
63        FieldDef {
64            is_primary_key: true,
65            ..f!($name, $ty)
66        }
67    };
68}
69
70macro_rules! f_col {
71    ($name:expr, $ty:expr, $column_name:expr) => {
72        FieldDef {
73            column_name: Some($column_name),
74            ..f!($name, $ty)
75        }
76    };
77}
78
79static USER_CORE: &[FieldDef] = &[
80    pk!("id", "String"),
81    f!("name", "String"),
82    f!("email", "String"),
83    f_col!("email_verified", "bool", "emailVerified"),
84    f!("image", "Option<String>"),
85    f_col!("created_at", "DateTimeUtc", "createdAt"),
86    f_col!("updated_at", "DateTimeUtc", "updatedAt"),
87];
88
89static SESSION_CORE: &[FieldDef] = &[
90    pk!("id", "String"),
91    f_col!("expires_at", "DateTimeUtc", "expiresAt"),
92    f!("token", "String"),
93    f_col!("created_at", "DateTimeUtc", "createdAt"),
94    f_col!("updated_at", "DateTimeUtc", "updatedAt"),
95    f_col!("ip_address", "Option<String>", "ipAddress"),
96    f_col!("user_agent", "Option<String>", "userAgent"),
97    f_col!("user_id", "String", "userId"),
98];
99
100static ACCOUNT_CORE: &[FieldDef] = &[
101    pk!("id", "String"),
102    f_col!("account_id", "String", "accountId"),
103    f_col!("provider_id", "String", "providerId"),
104    f_col!("user_id", "String", "userId"),
105    f_col!("access_token", "Option<String>", "accessToken"),
106    f_col!("refresh_token", "Option<String>", "refreshToken"),
107    f_col!("id_token", "Option<String>", "idToken"),
108    f_col!(
109        "access_token_expires_at",
110        "Option<DateTimeUtc>",
111        "accessTokenExpiresAt"
112    ),
113    f_col!(
114        "refresh_token_expires_at",
115        "Option<DateTimeUtc>",
116        "refreshTokenExpiresAt"
117    ),
118    f!("scope", "Option<String>"),
119    f!("password", "Option<String>"),
120    f_col!("created_at", "DateTimeUtc", "createdAt"),
121    f_col!("updated_at", "DateTimeUtc", "updatedAt"),
122];
123
124static VERIFICATION_CORE: &[FieldDef] = &[
125    pk!("id", "String"),
126    f!("identifier", "String"),
127    f!("value", "String"),
128    f_col!("expires_at", "DateTimeUtc", "expiresAt"),
129    f_col!("created_at", "DateTimeUtc", "createdAt"),
130    f_col!("updated_at", "DateTimeUtc", "updatedAt"),
131];
132
133static PLUGINS: &[PluginSchema] = &[
134    PluginSchema {
135        name: "siwe",
136        user_fields: &[],
137        session_fields: &[],
138        extra_entities: &[ExtraEntitySchema {
139            mod_name: "wallet_address",
140            table_name: "walletAddress",
141            role: None,
142            fields: &[
143                pk!("id", "String"),
144                f_col!("user_id", "String", "userId"),
145                f!("address", "String"),
146                f_col!("chain_id", "f64", "chainId"),
147                f_col!("is_primary", "bool", "isPrimary"),
148                f_col!("created_at", "DateTimeUtc", "createdAt"),
149            ],
150        }],
151    },
152    PluginSchema {
153        name: "jwt",
154        user_fields: &[],
155        session_fields: &[],
156        extra_entities: &[ExtraEntitySchema {
157            mod_name: "jwk",
158            table_name: "jwks",
159            role: None,
160            fields: &[
161                pk!("id", "String"),
162                f_col!("public_key", "String", "publicKey"),
163                f_col!("private_key", "String", "privateKey"),
164                f_col!("created_at", "DateTimeUtc", "createdAt"),
165                f_col!("expires_at", "Option<DateTimeUtc>", "expiresAt"),
166                f!("alg", "Option<String>"),
167                f!("crv", "Option<String>"),
168            ],
169        }],
170    },
171    PluginSchema {
172        name: "anonymous",
173        user_fields: &[f_col!("is_anonymous", "Option<bool>", "isAnonymous")],
174        session_fields: &[],
175        extra_entities: &[],
176    },
177    PluginSchema {
178        name: "phone-number",
179        user_fields: &[
180            f_col!("phone_number", "Option<String>", "phoneNumber"),
181            f_col!(
182                "phone_number_verified",
183                "Option<bool>",
184                "phoneNumberVerified"
185            ),
186        ],
187        session_fields: &[],
188        extra_entities: &[],
189    },
190    PluginSchema {
191        name: "last-login-method",
192        user_fields: &[f_col!(
193            "last_login_method",
194            "Option<String>",
195            "lastLoginMethod"
196        )],
197        session_fields: &[],
198        extra_entities: &[],
199    },
200    PluginSchema {
201        name: "organization-teams",
202        user_fields: &[],
203        session_fields: &[f_col!("active_team_id", "Option<String>", "activeTeamId")],
204        extra_entities: &[
205            ExtraEntitySchema {
206                mod_name: "team",
207                table_name: "team",
208                role: None,
209                fields: &[
210                    pk!("id", "String"),
211                    f!("name", "String"),
212                    f_col!("organization_id", "String", "organizationId"),
213                    f_col!("member_count", "i64", "memberCount"),
214                    f_col!("created_at", "DateTimeUtc", "createdAt"),
215                    f_col!("updated_at", "Option<DateTimeUtc>", "updatedAt"),
216                ],
217            },
218            ExtraEntitySchema {
219                mod_name: "team_member",
220                table_name: "teamMember",
221                role: None,
222                fields: &[
223                    pk!("id", "String"),
224                    f_col!("team_id", "String", "teamId"),
225                    f_col!("user_id", "String", "userId"),
226                    f_col!("membership_key", "Option<String>", "membershipKey"),
227                    f_col!("created_at", "Option<DateTimeUtc>", "createdAt"),
228                ],
229            },
230        ],
231    },
232    PluginSchema {
233        name: "organization-dynamic-roles",
234        user_fields: &[],
235        session_fields: &[],
236        extra_entities: &[ExtraEntitySchema {
237            mod_name: "organization_role",
238            table_name: "organizationRole",
239            role: None,
240            fields: &[
241                pk!("id", "String"),
242                f_col!("organization_id", "String", "organizationId"),
243                f!("role", "String"),
244                f!("permission", "String"),
245                f_col!("created_at", "DateTimeUtc", "createdAt"),
246                f_col!("updated_at", "Option<DateTimeUtc>", "updatedAt"),
247            ],
248        }],
249    },
250    PluginSchema {
251        name: "username",
252        user_fields: &[
253            f!("username", "Option<String>"),
254            f_col!("display_username", "Option<String>", "displayUsername"),
255        ],
256        session_fields: &[],
257        extra_entities: &[],
258    },
259    PluginSchema {
260        name: "two-factor",
261        user_fields: &[f_col!(
262            "two_factor_enabled",
263            "Option<bool>",
264            "twoFactorEnabled"
265        )],
266        session_fields: &[],
267        extra_entities: &[ExtraEntitySchema {
268            mod_name: "two_factor",
269            table_name: "twoFactor",
270            role: None,
271            fields: &[
272                pk!("id", "String"),
273                f!("secret", "String"),
274                f_col!("backup_codes", "String", "backupCodes"),
275                f_col!("user_id", "String", "userId"),
276                f!("verified", "Option<bool>"),
277                f_col!(
278                    "failed_verification_count",
279                    "Option<f64>",
280                    "failedVerificationCount"
281                ),
282                f_col!("locked_until", "Option<DateTimeUtc>", "lockedUntil"),
283            ],
284        }],
285    },
286    PluginSchema {
287        name: "device-authorization",
288        user_fields: &[],
289        session_fields: &[],
290        extra_entities: &[ExtraEntitySchema {
291            mod_name: "device_code",
292            table_name: "deviceCode",
293            role: None,
294            fields: &[
295                pk!("id", "String"),
296                f_col!("device_code", "String", "deviceCode"),
297                f_col!("user_code", "String", "userCode"),
298                f_col!("user_id", "Option<String>", "userId"),
299                f_col!("expires_at", "DateTimeUtc", "expiresAt"),
300                f!("status", "String"),
301                f_col!("last_polled_at", "Option<DateTimeUtc>", "lastPolledAt"),
302                f_col!("polling_interval", "Option<i64>", "pollingInterval"),
303                f_col!("client_id", "Option<String>", "clientId"),
304                f!("scope", "Option<String>"),
305            ],
306        }],
307    },
308    PluginSchema {
309        name: "admin",
310        user_fields: &[
311            f!("role", "Option<String>"),
312            f!("banned", "Option<bool>"),
313            f_col!("ban_reason", "Option<String>", "banReason"),
314            f_col!("ban_expires", "Option<DateTimeUtc>", "banExpires"),
315        ],
316        session_fields: &[f_col!(
317            "impersonated_by",
318            "Option<String>",
319            "impersonatedBy"
320        )],
321        extra_entities: &[],
322    },
323    PluginSchema {
324        name: "organization",
325        user_fields: &[],
326        session_fields: &[f_col!(
327            "active_organization_id",
328            "Option<String>",
329            "activeOrganizationId"
330        )],
331        extra_entities: &[
332            ExtraEntitySchema {
333                mod_name: "organization",
334                table_name: "organization",
335                role: None,
336                fields: &[
337                    pk!("id", "String"),
338                    f!("name", "String"),
339                    f!("slug", "String"),
340                    f!("logo", "Option<String>"),
341                    f!("metadata", "Option<Json>"),
342                    f_col!("created_at", "DateTimeUtc", "createdAt"),
343                ],
344            },
345            ExtraEntitySchema {
346                mod_name: "member",
347                table_name: "member",
348                role: None,
349                fields: &[
350                    pk!("id", "String"),
351                    f_col!("organization_id", "String", "organizationId"),
352                    f_col!("user_id", "String", "userId"),
353                    f!("role", "String"),
354                    f_col!("created_at", "DateTimeUtc", "createdAt"),
355                ],
356            },
357            ExtraEntitySchema {
358                mod_name: "invitation",
359                table_name: "invitation",
360                role: None,
361                fields: &[
362                    pk!("id", "String"),
363                    f_col!("organization_id", "String", "organizationId"),
364                    f!("email", "String"),
365                    f!("role", "Option<String>"),
366                    f_col!("team_id", "Option<String>", "teamId"),
367                    f!("status", "String"),
368                    f_col!("inviter_id", "String", "inviterId"),
369                    f_col!("expires_at", "DateTimeUtc", "expiresAt"),
370                    f_col!("created_at", "DateTimeUtc", "createdAt"),
371                ],
372            },
373        ],
374    },
375    PluginSchema {
376        name: "api-key",
377        user_fields: &[],
378        session_fields: &[],
379        extra_entities: &[ExtraEntitySchema {
380            mod_name: "api_key",
381            table_name: "apikey",
382            role: None,
383            fields: &[
384                pk!("id", "String"),
385                f!("name", "Option<String>"),
386                f!("start", "Option<String>"),
387                f!("prefix", "Option<String>"),
388                f_col!("key_hash", "String", "key"),
389                f_col!("reference_id", "String", "referenceId"),
390                f_col!("config_id", "String", "configId"),
391                f_col!("refill_interval", "Option<f64>", "refillInterval"),
392                f_col!("refill_amount", "Option<f64>", "refillAmount"),
393                f_col!("last_refill_at", "Option<DateTimeUtc>", "lastRefillAt"),
394                f!("enabled", "Option<bool>"),
395                f_col!("rate_limit_enabled", "Option<bool>", "rateLimitEnabled"),
396                f_col!(
397                    "rate_limit_time_window",
398                    "Option<f64>",
399                    "rateLimitTimeWindow"
400                ),
401                f_col!("rate_limit_max", "Option<f64>", "rateLimitMax"),
402                f_col!("request_count", "Option<f64>", "requestCount"),
403                f!("remaining", "Option<f64>"),
404                f_col!("last_request", "Option<DateTimeUtc>", "lastRequest"),
405                f_col!("expires_at", "Option<DateTimeUtc>", "expiresAt"),
406                f_col!("created_at", "DateTimeUtc", "createdAt"),
407                f_col!("updated_at", "DateTimeUtc", "updatedAt"),
408                f!("permissions", "Option<String>"),
409                f!("metadata", "Option<String>"),
410            ],
411        }],
412    },
413    PluginSchema {
414        name: "passkey",
415        user_fields: &[],
416        session_fields: &[],
417        extra_entities: &[ExtraEntitySchema {
418            mod_name: "passkey",
419            table_name: "passkey",
420            role: None,
421            fields: &[
422                pk!("id", "String"),
423                f!("name", "Option<String>"),
424                f_col!("public_key", "String", "publicKey"),
425                f_col!("user_id", "String", "userId"),
426                f_col!("credential_id", "String", "credentialID"),
427                f!("counter", "i64"),
428                f_col!("device_type", "String", "deviceType"),
429                f_col!("backed_up", "bool", "backedUp"),
430                f!("transports", "Option<String>"),
431                f!("aaguid", "Option<String>"),
432                f_col!("created_at", "Option<DateTimeUtc>", "createdAt"),
433            ],
434        }],
435    },
436    PluginSchema {
437        name: "oauth-provider",
438        user_fields: &[],
439        session_fields: &[],
440        extra_entities: &[
441            ExtraEntitySchema {
442                mod_name: "oauth_client",
443                table_name: "oauthClient",
444                role: None,
445                fields: &[
446                    pk!("id", "String"),
447                    f_col!("client_id", "String", "clientId"),
448                    f_col!("client_secret", "Option<String>", "clientSecret"),
449                    f_col!("client_discovery_id", "Option<String>", "clientDiscoveryId"),
450                    f_col!("disabled", "Option<bool>", "disabled"),
451                    f_col!("skip_consent", "Option<bool>", "skipConsent"),
452                    f_col!("enable_end_session", "Option<bool>", "enableEndSession"),
453                    f_col!("subject_type", "Option<String>", "subjectType"),
454                    f_col!("scopes", "Option<Json>", "scopes"),
455                    f_col!(
456                        "client_credentials_scopes",
457                        "Option<Json>",
458                        "clientCredentialsScopes"
459                    ),
460                    f_col!("user_id", "Option<String>", "userId"),
461                    f_col!("created_at", "Option<DateTimeUtc>", "createdAt"),
462                    f_col!("updated_at", "Option<DateTimeUtc>", "updatedAt"),
463                    f_col!("name", "Option<String>", "name"),
464                    f_col!("uri", "Option<String>", "uri"),
465                    f_col!("icon", "Option<String>", "icon"),
466                    f_col!("contacts", "Option<Json>", "contacts"),
467                    f_col!("tos", "Option<String>", "tos"),
468                    f_col!("policy", "Option<String>", "policy"),
469                    f_col!("software_id", "Option<String>", "softwareId"),
470                    f_col!("software_version", "Option<String>", "softwareVersion"),
471                    f_col!("software_statement", "Option<String>", "softwareStatement"),
472                    f_col!("redirect_uris", "Json", "redirectUris"),
473                    f_col!(
474                        "post_logout_redirect_uris",
475                        "Option<Json>",
476                        "postLogoutRedirectUris"
477                    ),
478                    f_col!(
479                        "backchannel_logout_uri",
480                        "Option<String>",
481                        "backchannelLogoutUri"
482                    ),
483                    f_col!(
484                        "backchannel_logout_session_required",
485                        "Option<bool>",
486                        "backchannelLogoutSessionRequired"
487                    ),
488                    f_col!(
489                        "token_endpoint_auth_method",
490                        "Option<String>",
491                        "tokenEndpointAuthMethod"
492                    ),
493                    f_col!("application_type", "Option<String>", "applicationType"),
494                    f_col!("jwks", "Option<String>", "jwks"),
495                    f_col!("jwks_uri", "Option<String>", "jwksUri"),
496                    f_col!("grant_types", "Option<Json>", "grantTypes"),
497                    f_col!("response_types", "Option<Json>", "responseTypes"),
498                    f_col!("require_pkce", "Option<bool>", "requirePKCE"),
499                    f_col!(
500                        "dpop_bound_access_tokens",
501                        "Option<bool>",
502                        "dpopBoundAccessTokens"
503                    ),
504                    f_col!("reference_id", "Option<String>", "referenceId"),
505                    f_col!("metadata", "Option<Json>", "metadata"),
506                ],
507            },
508            ExtraEntitySchema {
509                mod_name: "oauth_resource",
510                table_name: "oauthResource",
511                role: None,
512                fields: &[
513                    pk!("id", "String"),
514                    f_col!("identifier", "String", "identifier"),
515                    f_col!("name", "String", "name"),
516                    f_col!("access_token_ttl", "Option<i64>", "accessTokenTtl"),
517                    f_col!("refresh_token_ttl", "Option<i64>", "refreshTokenTtl"),
518                    f_col!("signing_algorithm", "Option<String>", "signingAlgorithm"),
519                    f_col!("signing_key_id", "Option<String>", "signingKeyId"),
520                    f_col!("allowed_scopes", "Option<Json>", "allowedScopes"),
521                    f_col!("custom_claims", "Option<Json>", "customClaims"),
522                    f_col!(
523                        "dpop_bound_access_tokens_required",
524                        "Option<bool>",
525                        "dpopBoundAccessTokensRequired"
526                    ),
527                    f_col!("disabled", "Option<bool>", "disabled"),
528                    f_col!("created_at", "Option<DateTimeUtc>", "createdAt"),
529                    f_col!("updated_at", "Option<DateTimeUtc>", "updatedAt"),
530                    f_col!("policy_version", "Option<i64>", "policyVersion"),
531                    f_col!("metadata", "Option<Json>", "metadata"),
532                ],
533            },
534            ExtraEntitySchema {
535                mod_name: "oauth_client_resource",
536                table_name: "oauthClientResource",
537                role: None,
538                fields: &[
539                    pk!("id", "String"),
540                    f_col!("client_id", "String", "clientId"),
541                    f_col!("resource_id", "String", "resourceId"),
542                    f_col!("metadata", "Option<Json>", "metadata"),
543                    f_col!("created_at", "Option<DateTimeUtc>", "createdAt"),
544                ],
545            },
546            ExtraEntitySchema {
547                mod_name: "oauth_refresh_token",
548                table_name: "oauthRefreshToken",
549                role: None,
550                fields: &[
551                    pk!("id", "String"),
552                    f_col!("token", "String", "token"),
553                    f_col!("client_id", "String", "clientId"),
554                    f_col!("session_id", "Option<String>", "sessionId"),
555                    f_col!("user_id", "String", "userId"),
556                    f_col!("reference_id", "Option<String>", "referenceId"),
557                    f_col!(
558                        "authorization_code_id",
559                        "Option<String>",
560                        "authorizationCodeId"
561                    ),
562                    f_col!("resources", "Option<Json>", "resources"),
563                    f_col!(
564                        "requested_user_info_claims",
565                        "Option<Json>",
566                        "requestedUserInfoClaims"
567                    ),
568                    f_col!("expires_at", "DateTimeUtc", "expiresAt"),
569                    f_col!("created_at", "DateTimeUtc", "createdAt"),
570                    f_col!("revoked", "Option<DateTimeUtc>", "revoked"),
571                    f_col!("rotated_at", "Option<DateTimeUtc>", "rotatedAt"),
572                    f_col!(
573                        "rotation_replay_response",
574                        "Option<String>",
575                        "rotationReplayResponse"
576                    ),
577                    f_col!(
578                        "rotation_replay_expires_at",
579                        "Option<DateTimeUtc>",
580                        "rotationReplayExpiresAt"
581                    ),
582                    f_col!("auth_time", "Option<DateTimeUtc>", "authTime"),
583                    f_col!("confirmation", "Option<Json>", "confirmation"),
584                    f_col!("scopes", "Json", "scopes"),
585                ],
586            },
587            ExtraEntitySchema {
588                mod_name: "oauth_access_token",
589                table_name: "oauthAccessToken",
590                role: None,
591                fields: &[
592                    pk!("id", "String"),
593                    f_col!("token", "String", "token"),
594                    f_col!("client_id", "String", "clientId"),
595                    f_col!("session_id", "Option<String>", "sessionId"),
596                    f_col!("user_id", "Option<String>", "userId"),
597                    f_col!("reference_id", "Option<String>", "referenceId"),
598                    f_col!(
599                        "authorization_code_id",
600                        "Option<String>",
601                        "authorizationCodeId"
602                    ),
603                    f_col!("resources", "Option<Json>", "resources"),
604                    f_col!(
605                        "requested_user_info_claims",
606                        "Option<Json>",
607                        "requestedUserInfoClaims"
608                    ),
609                    f_col!("refresh_id", "Option<String>", "refreshId"),
610                    f_col!("expires_at", "DateTimeUtc", "expiresAt"),
611                    f_col!("created_at", "DateTimeUtc", "createdAt"),
612                    f_col!("revoked", "Option<DateTimeUtc>", "revoked"),
613                    f_col!("confirmation", "Option<Json>", "confirmation"),
614                    f_col!("scopes", "Json", "scopes"),
615                ],
616            },
617            ExtraEntitySchema {
618                mod_name: "oauth_consent",
619                table_name: "oauthConsent",
620                role: None,
621                fields: &[
622                    pk!("id", "String"),
623                    f_col!("client_id", "String", "clientId"),
624                    f_col!("user_id", "Option<String>", "userId"),
625                    f_col!("reference_id", "Option<String>", "referenceId"),
626                    f_col!("resources", "Option<Json>", "resources"),
627                    f_col!(
628                        "requested_user_info_claims",
629                        "Option<Json>",
630                        "requestedUserInfoClaims"
631                    ),
632                    f_col!("scopes", "Json", "scopes"),
633                    f_col!("created_at", "DateTimeUtc", "createdAt"),
634                    f_col!("updated_at", "DateTimeUtc", "updatedAt"),
635                ],
636            },
637            ExtraEntitySchema {
638                mod_name: "oauth_client_assertion",
639                table_name: "oauthClientAssertion",
640                role: None,
641                fields: &[
642                    pk!("id", "String"),
643                    f_col!("expires_at", "DateTimeUtc", "expiresAt"),
644                ],
645            },
646        ],
647    },
648    PluginSchema {
649        name: "sso",
650        user_fields: &[],
651        session_fields: &[],
652        extra_entities: &[ExtraEntitySchema {
653            mod_name: "sso_provider",
654            table_name: "ssoProvider",
655            role: None,
656            fields: &[
657                pk!("id", "String"),
658                f!("issuer", "String"),
659                f!("domain", "String"),
660                f_col!("provider_id", "String", "providerId"),
661                f_col!("user_id", "String", "userId"),
662                f_col!("organization_id", "Option<String>", "organizationId"),
663                f_col!("oidc_config", "Option<String>", "oidcConfig"),
664                f_col!("saml_config", "Option<String>", "samlConfig"),
665                f_col!("domain_verified", "Option<bool>", "domainVerified"),
666            ],
667        }],
668    },
669    PluginSchema {
670        name: "rate-limit",
671        user_fields: &[],
672        session_fields: &[],
673        extra_entities: &[ExtraEntitySchema {
674            mod_name: "rate_limit",
675            table_name: "rateLimit",
676            role: None,
677            fields: &[
678                pk!("id", "String"),
679                f!("key", "String"),
680                f!("count", "i32"),
681                f_col!("last_request", "i64", "lastRequest"),
682            ],
683        }],
684    },
685];
686
687/// Core fields that are always required for a given entity role.
688#[must_use]
689pub fn core_fields(role: EntityRole) -> &'static [FieldDef] {
690    match role {
691        EntityRole::User => USER_CORE,
692        EntityRole::Session => SESSION_CORE,
693        EntityRole::Account => ACCOUNT_CORE,
694        EntityRole::Verification => VERIFICATION_CORE,
695    }
696}
697
698/// Plugin schemas — each plugin can add fields to user and/or session entities.
699#[must_use]
700pub fn plugin_schemas() -> &'static [PluginSchema] {
701    PLUGINS
702}
703
704/// All plugin field names for a given role (convenience for the macro).
705#[must_use]
706pub fn plugin_field_names(role: EntityRole) -> Vec<&'static str> {
707    plugin_schemas()
708        .iter()
709        .flat_map(|p| match role {
710            EntityRole::User => p.user_fields.iter(),
711            EntityRole::Session => p.session_fields.iter(),
712            EntityRole::Account | EntityRole::Verification => [].iter(),
713        })
714        .map(|f| f.name)
715        .collect()
716}
717
718/// Core field names only (convenience for the macro).
719#[must_use]
720pub fn core_field_names(role: EntityRole) -> Vec<&'static str> {
721    core_fields(role).iter().map(|f| f.name).collect()
722}
723
724/// Exact bundled SQL compiled from the pinned Better Auth TypeScript schema.
725pub const SQLITE_AUTH_SCHEMA: &str = include_str!("../schema/sqlite.sql");
726pub const POSTGRES_AUTH_SCHEMA: &str = include_str!("../schema/postgres.sql");
727pub const SQLITE_OAUTH_SCHEMA: &str = include_str!("../schema/sqlite_oauth_clients.sql");
728pub const POSTGRES_OAUTH_SCHEMA: &str = include_str!("../schema/postgres_oauth_clients.sql");
729pub const SQLITE_RATE_LIMIT_SCHEMA: &str = include_str!("../schema/sqlite_rate_limit.sql");
730pub const POSTGRES_RATE_LIMIT_SCHEMA: &str = include_str!("../schema/postgres_rate_limit.sql");
731
732pub const SQLITE_SSO_SCHEMA: &str = include_str!("../schema/sqlite_sso.sql");
733pub const POSTGRES_SSO_SCHEMA: &str = include_str!("../schema/postgres_sso.sql");
734
735pub const SQLITE_SCIM_MANAGED_SCHEMA: &str = include_str!("../schema/sqlite_scim_managed.sql");
736pub const POSTGRES_SCIM_MANAGED_SCHEMA: &str = include_str!("../schema/postgres_scim_managed.sql");
737
738pub const SQLITE_SCIM_BINDING_SCHEMA: &str = include_str!("../schema/sqlite_scim_binding.sql");
739pub const POSTGRES_SCIM_BINDING_SCHEMA: &str = include_str!("../schema/postgres_scim_binding.sql");
740
741pub const SQLITE_SCIM_CANONICAL_SCHEMA: &str = include_str!("../schema/sqlite_scim_canonical.sql");
742pub const POSTGRES_SCIM_CANONICAL_SCHEMA: &str =
743    include_str!("../schema/postgres_scim_canonical.sql");