diff --git a/.env.example b/.env.example index 01d90287..9eba738e 100644 --- a/.env.example +++ b/.env.example @@ -58,6 +58,13 @@ SPONSORKIT_AFDIAN_USER_ID= SPONSORKIT_AFDIAN_TOKEN= SPONSORKIT_AFDIAN_EXCHANGE_RATE=6.5 +# In-game 功德簿 / Afdian Webhook +# Set provider to afdian only after the migration, Redis and NATS are ready. +SPONSORSHIP_PROVIDER=disabled +SPONSORSHIP_FULFILLMENT_ENABLED=false +AFDIAN_USER_ID= +AFDIAN_TOKEN= + # Frontend public build variables # Configure these in GitHub Actions Environment/Repository vars, not in the # server runtime env file passed to `docker run --env-file`. diff --git a/docs/afdian-sponsorship.md b/docs/afdian-sponsorship.md new file mode 100644 index 00000000..7240ed9a --- /dev/null +++ b/docs/afdian-sponsorship.md @@ -0,0 +1,32 @@ +# 爱发电功德簿运行手册 + +## 能力边界 + +当前实现不依赖 OAuth2。爱发电 Webhook 负责低延迟通知,开放 API 负责二次核验、定时补单与私信认领码。游戏不会发放数值奖励,也不会根据爱发电昵称猜测游戏账号。 + +`SponsorshipProvider` 是编译期接口,内置 `afdian` 适配器;开源部署者可以替换适配器代码,但服务端不会加载任意运行时 JavaScript。四个档位、名称和主题固定,管理端只允许调整 `plan_id` 和按分计的最低金额。 + +档位解析遵循爱发电官方订单字段语义:非空 `plan_id` 必须命中管理端映射,固定方案即使发生折扣也按映射档位;只有官方定义的空 `plan_id` 自选金额订单才按 `total_amount` 命中金额门槛。未映射的非空方案不会降级成自选金额订单。 + +## 上线顺序 + +1. 执行主库 Drizzle migration,确认新增的 `wanjiedaoyou_sponsorship_*` 表和唯一索引存在。 +2. 确认 Redis 与 NATS JetStream 健康;订单按 Redis 单订单锁串行,数据库唯一约束是最终幂等防线,不使用 PostgreSQL advisory/task lock。 +3. 配置 `AFDIAN_USER_ID`、`AFDIAN_TOKEN`。 +4. 先设置 `SPONSORSHIP_PROVIDER=afdian`、`SPONSORSHIP_FULFILLMENT_ENABLED=false` 启动应用,在 `/admin/sponsorship` 填写真实方案 ID 和金额并测试连接。首次保存有效方案时,服务端会自动固化“自动处理起始时间”;管理员不能改写它。 +5. 在爱发电配置 Webhook 地址:`https:///api/sponsorship/providers/afdian/webhook`。该入口限制 256 KiB,请勿经代理改写 JSON。 +6. 观察签名校验、API 二次核验和 NATS consumer 正常后,将 `SPONSORSHIP_FULFILLMENT_ENABLED=true` 并重启。此前已核验订单会由十分钟补偿任务继续履约。 + +## 数据与任务 + +- 每个成功订单按 `provider + provider_order_id` 唯一;每个订单最多生成一条功德记录和一枚认领码。 +- Webhook 和定时对账只会自动处理起始时间之后的订单;更早或缺少创建时间的订单不会生成认领码,历史订单继续由管理员手动发放。 +- 原始 Webhook、查询和对账响应以 JSON 保存,默认两年清理;订单身份与金额字段同步脱敏。认领码保留哈希用于一次性校验,原码用于私信失败后的重试。 +- NATS WorkQueue 每 10 分钟运行近期对账与失败补偿;每天运行深度对账和敏感数据清理。Bun cron 只发布命令,Redis job lock 防止多实例并发。 +- Webhook、NATS 和 API 都可能重复到达;消费者、Redis 单订单锁、状态条件更新和数据库唯一约束共同保证幂等。 + +## 排障 + +管理端可查看订单校验/履约状态,重试订单、轮换并重发认领码、撤销错误留名、手动发放历史功德。原始快照只通过带管理员鉴权的审计接口查看,每次查看都会写入 `sponsorship_admin_actions`。 + +若爱发电 API、Redis 或 NATS 不可用,保持 `SPONSORSHIP_FULFILLMENT_ENABLED=false`;恢复后先执行 `/internal/cron/sponsorship-deep-reconcile`(Bearer `CRON_SECRET`),核对订单再重新开启自动履约。 diff --git a/drizzle/0031_damp_karnak.sql b/drizzle/0031_damp_karnak.sql new file mode 100644 index 00000000..d18a9d68 --- /dev/null +++ b/drizzle/0031_damp_karnak.sql @@ -0,0 +1,134 @@ +CREATE TABLE "wanjiedaoyou_sponsorship_admin_actions" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "admin_user_id" uuid NOT NULL, + "action" varchar(64) NOT NULL, + "order_id" uuid, + "metadata" jsonb DEFAULT '{}'::jsonb NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "wanjiedaoyou_sponsorship_checkout_intents" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "provider" varchar(32) NOT NULL, + "user_id" uuid, + "cultivator_id" uuid, + "tier" varchar(32) NOT NULL, + "expected_plan_id" varchar(80), + "public_listing" boolean DEFAULT true NOT NULL, + "status" varchar(24) DEFAULT 'pending' NOT NULL, + "provider_order_id" varchar(80), + "config_snapshot" jsonb NOT NULL, + "expires_at" timestamp NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "wanjiedaoyou_sponsorship_claims" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "order_id" uuid NOT NULL, + "code_hash" varchar(64) NOT NULL, + "code" text NOT NULL, + "public_listing" boolean DEFAULT true NOT NULL, + "version" integer DEFAULT 1 NOT NULL, + "status" varchar(24) DEFAULT 'active' NOT NULL, + "expires_at" timestamp NOT NULL, + "cultivator_id" uuid, + "claimed_at" timestamp, + "message_status" varchar(24) DEFAULT 'pending' NOT NULL, + "message_attempts" integer DEFAULT 0 NOT NULL, + "last_message_error" text, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "wanjiedaoyou_sponsorship_merit_profiles" ( + "cultivator_id" uuid PRIMARY KEY NOT NULL, + "is_public" boolean DEFAULT true NOT NULL, + "highest_tier" varchar(32) NOT NULL, + "merit_count" integer DEFAULT 0 NOT NULL, + "first_supported_at" timestamp NOT NULL, + "last_supported_at" timestamp NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "wanjiedaoyou_sponsorship_merit_records" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "order_id" uuid, + "cultivator_id" uuid NOT NULL, + "tier" varchar(32) NOT NULL, + "source" varchar(32) NOT NULL, + "supported_at" timestamp NOT NULL, + "mail_id" uuid, + "created_by" uuid, + "revoked_at" timestamp, + "created_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "wanjiedaoyou_sponsorship_order_snapshots" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "order_id" uuid NOT NULL, + "source" varchar(24) NOT NULL, + "payload" jsonb NOT NULL, + "purge_after" timestamp NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "wanjiedaoyou_sponsorship_orders" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "provider" varchar(32) NOT NULL, + "provider_order_id" varchar(80) NOT NULL, + "custom_order_id" varchar(128), + "provider_user_id" varchar(80), + "plan_id" varchar(80), + "sku_id" varchar(80), + "product_type" integer, + "total_amount_fen" integer, + "show_amount_fen" integer, + "month" integer, + "provider_status" integer, + "provider_created_at" timestamp, + "verification_status" varchar(24) DEFAULT 'received' NOT NULL, + "fulfillment_status" varchar(24) DEFAULT 'pending' NOT NULL, + "resolved_tier" varchar(32), + "checkout_intent_id" uuid, + "config_snapshot" jsonb, + "retry_count" integer DEFAULT 0 NOT NULL, + "last_error_code" varchar(80), + "last_error_message" text, + "signature_verified_at" timestamp, + "verified_at" timestamp, + "fulfilled_at" timestamp, + "revoked_at" timestamp, + "sensitive_purged_at" timestamp, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +ALTER TABLE "wanjiedaoyou_sponsorship_admin_actions" ADD CONSTRAINT "wanjiedaoyou_sponsorship_admin_actions_order_id_wanjiedaoyou_sponsorship_orders_id_fk" FOREIGN KEY ("order_id") REFERENCES "public"."wanjiedaoyou_sponsorship_orders"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "wanjiedaoyou_sponsorship_checkout_intents" ADD CONSTRAINT "wanjiedaoyou_sponsorship_checkout_intents_cultivator_id_wanjiedaoyou_cultivators_id_fk" FOREIGN KEY ("cultivator_id") REFERENCES "public"."wanjiedaoyou_cultivators"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "wanjiedaoyou_sponsorship_claims" ADD CONSTRAINT "wanjiedaoyou_sponsorship_claims_order_id_wanjiedaoyou_sponsorship_orders_id_fk" FOREIGN KEY ("order_id") REFERENCES "public"."wanjiedaoyou_sponsorship_orders"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "wanjiedaoyou_sponsorship_claims" ADD CONSTRAINT "wanjiedaoyou_sponsorship_claims_cultivator_id_wanjiedaoyou_cultivators_id_fk" FOREIGN KEY ("cultivator_id") REFERENCES "public"."wanjiedaoyou_cultivators"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "wanjiedaoyou_sponsorship_merit_profiles" ADD CONSTRAINT "wanjiedaoyou_sponsorship_merit_profiles_cultivator_id_wanjiedaoyou_cultivators_id_fk" FOREIGN KEY ("cultivator_id") REFERENCES "public"."wanjiedaoyou_cultivators"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "wanjiedaoyou_sponsorship_merit_records" ADD CONSTRAINT "wanjiedaoyou_sponsorship_merit_records_order_id_wanjiedaoyou_sponsorship_orders_id_fk" FOREIGN KEY ("order_id") REFERENCES "public"."wanjiedaoyou_sponsorship_orders"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "wanjiedaoyou_sponsorship_merit_records" ADD CONSTRAINT "wanjiedaoyou_sponsorship_merit_records_cultivator_id_wanjiedaoyou_cultivators_id_fk" FOREIGN KEY ("cultivator_id") REFERENCES "public"."wanjiedaoyou_cultivators"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "wanjiedaoyou_sponsorship_merit_records" ADD CONSTRAINT "wanjiedaoyou_sponsorship_merit_records_mail_id_wanjiedaoyou_mails_id_fk" FOREIGN KEY ("mail_id") REFERENCES "public"."wanjiedaoyou_mails"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "wanjiedaoyou_sponsorship_order_snapshots" ADD CONSTRAINT "wanjiedaoyou_sponsorship_order_snapshots_order_id_wanjiedaoyou_sponsorship_orders_id_fk" FOREIGN KEY ("order_id") REFERENCES "public"."wanjiedaoyou_sponsorship_orders"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "wanjiedaoyou_sponsorship_orders" ADD CONSTRAINT "wanjiedaoyou_sponsorship_orders_checkout_intent_id_wanjiedaoyou_sponsorship_checkout_intents_id_fk" FOREIGN KEY ("checkout_intent_id") REFERENCES "public"."wanjiedaoyou_sponsorship_checkout_intents"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +CREATE INDEX "sponsorship_admin_actions_admin_created_idx" ON "wanjiedaoyou_sponsorship_admin_actions" USING btree ("admin_user_id","created_at");--> statement-breakpoint +CREATE INDEX "sponsorship_admin_actions_order_created_idx" ON "wanjiedaoyou_sponsorship_admin_actions" USING btree ("order_id","created_at");--> statement-breakpoint +CREATE UNIQUE INDEX "sponsorship_checkout_provider_order_uidx" ON "wanjiedaoyou_sponsorship_checkout_intents" USING btree ("provider","provider_order_id");--> statement-breakpoint +CREATE INDEX "sponsorship_checkout_user_created_idx" ON "wanjiedaoyou_sponsorship_checkout_intents" USING btree ("user_id","created_at");--> statement-breakpoint +CREATE INDEX "sponsorship_checkout_status_expires_idx" ON "wanjiedaoyou_sponsorship_checkout_intents" USING btree ("status","expires_at");--> statement-breakpoint +CREATE UNIQUE INDEX "sponsorship_claims_order_uidx" ON "wanjiedaoyou_sponsorship_claims" USING btree ("order_id");--> statement-breakpoint +CREATE UNIQUE INDEX "sponsorship_claims_code_hash_uidx" ON "wanjiedaoyou_sponsorship_claims" USING btree ("code_hash");--> statement-breakpoint +CREATE INDEX "sponsorship_claims_status_expires_idx" ON "wanjiedaoyou_sponsorship_claims" USING btree ("status","expires_at");--> statement-breakpoint +CREATE INDEX "sponsorship_merit_public_tier_first_idx" ON "wanjiedaoyou_sponsorship_merit_profiles" USING btree ("is_public","highest_tier","first_supported_at");--> statement-breakpoint +CREATE UNIQUE INDEX "sponsorship_merit_order_uidx" ON "wanjiedaoyou_sponsorship_merit_records" USING btree ("order_id");--> statement-breakpoint +CREATE INDEX "sponsorship_merit_cultivator_supported_idx" ON "wanjiedaoyou_sponsorship_merit_records" USING btree ("cultivator_id","supported_at");--> statement-breakpoint +CREATE INDEX "sponsorship_snapshots_order_created_idx" ON "wanjiedaoyou_sponsorship_order_snapshots" USING btree ("order_id","created_at");--> statement-breakpoint +CREATE INDEX "sponsorship_snapshots_purge_idx" ON "wanjiedaoyou_sponsorship_order_snapshots" USING btree ("purge_after");--> statement-breakpoint +CREATE UNIQUE INDEX "sponsorship_orders_provider_order_uidx" ON "wanjiedaoyou_sponsorship_orders" USING btree ("provider","provider_order_id");--> statement-breakpoint +CREATE INDEX "sponsorship_orders_verification_created_idx" ON "wanjiedaoyou_sponsorship_orders" USING btree ("verification_status","created_at");--> statement-breakpoint +CREATE INDEX "sponsorship_orders_fulfillment_created_idx" ON "wanjiedaoyou_sponsorship_orders" USING btree ("fulfillment_status","created_at");--> statement-breakpoint +CREATE INDEX "sponsorship_orders_provider_user_idx" ON "wanjiedaoyou_sponsorship_orders" USING btree ("provider_user_id"); diff --git a/drizzle/meta/0031_snapshot.json b/drizzle/meta/0031_snapshot.json new file mode 100644 index 00000000..95ae47e9 --- /dev/null +++ b/drizzle/meta/0031_snapshot.json @@ -0,0 +1,7618 @@ +{ + "id": "37b945ba-dbe2-4f12-b03e-c8f25968ee24", + "prevId": "67cbde6b-05cf-4838-a8f9-f111fc295373", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.wanjiedaoyou_account_deletion_records": { + "name": "wanjiedaoyou_account_deletion_records", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "cultivator_ids": { + "name": "cultivator_ids", + "type": "uuid[]", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "requested_at": { + "name": "requested_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "account_deletion_records_user_uidx": { + "name": "account_deletion_records_user_uidx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_deletion_records_status_requested_idx": { + "name": "account_deletion_records_status_requested_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "requested_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_admin_message_templates": { + "name": "wanjiedaoyou_admin_message_templates", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "channel": { + "name": "channel", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "subject_template": { + "name": "subject_template", + "type": "varchar(300)", + "primaryKey": false, + "notNull": false + }, + "content_template": { + "name": "content_template", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "default_payload": { + "name": "default_payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "updated_by": { + "name": "updated_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "admin_templates_channel_status_created_idx": { + "name": "admin_templates_channel_status_created_idx", + "columns": [ + { + "expression": "channel", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_alchemy_formulas": { + "name": "wanjiedaoyou_alchemy_formulas", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "family": { + "name": "family", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "pattern": { + "name": "pattern", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "blueprint": { + "name": "blueprint", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "mastery": { + "name": "mastery", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{\"level\":0,\"exp\":0}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "alchemy_formulas_cultivator_updated_idx": { + "name": "alchemy_formulas_cultivator_updated_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "alchemy_formulas_cultivator_family_idx": { + "name": "alchemy_formulas_cultivator_family_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "family", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_alchemy_formulas_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_alchemy_formulas_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_alchemy_formulas", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_app_settings": { + "name": "wanjiedaoyou_app_settings", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "varchar(128)", + "primaryKey": true, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_by": { + "name": "updated_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_auction_listings": { + "name": "wanjiedaoyou_auction_listings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "seller_id": { + "name": "seller_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "seller_name": { + "name": "seller_name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "item_type": { + "name": "item_type", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "item_id": { + "name": "item_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "item_name": { + "name": "item_name", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "item_quality": { + "name": "item_quality", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "item_category": { + "name": "item_category", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "item_snapshot": { + "name": "item_snapshot", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "price": { + "name": "price", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "initial_quantity": { + "name": "initial_quantity", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "remaining_quantity": { + "name": "remaining_quantity", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "visibility": { + "name": "visibility", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'public'" + }, + "target_cultivator_id": { + "name": "target_cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "target_cultivator_name": { + "name": "target_cultivator_name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "sold_at": { + "name": "sold_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "auction_status_expires_created_idx": { + "name": "auction_status_expires_created_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auction_seller_status_idx": { + "name": "auction_seller_status_idx", + "columns": [ + { + "expression": "seller_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auction_status_expires_price_idx": { + "name": "auction_status_expires_price_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "price", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auction_status_type_expires_created_idx": { + "name": "auction_status_type_expires_created_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "item_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auction_status_expires_item_type_idx": { + "name": "auction_status_expires_item_type_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "item_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auction_status_type_category_expires_created_idx": { + "name": "auction_status_type_category_expires_created_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "item_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "item_category", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auction_status_type_quality_expires_created_idx": { + "name": "auction_status_type_quality_expires_created_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "item_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "item_quality", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auction_status_item_name_expires_created_idx": { + "name": "auction_status_item_name_expires_created_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "item_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auction_status_seller_name_expires_created_idx": { + "name": "auction_status_seller_name_expires_created_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "seller_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auction_visibility_target_status_idx": { + "name": "auction_visibility_target_status_idx", + "columns": [ + { + "expression": "visibility", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_auction_listings_seller_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_auction_listings_seller_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_auction_listings", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "seller_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "wanjiedaoyou_auction_listings_target_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_auction_listings_target_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_auction_listings", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "target_cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_battle_records_v3": { + "name": "wanjiedaoyou_battle_records_v3", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "opponent_cultivator_id": { + "name": "opponent_cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "battle_type": { + "name": "battle_type", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'normal'" + }, + "battle_result": { + "name": "battle_result", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "share_code": { + "name": "share_code", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "shared_at": { + "name": "shared_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "battle_records_v3_cultivator_created_idx": { + "name": "battle_records_v3_cultivator_created_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "battle_records_v3_opponent_created_idx": { + "name": "battle_records_v3_opponent_created_idx", + "columns": [ + { + "expression": "opponent_cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "battle_records_v3_user_created_idx": { + "name": "battle_records_v3_user_created_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "battle_records_v3_share_code_uidx": { + "name": "battle_records_v3_share_code_uidx", + "columns": [ + { + "expression": "share_code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_battle_records_v3_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_battle_records_v3_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_battle_records_v3", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "wanjiedaoyou_battle_records_v3_opponent_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_battle_records_v3_opponent_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_battle_records_v3", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "opponent_cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_battle_replay_archives": { + "name": "wanjiedaoyou_battle_replay_archives", + "schema": "", + "columns": { + "match_id": { + "name": "match_id", + "type": "varchar(120)", + "primaryKey": true, + "notNull": true + }, + "replay_version": { + "name": "replay_version", + "type": "varchar(40)", + "primaryKey": false, + "notNull": true + }, + "engine_version": { + "name": "engine_version", + "type": "varchar(40)", + "primaryKey": false, + "notNull": true + }, + "ruleset_version": { + "name": "ruleset_version", + "type": "varchar(60)", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "finished_at": { + "name": "finished_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "outcome": { + "name": "outcome", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "participants": { + "name": "participants", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "replay": { + "name": "replay", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "archived_at": { + "name": "archived_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "battle_replay_archives_finished_idx": { + "name": "battle_replay_archives_finished_idx", + "columns": [ + { + "expression": "finished_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "battle_replay_archives_participants_gin_idx": { + "name": "battle_replay_archives_participants_gin_idx", + "columns": [ + { + "expression": "participants", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_bet_battles": { + "name": "wanjiedaoyou_bet_battles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "creator_id": { + "name": "creator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "creator_name": { + "name": "creator_name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "min_realm": { + "name": "min_realm", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "max_realm": { + "name": "max_realm", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "taunt": { + "name": "taunt", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false + }, + "creator_stake_snapshot": { + "name": "creator_stake_snapshot", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "challenger_stake_snapshot": { + "name": "challenger_stake_snapshot", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "challenger_id": { + "name": "challenger_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "challenger_name": { + "name": "challenger_name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "winner_cultivator_id": { + "name": "winner_cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "battle_record_v3_id": { + "name": "battle_record_v3_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "matched_at": { + "name": "matched_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "settled_at": { + "name": "settled_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "bet_battles_status_expires_idx": { + "name": "bet_battles_status_expires_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "bet_battles_creator_status_idx": { + "name": "bet_battles_creator_status_idx", + "columns": [ + { + "expression": "creator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "bet_battles_status_created_idx": { + "name": "bet_battles_status_created_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_bet_battles_creator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_bet_battles_creator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_bet_battles", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "wanjiedaoyou_bet_battles_challenger_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_bet_battles_challenger_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_bet_battles", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "challenger_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "wanjiedaoyou_bet_battles_winner_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_bet_battles_winner_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_bet_battles", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "winner_cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "wanjiedaoyou_bet_battles_battle_record_v3_id_wanjiedaoyou_battle_records_v3_id_fk": { + "name": "wanjiedaoyou_bet_battles_battle_record_v3_id_wanjiedaoyou_battle_records_v3_id_fk", + "tableFrom": "wanjiedaoyou_bet_battles", + "tableTo": "wanjiedaoyou_battle_records_v3", + "columnsFrom": [ + "battle_record_v3_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_breakthrough_history": { + "name": "wanjiedaoyou_breakthrough_history", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "from_realm": { + "name": "from_realm", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "from_stage": { + "name": "from_stage", + "type": "varchar(10)", + "primaryKey": false, + "notNull": true + }, + "to_realm": { + "name": "to_realm", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "to_stage": { + "name": "to_stage", + "type": "varchar(10)", + "primaryKey": false, + "notNull": true + }, + "age": { + "name": "age", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "years_spent": { + "name": "years_spent", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "story": { + "name": "story", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "breakthrough_history_cultivator_created_idx": { + "name": "breakthrough_history_cultivator_created_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_breakthrough_history_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_breakthrough_history_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_breakthrough_history", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_consumables": { + "name": "wanjiedaoyou_consumables", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "prompt": { + "name": "prompt", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "quality": { + "name": "quality", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'凡品'" + }, + "spec": { + "name": "spec", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "stack_key": { + "name": "stack_key", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "quantity": { + "name": "quantity", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "score": { + "name": "score", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": { + "consumables_cultivator_idx": { + "name": "consumables_cultivator_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "consumables_cultivator_name_quality_idx": { + "name": "consumables_cultivator_name_quality_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "quality", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "consumables_cultivator_stack_key_idx": { + "name": "consumables_cultivator_stack_key_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "stack_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "consumables_cultivator_stack_unique": { + "name": "consumables_cultivator_stack_unique", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "quality", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "stack_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"wanjiedaoyou_consumables\".\"stack_key\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "consumables_score_idx": { + "name": "consumables_score_idx", + "columns": [ + { + "expression": "score", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_consumables_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_consumables_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_consumables", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_creation_products": { + "name": "wanjiedaoyou_creation_products", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "product_type": { + "name": "product_type", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "element": { + "name": "element", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "quality": { + "name": "quality", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false + }, + "slot": { + "name": "slot", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false + }, + "score": { + "name": "score", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "is_equipped": { + "name": "is_equipped", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "product_model": { + "name": "product_model", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": { + "creation_products_cultivator_type_idx": { + "name": "creation_products_cultivator_type_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "product_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "creation_products_type_score_idx": { + "name": "creation_products_type_score_idx", + "columns": [ + { + "expression": "product_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "score", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "creation_products_equipped_idx": { + "name": "creation_products_equipped_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_equipped", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_creation_products_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_creation_products_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_creation_products", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_cultivator_friends": { + "name": "wanjiedaoyou_cultivator_friends", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "friend_cultivator_id": { + "name": "friend_cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "cultivator_friends_pair_uidx": { + "name": "cultivator_friends_pair_uidx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "friend_cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "cultivator_friends_friend_idx": { + "name": "cultivator_friends_friend_idx", + "columns": [ + { + "expression": "friend_cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_cultivator_friends_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_cultivator_friends_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_cultivator_friends", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "wanjiedaoyou_cultivator_friends_friend_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_cultivator_friends_friend_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_cultivator_friends", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "friend_cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_cultivator_tasks": { + "name": "wanjiedaoyou_cultivator_tasks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "definition_id": { + "name": "definition_id", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "category": { + "name": "category", + "type": "varchar(40)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "current_stage": { + "name": "current_stage", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "objectives": { + "name": "objectives", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": { + "cultivator_tasks_cultivator_status_updated_idx": { + "name": "cultivator_tasks_cultivator_status_updated_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "cultivator_tasks_cultivator_definition_unique": { + "name": "cultivator_tasks_cultivator_definition_unique", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "definition_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_cultivator_tasks_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_cultivator_tasks_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_cultivator_tasks", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_cultivators": { + "name": "wanjiedaoyou_cultivators", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "gender": { + "name": "gender", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "origin": { + "name": "origin", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "personality": { + "name": "personality", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "background": { + "name": "background", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "player_race": { + "name": "player_race", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'human'" + }, + "race_narrative": { + "name": "race_narrative", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "realm": { + "name": "realm", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "realm_stage": { + "name": "realm_stage", + "type": "varchar(10)", + "primaryKey": false, + "notNull": true + }, + "age": { + "name": "age", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 18 + }, + "lifespan": { + "name": "lifespan", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 100 + }, + "closed_door_years_total": { + "name": "closed_door_years_total", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "died_at": { + "name": "died_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "vitality": { + "name": "vitality", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "strength": { + "name": "strength", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10 + }, + "spirit": { + "name": "spirit", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "endurance": { + "name": "endurance", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10 + }, + "speed": { + "name": "speed", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "willpower": { + "name": "willpower", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "unallocated_attribute_points": { + "name": "unallocated_attribute_points", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "spirit_stones": { + "name": "spirit_stones", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "reputation": { + "name": "reputation", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "qi": { + "name": "qi", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 200 + }, + "qi_last_refreshed_at": { + "name": "qi_last_refreshed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_yield_at": { + "name": "last_yield_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "last_active_at": { + "name": "last_active_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "balance_notes": { + "name": "balance_notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "condition": { + "name": "condition", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "game_settings": { + "name": "game_settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "cultivation_progress": { + "name": "cultivation_progress", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": { + "cultivators_user_status_updated_idx": { + "name": "cultivators_user_status_updated_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "cultivators_status_created_idx": { + "name": "cultivators_status_created_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "cultivators_name_idx": { + "name": "cultivators_name_idx", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "cultivators_status_spirit_stones_idx": { + "name": "cultivators_status_spirit_stones_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "spirit_stones", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_dungeon_histories": { + "name": "wanjiedaoyou_dungeon_histories", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "theme": { + "name": "theme", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "result": { + "name": "result", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "log": { + "name": "log", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "real_gains": { + "name": "real_gains", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "dungeon_histories_cultivator_created_idx": { + "name": "dungeon_histories_cultivator_created_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_dungeon_histories_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_dungeon_histories_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_dungeon_histories", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_dungeon_runs": { + "name": "wanjiedaoyou_dungeon_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "map_node_id": { + "name": "map_node_id", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "default": "'EXPLORING'" + }, + "current_round": { + "name": "current_round", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "max_rounds": { + "name": "max_rounds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 5 + }, + "danger_score": { + "name": "danger_score", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10 + }, + "run_state": { + "name": "run_state", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "cost_ledger": { + "name": "cost_ledger", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "gain_ledger": { + "name": "gain_ledger", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "pending_action": { + "name": "pending_action", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "active_battle_id": { + "name": "active_battle_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "battle_payload": { + "name": "battle_payload", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ended_at": { + "name": "ended_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "dungeon_runs_cultivator_status_updated_idx": { + "name": "dungeon_runs_cultivator_status_updated_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "dungeon_runs_status_updated_idx": { + "name": "dungeon_runs_status_updated_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_dungeon_runs_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_dungeon_runs_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_dungeon_runs", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_feedbacks": { + "name": "wanjiedaoyou_feedbacks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "feedback_user_created_at_idx": { + "name": "feedback_user_created_at_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "feedback_status_type_created_at_idx": { + "name": "feedback_status_type_created_at_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_feedbacks_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_feedbacks_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_feedbacks", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_item_library": { + "name": "wanjiedaoyou_item_library", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "item_id": { + "name": "item_id", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'published'" + }, + "name": { + "name": "name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "quality": { + "name": "quality", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false + }, + "element": { + "name": "element", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "category": { + "name": "category", + "type": "varchar(40)", + "primaryKey": false, + "notNull": false + }, + "sample_key": { + "name": "sample_key", + "type": "double precision", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "editor_config": { + "name": "editor_config", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "updated_by": { + "name": "updated_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "item_library_item_id_unique": { + "name": "item_library_item_id_unique", + "columns": [ + { + "expression": "item_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "item_library_status_type_idx": { + "name": "item_library_status_type_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "item_library_material_sample_idx": { + "name": "item_library_material_sample_idx", + "columns": [ + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "category", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "quality", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sample_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "item_library_name_idx": { + "name": "item_library_name_idx", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_mails": { + "name": "wanjiedaoyou_mails", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'system'" + }, + "attachments": { + "name": "attachments", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "is_read": { + "name": "is_read", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_claimed": { + "name": "is_claimed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "mails_cultivator_created_idx": { + "name": "mails_cultivator_created_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "mails_cultivator_is_read_created_idx": { + "name": "mails_cultivator_is_read_created_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_read", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_mails_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_mails_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_mails", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_materials": { + "name": "wanjiedaoyou_materials", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "rank": { + "name": "rank", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "element": { + "name": "element", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "details": { + "name": "details", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "quantity": { + "name": "quantity", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": { + "materials_cultivator_idx": { + "name": "materials_cultivator_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "materials_cultivator_name_idx": { + "name": "materials_cultivator_name_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "materials_cultivator_name_rank_idx": { + "name": "materials_cultivator_name_rank_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "rank", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_materials_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_materials_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_materials", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_message_consumptions": { + "name": "wanjiedaoyou_message_consumptions", + "schema": "", + "columns": { + "consumer_name": { + "name": "consumer_name", + "type": "varchar(96)", + "primaryKey": false, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "message_key": { + "name": "message_key", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "message_consumptions_processed_idx": { + "name": "message_consumptions_processed_idx", + "columns": [ + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "wanjiedaoyou_message_consumptions_consumer_name_message_id_pk": { + "name": "wanjiedaoyou_message_consumptions_consumer_name_message_id_pk", + "columns": [ + "consumer_name", + "message_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_player_mutation_requests": { + "name": "wanjiedaoyou_player_mutation_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "varchar(96)", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "request_fingerprint": { + "name": "request_fingerprint", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "result": { + "name": "result", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "player_mutation_requests_scope_unique": { + "name": "player_mutation_requests_scope_unique", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "source", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "player_mutation_requests_created_idx": { + "name": "player_mutation_requests_created_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_player_mutation_requests_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_player_mutation_requests_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_player_mutation_requests", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_pre_heaven_fates": { + "name": "wanjiedaoyou_pre_heaven_fates", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "quality": { + "name": "quality", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "details": { + "name": "details", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": { + "pre_heaven_fates_cultivator_idx": { + "name": "pre_heaven_fates_cultivator_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_pre_heaven_fates_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_pre_heaven_fates_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_pre_heaven_fates", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_qi_logs": { + "name": "wanjiedaoyou_qi_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "action_instance_id": { + "name": "action_instance_id", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "qi_cost": { + "name": "qi_cost", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "qi_gain": { + "name": "qi_gain", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "qi_before": { + "name": "qi_before", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "qi_after": { + "name": "qi_after", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "qi_logs_action_instance_uidx": { + "name": "qi_logs_action_instance_uidx", + "columns": [ + { + "expression": "action_instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "qi_logs_cultivator_created_idx": { + "name": "qi_logs_cultivator_created_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "qi_logs_status_created_idx": { + "name": "qi_logs_status_created_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_qi_logs_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_qi_logs_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_qi_logs", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_redeem_code_claims": { + "name": "wanjiedaoyou_redeem_code_claims", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "redeem_code_id": { + "name": "redeem_code_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "mail_id": { + "name": "mail_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "redeem_code_claims_code_user_unique": { + "name": "redeem_code_claims_code_user_unique", + "columns": [ + { + "expression": "redeem_code_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "redeem_code_claims_user_idx": { + "name": "redeem_code_claims_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "redeem_code_claims_code_idx": { + "name": "redeem_code_claims_code_idx", + "columns": [ + { + "expression": "redeem_code_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_redeem_code_claims_redeem_code_id_wanjiedaoyou_redeem_codes_id_fk": { + "name": "wanjiedaoyou_redeem_code_claims_redeem_code_id_wanjiedaoyou_redeem_codes_id_fk", + "tableFrom": "wanjiedaoyou_redeem_code_claims", + "tableTo": "wanjiedaoyou_redeem_codes", + "columnsFrom": [ + "redeem_code_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "wanjiedaoyou_redeem_code_claims_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_redeem_code_claims_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_redeem_code_claims", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "wanjiedaoyou_redeem_code_claims_mail_id_wanjiedaoyou_mails_id_fk": { + "name": "wanjiedaoyou_redeem_code_claims_mail_id_wanjiedaoyou_mails_id_fk", + "tableFrom": "wanjiedaoyou_redeem_code_claims", + "tableTo": "wanjiedaoyou_mails", + "columnsFrom": [ + "mail_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_redeem_codes": { + "name": "wanjiedaoyou_redeem_codes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "code": { + "name": "code", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "reward_preset_id": { + "name": "reward_preset_id", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "reward_attachments": { + "name": "reward_attachments", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "mail_title": { + "name": "mail_title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "mail_content": { + "name": "mail_content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "total_limit": { + "name": "total_limit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "claimed_count": { + "name": "claimed_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "starts_at": { + "name": "starts_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "ends_at": { + "name": "ends_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "updated_by": { + "name": "updated_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "redeem_codes_code_unique": { + "name": "redeem_codes_code_unique", + "columns": [ + { + "expression": "code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "redeem_codes_status_created_idx": { + "name": "redeem_codes_status_created_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "redeem_codes_created_idx": { + "name": "redeem_codes_created_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_reputation_shop_items": { + "name": "wanjiedaoyou_reputation_shop_items", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "item_library_item_id": { + "name": "item_library_item_id", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "price": { + "name": "price", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "per_user_limit": { + "name": "per_user_limit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "updated_by": { + "name": "updated_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "reputation_shop_item_library_item_uidx": { + "name": "reputation_shop_item_library_item_uidx", + "columns": [ + { + "expression": "item_library_item_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reputation_shop_status_sort_idx": { + "name": "reputation_shop_status_sort_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_reputation_shop_items_item_library_item_id_wanjiedaoyou_item_library_item_id_fk": { + "name": "wanjiedaoyou_reputation_shop_items_item_library_item_id_wanjiedaoyou_item_library_item_id_fk", + "tableFrom": "wanjiedaoyou_reputation_shop_items", + "tableTo": "wanjiedaoyou_item_library", + "columnsFrom": [ + "item_library_item_id" + ], + "columnsTo": [ + "item_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_reputation_shop_purchases": { + "name": "wanjiedaoyou_reputation_shop_purchases", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shop_item_id": { + "name": "shop_item_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "item_library_item_id": { + "name": "item_library_item_id", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "reputation_cost": { + "name": "reputation_cost", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "purchase_week": { + "name": "purchase_week", + "type": "varchar(10)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "reputation_shop_purchases_cultivator_item_idx": { + "name": "reputation_shop_purchases_cultivator_item_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shop_item_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reputation_shop_purchases_week_idx": { + "name": "reputation_shop_purchases_week_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shop_item_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "purchase_week", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reputation_shop_purchases_created_idx": { + "name": "reputation_shop_purchases_created_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_reputation_shop_purchases_shop_item_id_wanjiedaoyou_reputation_shop_items_id_fk": { + "name": "wanjiedaoyou_reputation_shop_purchases_shop_item_id_wanjiedaoyou_reputation_shop_items_id_fk", + "tableFrom": "wanjiedaoyou_reputation_shop_purchases", + "tableTo": "wanjiedaoyou_reputation_shop_items", + "columnsFrom": [ + "shop_item_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "wanjiedaoyou_reputation_shop_purchases_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_reputation_shop_purchases_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_reputation_shop_purchases", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_resource_events": { + "name": "wanjiedaoyou_resource_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "scope_id": { + "name": "scope_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "scope_version": { + "name": "scope_version", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "resource_version": { + "name": "resource_version", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "resource_key": { + "name": "resource_key", + "type": "varchar(96)", + "primaryKey": false, + "notNull": true + }, + "operation": { + "name": "operation", + "type": "varchar(24)", + "primaryKey": false, + "notNull": true + }, + "event_type": { + "name": "event_type", + "type": "varchar(96)", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "actor_cultivator_id": { + "name": "actor_cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_user_id": { + "name": "actor_user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "varchar(96)", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "mutation_ordinal": { + "name": "mutation_ordinal", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "resource_events_scope_version_ordinal_unique": { + "name": "resource_events_scope_version_ordinal_unique", + "columns": [ + { + "expression": "scope_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scope_version", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "mutation_ordinal", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "resource_events_scope_version_idx": { + "name": "resource_events_scope_version_idx", + "columns": [ + { + "expression": "scope_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scope_version", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "mutation_ordinal", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "resource_events_replay_idx": { + "name": "resource_events_replay_idx", + "columns": [ + { + "expression": "actor_cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "source", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "mutation_ordinal", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "resource_events_created_idx": { + "name": "resource_events_created_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_resource_events_scope_id_wanjiedaoyou_resource_scopes_id_fk": { + "name": "wanjiedaoyou_resource_events_scope_id_wanjiedaoyou_resource_scopes_id_fk", + "tableFrom": "wanjiedaoyou_resource_events", + "tableTo": "wanjiedaoyou_resource_scopes", + "columnsFrom": [ + "scope_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "wanjiedaoyou_resource_events_actor_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_resource_events_actor_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_resource_events", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "actor_cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_resource_scopes": { + "name": "wanjiedaoyou_resource_scopes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "scope_kind": { + "name": "scope_kind", + "type": "varchar(24)", + "primaryKey": false, + "notNull": true + }, + "scope_key": { + "name": "scope_key", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "scope_version": { + "name": "scope_version", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "resource_scopes_kind_key_unique": { + "name": "resource_scopes_kind_key_unique", + "columns": [ + { + "expression": "scope_kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scope_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_resource_versions": { + "name": "wanjiedaoyou_resource_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "scope_id": { + "name": "scope_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "resource_key": { + "name": "resource_key", + "type": "varchar(96)", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "resource_versions_scope_key_unique": { + "name": "resource_versions_scope_key_unique", + "columns": [ + { + "expression": "scope_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "resource_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "resource_versions_resource_idx": { + "name": "resource_versions_resource_idx", + "columns": [ + { + "expression": "resource_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_resource_versions_scope_id_wanjiedaoyou_resource_scopes_id_fk": { + "name": "wanjiedaoyou_resource_versions_scope_id_wanjiedaoyou_resource_scopes_id_fk", + "tableFrom": "wanjiedaoyou_resource_versions", + "tableTo": "wanjiedaoyou_resource_scopes", + "columnsFrom": [ + "scope_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_retreat_records": { + "name": "wanjiedaoyou_retreat_records", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "realm": { + "name": "realm", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "realm_stage": { + "name": "realm_stage", + "type": "varchar(10)", + "primaryKey": false, + "notNull": true + }, + "years": { + "name": "years", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "success": { + "name": "success", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "chance": { + "name": "chance", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "roll": { + "name": "roll", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "modifiers": { + "name": "modifiers", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "retreat_records_cultivator_timestamp_idx": { + "name": "retreat_records_cultivator_timestamp_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "timestamp", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_retreat_records_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_retreat_records_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_retreat_records", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sect_ability_loadouts": { + "name": "wanjiedaoyou_sect_ability_loadouts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "membership_id": { + "name": "membership_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "slot": { + "name": "slot", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "ability_id": { + "name": "ability_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sect_ability_membership_slot_unique": { + "name": "sect_ability_membership_slot_unique", + "columns": [ + { + "expression": "membership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slot", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sect_ability_membership_ability_unique": { + "name": "sect_ability_membership_ability_unique", + "columns": [ + { + "expression": "membership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "ability_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sect_ability_loadouts_membership_id_wanjiedaoyou_sect_memberships_id_fk": { + "name": "wanjiedaoyou_sect_ability_loadouts_membership_id_wanjiedaoyou_sect_memberships_id_fk", + "tableFrom": "wanjiedaoyou_sect_ability_loadouts", + "tableTo": "wanjiedaoyou_sect_memberships", + "columnsFrom": [ + "membership_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sect_facilities": { + "name": "wanjiedaoyou_sect_facilities", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "sect_id": { + "name": "sect_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "facility_key": { + "name": "facility_key", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "level": { + "name": "level", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sect_facilities_sect_key_unique": { + "name": "sect_facilities_sect_key_unique", + "columns": [ + { + "expression": "sect_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "facility_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sect_memberships": { + "name": "wanjiedaoyou_sect_memberships", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "sect_id": { + "name": "sect_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true, + "default": "'prospect'" + }, + "experienced_at": { + "name": "experienced_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "active_path_id": { + "name": "active_path_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "contribution": { + "name": "contribution", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "disciple_rank": { + "name": "disciple_rank", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true, + "default": "'registered'" + }, + "office": { + "name": "office", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true, + "default": "'none'" + }, + "promoted_at": { + "name": "promoted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "config_version": { + "name": "config_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 2 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sect_memberships_cultivator_sect_unique": { + "name": "sect_memberships_cultivator_sect_unique", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sect_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sect_memberships_active_cultivator_unique": { + "name": "sect_memberships_active_cultivator_unique", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"wanjiedaoyou_sect_memberships\".\"status\" = 'active'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "sect_memberships_sect_status_idx": { + "name": "sect_memberships_sect_status_idx", + "columns": [ + { + "expression": "sect_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sect_memberships_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_sect_memberships_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_sect_memberships", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sect_meridian_loadouts": { + "name": "wanjiedaoyou_sect_meridian_loadouts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "membership_id": { + "name": "membership_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "path_id": { + "name": "path_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "slot": { + "name": "slot", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "node_ids": { + "name": "node_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sect_meridian_membership_path_slot_unique": { + "name": "sect_meridian_membership_path_slot_unique", + "columns": [ + { + "expression": "membership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "path_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slot", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sect_meridian_loadouts_membership_id_wanjiedaoyou_sect_memberships_id_fk": { + "name": "wanjiedaoyou_sect_meridian_loadouts_membership_id_wanjiedaoyou_sect_memberships_id_fk", + "tableFrom": "wanjiedaoyou_sect_meridian_loadouts", + "tableTo": "wanjiedaoyou_sect_memberships", + "columnsFrom": [ + "membership_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sect_method_progress": { + "name": "wanjiedaoyou_sect_method_progress", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "membership_id": { + "name": "membership_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "method_id": { + "name": "method_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "level": { + "name": "level", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sect_method_membership_method_unique": { + "name": "sect_method_membership_method_unique", + "columns": [ + { + "expression": "membership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "method_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sect_method_progress_membership_id_wanjiedaoyou_sect_memberships_id_fk": { + "name": "wanjiedaoyou_sect_method_progress_membership_id_wanjiedaoyou_sect_memberships_id_fk", + "tableFrom": "wanjiedaoyou_sect_method_progress", + "tableTo": "wanjiedaoyou_sect_memberships", + "columnsFrom": [ + "membership_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sect_path_progress": { + "name": "wanjiedaoyou_sect_path_progress", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "membership_id": { + "name": "membership_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "path_id": { + "name": "path_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "unlocked_layer_ids": { + "name": "unlocked_layer_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "tactic_id": { + "name": "tactic_id", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "active_meridian_slot": { + "name": "active_meridian_slot", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sect_path_membership_path_unique": { + "name": "sect_path_membership_path_unique", + "columns": [ + { + "expression": "membership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "path_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sect_path_progress_membership_id_wanjiedaoyou_sect_memberships_id_fk": { + "name": "wanjiedaoyou_sect_path_progress_membership_id_wanjiedaoyou_sect_memberships_id_fk", + "tableFrom": "wanjiedaoyou_sect_path_progress", + "tableTo": "wanjiedaoyou_sect_memberships", + "columnsFrom": [ + "membership_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sect_shop_items": { + "name": "wanjiedaoyou_sect_shop_items", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "item_library_item_id": { + "name": "item_library_item_id", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "price": { + "name": "price", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "per_user_limit": { + "name": "per_user_limit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "updated_by": { + "name": "updated_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sect_shop_item_library_item_uidx": { + "name": "sect_shop_item_library_item_uidx", + "columns": [ + { + "expression": "item_library_item_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sect_shop_status_sort_idx": { + "name": "sect_shop_status_sort_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sect_shop_items_item_library_item_id_wanjiedaoyou_item_library_item_id_fk": { + "name": "wanjiedaoyou_sect_shop_items_item_library_item_id_wanjiedaoyou_item_library_item_id_fk", + "tableFrom": "wanjiedaoyou_sect_shop_items", + "tableTo": "wanjiedaoyou_item_library", + "columnsFrom": [ + "item_library_item_id" + ], + "columnsTo": [ + "item_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sect_shop_purchases": { + "name": "wanjiedaoyou_sect_shop_purchases", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shop_item_id": { + "name": "shop_item_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "membership_id": { + "name": "membership_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "item_library_item_id": { + "name": "item_library_item_id", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "contribution_cost": { + "name": "contribution_cost", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "purchase_week": { + "name": "purchase_week", + "type": "varchar(10)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sect_shop_purchases_cultivator_item_idx": { + "name": "sect_shop_purchases_cultivator_item_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shop_item_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sect_shop_purchases_week_idx": { + "name": "sect_shop_purchases_week_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shop_item_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "purchase_week", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sect_shop_purchases_created_idx": { + "name": "sect_shop_purchases_created_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sect_shop_purchases_shop_item_id_wanjiedaoyou_sect_shop_items_id_fk": { + "name": "wanjiedaoyou_sect_shop_purchases_shop_item_id_wanjiedaoyou_sect_shop_items_id_fk", + "tableFrom": "wanjiedaoyou_sect_shop_purchases", + "tableTo": "wanjiedaoyou_sect_shop_items", + "columnsFrom": [ + "shop_item_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "wanjiedaoyou_sect_shop_purchases_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_sect_shop_purchases_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_sect_shop_purchases", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "wanjiedaoyou_sect_shop_purchases_membership_id_wanjiedaoyou_sect_memberships_id_fk": { + "name": "wanjiedaoyou_sect_shop_purchases_membership_id_wanjiedaoyou_sect_memberships_id_fk", + "tableFrom": "wanjiedaoyou_sect_shop_purchases", + "tableTo": "wanjiedaoyou_sect_memberships", + "columnsFrom": [ + "membership_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sect_stipend_claims": { + "name": "wanjiedaoyou_sect_stipend_claims", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "membership_id": { + "name": "membership_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "week_key": { + "name": "week_key", + "type": "varchar(10)", + "primaryKey": false, + "notNull": true + }, + "spirit_stones": { + "name": "spirit_stones", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "claimed_at": { + "name": "claimed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sect_stipend_member_week_unique": { + "name": "sect_stipend_member_week_unique", + "columns": [ + { + "expression": "membership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "week_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sect_stipend_claimed_idx": { + "name": "sect_stipend_claimed_idx", + "columns": [ + { + "expression": "claimed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sect_stipend_claims_membership_id_wanjiedaoyou_sect_memberships_id_fk": { + "name": "wanjiedaoyou_sect_stipend_claims_membership_id_wanjiedaoyou_sect_memberships_id_fk", + "tableFrom": "wanjiedaoyou_sect_stipend_claims", + "tableTo": "wanjiedaoyou_sect_memberships", + "columnsFrom": [ + "membership_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sect_task_records": { + "name": "wanjiedaoyou_sect_task_records", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "membership_id": { + "name": "membership_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "task_id": { + "name": "task_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true + }, + "period_key": { + "name": "period_key", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true + }, + "attempt": { + "name": "attempt", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "status": { + "name": "status", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "claimed_at": { + "name": "claimed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sect_task_membership_period_task_attempt_unique": { + "name": "sect_task_membership_period_task_attempt_unique", + "columns": [ + { + "expression": "membership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "task_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "attempt", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sect_task_membership_kind_period_idx": { + "name": "sect_task_membership_kind_period_idx", + "columns": [ + { + "expression": "membership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sect_task_records_membership_id_wanjiedaoyou_sect_memberships_id_fk": { + "name": "wanjiedaoyou_sect_task_records_membership_id_wanjiedaoyou_sect_memberships_id_fk", + "tableFrom": "wanjiedaoyou_sect_task_records", + "tableTo": "wanjiedaoyou_sect_memberships", + "columnsFrom": [ + "membership_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_spiritual_roots": { + "name": "wanjiedaoyou_spiritual_roots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "element": { + "name": "element", + "type": "varchar(10)", + "primaryKey": false, + "notNull": true + }, + "strength": { + "name": "strength", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "marrow_wash_bonus": { + "name": "marrow_wash_bonus", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "grade": { + "name": "grade", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": { + "spiritual_roots_cultivator_idx": { + "name": "spiritual_roots_cultivator_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_spiritual_roots_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_spiritual_roots_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_spiritual_roots", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sponsorship_admin_actions": { + "name": "wanjiedaoyou_sponsorship_admin_actions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "admin_user_id": { + "name": "admin_user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "order_id": { + "name": "order_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sponsorship_admin_actions_admin_created_idx": { + "name": "sponsorship_admin_actions_admin_created_idx", + "columns": [ + { + "expression": "admin_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sponsorship_admin_actions_order_created_idx": { + "name": "sponsorship_admin_actions_order_created_idx", + "columns": [ + { + "expression": "order_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sponsorship_admin_actions_order_id_wanjiedaoyou_sponsorship_orders_id_fk": { + "name": "wanjiedaoyou_sponsorship_admin_actions_order_id_wanjiedaoyou_sponsorship_orders_id_fk", + "tableFrom": "wanjiedaoyou_sponsorship_admin_actions", + "tableTo": "wanjiedaoyou_sponsorship_orders", + "columnsFrom": [ + "order_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sponsorship_checkout_intents": { + "name": "wanjiedaoyou_sponsorship_checkout_intents", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "tier": { + "name": "tier", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "expected_plan_id": { + "name": "expected_plan_id", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "public_listing": { + "name": "public_listing", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "status": { + "name": "status", + "type": "varchar(24)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "provider_order_id": { + "name": "provider_order_id", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "config_snapshot": { + "name": "config_snapshot", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sponsorship_checkout_provider_order_uidx": { + "name": "sponsorship_checkout_provider_order_uidx", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_order_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sponsorship_checkout_user_created_idx": { + "name": "sponsorship_checkout_user_created_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sponsorship_checkout_status_expires_idx": { + "name": "sponsorship_checkout_status_expires_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sponsorship_checkout_intents_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_sponsorship_checkout_intents_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_sponsorship_checkout_intents", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sponsorship_claims": { + "name": "wanjiedaoyou_sponsorship_claims", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "order_id": { + "name": "order_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "code_hash": { + "name": "code_hash", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "code": { + "name": "code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "public_listing": { + "name": "public_listing", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "status": { + "name": "status", + "type": "varchar(24)", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "claimed_at": { + "name": "claimed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "message_status": { + "name": "message_status", + "type": "varchar(24)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "message_attempts": { + "name": "message_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_message_error": { + "name": "last_message_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sponsorship_claims_order_uidx": { + "name": "sponsorship_claims_order_uidx", + "columns": [ + { + "expression": "order_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sponsorship_claims_code_hash_uidx": { + "name": "sponsorship_claims_code_hash_uidx", + "columns": [ + { + "expression": "code_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sponsorship_claims_status_expires_idx": { + "name": "sponsorship_claims_status_expires_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sponsorship_claims_order_id_wanjiedaoyou_sponsorship_orders_id_fk": { + "name": "wanjiedaoyou_sponsorship_claims_order_id_wanjiedaoyou_sponsorship_orders_id_fk", + "tableFrom": "wanjiedaoyou_sponsorship_claims", + "tableTo": "wanjiedaoyou_sponsorship_orders", + "columnsFrom": [ + "order_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "wanjiedaoyou_sponsorship_claims_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_sponsorship_claims_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_sponsorship_claims", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sponsorship_merit_profiles": { + "name": "wanjiedaoyou_sponsorship_merit_profiles", + "schema": "", + "columns": { + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "is_public": { + "name": "is_public", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "highest_tier": { + "name": "highest_tier", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "merit_count": { + "name": "merit_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "first_supported_at": { + "name": "first_supported_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "last_supported_at": { + "name": "last_supported_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sponsorship_merit_public_tier_first_idx": { + "name": "sponsorship_merit_public_tier_first_idx", + "columns": [ + { + "expression": "is_public", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "highest_tier", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "first_supported_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sponsorship_merit_profiles_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_sponsorship_merit_profiles_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_sponsorship_merit_profiles", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sponsorship_merit_records": { + "name": "wanjiedaoyou_sponsorship_merit_records", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "order_id": { + "name": "order_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "cultivator_id": { + "name": "cultivator_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "tier": { + "name": "tier", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "supported_at": { + "name": "supported_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "mail_id": { + "name": "mail_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sponsorship_merit_order_uidx": { + "name": "sponsorship_merit_order_uidx", + "columns": [ + { + "expression": "order_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sponsorship_merit_cultivator_supported_idx": { + "name": "sponsorship_merit_cultivator_supported_idx", + "columns": [ + { + "expression": "cultivator_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "supported_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sponsorship_merit_records_order_id_wanjiedaoyou_sponsorship_orders_id_fk": { + "name": "wanjiedaoyou_sponsorship_merit_records_order_id_wanjiedaoyou_sponsorship_orders_id_fk", + "tableFrom": "wanjiedaoyou_sponsorship_merit_records", + "tableTo": "wanjiedaoyou_sponsorship_orders", + "columnsFrom": [ + "order_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "wanjiedaoyou_sponsorship_merit_records_cultivator_id_wanjiedaoyou_cultivators_id_fk": { + "name": "wanjiedaoyou_sponsorship_merit_records_cultivator_id_wanjiedaoyou_cultivators_id_fk", + "tableFrom": "wanjiedaoyou_sponsorship_merit_records", + "tableTo": "wanjiedaoyou_cultivators", + "columnsFrom": [ + "cultivator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "wanjiedaoyou_sponsorship_merit_records_mail_id_wanjiedaoyou_mails_id_fk": { + "name": "wanjiedaoyou_sponsorship_merit_records_mail_id_wanjiedaoyou_mails_id_fk", + "tableFrom": "wanjiedaoyou_sponsorship_merit_records", + "tableTo": "wanjiedaoyou_mails", + "columnsFrom": [ + "mail_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sponsorship_order_snapshots": { + "name": "wanjiedaoyou_sponsorship_order_snapshots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "order_id": { + "name": "order_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "varchar(24)", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "purge_after": { + "name": "purge_after", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sponsorship_snapshots_order_created_idx": { + "name": "sponsorship_snapshots_order_created_idx", + "columns": [ + { + "expression": "order_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sponsorship_snapshots_purge_idx": { + "name": "sponsorship_snapshots_purge_idx", + "columns": [ + { + "expression": "purge_after", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sponsorship_order_snapshots_order_id_wanjiedaoyou_sponsorship_orders_id_fk": { + "name": "wanjiedaoyou_sponsorship_order_snapshots_order_id_wanjiedaoyou_sponsorship_orders_id_fk", + "tableFrom": "wanjiedaoyou_sponsorship_order_snapshots", + "tableTo": "wanjiedaoyou_sponsorship_orders", + "columnsFrom": [ + "order_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_sponsorship_orders": { + "name": "wanjiedaoyou_sponsorship_orders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "provider_order_id": { + "name": "provider_order_id", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "custom_order_id": { + "name": "custom_order_id", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "provider_user_id": { + "name": "provider_user_id", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "plan_id": { + "name": "plan_id", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "sku_id": { + "name": "sku_id", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "product_type": { + "name": "product_type", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "total_amount_fen": { + "name": "total_amount_fen", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "show_amount_fen": { + "name": "show_amount_fen", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "month": { + "name": "month", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "provider_status": { + "name": "provider_status", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "provider_created_at": { + "name": "provider_created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "verification_status": { + "name": "verification_status", + "type": "varchar(24)", + "primaryKey": false, + "notNull": true, + "default": "'received'" + }, + "fulfillment_status": { + "name": "fulfillment_status", + "type": "varchar(24)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "resolved_tier": { + "name": "resolved_tier", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + }, + "checkout_intent_id": { + "name": "checkout_intent_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "config_snapshot": { + "name": "config_snapshot", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "retry_count": { + "name": "retry_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_error_code": { + "name": "last_error_code", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "last_error_message": { + "name": "last_error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signature_verified_at": { + "name": "signature_verified_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "verified_at": { + "name": "verified_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "fulfilled_at": { + "name": "fulfilled_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "sensitive_purged_at": { + "name": "sensitive_purged_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sponsorship_orders_provider_order_uidx": { + "name": "sponsorship_orders_provider_order_uidx", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_order_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sponsorship_orders_verification_created_idx": { + "name": "sponsorship_orders_verification_created_idx", + "columns": [ + { + "expression": "verification_status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sponsorship_orders_fulfillment_created_idx": { + "name": "sponsorship_orders_fulfillment_created_idx", + "columns": [ + { + "expression": "fulfillment_status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sponsorship_orders_provider_user_idx": { + "name": "sponsorship_orders_provider_user_idx", + "columns": [ + { + "expression": "provider_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "wanjiedaoyou_sponsorship_orders_checkout_intent_id_wanjiedaoyou_sponsorship_checkout_intents_id_fk": { + "name": "wanjiedaoyou_sponsorship_orders_checkout_intent_id_wanjiedaoyou_sponsorship_checkout_intents_id_fk", + "tableFrom": "wanjiedaoyou_sponsorship_orders", + "tableTo": "wanjiedaoyou_sponsorship_checkout_intents", + "columnsFrom": [ + "checkout_intent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_tower_enemy_floors": { + "name": "wanjiedaoyou_tower_enemy_floors", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "season_key": { + "name": "season_key", + "type": "varchar(40)", + "primaryKey": false, + "notNull": true + }, + "realm": { + "name": "realm", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "floor": { + "name": "floor", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'ready'" + }, + "schema_version": { + "name": "schema_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "enemy": { + "name": "enemy", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "generated_at": { + "name": "generated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "tower_enemy_floors_season_realm_floor_uidx": { + "name": "tower_enemy_floors_season_realm_floor_uidx", + "columns": [ + { + "expression": "season_key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "realm", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "floor", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "tower_enemy_floors_realm_floor_generated_idx": { + "name": "tower_enemy_floors_realm_floor_generated_idx", + "columns": [ + { + "expression": "realm", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "floor", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "generated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "tower_enemy_floors_season_realm_status_idx": { + "name": "tower_enemy_floors_season_realm_status_idx", + "columns": [ + { + "expression": "season_key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "realm", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.wanjiedaoyou_transactional_messages": { + "name": "wanjiedaoyou_transactional_messages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "message_key": { + "name": "message_key", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "destination": { + "name": "destination", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "deduplication_key": { + "name": "deduplication_key", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "publish_attempts": { + "name": "publish_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_publish_error": { + "name": "last_publish_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "transactional_messages_dedupe_unique": { + "name": "transactional_messages_dedupe_unique", + "columns": [ + { + "expression": "message_key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "deduplication_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"wanjiedaoyou_transactional_messages\".\"deduplication_key\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "transactional_messages_pending_idx": { + "name": "transactional_messages_pending_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"wanjiedaoyou_transactional_messages\".\"published_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index abf53fe2..9903e7e0 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -215,9 +215,16 @@ { "idx": 30, "version": "7", - "when": 1786608971546, + "when": 1786549787086, "tag": "0030_smart_harpoon", "breakpoints": true + }, + { + "idx": 31, + "version": "7", + "when": 1786931826016, + "tag": "0031_damp_karnak", + "breakpoints": true } ] -} \ No newline at end of file +} diff --git a/public/assets/sponsors/changyehudao.webp b/public/assets/sponsors/changyehudao.webp new file mode 100644 index 00000000..79a378d6 Binary files /dev/null and b/public/assets/sponsors/changyehudao.webp differ diff --git a/public/assets/sponsors/gongzhengchangsheng.webp b/public/assets/sponsors/gongzhengchangsheng.webp new file mode 100644 index 00000000..19c1469e Binary files /dev/null and b/public/assets/sponsors/gongzhengchangsheng.webp differ diff --git a/public/assets/sponsors/shanshuitongcheng.webp b/public/assets/sponsors/shanshuitongcheng.webp new file mode 100644 index 00000000..f36810df Binary files /dev/null and b/public/assets/sponsors/shanshuitongcheng.webp differ diff --git a/public/assets/sponsors/yidengweiguang.webp b/public/assets/sponsors/yidengweiguang.webp new file mode 100644 index 00000000..fbb64851 Binary files /dev/null and b/public/assets/sponsors/yidengweiguang.webp differ diff --git a/src/react-app/components/feature/merit/MeritStamp.tsx b/src/react-app/components/feature/merit/MeritStamp.tsx new file mode 100644 index 00000000..a48de5ab --- /dev/null +++ b/src/react-app/components/feature/merit/MeritStamp.tsx @@ -0,0 +1,51 @@ +import { cn } from '@shared/lib/cn'; +import type { SponsorshipTierId } from '@shared/lib/sponsorship'; +import { SPONSORSHIP_TIER_META } from '@shared/lib/sponsorship'; + +type MeritStampPresentation = { + stampSrc: string; + stampClassName: string; +}; + +const MERIT_STAMP_PRESENTATION: Record< + SponsorshipTierId, + MeritStampPresentation +> = { + faint_light: { + stampSrc: '/assets/sponsors/yidengweiguang.webp', + stampClassName: 'rotate-[1.5deg]', + }, + fellow_traveler: { + stampSrc: '/assets/sponsors/shanshuitongcheng.webp', + stampClassName: '-rotate-[1deg]', + }, + night_guardian: { + stampSrc: '/assets/sponsors/changyehudao.webp', + stampClassName: 'rotate-[0.5deg]', + }, + immortality_witness: { + stampSrc: '/assets/sponsors/gongzhengchangsheng.webp', + stampClassName: '-rotate-[0.5deg]', + }, +}; + +export function MeritStamp({ + tier, + className, +}: { + tier: SponsorshipTierId; + className?: string; +}) { + const presentation = MERIT_STAMP_PRESENTATION[tier]; + return ( + {`${SPONSORSHIP_TIER_META[tier].name}印戳`} + ); +} diff --git a/src/react-app/components/feature/retreat/BreakthroughChanceDetails.tsx b/src/react-app/components/feature/retreat/BreakthroughChanceDetails.tsx new file mode 100644 index 00000000..82f4a40a --- /dev/null +++ b/src/react-app/components/feature/retreat/BreakthroughChanceDetails.tsx @@ -0,0 +1,54 @@ +import { cn } from '@shared/lib/utils'; +import { format } from 'd3-format'; +import type { BreakthroughChancePresentation } from './breakthroughChancePresentation'; + +function formatPercent(value: number): string { + return format('.1%')(value); +} + +export function BreakthroughChanceDetails({ + presentation, + className, +}: { + presentation: BreakthroughChancePresentation; + className?: string; +}) { + return ( +
+
+
+

综合基础率

+

+ {formatPercent(presentation.adjustedBaseChance)} +

+
+
+

最终成功率

+

+ {formatPercent(presentation.finalChance)} +

+
+
+ + {presentation.factors.length > 0 ? ( +
+ {presentation.factors.map((factor) => ( + + {factor.label} + {factor.value} + + ))} +
+ ) : null} +
+ ); +} diff --git a/src/react-app/components/feature/retreat/BreakthroughConfirmModal.tsx b/src/react-app/components/feature/retreat/BreakthroughConfirmModal.tsx index cfdad49e..4eba5594 100644 --- a/src/react-app/components/feature/retreat/BreakthroughConfirmModal.tsx +++ b/src/react-app/components/feature/retreat/BreakthroughConfirmModal.tsx @@ -1,6 +1,6 @@ import { InkModal } from '@app/components/layout'; import { InkButton } from '@app/components/ui/InkButton'; -import { format } from 'd3-format'; +import { BreakthroughChanceDetails } from './BreakthroughChanceDetails'; import type { BreakthroughChancePreviewData } from './useRetreatViewModel'; interface BreakthroughConfirmModalProps { @@ -77,19 +77,9 @@ export function BreakthroughConfirmModal({ {chancePreview && ( -
+

【当前成功率推演】

-

- 基础成功率:{format('.1%')(Math.min(chancePreview.baseChance, 1))} -

- {chancePreview.buffBonus > 0 && ( -

- 外物与机缘加成:+{format('.1%')(chancePreview.buffBonus)} -

- )} -

- 最终成功率:{format('.1%')(Math.min(chancePreview.finalChance, 1))} -

+
)} diff --git a/src/react-app/components/feature/retreat/RetreatResultModal.tsx b/src/react-app/components/feature/retreat/RetreatResultModal.tsx index 374409c2..7b09baa0 100644 --- a/src/react-app/components/feature/retreat/RetreatResultModal.tsx +++ b/src/react-app/components/feature/retreat/RetreatResultModal.tsx @@ -10,6 +10,8 @@ import type { Attributes } from '@shared/types/cultivator'; import { getAttributeInfo } from '@shared/lib/gameConceptDisplay'; import { format } from 'd3-format'; import { useMemo } from 'react'; +import { BreakthroughChanceDetails } from './BreakthroughChanceDetails'; +import { buildBreakthroughChancePresentation } from './breakthroughChancePresentation'; import { isSuccessfulBreakthrough } from './retreatStream'; const COMPREHENSION_LABEL = getGameConceptLabel('comprehension_insight'); @@ -147,14 +149,10 @@ function BreakthroughResultContent({ retreatResult: RetreatResultData; }) { const summary = retreatResult.summary as BreakthroughResult['summary']; - const buffBonus = Math.max( - 0, - (summary.modifiers?.pillBonus ?? 0) + (summary.modifiers?.fateBonus ?? 0), - ); - const displayedBaseChance = Math.max( - 0, - Math.min(1, summary.chance - buffBonus), - ); + const chancePresentation = buildBreakthroughChancePresentation({ + modifiers: summary.modifiers, + finalChance: summary.chance, + }); const realmChangeText = summary.success && summary.toRealm && summary.toStage ? `${summary.fromRealm}${summary.fromStage} → ${summary.toRealm}${summary.toStage}` @@ -185,14 +183,10 @@ function BreakthroughResultContent({ {summary.success ? '🌅 突破成功!' : '☁️ 冲关失败'}

-

成功率 {format('.1%')(Math.min(summary.chance, 1))}

- {buffBonus > 0 ? ( -

- 机缘加成:+{format('.1%')(buffBonus)}( - {format('.1%')(displayedBaseChance)} →{' '} - {format('.1%')(Math.min(summary.chance, 1))}) -

- ) : null} +
+

【本次成功率推演】

+ +
{realmChangeText ?

境界突破:{realmChangeText}

: null} diff --git a/src/react-app/components/feature/retreat/RetreatView.tsx b/src/react-app/components/feature/retreat/RetreatView.tsx index f3c6a313..2ab646bc 100644 --- a/src/react-app/components/feature/retreat/RetreatView.tsx +++ b/src/react-app/components/feature/retreat/RetreatView.tsx @@ -14,6 +14,7 @@ import { cn } from '@shared/lib/utils'; import { useState } from 'react'; import { useNavigate } from 'react-router'; import { BreakthroughConfirmModal } from './BreakthroughConfirmModal'; +import { BreakthroughChanceDetails } from './BreakthroughChanceDetails'; import type { RetreatBuffTag, RetreatEfficiencyModel, @@ -21,6 +22,7 @@ import type { import { RetreatResultModal } from './RetreatResultModal'; import { useRetreatViewModel, + type BreakthroughChancePreviewData, type CultivationProgressData, } from './useRetreatViewModel'; @@ -319,6 +321,7 @@ function BreakthroughPanel({ cultivationProgress, canAttemptBreakthrough, guidanceText, + breakthroughPreview, retreatEfficiency, isMajorBreakthrough, majorBreakthroughBlocked, @@ -332,6 +335,7 @@ function BreakthroughPanel({ cultivationProgress: CultivationProgressData | null; canAttemptBreakthrough: boolean; guidanceText: string; + breakthroughPreview: BreakthroughChancePreviewData | null; retreatEfficiency: RetreatEfficiencyModel | null; isMajorBreakthrough: boolean; majorBreakthroughBlocked: boolean; @@ -361,7 +365,21 @@ function BreakthroughPanel({ ) : null} {guidanceText}
- + {breakthroughPreview ? ( +
+

成功率推演

+ +
+ ) : null} + + {(retreatEfficiency?.breakthroughTags.length ?? 0) > 0 ? ( +
+

破境准备

+ +
+ ) : null} {isMajorBreakthrough ? ( @@ -610,6 +628,7 @@ export function RetreatView({ sectContext }: RetreatViewProps) { cultivationProgress={cultivationProgress} canAttemptBreakthrough={canAttemptBreakthrough} guidanceText={guidanceText} + breakthroughPreview={breakthroughPreview} retreatEfficiency={retreatEfficiency} isMajorBreakthrough={isMajorBreakthrough} majorBreakthroughBlocked={majorBreakthroughBlocked} diff --git a/src/react-app/components/feature/retreat/breakthroughChancePresentation.ts b/src/react-app/components/feature/retreat/breakthroughChancePresentation.ts new file mode 100644 index 00000000..260d7987 --- /dev/null +++ b/src/react-app/components/feature/retreat/breakthroughChancePresentation.ts @@ -0,0 +1,109 @@ +import type { BreakthroughModifiers } from '@server/utils/breakthroughCalculator'; +import { format } from 'd3-format'; + +export type BreakthroughFactorTone = 'positive' | 'warning' | 'neutral'; + +export interface BreakthroughChanceFactor { + key: string; + label: string; + value: string; + tone: BreakthroughFactorTone; +} + +export interface BreakthroughChancePresentation { + adjustedBaseChance: number; + finalChance: number; + factors: BreakthroughChanceFactor[]; +} + +function formatPercent(value: number): string { + return format('.1%')(value); +} + +function formatSignedPercent(value: number): string { + if (value === 0) return '+0.0%'; + return `${value > 0 ? '+' : '-'}${formatPercent(Math.abs(value))}`; +} + +function getDeltaTone(value: number): BreakthroughFactorTone { + if (value > 0) return 'positive'; + if (value < 0) return 'warning'; + return 'neutral'; +} + +function getMultiplierTone(value: number): BreakthroughFactorTone { + if (value > 1) return 'positive'; + if (value < 1) return 'warning'; + return 'neutral'; +} + +export function buildBreakthroughChancePresentation(input: { + modifiers: BreakthroughModifiers; + finalChance?: number; +}): BreakthroughChancePresentation { + const { modifiers } = input; + const factors: BreakthroughChanceFactor[] = []; + + if (modifiers.realmDifficulty !== 1) { + factors.push({ + key: 'realm', + label: '境界难度', + value: `×${formatPercent(modifiers.realmDifficulty)}`, + tone: getMultiplierTone(modifiers.realmDifficulty), + }); + } + if (modifiers.progressMultiplier !== 1) { + factors.push({ + key: 'progress', + label: '修为进度', + value: `×${formatPercent(modifiers.progressMultiplier)}`, + tone: getMultiplierTone(modifiers.progressMultiplier), + }); + } + if (modifiers.insightMultiplier !== 1) { + factors.push({ + key: 'insight', + label: '道行感悟', + value: `×${formatPercent(modifiers.insightMultiplier)}`, + tone: getMultiplierTone(modifiers.insightMultiplier), + }); + } + if (modifiers.demonPenalty !== 1) { + factors.push({ + key: 'inner-demon', + label: '心魔影响', + value: `×${formatPercent(modifiers.demonPenalty)}`, + tone: getMultiplierTone(modifiers.demonPenalty), + }); + } + if (modifiers.fateBonus !== 0) { + factors.push({ + key: 'fate', + label: '命格机缘', + value: formatSignedPercent(modifiers.fateBonus), + tone: getDeltaTone(modifiers.fateBonus), + }); + } + if (modifiers.pillBonus !== 0) { + factors.push({ + key: 'pill', + label: '破境药力', + value: formatSignedPercent(modifiers.pillBonus), + tone: getDeltaTone(modifiers.pillBonus), + }); + } + if (modifiers.toxicityPenalty !== 0) { + factors.push({ + key: 'toxicity', + label: '丹毒惩罚', + value: `-${formatPercent(modifiers.toxicityPenalty)}`, + tone: 'warning', + }); + } + + return { + adjustedBaseChance: modifiers.adjustedBaseChance, + finalChance: input.finalChance ?? modifiers.finalChance, + factors, + }; +} diff --git a/src/react-app/components/feature/retreat/useRetreatViewModel.tsx b/src/react-app/components/feature/retreat/useRetreatViewModel.tsx index 62c13c9a..94b7d03a 100644 --- a/src/react-app/components/feature/retreat/useRetreatViewModel.tsx +++ b/src/react-app/components/feature/retreat/useRetreatViewModel.tsx @@ -34,6 +34,10 @@ import { buildRetreatEfficiencyModel, type RetreatEfficiencyModel, } from './retreatEfficiency'; +import { + buildBreakthroughChancePresentation, + type BreakthroughChancePresentation, +} from './breakthroughChancePresentation'; export interface CultivationProgressData { cultivation_exp: number; @@ -58,10 +62,8 @@ type RetreatCultivatorView = Pick< cultivation_progress: NonNullable; }; -export interface BreakthroughChancePreviewData { - baseChance: number; - finalChance: number; - buffBonus: number; +export interface BreakthroughChancePreviewData + extends BreakthroughChancePresentation { recommendation: string; } @@ -227,31 +229,19 @@ export function useRetreatViewModel(): UseRetreatViewModelReturn { useMemo((): BreakthroughChancePreviewData | null => { if ( !cultivator || - !cultivationProgress?.canBreakthrough || - (isMajorBreakthrough && majorBreakthroughBlocked) + !cultivationProgress?.canBreakthrough ) { return null; } try { const result = calculateBreakthroughChance(cultivator); - const baseChance = Math.min( - 1, - Math.max( - 0.05, - result.modifiers.baseChance * - result.modifiers.realmDifficulty * - result.modifiers.progressMultiplier * - result.modifiers.insightMultiplier * - result.modifiers.demonPenalty + - result.modifiers.toxicityPenalty, - ), - ); return { - baseChance, - finalChance: result.chance, - buffBonus: result.modifiers.pillBonus + result.modifiers.fateBonus, + ...buildBreakthroughChancePresentation({ + modifiers: result.modifiers, + finalChance: result.chance, + }), recommendation: result.recommendation, }; } catch { @@ -260,8 +250,6 @@ export function useRetreatViewModel(): UseRetreatViewModelReturn { }, [ cultivator, cultivationProgress?.canBreakthrough, - isMajorBreakthrough, - majorBreakthroughBlocked, ]); const handleRetreatYearsChange = useCallback((value: string) => { diff --git a/src/react-app/components/game-shell/GameTopHud.tsx b/src/react-app/components/game-shell/GameTopHud.tsx index 9bd79352..edcc7a58 100644 --- a/src/react-app/components/game-shell/GameTopHud.tsx +++ b/src/react-app/components/game-shell/GameTopHud.tsx @@ -3,6 +3,7 @@ import { MarrowWashSummaryContent, } from '@app/components/feature/cultivator/BodyCultivationPanels'; import { useQiState } from '@app/components/feature/cultivator/useQiState'; +import { MeritStamp } from '@app/components/feature/merit/MeritStamp'; import { getSectIdentityLabels } from '@app/components/feature/sect/sectIdentityDisplay'; import { useActiveSectContextQuery } from '@app/components/feature/sect/sectResources'; import { useSectIdentityDialog } from '@app/components/feature/sect/useSectIdentityDialog'; @@ -24,10 +25,49 @@ import { } from '@shared/config/qiSystem'; import { cn } from '@shared/lib/cn'; import { getGameConceptInfo } from '@shared/lib/gameConceptDisplay'; +import type { SponsorshipTierId } from '@shared/lib/sponsorship'; import type { ReactNode } from 'react'; +import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router'; import type { GameHudSnapshot } from './useGameHudModel'; +type MeritProfileResponse = { + profile: { highestTier: SponsorshipTierId } | null; +}; + +function usePlayerMeritTier( + cultivatorId: string | undefined, +): SponsorshipTierId | null { + const [tier, setTier] = useState(null); + + useEffect(() => { + if (!cultivatorId) return; + + let cancelled = false; + fetch('/api/sponsorship/me') + .then(async (response) => { + const data = (await response.json()) as + MeritProfileResponse | { error?: string }; + if (!response.ok) { + throw new Error('error' in data ? data.error : '请求失败'); + } + return data as MeritProfileResponse; + }) + .then((data) => { + if (!cancelled) setTier(data.profile?.highestTier ?? null); + }) + .catch(() => { + if (!cancelled) setTier(null); + }); + + return () => { + cancelled = true; + }; + }, [cultivatorId]); + + return tier; +} + function HudMeter({ label, display, @@ -295,6 +335,7 @@ export function GameTopHud({ snapshot }: { snapshot: GameHudSnapshot | null }) { } = useQiState({ cultivatorId: snapshot?.cultivatorId ?? '', }); + const meritTier = usePlayerMeritTier(snapshot?.cultivatorId); if (!snapshot) return ; @@ -764,6 +805,12 @@ export function GameTopHud({ snapshot }: { snapshot: GameHudSnapshot | null }) { > {snapshot.name} + {meritTier ? ( + + ) : null} {snapshot.title ? (
「{snapshot.title}」 diff --git a/src/react-app/components/game-shell/gameNavigation.ts b/src/react-app/components/game-shell/gameNavigation.ts index 7d37b37a..5197a65f 100644 --- a/src/react-app/components/game-shell/gameNavigation.ts +++ b/src/react-app/components/game-shell/gameNavigation.ts @@ -326,6 +326,12 @@ export const gameDockGroups: GameNavGroup[] = [ href: '/game/redeem', expandedDockLabel: '🎁 兑换码', }, + { + id: 'merit-ledger', + sceneLabel: '功德簿', + href: '/game/merit-ledger', + expandedDockLabel: '📜 功德簿', + }, { id: 'community', sceneLabel: '玩家交流群', diff --git a/src/react-app/lib/resources/player.ts b/src/react-app/lib/resources/player.ts index d6131cec..c6e96c23 100644 --- a/src/react-app/lib/resources/player.ts +++ b/src/react-app/lib/resources/player.ts @@ -37,10 +37,14 @@ export function usePlayerLoadout(enabled = true) { } export function useUnreadMailCount() { - const query = useSingletonResource(playerMailSummaryResource); + const query = usePlayerMailSummary(); return query.data?.unreadCount; } +export function usePlayerMailSummary() { + return useSingletonResource(playerMailSummaryResource); +} + export function useTaskSummary() { return useSingletonResource(playerTaskSummaryResource); } diff --git a/src/react-app/router.tsx b/src/react-app/router.tsx index f1070b64..39638398 100644 --- a/src/react-app/router.tsx +++ b/src/react-app/router.tsx @@ -909,6 +909,14 @@ export const router = createBrowserRouter( '兑换码', )} /> + import('@app/routes/game/merit-ledger/route'))} + handle={scene( + { id: 'merit-ledger', presentation: 'service', summary: '记同行之缘,不录金额与次数。' }, + '功德簿', + )} + /> import('@app/routes/game/settings/route'))} @@ -1244,6 +1252,11 @@ export const router = createBrowserRouter( )} handle={title('新建兑换码')} /> + import('@app/routes/admin/sponsorship/route'))} + handle={title('功德簿管理')} + /> import('@app/routes/admin/llm-metrics/route'))} diff --git a/src/react-app/routes/admin/_config/nav.ts b/src/react-app/routes/admin/_config/nav.ts index 62d6fa50..2c992290 100644 --- a/src/react-app/routes/admin/_config/nav.ts +++ b/src/react-app/routes/admin/_config/nav.ts @@ -60,6 +60,11 @@ export const adminNavItems: AdminNavItem[] = [ description: '活动兑换码创建与停用', href: '/admin/redeem-codes', }, + { + title: '功德簿管理', + description: '爱发电映射、订单与认领处理', + href: '/admin/sponsorship', + }, { title: 'LLM 观测', description: '查看场景体积、usage 与缓存迹象', diff --git a/src/react-app/routes/admin/sponsorship/route.tsx b/src/react-app/routes/admin/sponsorship/route.tsx new file mode 100644 index 00000000..97aee9bc --- /dev/null +++ b/src/react-app/routes/admin/sponsorship/route.tsx @@ -0,0 +1,495 @@ +import { InkButton } from '@app/components/ui/InkButton'; +import { + SPONSORSHIP_TIER_IDS, + SPONSORSHIP_TIER_META, + type SponsorshipTierId, +} from '@shared/lib/sponsorship'; +import { useCallback, useEffect, useState } from 'react'; + +type TierConfig = { planId: string; minimumAmountFen: number }; +type Config = { + ordersAcceptedAfter: string | null; + tiers: Record; +}; +type Order = { + id: string; + providerOrderId: string; + resolvedTier: SponsorshipTierId | null; + verificationStatus: string; + fulfillmentStatus: string; + lastErrorMessage: string | null; + createdAt: string; +}; +type OrderDetail = { + order: Order; + claims: { + id: string; + status: string; + messageStatus: string; + expiresAt: string; + }[]; + records: { + id: string; + cultivatorId: string; + tier: SponsorshipTierId; + revokedAt: string | null; + }[]; + snapshots: { + id: string; + source: string; + createdAt: string; + purgeAfter: string; + }[]; +}; +type OrderFilter = + 'all' | 'attention' | 'awaiting_claim' | 'fulfilled' | 'revoked'; + +async function request(url: string, init?: RequestInit): Promise { + const response = await fetch(url, init); + const data = await response.json(); + if (!response.ok) throw new Error(data.error ?? '请求失败'); + return data as T; +} + +export default function SponsorshipAdminPage() { + const [config, setConfig] = useState(null); + const [orders, setOrders] = useState([]); + const [message, setMessage] = useState(''); + const [cultivatorId, setCultivatorId] = useState(''); + const [manualTier, setManualTier] = + useState('faint_light'); + const [manualSupportedAt, setManualSupportedAt] = useState(''); + const [manualPublic, setManualPublic] = useState(true); + const [manualSendMail, setManualSendMail] = useState(true); + const [orderFilter, setOrderFilter] = useState('all'); + const [orderPage, setOrderPage] = useState(1); + const [orderTotal, setOrderTotal] = useState(0); + const [busy, setBusy] = useState(false); + const [detail, setDetail] = useState(null); + const [revealedSnapshot, setRevealedSnapshot] = useState(null); + + const load = useCallback(async () => { + const [nextConfig, nextOrders] = await Promise.all([ + request('/api/admin/sponsorship/config'), + request<{ orders: Order[]; total: number }>( + `/api/admin/sponsorship/orders?page=${orderPage}&pageSize=50&filter=${orderFilter}`, + ), + ]); + setConfig(nextConfig); + setOrders(nextOrders.orders); + setOrderTotal(nextOrders.total); + }, [orderFilter, orderPage]); + useEffect(() => { + void (async () => { + try { + await load(); + } catch (error) { + setMessage(error instanceof Error ? error.message : '加载失败'); + } + })(); + }, [load]); + + const save = async () => { + if (!config) return; + setBusy(true); + try { + await request('/api/admin/sponsorship/config', { + method: 'PUT', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify({ tiers: config.tiers }), + }); + await load(); + setMessage('档位映射已保存'); + } finally { + setBusy(false); + } + }; + const act = async ( + orderId: string, + action: 'retry' | 'revoke' | 'rotate-claim', + ) => { + if ( + action === 'revoke' && + !window.confirm( + '确认撤销该订单的功德记录?此操作会重新计算角色最高档位。', + ) + ) + return; + setBusy(true); + try { + await request(`/api/admin/sponsorship/orders/${orderId}/${action}`, { + method: 'POST', + }); + await load(); + setMessage('操作完成'); + } finally { + setBusy(false); + } + }; + const manualGrant = async () => { + if (!window.confirm('确认向该角色手动写入历史功德?')) return; + setBusy(true); + try { + await request('/api/admin/sponsorship/manual-grants', { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify({ + cultivatorId, + tier: manualTier, + supportedAt: manualSupportedAt + ? new Date(manualSupportedAt).toISOString() + : undefined, + publicListing: manualPublic, + sendMail: manualSendMail, + }), + }); + setCultivatorId(''); + setManualSupportedAt(''); + setMessage('历史功德已手动发放'); + } finally { + setBusy(false); + } + }; + const showDetail = async (orderId: string) => { + setRevealedSnapshot(null); + setDetail( + await request(`/api/admin/sponsorship/orders/${orderId}`), + ); + }; + const revealSnapshot = async (snapshotId: string) => { + if (!window.confirm('原始快照可能包含支付相关敏感信息,确认审计查看?')) + return; + const result = await request<{ snapshot: unknown }>( + `/api/admin/sponsorship/snapshots/${snapshotId}/reveal`, + { method: 'POST' }, + ); + setRevealedSnapshot(result.snapshot); + }; + + return ( +
+
+

+ SPONSORSHIP +

+

功德簿管理

+

+ 配置爱发电方案映射,核查订单、重试认领与手动处理历史订单。 +

+
+ {message &&

{message}

} +
+

档位映射

+

+ 仅方案 ID 与最低金额(分)可修改,档位名称和主题固定在代码中。 +

+ {config?.ordersAcceptedAfter && ( +

+ 自动处理起始: + {new Date(config.ordersAcceptedAfter).toLocaleString('zh-CN')} + (更早订单仅手动发放) +

+ )} +
+ {config && + SPONSORSHIP_TIER_IDS.map((tier) => ( + + ))} +
+
+ + void save().catch((error) => setMessage(error.message)) + } + > + 保存映射 + + + void request('/api/admin/sponsorship/ping', { method: 'POST' }) + .then(() => setMessage('爱发电连接正常')) + .catch((error) => setMessage(error.message)) + } + > + 测试连接 + +
+
+
+

历史手动发放

+
+ setCultivatorId(event.target.value)} + placeholder="角色 UUID" + /> + + setManualSupportedAt(event.target.value)} + /> + + + + void manualGrant().catch((error) => setMessage(error.message)) + } + > + 手动发放 + +
+
+
+
+

订单

+ +
+ + + + + + + + + + + + + {orders.map((order) => ( + + + + + + + + + ))} + +
订单档位校验履约错误操作
{order.providerOrderId} + {order.resolvedTier + ? SPONSORSHIP_TIER_META[order.resolvedTier].name + : '-'} + {order.verificationStatus}{order.fulfillmentStatus} + {order.lastErrorMessage ?? '-'} + + + + + +
+
+ setOrderPage((page) => page - 1)} + > + 上一页 + + + 第 {orderPage} 页 · 共 {orderTotal} 条 + + = orderTotal || busy} + onClick={() => setOrderPage((page) => page + 1)} + > + 下一页 + +
+
+ {detail && ( +
+

订单详情 · {detail.order.providerOrderId}

+
+
+

认领

+ {detail.claims.length ? ( + detail.claims.map((claim) => ( +

+ {claim.status} · 私信 {claim.messageStatus} ·{' '} + {new Date(claim.expiresAt).toLocaleString('zh-CN')} +

+ )) + ) : ( +

无认领码

+ )} +
+
+

功德记录

+ {detail.records.map((record) => ( +

+ {record.cultivatorId} ·{' '} + {SPONSORSHIP_TIER_META[record.tier].name} + {record.revokedAt ? ' · 已撤销' : ''} +

+ ))} +
+
+
+

原始快照

+

+ 查看会写入管理员审计日志,请仅在排障时使用。 +

+ {detail.snapshots.map((snapshot) => ( +
+ + {snapshot.source} ·{' '} + {new Date(snapshot.createdAt).toLocaleString('zh-CN')} + + +
+ ))} + {revealedSnapshot !== null && ( +
+                {JSON.stringify(revealedSnapshot, null, 2)}
+              
+ )} +
+
+ )} +
+ ); +} diff --git a/src/react-app/routes/game/merit-ledger/components/MeritTierCard.tsx b/src/react-app/routes/game/merit-ledger/components/MeritTierCard.tsx new file mode 100644 index 00000000..31ca1a1a --- /dev/null +++ b/src/react-app/routes/game/merit-ledger/components/MeritTierCard.tsx @@ -0,0 +1,104 @@ +import { MeritStamp } from '@app/components/feature/merit/MeritStamp'; +import { cn } from '@shared/lib/cn'; +import type { SponsorshipTierId } from '@shared/lib/sponsorship'; +import { SPONSORSHIP_TIER_META } from '@shared/lib/sponsorship'; +import type { ReactNode } from 'react'; + +type TierPresentation = { + cardClassName: string; + ruleClassName: string; +}; + +const MERIT_TIER_PRESENTATION: Record = { + faint_light: { + cardClassName: + 'border-[#9a7954]/55 bg-[#ede0c5] text-[#2a1a12] shadow-[0_6px_18px_rgba(72,45,24,0.06)]', + ruleClassName: 'bg-[#7c5b39]/55', + }, + fellow_traveler: { + cardClassName: + 'border-[#718084]/55 bg-[#dce2e0] text-[#253034] shadow-[0_6px_18px_rgba(45,62,64,0.06)]', + ruleClassName: 'bg-[#596a6e]/55', + }, + night_guardian: { + cardClassName: + 'border-[#b69649]/70 bg-[#27241e] text-[#d7b666] shadow-[0_8px_20px_rgba(21,17,11,0.16)]', + ruleClassName: 'bg-[#c6a653]/65', + }, + immortality_witness: { + cardClassName: + 'border-[#9e9a64]/55 bg-[#e4e4d2] text-[#292719] shadow-[0_6px_18px_rgba(64,61,34,0.06)]', + ruleClassName: 'bg-[#77733f]/55', + }, +}; + +function CardCorner({ className }: { className: string }) { + return ( +