Data structure
Generated from src/server/db/tables/ and the app/admin auth schemas. The diagram shows 37 tables, 407 columns and 46 foreign keys. Each table lists every column with its SQL type, nullability and keys. NN means NOT NULL.
Drag a node heading, or focus it and use arrow keys. Select a table to inspect its foreign keys.
- idtextNNPK
- numbertextNN—
- enrollment_idtextNNFK
- course_idtextNNFK
- user_idtextNNFK
- issued_atintegerNN—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- category_idtextNULLFK
- instructor_idtextNULLFK
- titletextNN—
- slugtextNN—
- summarytextNN—
- descriptiontextNN—
- thumbnailtextNULL—
- leveltextNN—
- priceintegerNN—
- discount_priceintegerNULL—
- discount_ends_atintegerNULL—
- statustextNN—
- lesson_countintegerNN—
- total_duration_secondsintegerNN—
- enrollment_countintegerNN—
- rating_sumintegerNN—
- review_countintegerNN—
- published_atintegerNULL—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- nametextNN—
- titletextNN—
- biotextNN—
- imagetextNULL—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- course_idtextNNFK
- titletextNN—
- positionintegerNN—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- course_idtextNNFK
- user_idtextNNFK
- enrollment_idtextNNFK
- ratingintegerNN—
- contenttextNN—
- statustextNN—
- admin_replytextNULL—
- admin_replied_atintegerNULL—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- course_idtextNNFK
- user_idtextNNFK
- order_idtextNULL—
- sourcetextNN—
- statustextNN—
- progress_percentintegerNN—
- completed_lessonsintegerNN—
- last_lesson_idtextNULL—
- expires_atintegerNULL—
- completed_atintegerNULL—
- granted_bytextNULL—
- revoke_reasontextNULL—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- enrollment_idtextNNFK
- lesson_idtextNNFK
- position_secondsintegerNN—
- completedintegerNN—
- completed_atintegerNULL—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- course_idtextNNFK
- section_idtextNNFK
- titletextNN—
- positionintegerNN—
- videotextNULL—
- duration_secondsintegerNN—
- is_previewintegerNN—
- contenttextNN—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- accountIdtextNN—
- providerIdtextNN—
- userIdtextNNFK
- accessTokentextNULL—
- refreshTokentextNULL—
- idTokentextNULL—
- accessTokenExpiresAtintegerNULL—
- refreshTokenExpiresAtintegerNULL—
- scopetextNULL—
- passwordtextNULL—
- createdAtintegerNN—
- updatedAtintegerNN—
- idtextNNPK
- nametextNULL—
- emailtextNN—
- emailVerifiedintegerNN—
- imagetextNULL—
- createdAtintegerNN—
- updatedAtintegerNN—
- idtextNNPK
- course_idtextNNFK
- lesson_idtextNULLFK
- user_idtextNNFK
- titletextNN—
- contenttextNN—
- statustextNN—
- pinnedintegerNN—
- comment_countintegerNN—
- answered_atintegerNULL—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- question_idtextNNFK
- author_typetextNN—
- author_idtextNN—
- author_nametextNN—
- contenttextNN—
- is_answerintegerNN—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- coupon_idtextNNFK
- user_idtextNNFK
- order_idtextNN—
- statustextNN—
- discountintegerNN—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- numbertextNN—
- customer_idtextNNFK
- customer_emailtextNN—
- request_keytextNN—
- item_typetextNN—
- course_idtextNULLFK
- product_idtextNULLFK
- item_titletextNN—
- statustextNN—
- payment_statustextNN—
- list_priceintegerNN—
- discountintegerNN—
- coupon_idtextNULL—
- coupon_codetextNULL—
- coupon_discountintegerNN—
- totalintegerNN—
- expires_atintegerNN—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- order_idtextNNFK
- provider_order_idtextNN—
- payment_keytextNULL—
- statustextNN—
- amountintegerNN—
- refunded_amountintegerNN—
- idempotency_keytextNN—
- pending_refund_idtextNULL—
- modetextNN—
- methodtextNULL—
- receipt_urltextNULL—
- last_errortextNULL—
- approved_atintegerNULL—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- payment_idtextNNFK
- order_idtextNNFK
- request_keytextNN—
- statustextNN—
- amountintegerNN—
- reasontextNN—
- actor_idtextNN—
- provider_transaction_keytextNULL—
- last_errortextNULL—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- order_idtextNNFK
- user_idtextNNFK
- reasontextNN—
- statustextNN—
- notetextNN—
- decided_bytextNULL—
- decided_atintegerNULL—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- codetextNN—
- nametextNN—
- typetextNN—
- valueintegerNN—
- min_amountintegerNN—
- max_discountintegerNULL—
- course_idtextNULLFK
- product_idtextNULLFK
- starts_atintegerNULL—
- ends_atintegerNULL—
- usage_limitintegerNULL—
- used_countintegerNN—
- per_user_limitintegerNN—
- activeintegerNN—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- category_idtextNULLFK
- titletextNN—
- slugtextNN—
- summarytextNN—
- descriptiontextNN—
- thumbnailtextNULL—
- kindtextNN—
- priceintegerNN—
- discount_priceintegerNULL—
- discount_ends_atintegerNULL—
- statustextNN—
- download_limitintegerNULL—
- file_countintegerNN—
- course_countintegerNN—
- purchase_countintegerNN—
- published_atintegerNULL—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- product_idtextNNFK
- owner_idtextNN—
- nametextNN—
- storage_keytextNN—
- content_typetextNN—
- sizeintegerNN—
- positionintegerNN—
- statustextNN—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- nametextNULL—
- emailtextNN—
- emailVerifiedintegerNN—
- imagetextNULL—
- createdAtintegerNN—
- updatedAtintegerNN—
- roletextNULL—
- bannedintegerNULL—
- banReasontextNULL—
- banExpiresintegerNULL—
- idtextNNPK
- product_idtextNNFK
- user_idtextNNFK
- order_idtextNULL—
- sourcetextNN—
- statustextNN—
- download_countintegerNN—
- last_downloaded_atintegerNULL—
- granted_bytextNULL—
- revoke_reasontextNULL—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- product_idtextNNFK
- course_idtextNNFK
- positionintegerNN—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- purchase_idtextNNFK
- file_idtextNNFK
- user_idtextNN—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- user_idtextNULLFK
- nametextNN—
- emailtextNN—
- phonetextNN—
- sourcetextNN—
- course_idtextNULLFK
- product_idtextNULLFK
- order_idtextNULL—
- item_titletextNN—
- consentintegerNN—
- notetextNN—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- expiresAtintegerNN—
- tokentextNN—
- createdAtintegerNN—
- updatedAtintegerNN—
- ipAddresstextNULL—
- userAgenttextNULL—
- userIdtextNNFK
- idtextNNPK
- identifiertextNN—
- valuetextNN—
- expiresAtintegerNN—
- createdAtintegerNULL—
- updatedAtintegerNULL—
- idtextNNPK
- owner_idtextNN—
- storage_keytextNN—
- imagetextNULL—
- statustextNN—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- titletextNN—
- contenttextNN—
- pinnedintegerNN—
- statustextNN—
- published_atintegerNULL—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- accountIdtextNN—
- providerIdtextNN—
- userIdtextNNFK
- accessTokentextNULL—
- refreshTokentextNULL—
- idTokentextNULL—
- accessTokenExpiresAtintegerNULL—
- refreshTokenExpiresAtintegerNULL—
- scopetextNULL—
- passwordtextNULL—
- createdAtintegerNN—
- updatedAtintegerNN—
- idtextNNPK
- expiresAtintegerNN—
- tokentextNN—
- createdAtintegerNN—
- updatedAtintegerNN—
- ipAddresstextNULL—
- userAgenttextNULL—
- userIdtextNNFK
- impersonatedBytextNULL—
- idtextNNPK
- identifiertextNN—
- valuetextNN—
- expiresAtintegerNN—
- createdAtintegerNULL—
- updatedAtintegerNULL—
- idtextNNPK
- nametextNN—
- slugtextNN—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- titletextNN—
- imagetextNN—
- link_urltextNN—
- positionintegerNN—
- activeintegerNN—
- starts_atintegerNULL—
- ends_atintegerNULL—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- event_keytextNN—
- payment_keytextNN—
- statustextNN—
- attemptsintegerNN—
- last_errortextNULL—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- actor_idtextNN—
- actiontextNN—
- entity_idtextNN—
- detailtextNN—
- created_atintegerNN—
- updated_atintegerNN—
- deleted_atintegerNULL—
- idtextNNPK
- revisionintegerNN—
Select a table to inspect its columns and relationships.
All tables (37)
- · 9
- · 22
- · 8
- · 7
- · 12
- · 16
- · 9
- · 12
- · 13
- · 7
- · 13
- · 10
- · 9
- · 21
- · 17
- · 13
- · 11
- · 18
- · 20
- · 12
- · 11
- · 13
- · 7
- · 7
- · 15
- · 8
- · 6
- · 8
- · 9
- · 13
- · 9
- · 6
- · 6
- · 11
- · 9
- · 8
- · 2
Schema changes
Add or edit tables in src/server/db/tables/<domain>-schema.ts and export them from src/server/db/schema.ts. Generate the migration and review its SQL. Apply it only after explicit approval; it targets the connected database. Courses and curriculum, enrollments and lesson progress, digital products and downloads, orders, payments, refunds and coupons already have dedicated tables. Auth tables separate learner and admin accounts.
The diagram includes declared foreign keys only; a similar column name does not imply a relationship. Data goes through repositories and the shared layers.